Skip to content

fix: [branch-1.0] backport four bug fixes for 1.0.1 - #5321

Open
andygrove wants to merge 4 commits into
apache:branch-1.0from
andygrove:backport-fixes-branch-1.0
Open

fix: [branch-1.0] backport four bug fixes for 1.0.1#5321
andygrove wants to merge 4 commits into
apache:branch-1.0from
andygrove:backport-fixes-branch-1.0

Conversation

@andygrove

Copy link
Copy Markdown
Member

Which issue does this PR close?

This backports fixes for the following issues to branch-1.0, for a 1.0.1 patch release:

Rationale for this change

1.0.0 was released from branch-1.0, and four bug fixes have merged to main since the branch point. All four are user-visible failures rather than enhancements, so they belong in a patch release:

main also carries #5225 (duplicate CheckOverflow evaluation for decimal division). That one is deliberately excluded: #5190 is labeled enhancement, the double wrapper produces correct results in LEGACY, TRY, and ANSI modes, and the fix reorganizes ownership of decimal overflow wrapping, which is more churn than a patch release warrants.

What changes are included in this PR?

Four clean cherry-picks from main, in merge order, with no conflicts and no changes to the original commits:

How are these changes tested?

Each cherry-pick carries the regression tests from its original PR. Verified on this branch:

  • make (native plus all Maven modules, Spark 4.1): BUILD SUCCESS
  • cargo test -p datafusion-comet-common -p datafusion-comet-spark-expr -p datafusion-comet: 793 passed, 0 failed, covering the new native/common/src/schema.rs and the rewritten negative.rs
  • CometScalaUDFClassLoaderSuite and CometTemporalExpressionSuite: 37 tests, 0 failures, including ScalaUDF closure captured by a user-jar class for both nativeScan=true and nativeScan=false, and next_day and make_date ANSI errors match Spark exceptions
  • CometExpressionSuite unary negation tests: 3 tests, 0 failures, including unary negative integer overflow test
  • dev/ci/check-suites.py: passes, with CometScalaUDFClassLoaderSuite registered in both pr_build_linux.yml and pr_build_macos.yml

Smallfu666 and others added 4 commits August 9, 2026 09:08
…#5162)

* fix: skip null slots when checking overflow in unary negation (apache#5093)

* review: collapse ANSI negate dispatch, pin interval null regression

Addresses review feedback on apache#5162:
- Collapse the five near-identical array arms into a from_type lookup and
  rename map_neg_error's parameter to match the SparkError field.
- Pin the interval half of the regression: a MIN sentinel in a *null* slot for
  Interval(YearMonth) and the whole Interval(DayTime)::MIN value both raised a
  spurious ANSI overflow, because the pre-scan walked value(i) without
  consulting the null buffer.
- Reposition the single-component DayTime cases as error-mapping coverage: they
  already failed before this PR (neg_wrapping delegates to neg for every
  non-integer type), just with a raw ArrowError instead of a Spark error, so the
  failure set is unchanged.
- Use "byte" / "short" as from_type for Int8/Int16 on both the array and
  scalar paths. The scalar arms previously passed a bare " caused", rendering
  as "[ARITHMETIC_OVERFLOW]  caused overflow.". No string matches every Spark
  version here -- 3.4/3.5 throw _LEGACY_ERROR_TEMP_2043 ("- <sqlValue> caused
  overflow.") while 4.x uses MathUtils.negateExact ("byte overflow") -- and
  since the shims always render ARITHMETIC_OVERFLOW, the 3.x class is out of
  reach regardless. "byte"/"short" is exact on 4.x and needs no hardcoded value.
- Turn the byte/short dtype placeholders in CometExpressionSuite's unary
  negative overflow test into version-specific Spark and Comet byte/short
  overflow assertions.
- Drop the stale supported-datatypes comment and record why the fallthrough is
  still overflow-safe.
- Deduplicate the per-width test bodies behind generic helpers and give the
  let-else arms diagnostic panic messages.

---------

Co-authored-by: Andy Grove <agrove@apache.org>
(cherry picked from commit 5783793)
…Exec (apache#5138)

* fix: normalize nested field nullability in ShuffleScanExec and ExpandExec

Arrow treats nested field nullability as part of `DataType` identity, so
`RecordBatch::try_new_with_options` rejects a column whose nested `nullable`
flags are narrower than the declared type even though the data is fine — a
non-null child is a strict subset of a nullable one.

Most Comet boundaries already normalize instead of asserting (`ScanExec` casts
at the FFI boundary, `SchemaAlignExec` casts the shuffle writer's input,
`CometLocalTableScanExec` widens with `.asNullable`), which is why this drift is
usually invisible. Two stamp points still asserted and aborted the task:

- `ShuffleScanExec` stamped the catalyst schema onto the decoded shuffle block
  with no cast. This is the direct-read shuffle path, enabled by default.
- `ExpandExec` derived its schema from `projections[0]` only and stamped it onto
  the output of every projection, so it failed if any two projections disagreed
  on a nested nullable flag for the same output column.

Add `cast_and_stamp_schema` to `datafusion-comet-common` and use it at both
sites, so the drift is absorbed the way the other boundaries absorb it. Also
derive `ExpandExec`'s schema by widening nested nullability across all
projections rather than reading it off the first, so the declared schema is
valid for every projection.

When a stamp genuinely cannot be reconciled, the error now names the operator
and the dotted path of the offending column instead of only `at column index N`,
which was very hard to act on for wide schemas of deeply nested structs.

Upstream nested-nullability drift itself is tracked by apache#4515.

Closes apache#5137

* refactor: address /simplify review of the nested-nullability fix

Reuse:
- Route `SchemaAlignExec::align` through the new shared `cast_and_stamp_schema`
  instead of keeping its own copy of the same cast-then-stamp loop. This deletes
  the `ColumnAction` enum and its plan-time precomputation and plumbing; the
  per-batch type comparison it avoided is negligible against batch-sized work,
  and the operator gets the improved error messages for free.
- Share one nested-nullability test fixture between the `expand` and
  `shuffle_scan` tests rather than defining the same list-of-struct builder in
  each.
- Use `datafusion::physical_plan::collect` and
  `MemorySourceConfig::try_new_exec` instead of hand-rolled equivalents.

Simplification:
- Drop the `residual_mismatch` tracking from `cast_and_stamp_schema`. It guarded
  against `cast_with_options` returning a type other than the one requested,
  which it never does — it returns that type or an error — so after the cast loop
  the stamp can only fail on row counts.
- Drop the `ListView`/`LargeListView`/`Dictionary` arms and the nested-metadata
  comparison. The reachable nested set is Struct/List/LargeList/FixedSizeList/Map
  — the same set `make_all_fields_nullable` walks — and a metadata-only
  difference always casts cleanly, so the describer never sees one.
- Make `describe_type_mismatch` private; nothing outside the module used it.
- Drop the planner's `assert!(!projections.is_empty())`, now that
  `build_schema` returns a proper error for the same condition.

Efficiency:
- Take `columns` by value so `ExpandStream::expand` moves its vector in as it did
  before this change, instead of the helper allocating a second one per
  projection per batch.

Documentation:
- Record that reconciliation follows the declared schema in both directions and
  will narrow as well as widen, and point callers that must not narrow at
  `widen_nested_nullability`. Cross-reference the pre-existing
  `make_all_fields_nullable` and arrow's `Field::try_merge`, noting why neither
  substitutes for it.

* docs: explain why Expand's output field names stay col_{idx}

Addresses review feedback on apache#5138: the naming is inherited verbatim from
the planner, and parent operators bind to these columns by index, so the
name is positional either way.

(cherry picked from commit cd4d0e2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants