andygrove commented on code in PR #6563:
URL: https://github.com/apache/datafusion-comet/pull/6563#discussion_r4194799346


##########
spark/src/main/scala/org/apache/comet/serde/arrays.scala:
##########
@@ -540,39 +540,73 @@ object CometSlice extends CometExpressionSerde[Slice] {
 
 private[comet] object ArraySetSupport {
   val floatingPointReason: String =
-    "Floating-point elements match Spark's signed-zero and NaN semantics 
natively only on " +
-      "Spark 4.2.0, whose optimizer normalizes the arguments (SPARK-54918)"
-
-  // The native kernels match Spark only when the plan has already normalized 
the arguments, and
-  // only Spark 4.2.0 does that (SPARK-54918). Earlier releases keep flat 
signed zeros apart.
-  // From 4.0.5, 4.1.4 and 4.2.1, SPARK-59602 normalizes during evaluation 
instead, which the
-  // native kernels do not match for NaN payloads or nested zeros. A top-level
-  // KnownFloatingPointNormalized marker cannot replace the version check: 
Spark also normalizes
-  // CreateArray, If, CaseWhen, and Coalesce recursively without wrapping the 
resulting array.
-  def normalizesArgumentsInPlan(version: String): Boolean =
-    Utils.majorMinorPatchVersion(version).contains((4, 2, 0))
+    "Floating-point elements match Spark's signed-zero semantics natively only 
on Spark " +
+      "4.0.5+, 4.1.4+ and 4.2+, which treat -0.0 and 0.0 as one value in these 
functions " +
+      "(SPARK-54918, SPARK-59602)"
+
+  val collationReason: String =
+    "Elements that hold both a floating-point value and a non-UTF8_BINARY 
collated string fall " +
+      "back to Spark, which compares the strings under their collation, while 
Comet's native " +
+      "kernels compare their raw bytes"
+
+  // Spark 4.2.0 normalizes the arguments of these functions in the plan 
(SPARK-54918), and 4.0.5,
+  // 4.1.4 and 4.2.1 normalize while evaluating them (SPARK-59602). Either 
way, Spark treats -0.0
+  // and 0.0, and every NaN, as one value at any depth, which the spark_ 
variants match. Earlier
+  // releases keep -0.0 and 0.0 apart in a flat array. The check reads the 
version rather than a
+  // KnownFloatingPointNormalized marker, because SPARK-59602 adds no marker, 
and SPARK-54918
+  // normalizes CreateArray, If, CaseWhen and Coalesce without wrapping the 
resulting array.
+  def normalizesFloats(version: String): Boolean =
+    Utils.majorMinorPatchVersion(version).exists {
+      case (4, 0, patch) => patch >= 5
+      case (4, 1, patch) => patch >= 4

Review Comment:
   Reproduced, but `main` already fails this way, so it isn't new with this PR. 
On `main` at 9dc8c3ca8, `array_union(a, slice(b, 0, 1))` over a NULL 
`ARRAY<INT>` fails with the `slice` error on both 4.1.3 and 4.2.0, where Spark 
returns NULL. Your `ARRAY<DOUBLE>` query fails the same way on 4.2.0, which 
already runs float elements natively. The ANSI form, `array_union(a, 
array(CAST(s AS INT)))` with `'bad'` on a row whose `a` is NULL, fails with 
`CAST_INVALID_INPUT` too. `array_intersect` and `array_except` return NULL, 
because both always go through the codegen dispatcher.
   
   It's the same eager evaluation that #6613 tracks for the lookup functions. 
I'd rather fix `array_union` there, with a `CASE WHEN a IS NOT NULL` guard like 
the one `element_at` uses, than add a float-only fallback here that would leave 
every other element type failing.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to