minni31 commented on code in PR #12766:
URL: https://github.com/apache/gluten/pull/12766#discussion_r3783017842


##########
gluten-substrait/src/main/scala/org/apache/gluten/config/GlutenConfig.scala:
##########
@@ -935,6 +937,16 @@ object GlutenConfig extends ConfigRegistry {
       .booleanConf
       .createWithDefault(true)
 
+  val COLUMNAR_EMPTY_RELATION_ENABLED =
+    buildConf("spark.gluten.sql.columnar.emptyRelation")
+      .doc(
+        "Enable or disable native columnar execution of EmptyRelationExec 
(Spark 4.0+). When " +
+          "true, Gluten replaces EmptyRelationExec (a leaf node AQE creates 
when it proves a " +
+          "subtree produces no output) with a columnar transformer, avoiding 
unnecessary " +
+          "ColumnarToRow / RowToColumnar transitions around the empty 
relation.")

Review Comment:
   Good catch — reworded to "columnar execution". The transformer is a JVM-side 
columnar leaf that returns an empty `RDD[ColumnarBatch]`, so "native" was 
misleading. Fixed in the config `doc()` string and the generated 
`docs/Configuration.md` row now matches.



##########
docs/Configuration.md:
##########
@@ -55,6 +55,7 @@ nav_order: 15
 | spark.gluten.sql.columnar.coalesce                                  | 🔄 
Dynamic    | true              | Enable or disable columnar coalesce.           
                                                                                
                                                                                
                                                                                
                                                                                
                                                           |
 | spark.gluten.sql.columnar.collectLimit                              | 🔄 
Dynamic    | true              | Enable or disable columnar collectLimit.       
                                                                                
                                                                                
                                                                                
                                                                                
                                                           |
 | spark.gluten.sql.columnar.collectTail                               | 🔄 
Dynamic    | true              | Enable or disable columnar collectTail.        
                                                                                
                                                                                
                                                                                
                                                                                
                                                           |
+| spark.gluten.sql.columnar.emptyRelation                             | 🔄 
Dynamic    | true              | Enable or disable native columnar execution of 
EmptyRelationExec (Spark 4.0+). When true, Gluten replaces EmptyRelationExec 
with a columnar transformer, avoiding unnecessary ColumnarToRow / RowToColumnar 
transitions around the empty relation.                                          
                                                                                
                                                                |

Review Comment:
   Done — the row is regenerated from the config `doc()` string and now reads 
"columnar execution" instead of "native columnar execution".



##########
gluten-substrait/src/main/scala/org/apache/gluten/backendsapi/SparkPlanExecApi.scala:
##########
@@ -655,6 +655,17 @@ trait SparkPlanExecApi {
   def getRDDScanTransform(plan: RDDScanExec): RDDScanTransformer =
     throw new GlutenNotSupportException("RDDScanExec is not supported")
 
+  /**
+   * Whether the backend supports offloading the given empty-relation plan to 
native. Typed as
+   * [[SparkPlan]] because EmptyRelationExec only exists on Spark 4.0+; 
callers must first confirm
+   * the type through `SparkShims.isEmptyRelationExec`.
+   */

Review Comment:
   Done — reworded to "offloading the given empty-relation plan to a columnar 
transformer" to avoid implying native execution.



##########
gluten-substrait/src/main/scala/org/apache/spark/sql/execution/EmptyRelationExecTransformer.scala:
##########
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.spark.sql.execution
+
+import org.apache.gluten.backendsapi.BackendsApiManager
+import org.apache.gluten.execution.{ValidatablePlan, ValidationResult}
+import org.apache.gluten.extension.columnar.transition.Convention
+
+import org.apache.spark.rdd.RDD
+import org.apache.spark.sql.catalyst.InternalRow
+import org.apache.spark.sql.catalyst.expressions.Attribute
+import org.apache.spark.sql.vectorized.ColumnarBatch
+
+/**
+ * Columnar-aware replacement for Spark's EmptyRelationExec (Spark 4.0+). It 
produces an empty
+ * RDD[ColumnarBatch] so that surrounding columnar operators do not need to be 
wrapped in
+ * unnecessary ColumnarToRow / RowToColumnar transitions when AQE propagates 
an empty relation
+ * through the plan.
+ */
+case class EmptyRelationExecTransformer(output: Seq[Attribute]) extends 
ValidatablePlan {
+
+  override def rowType(): Convention.RowType = Convention.RowType.None
+
+  override def batchType(): Convention.BatchType = 
BackendsApiManager.getSettings.primaryBatchType
+
+  override protected def doValidateInternal(): ValidationResult = 
ValidationResult.succeeded
+
+  override protected def doExecute(): RDD[InternalRow] =
+    throw new UnsupportedOperationException(
+      "EmptyRelationExecTransformer does not support row execution.")
+
+  override protected def doExecuteColumnar(): RDD[ColumnarBatch] =
+    sparkContext.emptyRDD[ColumnarBatch]
+
+  override def children: Seq[SparkPlan] = Seq.empty
+
+  override protected def withNewChildrenInternal(
+      newChildren: IndexedSeq[SparkPlan]): SparkPlan = this
+}
+
+object EmptyRelationExecTransformer {
+
+  /**
+   * Whether the backend supports offloading the given empty-relation plan to 
native. The plan is
+   * typed as [[SparkPlan]] because EmptyRelationExec only exists on Spark 
4.0+; callers must first
+   * confirm the type through `SparkShims.isEmptyRelationExec`.
+   */

Review Comment:
   Done — reworded to "offloading ... to a columnar transformer" to match the 
JVM-side columnar leaf behavior.



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