Skip to content

Native explode returns wrong booleans for arrays of structs after the first batch of output #6464

Closed

Description

@andygrove

Describe the bug

In 1.1.0-rc1, explode, posexplode and explode_outer of an array of structs with a boolean field return wrong booleans and misplaced NULLs once an input batch explodes to more than spark.comet.batchSize rows. This happens with default configs. 1.0.0 returns the right answer for the same queries.

#5362 split the native explode output into chunks of at most spark.comet.batchSize rows, and #5667 slices each chunk out of the child arrays instead of gathering it with take. A sliced struct keeps a bit offset on its boolean children. Arrow Java ignores that offset when it imports the batch (#6288), so the JVM reads those booleans from the start of the buffer. An exploded top-level boolean goes wrong the same way when a native named_struct wraps it or a boolean Scala UDF reads it.

Steps to reproduce

withTempPath { dir =>
  val path = dir.getCanonicalPath
  withSQLConf(CometConf.COMET_ENABLED.key -> "false") {
    spark
      .range(0, 3000, 1, 1)
      .selectExpr(
        "id",
        "transform(sequence(0, 11), i -> named_struct(" +
          "'b', hash(id, i) % 2 = 0, " +
          "'bn', IF(hash(id, i, 7) % 5 = 0, NULL, hash(id, i, 3) % 2 = 0), " +
          "'n', id * 12 + i)) AS arr")
      .write
      .parquet(path)
  }
  spark.read.parquet(path).createOrReplaceTempView("t")
  checkSparkAnswer(sql("SELECT id, s FROM t LATERAL VIEW explode(arr) x AS s"))
}

The native explode runs at both 1.0.0 and rc1. On rc1, 22,824 of the 36,000 rows differ from Spark, starting at output row 8,184, the first row of the second chunk. n is right everywhere, and b and bn are wrong.

Expected behavior

The same rows as Spark, as in 1.0.0.

Additional context

#6339 fixes #6288 on main by zeroing boolean offsets at every level before export, and its branch-1.1 backport, #6449, fixes all of these queries on rc1. This was found by the 1.1.0 regression audit in #6399 and is tracked in #6402.

Activity

  1. self-assigned this
    on Sep 30, 2026
  2. added
    bugSomething isn't working
    regressionA bug that did not affect the most recent Comet release
    on Sep 30, 2026
  3. andygrove commented on Sep 30, 2026

    @andygrove
    MemberAuthor

    This is already fixed on main by #6339, and the reproducer above passes there. None of #6339's tests go through explode, though, so #6473 adds tests for explode, explode_outer, posexplode and posexplode_outer of structs with boolean fields, for a single row longer than the batch size, and for a native named_struct and a boolean Scala UDF over an exploded boolean. They all fail when native goes back to zeroing only the top-level offsets, which is what rc1 does.

    For branch-1.1 the fix is still #6449. Once it merges, the new tests can be cherry-picked there too.

  4. andygrove commented on Sep 30, 2026

    @andygrove
    MemberAuthor

    #6449 is now merged, so this is fixed on branch-1.1 as well as main. The merged code is identical to the backport I ran the reproducers against.

  5. added a commit that references this issue on Oct 1, 2026
    85316e8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingcorrectnessregressionA bug that did not affect the most recent Comet releaserequires-triage

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions