Skip to content

test: validate AtLeastNNonNulls with shared CASE evaluation - #42

Draft
rich7420 wants to merge 20 commits into
ci-base/6180-shared-casewhenfrom
ci/6180-shared-casewhen
Draft

rich7420 wants to merge 20 commits into
ci-base/6180-shared-casewhenfrom
ci/6180-shared-casewhen

Conversation

@rich7420

@rich7420 rich7420 commented Sep 30, 2026 •

Copy link
Copy Markdown
Owner

Historical integration evidence, status updated 2026-10-07. The measurements and completed CI below apply only to 4528a2a67 against main 62ed9d16d. Upstream #6350, #6396, and #6397 have all merged. This candidate is no longer waiting on those prerequisites and does not validate the later published feature refresh c34480068. Current delivery and final-head verification belong to upstream #6180.

Current delivery plan.

Historical scope and commit-specific validation (retained unchanged)

Which issue does this PR close?

Related to apache#6093 and apache#6180. Fork integration verification only; this PR does not close an upstream issue.

Rationale for this change

The AtLeastNNonNulls query workload exposed the cost of conditional expressions and filtering unused output columns. Shared CASE/IF evaluation has now merged upstream in apache#6350. This candidate verifies the feature and the remaining projection prerequisite against actual main before updating upstream apache#6180.

What changes are included in this PR?

The candidate is 4528a2a67cff87c06179337ce4e1b35de2355839, with pinned actual-main base 62ed9d16d547fed1ac25260a1910893f076ab638. This advances the previous published fork candidate through a normal merge, preserving its history.

Relative to actual main, the combined candidate changes 18 files. Relative to a prerequisite-only tree (main + apache#6396 + apache#6397's SQL tests), it changes 13 AtLeastNNonNulls files. Upstream apache#6180 remains Draft until apache#6396 merges; its final branch will be updated from actual main and independently verified.

How are these changes tested?

Local verification for this exact tree passed on Apple M3 Pro / JDK 21:

  • Release native build; the JVM tests and benchmarks used the freshly built library, SHA256 438cf2533d3f4af082aa3e8355a511063053deb60fef0167ab1a6672163c5817.
  • 24 Spark 4.1.3 tests: conditional SQL, AtLeastNNonNulls, projection SQL and projection metrics. Six Spark 3.5 tests with strict warnings: AtLeastNNonNulls and projection/metrics. Neither run failed, cancelled or skipped tests. JDK 17 validation remains a CI check.
  • 16 Rust conditional tests, seven AtLeastNNonNulls tests and 50 planner tests; workspace/all-target release Clippy with -D warnings, cargo fmt, Spotless and RAT.
  • Two independent full-query processes passed every answer and native/dispatcher-path assertion. Each used 1,048,576 Parquet rows, 32 Double columns, 0% NULL, na.drop(16), count and all 32 cleaned sums. Twelve rounds alternated mode order; medians exclude the first three. The second process reversed initial mode and NaN-rate order. Spark used local[1], release native code with target-cpu=native.
NaN Process Native median ms Comet fallback median ms
0% 1 290.71 319.72
0% 2 302.48 329.58
5% 1 329.92 333.53
5% 2 319.96 360.13

The 5% NaN comparisons range from near parity (1.1%) to 11.2% lower median time. Variance is material; these are combined-candidate measurements for this workload, not a fixed or universal speedup. The original issue author's workload remains unverified.

The permanent CometPredicateExpressionBenchmark atleastnnonnulls --focus-double also passed its answer/path checks. Native/fallback averages were 320/338 ms at 0% NaN and 325/354 ms at 5% NaN; the latter standard deviations were 11/37 ms.

Earlier full fork CI passed at old head 7e5e2a73c, including all seven Spark 4.1 SQL shards selected by that older workflow. Current-head fork CI now passes at 4528a2a67, including Required Checks, all Comet suites, Rust tests, strict Spark 3.5/JDK17 compilation, benchmark checks, TPC-H/TPC-DS and all nine Spark 4.1 SQL shards. The earlier same-head run cancelled during this push is superseded by that completed run. Other Spark runtime profiles, Iceberg and macOS suites were skipped by this run and are not covered by its verdict. Upstream apache#6180 still waits for apache#6396 to merge and requires verification after its final actual-main update.

rich7420 and others added 18 commits September 28, 2026 22:29
When no branch value, and no WHEN after the first, can fail, evaluate them
for the whole batch and take each row's value from its branch with typed
merges, instead of filtering the batch for each branch and merging the
partial results through MutableArrayData. A branch that can fail still goes
to DataFusion's CaseExpr, which evaluates it only for the rows that choose
it. The planner also stops wrapping each branch in a cast to the type it
already has.

Closes apache#3025.
…branch

Take the branches, Display, fmt_sql, Hash and PartialEq from the wrapped
CaseExpr instead of keeping a second copy, and keep the result type with
the eager decision instead of working it out again for every batch.

When one array branch is the only one with valid values, as in
`CASE WHEN p THEN col END` and Comet's divisor guard, keep its buffers and
only clear validity, as nullif does. Those shapes get 1.4x faster.

The rules for which casts and float normalizations cannot fail now sit on
Cast and NormalizeNaNAndZero, next to the code they describe.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:expressions enhancement New feature or request run-benchmark-check run-spark-4.1-tests Run Spark 4.1 SQL tests across all modules test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants