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


##########
gluten-ut/spark40/src/test/scala/org/apache/spark/sql/GlutenSubquerySuite.scala:
##########
@@ -32,24 +37,81 @@ class GlutenSubquerySuite extends SubquerySuite with 
GlutenSQLTestsTrait {
     "SPARK-28441: COUNT bug with attribute ref in subquery input and output 
with PythonUDF"
   )
 
-  // === Following cases override super class's cases ===
-  // TODO: fix in Spark-4.0
-  ignoreGluten("SPARK-26893 Allow pushdown of partition pruning subquery 
filters to file source") {
+  testGluten("SPARK-26893: Allow pushdown of partition pruning subquery 
filters to file source") {
     withTable("a", "b") {
       spark.range(4).selectExpr("id", "id % 2 AS 
p").write.partitionBy("p").saveAsTable("a")
       spark.range(2).write.saveAsTable("b")
 
-      // need to execute the query before we can examine fs.inputRDDs()
       val df = sql("SELECT * FROM a WHERE p <= (SELECT MIN(id) FROM b)")
       checkAnswer(df, Seq(Row(0, 0), Row(2, 0)))
-      assert(stripAQEPlan(df.queryExecution.executedPlan).collectFirst {
-        case t: WholeStageTransformer => t
-      } match {
-        case Some(WholeStageTransformer(fs: FileSourceScanExecTransformer, _)) 
=>
-          fs.dynamicallySelectedPartitions.toPartitionArray
-            .exists(_.filePath.toString.contains("p=0"))
-        case _ => false
+      // need to execute the query before we can examine fs.inputRDDs()
+      val fileSourceScanExec = 
collect(stripAQEPlan(df.queryExecution.executedPlan)) {
+        case fs: FileSourceScanExecTransformer => fs
+      }
+      assert(fileSourceScanExec.size === 1)
+      val scan = fileSourceScanExec.head
+      assert(scan.partitionFilters.exists(ExecSubqueryExpression.hasSubquery))
+      val selectedPartitions = 
scan.dynamicallySelectedPartitions.toPartitionArray
+      assert(selectedPartitions.nonEmpty)
+      assert(selectedPartitions.forall(_.filePath.toString.contains("p=0")))
+    }
+  }
+
+  testGluten("SPARK-36280: Remove redundant aliases after 
RewritePredicateSubquery") {
+    withTable("t1", "t2") {
+      sql("CREATE TABLE t1 USING parquet AS SELECT id AS a, id AS b, id AS c 
FROM range(10)")
+      sql("CREATE TABLE t2 USING parquet AS SELECT id AS x, id AS y FROM 
range(8)")
+      val df = sql(
+        """
+          |SELECT *
+          |FROM   t1
+          |WHERE  a IN (SELECT x
+          |             FROM   (SELECT x AS x,
+          |                            RANK() OVER (PARTITION BY x ORDER BY 
SUM(y) DESC) AS ranking
+          |                     FROM   t2
+          |                     GROUP  BY x) tmp1
+          |             WHERE  ranking <= 5)
+          |""".stripMargin)
+
+      df.collect()
+      val exchanges = collect(df.queryExecution.executedPlan) {
+        case s: ColumnarShuffleExchangeExec => s
+      }
+      assert(exchanges.size === 1)
+    }
+  }
+
+  testGluten(
+    "SPARK-43402: FileSourceScanExec supports push down data filter with 
scalar subquery") {
+    def checkFileSourceScan(query: String, answer: Seq[Row]): Unit = {
+      val df = sql(query)
+      checkAnswer(df, answer)
+      val fileSourceScanExec = collect(df.queryExecution.executedPlan) {
+        case f: FileSourceScanExecTransformer => f
+      }
+      sparkContext.listenerBus.waitUntilEmpty()
+      assert(fileSourceScanExec.size === 1)
+      val scalarSubquery = 
fileSourceScanExec.head.dataFilters.flatMap(_.collect {
+        case s: ScalarSubquery => s
       })
+      assert(scalarSubquery.length === 1)
+      assert(scalarSubquery.head.plan.isInstanceOf[ReusedSubqueryExec])
+      assert(fileSourceScanExec.head.metrics("numFiles").value === 1)
+      assert(fileSourceScanExec.head.metrics("numOutputRows").value === 
answer.size)

Review Comment:
   The SPARK-43402 test assumes the scalar subquery plan is always a 
ReusedSubqueryExec and that scan metrics always contain 
"numFiles"/"numOutputRows". In practice the scalar subquery can be a plain 
SubqueryExec (no reuse when it appears once), and missing metric keys would 
currently throw a NoSuchElementException, making the test flaky across Spark 
configs/backends.



##########
gluten-ut/spark41/src/test/scala/org/apache/spark/sql/GlutenSubquerySuite.scala:
##########
@@ -32,24 +37,81 @@ class GlutenSubquerySuite extends SubquerySuite with 
GlutenSQLTestsTrait {
     "SPARK-28441: COUNT bug with attribute ref in subquery input and output 
with PythonUDF"
   )
 
-  // === Following cases override super class's cases ===
-  // TODO: fix in Spark-4.0
-  ignoreGluten("SPARK-26893 Allow pushdown of partition pruning subquery 
filters to file source") {
+  testGluten("SPARK-26893: Allow pushdown of partition pruning subquery 
filters to file source") {
     withTable("a", "b") {
       spark.range(4).selectExpr("id", "id % 2 AS 
p").write.partitionBy("p").saveAsTable("a")
       spark.range(2).write.saveAsTable("b")
 
-      // need to execute the query before we can examine fs.inputRDDs()
       val df = sql("SELECT * FROM a WHERE p <= (SELECT MIN(id) FROM b)")
       checkAnswer(df, Seq(Row(0, 0), Row(2, 0)))
-      assert(stripAQEPlan(df.queryExecution.executedPlan).collectFirst {
-        case t: WholeStageTransformer => t
-      } match {
-        case Some(WholeStageTransformer(fs: FileSourceScanExecTransformer, _)) 
=>
-          fs.dynamicallySelectedPartitions.toPartitionArray
-            .exists(_.filePath.toString.contains("p=0"))
-        case _ => false
+      // need to execute the query before we can examine fs.inputRDDs()
+      val fileSourceScanExec = 
collect(stripAQEPlan(df.queryExecution.executedPlan)) {
+        case fs: FileSourceScanExecTransformer => fs
+      }
+      assert(fileSourceScanExec.size === 1)
+      val scan = fileSourceScanExec.head
+      assert(scan.partitionFilters.exists(ExecSubqueryExpression.hasSubquery))
+      val selectedPartitions = 
scan.dynamicallySelectedPartitions.toPartitionArray
+      assert(selectedPartitions.nonEmpty)
+      assert(selectedPartitions.forall(_.filePath.toString.contains("p=0")))
+    }
+  }
+
+  testGluten("SPARK-36280: Remove redundant aliases after 
RewritePredicateSubquery") {
+    withTable("t1", "t2") {
+      sql("CREATE TABLE t1 USING parquet AS SELECT id AS a, id AS b, id AS c 
FROM range(10)")
+      sql("CREATE TABLE t2 USING parquet AS SELECT id AS x, id AS y FROM 
range(8)")
+      val df = sql(
+        """
+          |SELECT *
+          |FROM   t1
+          |WHERE  a IN (SELECT x
+          |             FROM   (SELECT x AS x,
+          |                            RANK() OVER (PARTITION BY x ORDER BY 
SUM(y) DESC) AS ranking
+          |                     FROM   t2
+          |                     GROUP  BY x) tmp1
+          |             WHERE  ranking <= 5)
+          |""".stripMargin)
+
+      df.collect()
+      val exchanges = collect(df.queryExecution.executedPlan) {
+        case s: ColumnarShuffleExchangeExec => s
+      }
+      assert(exchanges.size === 1)
+    }
+  }
+
+  testGluten(
+    "SPARK-43402: FileSourceScanExec supports push down data filter with 
scalar subquery") {
+    def checkFileSourceScan(query: String, answer: Seq[Row]): Unit = {
+      val df = sql(query)
+      checkAnswer(df, answer)
+      val fileSourceScanExec = collect(df.queryExecution.executedPlan) {
+        case f: FileSourceScanExecTransformer => f
+      }
+      sparkContext.listenerBus.waitUntilEmpty()
+      assert(fileSourceScanExec.size === 1)
+      val scalarSubquery = 
fileSourceScanExec.head.dataFilters.flatMap(_.collect {
+        case s: ScalarSubquery => s
       })
+      assert(scalarSubquery.length === 1)
+      assert(scalarSubquery.head.plan.isInstanceOf[ReusedSubqueryExec])
+      assert(fileSourceScanExec.head.metrics("numFiles").value === 1)
+      assert(fileSourceScanExec.head.metrics("numOutputRows").value === 
answer.size)

Review Comment:
   The SPARK-43402 test assumes the scalar subquery plan is always a 
ReusedSubqueryExec and that scan metrics always contain 
"numFiles"/"numOutputRows". In practice the scalar subquery can be a plain 
SubqueryExec (no reuse when it appears once), and missing metric keys would 
currently throw a NoSuchElementException, making the test flaky across Spark 
configs/backends.



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