Copilot commented on code in PR #13109:
URL: https://github.com/apache/gluten/pull/13109#discussion_r4104933268


##########
gluten-substrait/src/main/scala/org/apache/gluten/execution/BatchScanExecTransformer.scala:
##########
@@ -80,6 +81,13 @@ case class BatchScanExecTransformer(
     this.copy(pushDownFilters = Some(filters))
   }
 
+  override def supportsMapKeyPruning: Boolean = true
+
+  override def withRequiredMapSubfields(
+      subfields: Map[String, Seq[SubfieldPath]]): BatchScanExecTransformerBase 
= {
+    this.copy(requiredMapSubfields = subfields)

Review Comment:
   `requiredMapSubfields` is dropped by `doCanonicalize`: this `copy` does not 
pass the new field, so a BatchScan with `m["a"]` and one with `m["b"]` both 
canonicalize with an empty declaration. Spark uses canonicalized plans for 
exchange reuse, which can then reuse a scan/exchange materialized with the 
wrong key set and return nulls for the other branch. Preserve 
`requiredMapSubfields` in this copy so canonicalization and the custom equality 
remain consistent.



##########
gluten-delta/src/test/scala/org/apache/gluten/execution/DeltaSuite.scala:
##########
@@ -632,7 +661,62 @@ abstract class DeltaSuite extends 
WholeStageTransformerSuite {
     }
   }
 
-  test("deletion vector on partitioned table") {
+  testWithMinSparkVersion("map-key pruning on delta scan with and without 
deletion vector", "3.4") {
+    withTempPath {
+      p =>
+        val path = p.getCanonicalPath
+        spark
+          .range(0, 2000)
+          .selectExpr(
+            "id",
+            "map('a', named_struct('s', concat('v', cast(id % 7 as string)), 
't', id), " +
+              "'b', named_struct('s', 'x', 't', id * 2), " +
+              "'c', named_struct('s', 'y', 't', id + 1)) as m"
+          )
+          .coalesce(1)
+          .write
+          .format("delta")
+          .save(path)
+        val sql = s"SELECT count(*), sum(m['a'].t), max(m['a'].s) " +
+          s"FROM delta.`$path` WHERE m['a'].s = 'v3'"
+        val pruningFlag = 
"spark.gluten.sql.columnar.backend.velox.scanMapKeyPruningEnabled"
+
+        def scanSubfields(df: DataFrame): Map[String, Seq[String]] =
+          getExecutedPlan(df)
+            .collect { case scan: DeltaScanTransformer => 
scan.requiredMapSubfields }
+            .flatten
+            .toMap
+            .map { case (col, paths) => col -> paths.map(_.toString) }
+
+        withSQLConf(pruningFlag -> "true", "spark.sql.adaptive.enabled" -> 
"false") {
+          runQueryAndCompare(sql) {
+            df =>
+              val subfields = scanSubfields(df)
+              assert(subfields.contains("m"), s"expected pruning on m, got 
$subfields")

Review Comment:
   This test is in the shared `DeltaSuite`, which is inherited by both 
`VeloxDeltaSuite` and `BoltDeltaSuite`. The map-key pruning rule and Velox 
config are only installed for Velox, so Bolt will reach this assertion with an 
empty `requiredMapSubfields` and fail; move the test to a Velox-only suite or 
gate the Velox-specific assertions/backend setup.



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