Repository navigation
Description
Describe the bug
array_distinct and array_union run natively by default (ArrayDistinct via a plain CometScalarFunction, ArrayUnion via CometArrayUnion; neither overrides getSupportLevel). DataFusion collapses -0.0 and 0.0, so on a Spark version that does not normalize signed zeros in array functions, Comet silently returns a different answer:
SELECT array_distinct(array(0.0, double('-0.0'), 1.0))
Spark: [0.0, -0.0, 1.0]
Comet: [0.0, 1.0]
The plan is CometProject with no fallback. NormalizeFloatingNumbers only rewrites grouping keys, join keys, window partition specs and Distinct, so a plain SELECT diverges for literals as well as column-sourced values.
SPARK-54918 makes Spark normalize signed zeros in array_distinct, array_union, array_intersect, array_except and arrays_overlap, which makes [0.0, 1.0] the correct answer. Its fix versions are 4.2.0, 4.1.4 and 4.0.5. Comet also supports 3.4 and 3.5, which will never get it, and any 4.0.x before 4.0.5 or 4.1.x before 4.1.4.
array_intersect and array_except already report Incompatible, so they only reach the native path under allowIncompatible. array_distinct and array_union do not.
Steps to reproduce
Run the query above on Spark 3.5, or on 4.1.3 (the version the build currently pins).
Expected behavior
On a Spark version without SPARK-54918, either match Spark or fall back. On a version with it, keep the native path.
Additional context
The split is at the patch level, so a compile-time shim keyed on shims.minorVerSrc is not sufficient: the build pins 4.0.4 and 4.1.3, but Comet runs against any patch release of those lines. It needs a runtime check.
Note that CometSparkSessionExtensions.isSparkNNPlus compares org.apache.spark.SPARK_VERSION as a string, so SPARK_VERSION >= "4.0.5" would be wrong once 4.0.10 ships. A numeric comparison helper is needed.
Suggested shape: a getSupportLevel override on the ArrayDistinct and ArrayUnion serdes returning Incompatible when the element type contains FloatType/DoubleType and the running Spark version predates the fix, in the shape CometArrayExcept already uses for its unsupported element types. That keeps the fast path for every other element type and every fixed Spark version.
The signed-zero cases in array_distinct.sql, array_union.sql, array_except.sql and array_intersect.sql are currently query ignore(...); they should be restored once behavior is version-correct.
Found while reviewing #5262.
Activity
andygrove commentedon Sep 5, 2026
Tracked under #5709 ([EPIC] DataFusion 55 upgrade follow-ups).
peterxcli commentedon Sep 6, 2026
take
andygrove commentedon Sep 14, 2026
Checked against
apache/mainat commit481aefea9c60592612650de73bd2e1c7aa173979(2026-09-13), Spark 3.5.3, JDK 17, Linux x86_64, stock config (spark.comet.enabled=true,spark.comet.exec.enabled=true,spark.comet.exec.shuffle.enabled=true,spark.shuffle.manager=org.apache.spark.sql.comet.execution.shuffle.CometShuffleManager, off-heap 8g).array_distinctandarray_unionstill reproduce as described here. The same-0.0handling also shows up in three more functions that don't seem to be tracked yet; all three execute in Comet (CometProjectoverCometNativeScan).array_exceptandarray_intersectare marked Incompatible and only run natively withspark.comet.expression.ArrayExcept.allowIncompatible=true/spark.comet.expression.ArrayIntersect.allowIncompatible=true; they are included because the divergence is the same signed-zero handling. Values come from parquet tables so the queries are not constant-folded away:array_minon the same kind of input is covered by #5401.kazuyukitanimura commentedon Sep 14, 2026
This is a Spark bug, Spark side is fixed. Lowering the priority.
andygrove commentedon Oct 1, 2026
This is a regression in 1.1.0. The 1.1.0 regression audit (#6399) ran the same Parquet-backed query on both releases with the Spark 4.1 profile. On 1.0.0, which used DataFusion 54.1, native
array_distinctandarray_unionkeep-0.0and0.0apart and match Spark 4.1.3. On 1.1.0-rc1, which uses DataFusion 55.1, they merge the two and turn-0.0into0.0, sosize(array_distinct(array(0.0, -0.0, 1.0)))is 2 instead of 3. Both releases run it natively. It's tracked in #6402.docs: list the DataFusion 55 regressions (apache#5701, apache#6254) i…
test: drop the apache#5701 float semantics known gap
docs: drop the Iceberg nested-field and array set regressions, which …
fix: gate array distinct and union signed-zero semantics by Spark ver…