rich7420 commented on code in PR #6073:
URL: https://github.com/apache/datafusion-comet/pull/6073#discussion_r4060561099


##########
native/core/src/execution/planner.rs:
##########
@@ -762,6 +762,14 @@ impl PhysicalPlanner {
                     .map(|x| self.create_expr(x, Arc::clone(&input_schema)))
                     .collect::<Result<Vec<_>, _>>()?;
 
+                // Normalize both sides before DataFusion hashes or compares 
nested values.
+                let value = NormalizeNestedFloats::wrap_if_needed(value, 
input_schema.as_ref())?;

Review Comment:
   With the default optimizer, `a IN (array(double('0.0')))` still returns 
`false` for `a = [-0.0]` (Spark: `true`). `OptimizeIn` rewrites it to 
`EqualTo`, bypassing this branch. Please normalize both `Eq` and `NotEq`, which 
also covers `NOT IN`.
   
   The patch below adds regression coverage with constant folding enabled. The 
regression fails before the fix and all five focused tests pass after it on 
Spark 4.1.3.
   
   <details>
   <summary>Patch (save as nested-in.patch and run git apply 
nested-in.patch)</summary>
   
   ```diff
   diff --git a/native/core/src/execution/planner/macros.rs 
b/native/core/src/execution/planner/macros.rs
   index 0ec60c0f7..c36e843f9 100644
   --- a/native/core/src/execution/planner/macros.rs
   +++ b/native/core/src/execution/planner/macros.rs
   @@ -93,6 +93,18 @@ macro_rules! binary_expr_builder {
                            &$operator,
                            &input_schema,
                        );
   +                // OptimizeIn can rewrite singleton IN/NOT IN to equality 
comparisons.
   +                let (left, right) = match $operator {
   +                    datafusion::logical_expr::Operator::Eq
   +                    | datafusion::logical_expr::Operator::NotEq => {
   +                        use 
datafusion_comet_spark_expr::NormalizeNestedFloats;
   +                        (
   +                            NormalizeNestedFloats::wrap_if_needed(left, 
&input_schema)?,
   +                            NormalizeNestedFloats::wrap_if_needed(right, 
&input_schema)?,
   +                        )
   +                    }
   +                    _ => (left, right),
   +                };
                    Ok(std::sync::Arc::new(
                        
datafusion::physical_expr::expressions::BinaryExpr::new(left, $operator, right),
                    ))
   diff --git 
a/spark/src/test/scala/org/apache/comet/CometExpressionSuite.scala 
b/spark/src/test/scala/org/apache/comet/CometExpressionSuite.scala
   index 028dc0475..56692797f 100644
   --- a/spark/src/test/scala/org/apache/comet/CometExpressionSuite.scala
   +++ b/spark/src/test/scala/org/apache/comet/CometExpressionSuite.scala
   @@ -52,7 +52,19 @@ class CometExpressionSuite extends CometTestBase with 
AdaptiveSparkPlanHelper {
      test("nested floating point membership uses native In and InSet") {
        withTable("nested_in_plan") {
          sql("CREATE TABLE nested_in_plan (a ARRAY<DOUBLE>) USING parquet")
   -      sql("INSERT INTO nested_in_plan VALUES (array(CAST('-0.0' AS 
DOUBLE)))")
   +      sql("""INSERT INTO nested_in_plan VALUES
   +        |(array(CAST('-0.0' AS DOUBLE))), (array(CAST('0.0' AS DOUBLE))),
   +        |(array(CAST('NaN' AS DOUBLE))), (array(CAST('1.0' AS DOUBLE))),
   +        |(array(CAST(NULL AS DOUBLE))), (array()), (NULL)""".stripMargin)
   +      withSQLConf(SQLConf.OPTIMIZER_EXCLUDED_RULES.key -> "") {
   +        for (size <- Seq(1, 2)) {
   +          val candidates = Seq.fill(size)("array(CAST('0.0' AS 
DOUBLE))").mkString(", ")
   +          val df = sql(s"SELECT a IN ($candidates), a NOT IN ($candidates) 
FROM nested_in_plan")
   +          val expressions = 
df.queryExecution.optimizedPlan.flatMap(_.expressions)
   +          assert(!expressions.exists(_.exists(_.isInstanceOf[In])))
   +          checkSparkAnswerAndImpl(df, native = Seq("equalto"))
   +        }
   +      }
          for (threshold <- Seq(100, 0)) {
            withSQLConf("spark.sql.optimizer.inSetConversionThreshold" -> 
threshold.toString) {
              val df = sql("""SELECT a IN (array(CAST('0.0' AS DOUBLE)),
   ```
   
   </details>
   



-- 
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