This is an automated email from the ASF dual-hosted git repository.

chengchengjin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-gluten.git


The following commit(s) were added to refs/heads/main by this push:
     new 4d88d6719c [GLUTEN-8953][VL] Support Iceberg overwrite table #10514
4d88d6719c is described below

commit 4d88d6719c2f7d0011633b43ccc2d913e7e5e8bd
Author: Zouxxyy <[email protected]>
AuthorDate: Mon Aug 25 17:06:11 2025 +0800

    [GLUTEN-8953][VL] Support Iceberg overwrite table #10514
---
 ...taExec.scala => AbstractIcebergWriteExec.scala} | 22 ++----------
 .../gluten/execution/OffloadIcebergWrite.scala     | 15 ++++++--
 .../execution/VeloxIcebergAppendDataExec.scala     | 27 ++------------
 .../VeloxIcebergOverwriteByExpressionExec.scala    | 41 ++++++++++++++++++++++
 .../execution/VeloxIcebergReplaceDataExec.scala    | 25 ++-----------
 .../execution/enhanced/VeloxIcebergSuite.scala     | 33 +++++++++++++++--
 .../gluten/backendsapi/velox/VeloxBackend.scala    |  3 ++
 docs/Configuration.md                              |  1 +
 ...AppendDataExec.scala => IcebergWriteExec.scala} |  2 +-
 .../gluten/backendsapi/BackendSettingsApi.scala    |  2 ++
 .../org/apache/gluten/config/GlutenConfig.scala    |  9 +++++
 ...V2Exec.scala => ColumnarV2TableWriteExec.scala} |  2 +-
 .../extension/columnar/validator/Validators.scala  |  3 +-
 13 files changed, 109 insertions(+), 76 deletions(-)

diff --git 
a/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/VeloxIcebergAppendDataExec.scala
 
b/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/AbstractIcebergWriteExec.scala
similarity index 68%
copy from 
backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/VeloxIcebergAppendDataExec.scala
copy to 
backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/AbstractIcebergWriteExec.scala
index 1fd5374272..3ac518cf76 100644
--- 
a/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/VeloxIcebergAppendDataExec.scala
+++ 
b/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/AbstractIcebergWriteExec.scala
@@ -19,21 +19,14 @@ package org.apache.gluten.execution
 import org.apache.gluten.IcebergNestedFieldVisitor
 import org.apache.gluten.connector.write.{ColumnarBatchDataWriterFactory, 
IcebergDataWriteFactory}
 
-import org.apache.spark.sql.connector.write.Write
-import org.apache.spark.sql.execution.SparkPlan
-import org.apache.spark.sql.execution.datasources.v2._
 import org.apache.spark.sql.types.StructType
 
 import org.apache.iceberg.spark.source.IcebergWriteUtil
 import org.apache.iceberg.types.TypeUtil
 
-case class VeloxIcebergAppendDataExec(query: SparkPlan, refreshCache: () => 
Unit, write: Write)
-  extends IcebergAppendDataExec {
+abstract class AbstractIcebergWriteExec extends IcebergWriteExec {
 
-  override protected def withNewChildInternal(newChild: SparkPlan): 
IcebergAppendDataExec =
-    copy(query = newChild)
-
-  override def createFactory(schema: StructType): 
ColumnarBatchDataWriterFactory = {
+  override protected def createFactory(schema: StructType): 
ColumnarBatchDataWriterFactory = {
     val writeSchema = IcebergWriteUtil.getWriteSchema(write)
     val nestedField = TypeUtil.visit(writeSchema, new 
IcebergNestedFieldVisitor)
     IcebergDataWriteFactory(
@@ -47,14 +40,3 @@ case class VeloxIcebergAppendDataExec(query: SparkPlan, 
refreshCache: () => Unit
     )
   }
 }
-
-object VeloxIcebergAppendDataExec {
-  def apply(original: AppendDataExec): IcebergAppendDataExec = {
-    VeloxIcebergAppendDataExec(
-      original.query,
-      original.refreshCache,
-      original.write
-    )
-  }
-
-}
diff --git 
a/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/OffloadIcebergWrite.scala
 
b/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/OffloadIcebergWrite.scala
index f8f7abdaa4..1e2beff366 100644
--- 
a/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/OffloadIcebergWrite.scala
+++ 
b/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/OffloadIcebergWrite.scala
@@ -24,7 +24,7 @@ import 
org.apache.gluten.extension.columnar.validator.Validators
 import org.apache.gluten.extension.injector.Injector
 
 import org.apache.spark.sql.execution.SparkPlan
-import org.apache.spark.sql.execution.datasources.v2.{AppendDataExec, 
ReplaceDataExec}
+import org.apache.spark.sql.execution.datasources.v2.{AppendDataExec, 
OverwriteByExpressionExec, ReplaceDataExec}
 
 case class OffloadIcebergWrite() extends OffloadSingleNode {
   override def offload(plan: SparkPlan): SparkPlan = plan match {
@@ -42,12 +42,20 @@ case class OffloadIcebergDelete() extends OffloadSingleNode 
{
   }
 }
 
+case class OffloadIcebergOverwrite() extends OffloadSingleNode {
+  override def offload(plan: SparkPlan): SparkPlan = plan match {
+    case r: OverwriteByExpressionExec =>
+      VeloxIcebergOverwriteByExpressionExec(r)
+    case other => other
+  }
+}
+
 object OffloadIcebergWrite {
   def inject(injector: Injector): Unit = {
     // Inject legacy rule.
     injector.gluten.legacy.injectTransform {
       c =>
-        val offload = Seq(OffloadIcebergWrite(), OffloadIcebergDelete())
+        val offload = Seq(OffloadIcebergWrite(), OffloadIcebergDelete(), 
OffloadIcebergOverwrite())
         HeuristicTransform.Simple(
           Validators.newValidator(new GlutenConfig(c.sqlConf), offload),
           offload
@@ -56,7 +64,8 @@ object OffloadIcebergWrite {
 
     val offloads: Seq[RasOffload] = Seq(
       RasOffload.from[AppendDataExec](OffloadIcebergWrite()),
-      RasOffload.from[ReplaceDataExec](OffloadIcebergDelete())
+      RasOffload.from[ReplaceDataExec](OffloadIcebergDelete()),
+      RasOffload.from[OverwriteByExpressionExec](OffloadIcebergOverwrite())
     )
     offloads.foreach(
       offload =>
diff --git 
a/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/VeloxIcebergAppendDataExec.scala
 
b/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/VeloxIcebergAppendDataExec.scala
index 1fd5374272..013df1e476 100644
--- 
a/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/VeloxIcebergAppendDataExec.scala
+++ 
b/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/VeloxIcebergAppendDataExec.scala
@@ -16,40 +16,19 @@
  */
 package org.apache.gluten.execution
 
-import org.apache.gluten.IcebergNestedFieldVisitor
-import org.apache.gluten.connector.write.{ColumnarBatchDataWriterFactory, 
IcebergDataWriteFactory}
-
 import org.apache.spark.sql.connector.write.Write
 import org.apache.spark.sql.execution.SparkPlan
 import org.apache.spark.sql.execution.datasources.v2._
-import org.apache.spark.sql.types.StructType
-
-import org.apache.iceberg.spark.source.IcebergWriteUtil
-import org.apache.iceberg.types.TypeUtil
 
 case class VeloxIcebergAppendDataExec(query: SparkPlan, refreshCache: () => 
Unit, write: Write)
-  extends IcebergAppendDataExec {
+  extends AbstractIcebergWriteExec {
 
-  override protected def withNewChildInternal(newChild: SparkPlan): 
IcebergAppendDataExec =
+  override protected def withNewChildInternal(newChild: SparkPlan): 
IcebergWriteExec =
     copy(query = newChild)
-
-  override def createFactory(schema: StructType): 
ColumnarBatchDataWriterFactory = {
-    val writeSchema = IcebergWriteUtil.getWriteSchema(write)
-    val nestedField = TypeUtil.visit(writeSchema, new 
IcebergNestedFieldVisitor)
-    IcebergDataWriteFactory(
-      schema,
-      getFileFormat(IcebergWriteUtil.getFileFormat(write)),
-      IcebergWriteUtil.getDirectory(write),
-      getCodec,
-      getPartitionSpec,
-      IcebergWriteUtil.getSortOrder(write),
-      nestedField
-    )
-  }
 }
 
 object VeloxIcebergAppendDataExec {
-  def apply(original: AppendDataExec): IcebergAppendDataExec = {
+  def apply(original: AppendDataExec): IcebergWriteExec = {
     VeloxIcebergAppendDataExec(
       original.query,
       original.refreshCache,
diff --git 
a/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/VeloxIcebergOverwriteByExpressionExec.scala
 
b/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/VeloxIcebergOverwriteByExpressionExec.scala
new file mode 100644
index 0000000000..00f2160513
--- /dev/null
+++ 
b/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/VeloxIcebergOverwriteByExpressionExec.scala
@@ -0,0 +1,41 @@
+/*
+ * 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.gluten.execution
+
+import org.apache.spark.sql.connector.write.Write
+import org.apache.spark.sql.execution.SparkPlan
+import org.apache.spark.sql.execution.datasources.v2.OverwriteByExpressionExec
+
+case class VeloxIcebergOverwriteByExpressionExec(
+    query: SparkPlan,
+    refreshCache: () => Unit,
+    write: Write)
+  extends AbstractIcebergWriteExec {
+
+  override protected def withNewChildInternal(newChild: SparkPlan): 
IcebergWriteExec =
+    copy(query = newChild)
+}
+
+object VeloxIcebergOverwriteByExpressionExec {
+  def apply(original: OverwriteByExpressionExec): IcebergWriteExec = {
+    VeloxIcebergOverwriteByExpressionExec(
+      original.query,
+      original.refreshCache,
+      original.write
+    )
+  }
+}
diff --git 
a/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/VeloxIcebergReplaceDataExec.scala
 
b/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/VeloxIcebergReplaceDataExec.scala
index 2a6df03e8a..c4f20e4fd1 100644
--- 
a/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/VeloxIcebergReplaceDataExec.scala
+++ 
b/backends-velox/src-iceberg/main/scala/org/apache/gluten/execution/VeloxIcebergReplaceDataExec.scala
@@ -16,36 +16,15 @@
  */
 package org.apache.gluten.execution
 
-import org.apache.gluten.IcebergNestedFieldVisitor
-import org.apache.gluten.connector.write.{ColumnarBatchDataWriterFactory, 
IcebergDataWriteFactory}
-
 import org.apache.spark.sql.connector.write.Write
 import org.apache.spark.sql.execution.SparkPlan
 import org.apache.spark.sql.execution.datasources.v2._
-import org.apache.spark.sql.types.StructType
-
-import org.apache.iceberg.spark.source.IcebergWriteUtil
-import org.apache.iceberg.types.TypeUtil
 
 case class VeloxIcebergReplaceDataExec(query: SparkPlan, refreshCache: () => 
Unit, write: Write)
-  extends IcebergAppendDataExec {
+  extends AbstractIcebergWriteExec {
 
-  override protected def withNewChildInternal(newChild: SparkPlan): 
IcebergAppendDataExec =
+  override protected def withNewChildInternal(newChild: SparkPlan): 
IcebergWriteExec =
     copy(query = newChild)
-
-  override def createFactory(schema: StructType): 
ColumnarBatchDataWriterFactory = {
-    val writeSchema = IcebergWriteUtil.getWriteSchema(write)
-    val nestedField = TypeUtil.visit(writeSchema, new 
IcebergNestedFieldVisitor)
-    IcebergDataWriteFactory(
-      schema,
-      getFileFormat(IcebergWriteUtil.getFileFormat(write)),
-      IcebergWriteUtil.getDirectory(write),
-      getCodec,
-      getPartitionSpec,
-      IcebergWriteUtil.getSortOrder(write),
-      nestedField
-    )
-  }
 }
 
 object VeloxIcebergReplaceDataExec {
diff --git 
a/backends-velox/src-iceberg/test/scala/org/apache/gluten/execution/enhanced/VeloxIcebergSuite.scala
 
b/backends-velox/src-iceberg/test/scala/org/apache/gluten/execution/enhanced/VeloxIcebergSuite.scala
index 06c8ee0c0a..ee228d5120 100644
--- 
a/backends-velox/src-iceberg/test/scala/org/apache/gluten/execution/enhanced/VeloxIcebergSuite.scala
+++ 
b/backends-velox/src-iceberg/test/scala/org/apache/gluten/execution/enhanced/VeloxIcebergSuite.scala
@@ -16,7 +16,7 @@
  */
 package org.apache.gluten.execution.enhanced
 
-import org.apache.gluten.execution.{IcebergAppendDataExec, IcebergSuite, 
VeloxIcebergReplaceDataExec}
+import org.apache.gluten.execution.{IcebergSuite, VeloxIcebergAppendDataExec, 
VeloxIcebergOverwriteByExpressionExec, VeloxIcebergReplaceDataExec}
 import org.apache.gluten.tags.EnhancedFeaturesTest
 
 import org.apache.spark.sql.execution.CommandResultExec
@@ -36,7 +36,7 @@ class VeloxIcebergSuite extends IcebergSuite {
         df.queryExecution.executedPlan
           .asInstanceOf[CommandResultExec]
           .commandPhysicalPlan
-          .isInstanceOf[IcebergAppendDataExec])
+          .isInstanceOf[VeloxIcebergAppendDataExec])
       val selectDf = spark.sql("""
                                  |select * from iceberg_tb2;
                                  |""".stripMargin)
@@ -61,7 +61,7 @@ class VeloxIcebergSuite extends IcebergSuite {
         df.queryExecution.executedPlan
           .asInstanceOf[CommandResultExec]
           .commandPhysicalPlan
-          .isInstanceOf[IcebergAppendDataExec])
+          .isInstanceOf[VeloxIcebergAppendDataExec])
       val selectDf = spark.sql("""
                                  |select * from iceberg_tb2;
                                  |""".stripMargin)
@@ -113,4 +113,31 @@ class VeloxIcebergSuite extends IcebergSuite {
       assert(result.length == 5)
     }
   }
+
+  test("iceberg insert overwrite") {
+    withTable("iceberg_tb2") {
+      spark.sql("""
+                  |create table if not exists iceberg_tb2(a int) using iceberg
+                  |""".stripMargin)
+
+      spark.sql("insert into table iceberg_tb2 values (1)")
+
+      // Overwrite table
+      val df = spark.sql("""
+                           |insert overwrite table iceberg_tb2 values (2)
+                           |""".stripMargin)
+      assert(
+        df.queryExecution.executedPlan
+          .asInstanceOf[CommandResultExec]
+          .commandPhysicalPlan
+          .isInstanceOf[VeloxIcebergOverwriteByExpressionExec])
+
+      val selectDf = spark.sql("""
+                                 |select * from iceberg_tb2;
+                                 |""".stripMargin)
+      val result = selectDf.collect()
+      assert(result.length == 1)
+      assert(result(0).get(0) == 2)
+    }
+  }
 }
diff --git 
a/backends-velox/src/main/scala/org/apache/gluten/backendsapi/velox/VeloxBackend.scala
 
b/backends-velox/src/main/scala/org/apache/gluten/backendsapi/velox/VeloxBackend.scala
index 9821efa66e..a838897352 100644
--- 
a/backends-velox/src/main/scala/org/apache/gluten/backendsapi/velox/VeloxBackend.scala
+++ 
b/backends-velox/src/main/scala/org/apache/gluten/backendsapi/velox/VeloxBackend.scala
@@ -562,4 +562,7 @@ object VeloxBackendSettings extends BackendSettingsApi {
 
   override def supportReplaceDataExec(): Boolean =
     GlutenConfig.get.enableReplaceData && enableEnhancedFeatures()
+
+  override def supportOverwriteByExpression(): Boolean =
+    GlutenConfig.get.enableOverwriteByExpression && enableEnhancedFeatures()
 }
diff --git a/docs/Configuration.md b/docs/Configuration.md
index 082ae13945..7b9bcbe49a 100644
--- a/docs/Configuration.md
+++ b/docs/Configuration.md
@@ -96,6 +96,7 @@ nav_order: 15
 | spark.gluten.sql.columnar.limit                                    | true    
          |
 | spark.gluten.sql.columnar.maxBatchSize                             | 4096    
          |
 | spark.gluten.sql.columnar.numaBinding                              | false   
          |
+| spark.gluten.sql.columnar.overwriteByExpression                    | true    
          | Enable or disable columnar v2 command overwrite by expression.      
                                                                                
                                                                                
                                                                                
                                                                                
              [...]
 | spark.gluten.sql.columnar.parquet.write.blockSize                  | 128MB   
          |
 | spark.gluten.sql.columnar.partial.project                          | true    
          | Break up one project node into 2 phases when some of the 
expressions are non offload-able. Phase one is a regular offloaded project 
transformer that evaluates the offload-able expressions in native, phase two 
preserves the output from phase one and evaluates the remaining 
non-offload-able expressions using vanilla Spark projections                    
                                                 [...]
 | spark.gluten.sql.columnar.physicalJoinOptimizationLevel            | 12      
          | Fallback to row operators if there are several continuous joins.    
                                                                                
                                                                                
                                                                                
                                                                                
              [...]
diff --git 
a/gluten-iceberg/src/main/scala/org/apache/gluten/execution/IcebergAppendDataExec.scala
 
b/gluten-iceberg/src/main/scala/org/apache/gluten/execution/IcebergWriteExec.scala
similarity index 98%
rename from 
gluten-iceberg/src/main/scala/org/apache/gluten/execution/IcebergAppendDataExec.scala
rename to 
gluten-iceberg/src/main/scala/org/apache/gluten/execution/IcebergWriteExec.scala
index 3a21d78b94..0f040f8775 100644
--- 
a/gluten-iceberg/src/main/scala/org/apache/gluten/execution/IcebergAppendDataExec.scala
+++ 
b/gluten-iceberg/src/main/scala/org/apache/gluten/execution/IcebergWriteExec.scala
@@ -26,7 +26,7 @@ import org.apache.iceberg.types.Type.TypeID
 
 import scala.collection.JavaConverters._
 
-trait IcebergAppendDataExec extends ColumnarAppendDataExec {
+trait IcebergWriteExec extends ColumnarV2TableWriteExec {
 
   protected def getFileFormat(format: FileFormat): Int = {
     format match {
diff --git 
a/gluten-substrait/src/main/scala/org/apache/gluten/backendsapi/BackendSettingsApi.scala
 
b/gluten-substrait/src/main/scala/org/apache/gluten/backendsapi/BackendSettingsApi.scala
index f4b9c46df1..a8c2d75fe7 100644
--- 
a/gluten-substrait/src/main/scala/org/apache/gluten/backendsapi/BackendSettingsApi.scala
+++ 
b/gluten-substrait/src/main/scala/org/apache/gluten/backendsapi/BackendSettingsApi.scala
@@ -163,4 +163,6 @@ trait BackendSettingsApi {
   def supportAppendDataExec(): Boolean = false
 
   def supportReplaceDataExec(): Boolean = false
+
+  def supportOverwriteByExpression(): Boolean = false
 }
diff --git 
a/gluten-substrait/src/main/scala/org/apache/gluten/config/GlutenConfig.scala 
b/gluten-substrait/src/main/scala/org/apache/gluten/config/GlutenConfig.scala
index 9d91bb6379..ef2bd560f8 100644
--- 
a/gluten-substrait/src/main/scala/org/apache/gluten/config/GlutenConfig.scala
+++ 
b/gluten-substrait/src/main/scala/org/apache/gluten/config/GlutenConfig.scala
@@ -95,6 +95,8 @@ class GlutenConfig(conf: SQLConf) extends 
GlutenCoreConfig(conf) {
 
   def enableReplaceData: Boolean = getConf(COLUMNAR_REPLACE_DATA_ENABLED)
 
+  def enableOverwriteByExpression: Boolean = 
getConf(COLUMNAR_OVERWRIET_BY_EXPRESSION_ENABLED)
+
   def enableColumnarShuffledHashJoin: Boolean = 
getConf(COLUMNAR_SHUFFLED_HASH_JOIN_ENABLED)
 
   def shuffledHashJoinOptimizeBuildSide: Boolean =
@@ -887,6 +889,13 @@ object GlutenConfig {
       .booleanConf
       .createWithDefault(true)
 
+  val COLUMNAR_OVERWRIET_BY_EXPRESSION_ENABLED =
+    buildConf("spark.gluten.sql.columnar.overwriteByExpression")
+      .internal()
+      .doc("Enable or disable columnar v2 command overwrite by expression.")
+      .booleanConf
+      .createWithDefault(true)
+
   val COLUMNAR_PREFER_STREAMING_AGGREGATE =
     buildConf("spark.gluten.sql.columnar.preferStreamingAggregate")
       .internal()
diff --git 
a/gluten-substrait/src/main/scala/org/apache/gluten/execution/ColumnarWriteToDatasourceV2Exec.scala
 
b/gluten-substrait/src/main/scala/org/apache/gluten/execution/ColumnarV2TableWriteExec.scala
similarity index 98%
rename from 
gluten-substrait/src/main/scala/org/apache/gluten/execution/ColumnarWriteToDatasourceV2Exec.scala
rename to 
gluten-substrait/src/main/scala/org/apache/gluten/execution/ColumnarV2TableWriteExec.scala
index d174f5a128..7265814de7 100644
--- 
a/gluten-substrait/src/main/scala/org/apache/gluten/execution/ColumnarWriteToDatasourceV2Exec.scala
+++ 
b/gluten-substrait/src/main/scala/org/apache/gluten/execution/ColumnarV2TableWriteExec.scala
@@ -32,7 +32,7 @@ import org.apache.spark.sql.types.StructType
 import org.apache.spark.sql.vectorized.ColumnarBatch
 import org.apache.spark.util.LongAccumulator
 
-trait ColumnarAppendDataExec extends V2ExistingTableWriteExec with 
ValidatablePlan {
+trait ColumnarV2TableWriteExec extends V2ExistingTableWriteExec with 
ValidatablePlan {
 
   protected def createFactory(schema: StructType): 
ColumnarBatchDataWriterFactory
 
diff --git 
a/gluten-substrait/src/main/scala/org/apache/gluten/extension/columnar/validator/Validators.scala
 
b/gluten-substrait/src/main/scala/org/apache/gluten/extension/columnar/validator/Validators.scala
index 8456fd4a70..ef4a50ee7a 100644
--- 
a/gluten-substrait/src/main/scala/org/apache/gluten/extension/columnar/validator/Validators.scala
+++ 
b/gluten-substrait/src/main/scala/org/apache/gluten/extension/columnar/validator/Validators.scala
@@ -29,7 +29,7 @@ import org.apache.spark.internal.Logging
 import org.apache.spark.sql.execution._
 import org.apache.spark.sql.execution.aggregate.{HashAggregateExec, 
ObjectHashAggregateExec, SortAggregateExec}
 import org.apache.spark.sql.execution.datasources.WriteFilesExec
-import org.apache.spark.sql.execution.datasources.v2.{AppendDataExec, 
BatchScanExec, ReplaceDataExec}
+import org.apache.spark.sql.execution.datasources.v2.{AppendDataExec, 
BatchScanExec, OverwriteByExpressionExec, ReplaceDataExec}
 import org.apache.spark.sql.execution.exchange.{BroadcastExchangeExec, 
ShuffleExchangeExec}
 import org.apache.spark.sql.execution.joins._
 import org.apache.spark.sql.execution.window.WindowExec
@@ -138,6 +138,7 @@ object Validators {
       case p: TakeOrderedAndProjectExec if 
!settings.supportColumnarShuffleExec() => fail(p)
       case p: AppendDataExec if !settings.supportAppendDataExec() => fail(p)
       case p: ReplaceDataExec if !settings.supportReplaceDataExec() => fail(p)
+      case p: OverwriteByExpressionExec if 
!settings.supportOverwriteByExpression() => fail(p)
       case _ => pass()
     }
   }


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

Reply via email to