diff --git a/.github/workflows/pr_build_linux.yml b/.github/workflows/pr_build_linux.yml
index 8376afbc6e..0647464926 100644
--- a/.github/workflows/pr_build_linux.yml
+++ b/.github/workflows/pr_build_linux.yml
@@ -190,6 +190,11 @@ jobs:
java_version: "17"
maven_opts: "-Pspark-4.0"
scan_impl: "auto"
+
+ - name: "Spark 4.1, JDK 17"
+ java_version: "17"
+ maven_opts: "-Pspark-4.1"
+ scan_impl: "auto"
suite:
- name: "fuzz"
value: |
diff --git a/.github/workflows/spark_sql_test.yml b/.github/workflows/spark_sql_test.yml
index 2e4b6926c2..2eb44e3b56 100644
--- a/.github/workflows/spark_sql_test.yml
+++ b/.github/workflows/spark_sql_test.yml
@@ -115,20 +115,24 @@ jobs:
- {name: "sql_hive-2", args1: "", args2: "hive/testOnly * -- -n org.apache.spark.tags.ExtendedHiveTest"}
- {name: "sql_hive-3", args1: "", args2: "hive/testOnly * -- -n org.apache.spark.tags.SlowHiveTest"}
# Test combinations:
- # - auto scan: all Spark versions (3.4, 3.5, 4.0)
+ # - auto scan: all Spark versions (3.4, 3.5, 4.0, 4.1)
# - native_comet: Spark 3.4, 3.5
# - native_iceberg_compat: Spark 3.5 only
config:
- {spark-short: '3.4', spark-full: '3.4.3', java: 11, scan-impl: 'auto', scan-env: ''}
- {spark-short: '3.5', spark-full: '3.5.8', java: 11, scan-impl: 'auto', scan-env: ''}
- {spark-short: '4.0', spark-full: '4.0.1', java: 17, scan-impl: 'auto', scan-env: ''}
+ - {spark-short: '4.1', spark-full: '4.1.1', java: 17, scan-impl: 'auto', scan-env: ''}
- {spark-short: '3.4', spark-full: '3.4.3', java: 11, scan-impl: 'native_comet', scan-env: 'COMET_PARQUET_SCAN_IMPL=native_comet'}
- {spark-short: '3.5', spark-full: '3.5.8', java: 11, scan-impl: 'native_comet', scan-env: 'COMET_PARQUET_SCAN_IMPL=native_comet'}
- {spark-short: '3.5', spark-full: '3.5.8', java: 11, scan-impl: 'native_iceberg_compat', scan-env: 'COMET_PARQUET_SCAN_IMPL=native_iceberg_compat'}
- # Skip sql_hive-1 for Spark 4.0 due to https://github.com/apache/datafusion-comet/issues/2946
+ # Skip sql_hive-1 for Spark 4.0+ due to https://github.com/apache/datafusion-comet/issues/2946
exclude:
- config: {spark-short: '4.0', spark-full: '4.0.1', java: 17, scan-impl: 'auto', scan-env: ''}
module: {name: "sql_hive-1", args1: "", args2: "hive/testOnly * -- -l org.apache.spark.tags.ExtendedHiveTest -l org.apache.spark.tags.SlowHiveTest"}
+ - config: { spark-short: '4.1', spark-full: '4.1.1', java: 17, scan-impl: 'auto', scan-env: '' }
+ module: { name: "sql_hive-1", args1: "", args2: "hive/testOnly * -- -l org.apache.spark.tags.ExtendedHiveTest -l org.apache.spark.tags.SlowHiveTest" }
+
fail-fast: false
name: spark-sql-${{ matrix.config.scan-impl }}-${{ matrix.module.name }}/spark-${{ matrix.config.spark-full }}
runs-on: ${{ matrix.os }}
@@ -156,6 +160,10 @@ jobs:
run: |
cd apache-spark
rm -rf /root/.m2/repository/org/apache/parquet # somehow parquet cache requires cleanups
+ rm -rf /root/.m2/repository/org/scala-lang/modules/scala-xml_2.13
+ rm -rf /root/.m2/repository/org/xerial/snappy/snappy-java/1.1.10.4
+ rm -rf /root/.m2/repository/com/google/protobuf/protobuf-java/4.28.2
+ rm -rf /root/.m2/repository/org/bouncycastle/bcprov-jdk18on/1.80
ENABLE_COMET=true ENABLE_COMET_ONHEAP=true ${{ matrix.config.scan-env }} ENABLE_COMET_LOG_FALLBACK_REASONS=${{ github.event.inputs.collect-fallback-logs || 'false' }} \
build/sbt -Dsbt.log.noformat=true ${{ matrix.module.args1 }} "${{ matrix.module.args2 }}"
if [ "${{ github.event.inputs.collect-fallback-logs }}" = "true" ]; then
diff --git a/common/src/main/spark-4.0/org/apache/comet/shims/CometTypeShim.scala b/common/src/main/spark-4.x/org/apache/comet/shims/CometTypeShim.scala
similarity index 100%
rename from common/src/main/spark-4.0/org/apache/comet/shims/CometTypeShim.scala
rename to common/src/main/spark-4.x/org/apache/comet/shims/CometTypeShim.scala
diff --git a/common/src/main/spark-4.0/org/apache/comet/shims/ShimBatchReader.scala b/common/src/main/spark-4.x/org/apache/comet/shims/ShimBatchReader.scala
similarity index 100%
rename from common/src/main/spark-4.0/org/apache/comet/shims/ShimBatchReader.scala
rename to common/src/main/spark-4.x/org/apache/comet/shims/ShimBatchReader.scala
diff --git a/common/src/main/spark-4.0/org/apache/comet/shims/ShimCometConf.scala b/common/src/main/spark-4.x/org/apache/comet/shims/ShimCometConf.scala
similarity index 100%
rename from common/src/main/spark-4.0/org/apache/comet/shims/ShimCometConf.scala
rename to common/src/main/spark-4.x/org/apache/comet/shims/ShimCometConf.scala
diff --git a/common/src/main/spark-4.0/org/apache/comet/shims/ShimFileFormat.scala b/common/src/main/spark-4.x/org/apache/comet/shims/ShimFileFormat.scala
similarity index 100%
rename from common/src/main/spark-4.0/org/apache/comet/shims/ShimFileFormat.scala
rename to common/src/main/spark-4.x/org/apache/comet/shims/ShimFileFormat.scala
diff --git a/common/src/main/spark-4.0/org/apache/spark/sql/comet/shims/ShimTaskMetrics.scala b/common/src/main/spark-4.x/org/apache/spark/sql/comet/shims/ShimTaskMetrics.scala
similarity index 100%
rename from common/src/main/spark-4.0/org/apache/spark/sql/comet/shims/ShimTaskMetrics.scala
rename to common/src/main/spark-4.x/org/apache/spark/sql/comet/shims/ShimTaskMetrics.scala
diff --git a/dev/diffs/4.1.1.diff b/dev/diffs/4.1.1.diff
new file mode 100644
index 0000000000..d341ed60f5
--- /dev/null
+++ b/dev/diffs/4.1.1.diff
@@ -0,0 +1,3998 @@
+diff --git a/pom.xml b/pom.xml
+index dc757d78812..0dc4099c5d8 100644
+--- a/pom.xml
++++ b/pom.xml
+@@ -152,6 +152,8 @@
+ 4.0.3
+ 2.5.3
+ 2.0.8
++ 4.1
++ 0.14.0-SNAPSHOT
+
+
+ org.apache.datasketches
+diff --git a/sql/core/pom.xml b/sql/core/pom.xml
+index d2d07a08aa9..d89f80e5b68 100644
+--- a/sql/core/pom.xml
++++ b/sql/core/pom.xml
+@@ -97,6 +97,10 @@
+ org.apache.spark
+ spark-tags_${scala.binary.version}
+
++
++ org.apache.datafusion
++ comet-spark-spark${spark.version.short}_${scala.binary.version}
++
+
+
+ 17
+ ${java.version}
+ ${java.version}
+
+
+
+
+
+ spark-4.1
+
+
+ 2.13.17
+ 2.13
+ 4.1.1
+ 4.1
+ 1.16.0
+ 4.13.9
+ 2.0.17
+ spark-4.x
+ spark-4.1
17
${java.version}
diff --git a/spark/pom.xml b/spark/pom.xml
index a9cd72f51b..0172e6f13b 100644
--- a/spark/pom.xml
+++ b/spark/pom.xml
@@ -256,6 +256,33 @@ under the License.
+
+
+ spark-4.1
+
+
+ org.apache.iceberg
+
+ iceberg-spark-runtime-4.0_${scala.binary.version}
+ 1.10.0
+ test
+
+
+
+ org.eclipse.jetty
+ jetty-server
+ 11.0.24
+ test
+
+
+ org.eclipse.jetty
+ jetty-servlet
+ 11.0.24
+ test
+
+
+
+
generate-docs
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_datafusion/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_datafusion/explain.txt
new file mode 100644
index 0000000000..d1964eee2a
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_datafusion/explain.txt
@@ -0,0 +1,291 @@
+== Physical Plan ==
+TakeOrderedAndProject (44)
++- * Project (43)
+ +- * BroadcastHashJoin Inner BuildRight (42)
+ :- * Project (36)
+ : +- * BroadcastHashJoin Inner BuildRight (35)
+ : :- * Project (29)
+ : : +- * BroadcastHashJoin Inner BuildRight (28)
+ : : :- * Filter (11)
+ : : : +- * HashAggregate (10)
+ : : : +- * CometColumnarToRow (9)
+ : : : +- CometColumnarExchange (8)
+ : : : +- * HashAggregate (7)
+ : : : +- * Project (6)
+ : : : +- * BroadcastHashJoin Inner BuildRight (5)
+ : : : :- * Filter (3)
+ : : : : +- * ColumnarToRow (2)
+ : : : : +- Scan parquet spark_catalog.default.store_returns (1)
+ : : : +- ReusedExchange (4)
+ : : +- BroadcastExchange (27)
+ : : +- * Filter (26)
+ : : +- * HashAggregate (25)
+ : : +- * CometColumnarToRow (24)
+ : : +- CometColumnarExchange (23)
+ : : +- * HashAggregate (22)
+ : : +- * HashAggregate (21)
+ : : +- * CometColumnarToRow (20)
+ : : +- CometColumnarExchange (19)
+ : : +- * HashAggregate (18)
+ : : +- * Project (17)
+ : : +- * BroadcastHashJoin Inner BuildRight (16)
+ : : :- * Filter (14)
+ : : : +- * ColumnarToRow (13)
+ : : : +- Scan parquet spark_catalog.default.store_returns (12)
+ : : +- ReusedExchange (15)
+ : +- BroadcastExchange (34)
+ : +- * CometColumnarToRow (33)
+ : +- CometProject (32)
+ : +- CometFilter (31)
+ : +- CometNativeScan parquet spark_catalog.default.store (30)
+ +- BroadcastExchange (41)
+ +- * CometColumnarToRow (40)
+ +- CometProject (39)
+ +- CometFilter (38)
+ +- CometNativeScan parquet spark_catalog.default.customer (37)
+
+
+(1) Scan parquet spark_catalog.default.store_returns
+Output [4]: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3, sr_returned_date_sk#4]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(sr_returned_date_sk#4), dynamicpruningexpression(sr_returned_date_sk#4 IN dynamicpruning#5)]
+PushedFilters: [IsNotNull(sr_store_sk), IsNotNull(sr_customer_sk)]
+ReadSchema: struct
+
+(2) ColumnarToRow [codegen id : 2]
+Input [4]: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3, sr_returned_date_sk#4]
+
+(3) Filter [codegen id : 2]
+Input [4]: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3, sr_returned_date_sk#4]
+Condition : (isnotnull(sr_store_sk#2) AND isnotnull(sr_customer_sk#1))
+
+(4) ReusedExchange [Reuses operator id: 49]
+Output [1]: [d_date_sk#6]
+
+(5) BroadcastHashJoin [codegen id : 2]
+Left keys [1]: [sr_returned_date_sk#4]
+Right keys [1]: [d_date_sk#6]
+Join type: Inner
+Join condition: None
+
+(6) Project [codegen id : 2]
+Output [3]: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3]
+Input [5]: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3, sr_returned_date_sk#4, d_date_sk#6]
+
+(7) HashAggregate [codegen id : 2]
+Input [3]: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3]
+Keys [2]: [sr_customer_sk#1, sr_store_sk#2]
+Functions [1]: [partial_sum(UnscaledValue(sr_return_amt#3))]
+Aggregate Attributes [1]: [sum#7]
+Results [3]: [sr_customer_sk#1, sr_store_sk#2, sum#8]
+
+(8) CometColumnarExchange
+Input [3]: [sr_customer_sk#1, sr_store_sk#2, sum#8]
+Arguments: hashpartitioning(sr_customer_sk#1, sr_store_sk#2, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=1]
+
+(9) CometColumnarToRow [codegen id : 9]
+Input [3]: [sr_customer_sk#1, sr_store_sk#2, sum#8]
+
+(10) HashAggregate [codegen id : 9]
+Input [3]: [sr_customer_sk#1, sr_store_sk#2, sum#8]
+Keys [2]: [sr_customer_sk#1, sr_store_sk#2]
+Functions [1]: [sum(UnscaledValue(sr_return_amt#3))]
+Aggregate Attributes [1]: [sum(UnscaledValue(sr_return_amt#3))#9]
+Results [3]: [sr_customer_sk#1 AS ctr_customer_sk#10, sr_store_sk#2 AS ctr_store_sk#11, MakeDecimal(sum(UnscaledValue(sr_return_amt#3))#9,17,2) AS ctr_total_return#12]
+
+(11) Filter [codegen id : 9]
+Input [3]: [ctr_customer_sk#10, ctr_store_sk#11, ctr_total_return#12]
+Condition : isnotnull(ctr_total_return#12)
+
+(12) Scan parquet spark_catalog.default.store_returns
+Output [4]: [sr_customer_sk#13, sr_store_sk#14, sr_return_amt#15, sr_returned_date_sk#16]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(sr_returned_date_sk#16), dynamicpruningexpression(sr_returned_date_sk#16 IN dynamicpruning#5)]
+PushedFilters: [IsNotNull(sr_store_sk)]
+ReadSchema: struct
+
+(13) ColumnarToRow [codegen id : 4]
+Input [4]: [sr_customer_sk#13, sr_store_sk#14, sr_return_amt#15, sr_returned_date_sk#16]
+
+(14) Filter [codegen id : 4]
+Input [4]: [sr_customer_sk#13, sr_store_sk#14, sr_return_amt#15, sr_returned_date_sk#16]
+Condition : isnotnull(sr_store_sk#14)
+
+(15) ReusedExchange [Reuses operator id: 49]
+Output [1]: [d_date_sk#17]
+
+(16) BroadcastHashJoin [codegen id : 4]
+Left keys [1]: [sr_returned_date_sk#16]
+Right keys [1]: [d_date_sk#17]
+Join type: Inner
+Join condition: None
+
+(17) Project [codegen id : 4]
+Output [3]: [sr_customer_sk#13, sr_store_sk#14, sr_return_amt#15]
+Input [5]: [sr_customer_sk#13, sr_store_sk#14, sr_return_amt#15, sr_returned_date_sk#16, d_date_sk#17]
+
+(18) HashAggregate [codegen id : 4]
+Input [3]: [sr_customer_sk#13, sr_store_sk#14, sr_return_amt#15]
+Keys [2]: [sr_customer_sk#13, sr_store_sk#14]
+Functions [1]: [partial_sum(UnscaledValue(sr_return_amt#15))]
+Aggregate Attributes [1]: [sum#18]
+Results [3]: [sr_customer_sk#13, sr_store_sk#14, sum#19]
+
+(19) CometColumnarExchange
+Input [3]: [sr_customer_sk#13, sr_store_sk#14, sum#19]
+Arguments: hashpartitioning(sr_customer_sk#13, sr_store_sk#14, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=2]
+
+(20) CometColumnarToRow [codegen id : 5]
+Input [3]: [sr_customer_sk#13, sr_store_sk#14, sum#19]
+
+(21) HashAggregate [codegen id : 5]
+Input [3]: [sr_customer_sk#13, sr_store_sk#14, sum#19]
+Keys [2]: [sr_customer_sk#13, sr_store_sk#14]
+Functions [1]: [sum(UnscaledValue(sr_return_amt#15))]
+Aggregate Attributes [1]: [sum(UnscaledValue(sr_return_amt#15))#9]
+Results [2]: [sr_store_sk#14 AS ctr_store_sk#20, MakeDecimal(sum(UnscaledValue(sr_return_amt#15))#9,17,2) AS ctr_total_return#21]
+
+(22) HashAggregate [codegen id : 5]
+Input [2]: [ctr_store_sk#20, ctr_total_return#21]
+Keys [1]: [ctr_store_sk#20]
+Functions [1]: [partial_avg(ctr_total_return#21)]
+Aggregate Attributes [2]: [sum#22, count#23]
+Results [3]: [ctr_store_sk#20, sum#24, count#25]
+
+(23) CometColumnarExchange
+Input [3]: [ctr_store_sk#20, sum#24, count#25]
+Arguments: hashpartitioning(ctr_store_sk#20, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=3]
+
+(24) CometColumnarToRow [codegen id : 6]
+Input [3]: [ctr_store_sk#20, sum#24, count#25]
+
+(25) HashAggregate [codegen id : 6]
+Input [3]: [ctr_store_sk#20, sum#24, count#25]
+Keys [1]: [ctr_store_sk#20]
+Functions [1]: [avg(ctr_total_return#21)]
+Aggregate Attributes [1]: [avg(ctr_total_return#21)#26]
+Results [2]: [(avg(ctr_total_return#21)#26 * 1.2) AS (avg(ctr_total_return) * 1.2)#27, ctr_store_sk#20]
+
+(26) Filter [codegen id : 6]
+Input [2]: [(avg(ctr_total_return) * 1.2)#27, ctr_store_sk#20]
+Condition : isnotnull((avg(ctr_total_return) * 1.2)#27)
+
+(27) BroadcastExchange
+Input [2]: [(avg(ctr_total_return) * 1.2)#27, ctr_store_sk#20]
+Arguments: HashedRelationBroadcastMode(List(cast(input[1, int, true] as bigint)),false), [plan_id=4]
+
+(28) BroadcastHashJoin [codegen id : 9]
+Left keys [1]: [ctr_store_sk#11]
+Right keys [1]: [ctr_store_sk#20]
+Join type: Inner
+Join condition: (cast(ctr_total_return#12 as decimal(24,7)) > (avg(ctr_total_return) * 1.2)#27)
+
+(29) Project [codegen id : 9]
+Output [2]: [ctr_customer_sk#10, ctr_store_sk#11]
+Input [5]: [ctr_customer_sk#10, ctr_store_sk#11, ctr_total_return#12, (avg(ctr_total_return) * 1.2)#27, ctr_store_sk#20]
+
+(30) CometNativeScan parquet spark_catalog.default.store
+Output [2]: [s_store_sk#28, s_state#29]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/store]
+PushedFilters: [IsNotNull(s_state), IsNotNull(s_store_sk)]
+ReadSchema: struct
+
+(31) CometFilter
+Input [2]: [s_store_sk#28, s_state#29]
+Condition : ((isnotnull(s_state#29) AND (static_invoke(CharVarcharCodegenUtils.readSidePadding(s_state#29, 2)) = TN)) AND isnotnull(s_store_sk#28))
+
+(32) CometProject
+Input [2]: [s_store_sk#28, s_state#29]
+Arguments: [s_store_sk#28], [s_store_sk#28]
+
+(33) CometColumnarToRow [codegen id : 7]
+Input [1]: [s_store_sk#28]
+
+(34) BroadcastExchange
+Input [1]: [s_store_sk#28]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=5]
+
+(35) BroadcastHashJoin [codegen id : 9]
+Left keys [1]: [ctr_store_sk#11]
+Right keys [1]: [s_store_sk#28]
+Join type: Inner
+Join condition: None
+
+(36) Project [codegen id : 9]
+Output [1]: [ctr_customer_sk#10]
+Input [3]: [ctr_customer_sk#10, ctr_store_sk#11, s_store_sk#28]
+
+(37) CometNativeScan parquet spark_catalog.default.customer
+Output [2]: [c_customer_sk#30, c_customer_id#31]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk)]
+ReadSchema: struct
+
+(38) CometFilter
+Input [2]: [c_customer_sk#30, c_customer_id#31]
+Condition : isnotnull(c_customer_sk#30)
+
+(39) CometProject
+Input [2]: [c_customer_sk#30, c_customer_id#31]
+Arguments: [c_customer_sk#30, c_customer_id#32], [c_customer_sk#30, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#31, 16)) AS c_customer_id#32]
+
+(40) CometColumnarToRow [codegen id : 8]
+Input [2]: [c_customer_sk#30, c_customer_id#32]
+
+(41) BroadcastExchange
+Input [2]: [c_customer_sk#30, c_customer_id#32]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=6]
+
+(42) BroadcastHashJoin [codegen id : 9]
+Left keys [1]: [ctr_customer_sk#10]
+Right keys [1]: [c_customer_sk#30]
+Join type: Inner
+Join condition: None
+
+(43) Project [codegen id : 9]
+Output [1]: [c_customer_id#32]
+Input [3]: [ctr_customer_sk#10, c_customer_sk#30, c_customer_id#32]
+
+(44) TakeOrderedAndProject
+Input [1]: [c_customer_id#32]
+Arguments: 100, [c_customer_id#32 ASC NULLS FIRST], [c_customer_id#32]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 1 Hosting Expression = sr_returned_date_sk#4 IN dynamicpruning#5
+BroadcastExchange (49)
++- * CometColumnarToRow (48)
+ +- CometProject (47)
+ +- CometFilter (46)
+ +- CometNativeScan parquet spark_catalog.default.date_dim (45)
+
+
+(45) CometNativeScan parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#6, d_year#33]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2000), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(46) CometFilter
+Input [2]: [d_date_sk#6, d_year#33]
+Condition : ((isnotnull(d_year#33) AND (d_year#33 = 2000)) AND isnotnull(d_date_sk#6))
+
+(47) CometProject
+Input [2]: [d_date_sk#6, d_year#33]
+Arguments: [d_date_sk#6], [d_date_sk#6]
+
+(48) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#6]
+
+(49) BroadcastExchange
+Input [1]: [d_date_sk#6]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=7]
+
+Subquery:2 Hosting operator id = 12 Hosting Expression = sr_returned_date_sk#16 IN dynamicpruning#5
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_datafusion/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_datafusion/extended.txt
new file mode 100644
index 0000000000..0622aad9d5
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_datafusion/extended.txt
@@ -0,0 +1,61 @@
+TakeOrderedAndProject
++- Project
+ +- BroadcastHashJoin
+ :- Project
+ : +- BroadcastHashJoin
+ : :- Project
+ : : +- BroadcastHashJoin
+ : : :- Filter
+ : : : +- HashAggregate
+ : : : +- CometColumnarToRow
+ : : : +- CometColumnarExchange
+ : : : +- HashAggregate
+ : : : +- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Filter
+ : : : : +- ColumnarToRow
+ : : : : +- Scan parquet spark_catalog.default.store_returns [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- Filter
+ : : +- HashAggregate
+ : : +- CometColumnarToRow
+ : : +- CometColumnarExchange
+ : : +- HashAggregate
+ : : +- HashAggregate
+ : : +- CometColumnarToRow
+ : : +- CometColumnarExchange
+ : : +- HashAggregate
+ : : +- Project
+ : : +- BroadcastHashJoin
+ : : :- Filter
+ : : : +- ColumnarToRow
+ : : : +- Scan parquet spark_catalog.default.store_returns [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : +- ReusedSubquery
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : +- BroadcastExchange
+ : +- CometColumnarToRow
+ : +- CometProject
+ : +- CometFilter
+ : +- CometNativeScan parquet spark_catalog.default.store
+ +- BroadcastExchange
+ +- CometColumnarToRow
+ +- CometProject
+ +- CometFilter
+ +- CometNativeScan parquet spark_catalog.default.customer
+
+Comet accelerated 18 out of 49 eligible operators (36%). Final plan contains 10 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_datafusion/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_datafusion/simplified.txt
new file mode 100644
index 0000000000..ed85c142aa
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_datafusion/simplified.txt
@@ -0,0 +1,72 @@
+TakeOrderedAndProject [c_customer_id]
+ WholeStageCodegen (9)
+ Project [c_customer_id]
+ BroadcastHashJoin [ctr_customer_sk,c_customer_sk]
+ Project [ctr_customer_sk]
+ BroadcastHashJoin [ctr_store_sk,s_store_sk]
+ Project [ctr_customer_sk,ctr_store_sk]
+ BroadcastHashJoin [ctr_store_sk,ctr_store_sk,ctr_total_return,(avg(ctr_total_return) * 1.2)]
+ Filter [ctr_total_return]
+ HashAggregate [sr_customer_sk,sr_store_sk,sum] [sum(UnscaledValue(sr_return_amt)),ctr_customer_sk,ctr_store_sk,ctr_total_return,sum]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [sr_customer_sk,sr_store_sk] #1
+ WholeStageCodegen (2)
+ HashAggregate [sr_customer_sk,sr_store_sk,sr_return_amt] [sum,sum]
+ Project [sr_customer_sk,sr_store_sk,sr_return_amt]
+ BroadcastHashJoin [sr_returned_date_sk,d_date_sk]
+ Filter [sr_store_sk,sr_customer_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.store_returns [sr_customer_sk,sr_store_sk,sr_return_amt,sr_returned_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #2
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometNativeScan parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ InputAdapter
+ ReusedExchange [d_date_sk] #2
+ InputAdapter
+ BroadcastExchange #3
+ WholeStageCodegen (6)
+ Filter [(avg(ctr_total_return) * 1.2)]
+ HashAggregate [ctr_store_sk,sum,count] [avg(ctr_total_return),(avg(ctr_total_return) * 1.2),sum,count]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [ctr_store_sk] #4
+ WholeStageCodegen (5)
+ HashAggregate [ctr_store_sk,ctr_total_return] [sum,count,sum,count]
+ HashAggregate [sr_customer_sk,sr_store_sk,sum] [sum(UnscaledValue(sr_return_amt)),ctr_store_sk,ctr_total_return,sum]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [sr_customer_sk,sr_store_sk] #5
+ WholeStageCodegen (4)
+ HashAggregate [sr_customer_sk,sr_store_sk,sr_return_amt] [sum,sum]
+ Project [sr_customer_sk,sr_store_sk,sr_return_amt]
+ BroadcastHashJoin [sr_returned_date_sk,d_date_sk]
+ Filter [sr_store_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.store_returns [sr_customer_sk,sr_store_sk,sr_return_amt,sr_returned_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ InputAdapter
+ ReusedExchange [d_date_sk] #2
+ InputAdapter
+ BroadcastExchange #6
+ WholeStageCodegen (7)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [s_store_sk]
+ CometFilter [s_store_sk,s_state]
+ CometNativeScan parquet spark_catalog.default.store [s_store_sk,s_state]
+ InputAdapter
+ BroadcastExchange #7
+ WholeStageCodegen (8)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [c_customer_id] [c_customer_sk,c_customer_id]
+ CometFilter [c_customer_sk,c_customer_id]
+ CometNativeScan parquet spark_catalog.default.customer [c_customer_sk,c_customer_id]
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_iceberg_compat/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_iceberg_compat/explain.txt
new file mode 100644
index 0000000000..a37054da2d
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_iceberg_compat/explain.txt
@@ -0,0 +1,269 @@
+== Physical Plan ==
+* CometColumnarToRow (41)
++- CometTakeOrderedAndProject (40)
+ +- CometProject (39)
+ +- CometBroadcastHashJoin (38)
+ :- CometProject (33)
+ : +- CometBroadcastHashJoin (32)
+ : :- CometProject (27)
+ : : +- CometBroadcastHashJoin (26)
+ : : :- CometFilter (12)
+ : : : +- CometHashAggregate (11)
+ : : : +- CometExchange (10)
+ : : : +- CometHashAggregate (9)
+ : : : +- CometProject (8)
+ : : : +- CometBroadcastHashJoin (7)
+ : : : :- CometFilter (2)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns (1)
+ : : : +- CometBroadcastExchange (6)
+ : : : +- CometProject (5)
+ : : : +- CometFilter (4)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (3)
+ : : +- CometBroadcastExchange (25)
+ : : +- CometFilter (24)
+ : : +- CometHashAggregate (23)
+ : : +- CometExchange (22)
+ : : +- CometHashAggregate (21)
+ : : +- CometHashAggregate (20)
+ : : +- CometExchange (19)
+ : : +- CometHashAggregate (18)
+ : : +- CometProject (17)
+ : : +- CometBroadcastHashJoin (16)
+ : : :- CometFilter (14)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns (13)
+ : : +- ReusedExchange (15)
+ : +- CometBroadcastExchange (31)
+ : +- CometProject (30)
+ : +- CometFilter (29)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store (28)
+ +- CometBroadcastExchange (37)
+ +- CometProject (36)
+ +- CometFilter (35)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer (34)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns
+Output [4]: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3, sr_returned_date_sk#4]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(sr_returned_date_sk#4), dynamicpruningexpression(sr_returned_date_sk#4 IN dynamicpruning#5)]
+PushedFilters: [IsNotNull(sr_store_sk), IsNotNull(sr_customer_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [4]: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3, sr_returned_date_sk#4]
+Condition : (isnotnull(sr_store_sk#2) AND isnotnull(sr_customer_sk#1))
+
+(3) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#6, d_year#7]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2000), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(4) CometFilter
+Input [2]: [d_date_sk#6, d_year#7]
+Condition : ((isnotnull(d_year#7) AND (d_year#7 = 2000)) AND isnotnull(d_date_sk#6))
+
+(5) CometProject
+Input [2]: [d_date_sk#6, d_year#7]
+Arguments: [d_date_sk#6], [d_date_sk#6]
+
+(6) CometBroadcastExchange
+Input [1]: [d_date_sk#6]
+Arguments: [d_date_sk#6]
+
+(7) CometBroadcastHashJoin
+Left output [4]: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3, sr_returned_date_sk#4]
+Right output [1]: [d_date_sk#6]
+Arguments: [sr_returned_date_sk#4], [d_date_sk#6], Inner, BuildRight
+
+(8) CometProject
+Input [5]: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3, sr_returned_date_sk#4, d_date_sk#6]
+Arguments: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3], [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3]
+
+(9) CometHashAggregate
+Input [3]: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3]
+Keys [2]: [sr_customer_sk#1, sr_store_sk#2]
+Functions [1]: [partial_sum(UnscaledValue(sr_return_amt#3))]
+
+(10) CometExchange
+Input [3]: [sr_customer_sk#1, sr_store_sk#2, sum#8]
+Arguments: hashpartitioning(sr_customer_sk#1, sr_store_sk#2, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=1]
+
+(11) CometHashAggregate
+Input [3]: [sr_customer_sk#1, sr_store_sk#2, sum#8]
+Keys [2]: [sr_customer_sk#1, sr_store_sk#2]
+Functions [1]: [sum(UnscaledValue(sr_return_amt#3))]
+
+(12) CometFilter
+Input [3]: [ctr_customer_sk#9, ctr_store_sk#10, ctr_total_return#11]
+Condition : isnotnull(ctr_total_return#11)
+
+(13) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns
+Output [4]: [sr_customer_sk#12, sr_store_sk#13, sr_return_amt#14, sr_returned_date_sk#15]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(sr_returned_date_sk#15), dynamicpruningexpression(sr_returned_date_sk#15 IN dynamicpruning#16)]
+PushedFilters: [IsNotNull(sr_store_sk)]
+ReadSchema: struct
+
+(14) CometFilter
+Input [4]: [sr_customer_sk#12, sr_store_sk#13, sr_return_amt#14, sr_returned_date_sk#15]
+Condition : isnotnull(sr_store_sk#13)
+
+(15) ReusedExchange [Reuses operator id: 6]
+Output [1]: [d_date_sk#17]
+
+(16) CometBroadcastHashJoin
+Left output [4]: [sr_customer_sk#12, sr_store_sk#13, sr_return_amt#14, sr_returned_date_sk#15]
+Right output [1]: [d_date_sk#17]
+Arguments: [sr_returned_date_sk#15], [d_date_sk#17], Inner, BuildRight
+
+(17) CometProject
+Input [5]: [sr_customer_sk#12, sr_store_sk#13, sr_return_amt#14, sr_returned_date_sk#15, d_date_sk#17]
+Arguments: [sr_customer_sk#12, sr_store_sk#13, sr_return_amt#14], [sr_customer_sk#12, sr_store_sk#13, sr_return_amt#14]
+
+(18) CometHashAggregate
+Input [3]: [sr_customer_sk#12, sr_store_sk#13, sr_return_amt#14]
+Keys [2]: [sr_customer_sk#12, sr_store_sk#13]
+Functions [1]: [partial_sum(UnscaledValue(sr_return_amt#14))]
+
+(19) CometExchange
+Input [3]: [sr_customer_sk#12, sr_store_sk#13, sum#18]
+Arguments: hashpartitioning(sr_customer_sk#12, sr_store_sk#13, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=2]
+
+(20) CometHashAggregate
+Input [3]: [sr_customer_sk#12, sr_store_sk#13, sum#18]
+Keys [2]: [sr_customer_sk#12, sr_store_sk#13]
+Functions [1]: [sum(UnscaledValue(sr_return_amt#14))]
+
+(21) CometHashAggregate
+Input [2]: [ctr_store_sk#19, ctr_total_return#20]
+Keys [1]: [ctr_store_sk#19]
+Functions [1]: [partial_avg(ctr_total_return#20)]
+
+(22) CometExchange
+Input [3]: [ctr_store_sk#19, sum#21, count#22]
+Arguments: hashpartitioning(ctr_store_sk#19, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=3]
+
+(23) CometHashAggregate
+Input [3]: [ctr_store_sk#19, sum#21, count#22]
+Keys [1]: [ctr_store_sk#19]
+Functions [1]: [avg(ctr_total_return#20)]
+
+(24) CometFilter
+Input [2]: [(avg(ctr_total_return) * 1.2)#23, ctr_store_sk#19]
+Condition : isnotnull((avg(ctr_total_return) * 1.2)#23)
+
+(25) CometBroadcastExchange
+Input [2]: [(avg(ctr_total_return) * 1.2)#23, ctr_store_sk#19]
+Arguments: [(avg(ctr_total_return) * 1.2)#23, ctr_store_sk#19]
+
+(26) CometBroadcastHashJoin
+Left output [3]: [ctr_customer_sk#9, ctr_store_sk#10, ctr_total_return#11]
+Right output [2]: [(avg(ctr_total_return) * 1.2)#23, ctr_store_sk#19]
+Arguments: [ctr_store_sk#10], [ctr_store_sk#19], Inner, (cast(ctr_total_return#11 as decimal(24,7)) > (avg(ctr_total_return) * 1.2)#23), BuildRight
+
+(27) CometProject
+Input [5]: [ctr_customer_sk#9, ctr_store_sk#10, ctr_total_return#11, (avg(ctr_total_return) * 1.2)#23, ctr_store_sk#19]
+Arguments: [ctr_customer_sk#9, ctr_store_sk#10], [ctr_customer_sk#9, ctr_store_sk#10]
+
+(28) CometScan [native_iceberg_compat] parquet spark_catalog.default.store
+Output [2]: [s_store_sk#24, s_state#25]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/store]
+PushedFilters: [IsNotNull(s_state), IsNotNull(s_store_sk)]
+ReadSchema: struct
+
+(29) CometFilter
+Input [2]: [s_store_sk#24, s_state#25]
+Condition : ((isnotnull(s_state#25) AND (static_invoke(CharVarcharCodegenUtils.readSidePadding(s_state#25, 2)) = TN)) AND isnotnull(s_store_sk#24))
+
+(30) CometProject
+Input [2]: [s_store_sk#24, s_state#25]
+Arguments: [s_store_sk#24], [s_store_sk#24]
+
+(31) CometBroadcastExchange
+Input [1]: [s_store_sk#24]
+Arguments: [s_store_sk#24]
+
+(32) CometBroadcastHashJoin
+Left output [2]: [ctr_customer_sk#9, ctr_store_sk#10]
+Right output [1]: [s_store_sk#24]
+Arguments: [ctr_store_sk#10], [s_store_sk#24], Inner, BuildRight
+
+(33) CometProject
+Input [3]: [ctr_customer_sk#9, ctr_store_sk#10, s_store_sk#24]
+Arguments: [ctr_customer_sk#9], [ctr_customer_sk#9]
+
+(34) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+Output [2]: [c_customer_sk#26, c_customer_id#27]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk)]
+ReadSchema: struct
+
+(35) CometFilter
+Input [2]: [c_customer_sk#26, c_customer_id#27]
+Condition : isnotnull(c_customer_sk#26)
+
+(36) CometProject
+Input [2]: [c_customer_sk#26, c_customer_id#27]
+Arguments: [c_customer_sk#26, c_customer_id#28], [c_customer_sk#26, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#27, 16)) AS c_customer_id#28]
+
+(37) CometBroadcastExchange
+Input [2]: [c_customer_sk#26, c_customer_id#28]
+Arguments: [c_customer_sk#26, c_customer_id#28]
+
+(38) CometBroadcastHashJoin
+Left output [1]: [ctr_customer_sk#9]
+Right output [2]: [c_customer_sk#26, c_customer_id#28]
+Arguments: [ctr_customer_sk#9], [c_customer_sk#26], Inner, BuildRight
+
+(39) CometProject
+Input [3]: [ctr_customer_sk#9, c_customer_sk#26, c_customer_id#28]
+Arguments: [c_customer_id#28], [c_customer_id#28]
+
+(40) CometTakeOrderedAndProject
+Input [1]: [c_customer_id#28]
+Arguments: TakeOrderedAndProject(limit=100, orderBy=[c_customer_id#28 ASC NULLS FIRST], output=[c_customer_id#28]), [c_customer_id#28], 100, 0, [c_customer_id#28 ASC NULLS FIRST], [c_customer_id#28]
+
+(41) CometColumnarToRow [codegen id : 1]
+Input [1]: [c_customer_id#28]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 1 Hosting Expression = sr_returned_date_sk#4 IN dynamicpruning#5
+BroadcastExchange (46)
++- * CometColumnarToRow (45)
+ +- CometProject (44)
+ +- CometFilter (43)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (42)
+
+
+(42) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#6, d_year#7]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2000), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(43) CometFilter
+Input [2]: [d_date_sk#6, d_year#7]
+Condition : ((isnotnull(d_year#7) AND (d_year#7 = 2000)) AND isnotnull(d_date_sk#6))
+
+(44) CometProject
+Input [2]: [d_date_sk#6, d_year#7]
+Arguments: [d_date_sk#6], [d_date_sk#6]
+
+(45) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#6]
+
+(46) BroadcastExchange
+Input [1]: [d_date_sk#6]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=4]
+
+Subquery:2 Hosting operator id = 13 Hosting Expression = sr_returned_date_sk#15 IN dynamicpruning#5
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_iceberg_compat/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_iceberg_compat/extended.txt
new file mode 100644
index 0000000000..8aa14c43dd
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_iceberg_compat/extended.txt
@@ -0,0 +1,53 @@
+CometColumnarToRow
++- CometTakeOrderedAndProject
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometHashAggregate
+ : : : +- CometExchange
+ : : : +- CometHashAggregate
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometFilter
+ : : +- CometHashAggregate
+ : : +- CometExchange
+ : : +- CometHashAggregate
+ : : +- CometHashAggregate
+ : : +- CometExchange
+ : : +- CometHashAggregate
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns
+ : : : +- ReusedSubquery
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store
+ +- CometBroadcastExchange
+ +- CometProject
+ +- CometFilter
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+
+Comet accelerated 46 out of 49 eligible operators (93%). Final plan contains 2 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_iceberg_compat/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_iceberg_compat/simplified.txt
new file mode 100644
index 0000000000..3e1d6243f8
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1.native_iceberg_compat/simplified.txt
@@ -0,0 +1,52 @@
+WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometTakeOrderedAndProject [c_customer_id]
+ CometProject [c_customer_id]
+ CometBroadcastHashJoin [ctr_customer_sk,c_customer_sk,c_customer_id]
+ CometProject [ctr_customer_sk]
+ CometBroadcastHashJoin [ctr_customer_sk,ctr_store_sk,s_store_sk]
+ CometProject [ctr_customer_sk,ctr_store_sk]
+ CometBroadcastHashJoin [ctr_customer_sk,ctr_store_sk,ctr_total_return,(avg(ctr_total_return) * 1.2),ctr_store_sk]
+ CometFilter [ctr_customer_sk,ctr_store_sk,ctr_total_return]
+ CometHashAggregate [sum] [ctr_customer_sk,ctr_store_sk,ctr_total_return,sr_customer_sk,sr_store_sk,sum(UnscaledValue(sr_return_amt))]
+ CometExchange [sr_customer_sk,sr_store_sk] #1
+ CometHashAggregate [sr_return_amt] [sr_customer_sk,sr_store_sk,sum]
+ CometProject [sr_customer_sk,sr_store_sk,sr_return_amt]
+ CometBroadcastHashJoin [sr_customer_sk,sr_store_sk,sr_return_amt,sr_returned_date_sk,d_date_sk]
+ CometFilter [sr_customer_sk,sr_store_sk,sr_return_amt,sr_returned_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns [sr_customer_sk,sr_store_sk,sr_return_amt,sr_returned_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #2
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [d_date_sk] #3
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [(avg(ctr_total_return) * 1.2),ctr_store_sk] #4
+ CometFilter [(avg(ctr_total_return) * 1.2),ctr_store_sk]
+ CometHashAggregate [sum,count] [(avg(ctr_total_return) * 1.2),ctr_store_sk,avg(ctr_total_return)]
+ CometExchange [ctr_store_sk] #5
+ CometHashAggregate [ctr_total_return] [ctr_store_sk,sum,count]
+ CometHashAggregate [sr_customer_sk,sum] [ctr_store_sk,ctr_total_return,sr_store_sk,sum(UnscaledValue(sr_return_amt))]
+ CometExchange [sr_customer_sk,sr_store_sk] #6
+ CometHashAggregate [sr_return_amt] [sr_customer_sk,sr_store_sk,sum]
+ CometProject [sr_customer_sk,sr_store_sk,sr_return_amt]
+ CometBroadcastHashJoin [sr_customer_sk,sr_store_sk,sr_return_amt,sr_returned_date_sk,d_date_sk]
+ CometFilter [sr_customer_sk,sr_store_sk,sr_return_amt,sr_returned_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns [sr_customer_sk,sr_store_sk,sr_return_amt,sr_returned_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ ReusedExchange [d_date_sk] #3
+ CometBroadcastExchange [s_store_sk] #7
+ CometProject [s_store_sk]
+ CometFilter [s_store_sk,s_state]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store [s_store_sk,s_state]
+ CometBroadcastExchange [c_customer_sk,c_customer_id] #8
+ CometProject [c_customer_id] [c_customer_sk,c_customer_id]
+ CometFilter [c_customer_sk,c_customer_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer [c_customer_sk,c_customer_id]
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1/explain.txt
new file mode 100644
index 0000000000..a37054da2d
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1/explain.txt
@@ -0,0 +1,269 @@
+== Physical Plan ==
+* CometColumnarToRow (41)
++- CometTakeOrderedAndProject (40)
+ +- CometProject (39)
+ +- CometBroadcastHashJoin (38)
+ :- CometProject (33)
+ : +- CometBroadcastHashJoin (32)
+ : :- CometProject (27)
+ : : +- CometBroadcastHashJoin (26)
+ : : :- CometFilter (12)
+ : : : +- CometHashAggregate (11)
+ : : : +- CometExchange (10)
+ : : : +- CometHashAggregate (9)
+ : : : +- CometProject (8)
+ : : : +- CometBroadcastHashJoin (7)
+ : : : :- CometFilter (2)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns (1)
+ : : : +- CometBroadcastExchange (6)
+ : : : +- CometProject (5)
+ : : : +- CometFilter (4)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (3)
+ : : +- CometBroadcastExchange (25)
+ : : +- CometFilter (24)
+ : : +- CometHashAggregate (23)
+ : : +- CometExchange (22)
+ : : +- CometHashAggregate (21)
+ : : +- CometHashAggregate (20)
+ : : +- CometExchange (19)
+ : : +- CometHashAggregate (18)
+ : : +- CometProject (17)
+ : : +- CometBroadcastHashJoin (16)
+ : : :- CometFilter (14)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns (13)
+ : : +- ReusedExchange (15)
+ : +- CometBroadcastExchange (31)
+ : +- CometProject (30)
+ : +- CometFilter (29)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store (28)
+ +- CometBroadcastExchange (37)
+ +- CometProject (36)
+ +- CometFilter (35)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer (34)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns
+Output [4]: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3, sr_returned_date_sk#4]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(sr_returned_date_sk#4), dynamicpruningexpression(sr_returned_date_sk#4 IN dynamicpruning#5)]
+PushedFilters: [IsNotNull(sr_store_sk), IsNotNull(sr_customer_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [4]: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3, sr_returned_date_sk#4]
+Condition : (isnotnull(sr_store_sk#2) AND isnotnull(sr_customer_sk#1))
+
+(3) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#6, d_year#7]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2000), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(4) CometFilter
+Input [2]: [d_date_sk#6, d_year#7]
+Condition : ((isnotnull(d_year#7) AND (d_year#7 = 2000)) AND isnotnull(d_date_sk#6))
+
+(5) CometProject
+Input [2]: [d_date_sk#6, d_year#7]
+Arguments: [d_date_sk#6], [d_date_sk#6]
+
+(6) CometBroadcastExchange
+Input [1]: [d_date_sk#6]
+Arguments: [d_date_sk#6]
+
+(7) CometBroadcastHashJoin
+Left output [4]: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3, sr_returned_date_sk#4]
+Right output [1]: [d_date_sk#6]
+Arguments: [sr_returned_date_sk#4], [d_date_sk#6], Inner, BuildRight
+
+(8) CometProject
+Input [5]: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3, sr_returned_date_sk#4, d_date_sk#6]
+Arguments: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3], [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3]
+
+(9) CometHashAggregate
+Input [3]: [sr_customer_sk#1, sr_store_sk#2, sr_return_amt#3]
+Keys [2]: [sr_customer_sk#1, sr_store_sk#2]
+Functions [1]: [partial_sum(UnscaledValue(sr_return_amt#3))]
+
+(10) CometExchange
+Input [3]: [sr_customer_sk#1, sr_store_sk#2, sum#8]
+Arguments: hashpartitioning(sr_customer_sk#1, sr_store_sk#2, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=1]
+
+(11) CometHashAggregate
+Input [3]: [sr_customer_sk#1, sr_store_sk#2, sum#8]
+Keys [2]: [sr_customer_sk#1, sr_store_sk#2]
+Functions [1]: [sum(UnscaledValue(sr_return_amt#3))]
+
+(12) CometFilter
+Input [3]: [ctr_customer_sk#9, ctr_store_sk#10, ctr_total_return#11]
+Condition : isnotnull(ctr_total_return#11)
+
+(13) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns
+Output [4]: [sr_customer_sk#12, sr_store_sk#13, sr_return_amt#14, sr_returned_date_sk#15]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(sr_returned_date_sk#15), dynamicpruningexpression(sr_returned_date_sk#15 IN dynamicpruning#16)]
+PushedFilters: [IsNotNull(sr_store_sk)]
+ReadSchema: struct
+
+(14) CometFilter
+Input [4]: [sr_customer_sk#12, sr_store_sk#13, sr_return_amt#14, sr_returned_date_sk#15]
+Condition : isnotnull(sr_store_sk#13)
+
+(15) ReusedExchange [Reuses operator id: 6]
+Output [1]: [d_date_sk#17]
+
+(16) CometBroadcastHashJoin
+Left output [4]: [sr_customer_sk#12, sr_store_sk#13, sr_return_amt#14, sr_returned_date_sk#15]
+Right output [1]: [d_date_sk#17]
+Arguments: [sr_returned_date_sk#15], [d_date_sk#17], Inner, BuildRight
+
+(17) CometProject
+Input [5]: [sr_customer_sk#12, sr_store_sk#13, sr_return_amt#14, sr_returned_date_sk#15, d_date_sk#17]
+Arguments: [sr_customer_sk#12, sr_store_sk#13, sr_return_amt#14], [sr_customer_sk#12, sr_store_sk#13, sr_return_amt#14]
+
+(18) CometHashAggregate
+Input [3]: [sr_customer_sk#12, sr_store_sk#13, sr_return_amt#14]
+Keys [2]: [sr_customer_sk#12, sr_store_sk#13]
+Functions [1]: [partial_sum(UnscaledValue(sr_return_amt#14))]
+
+(19) CometExchange
+Input [3]: [sr_customer_sk#12, sr_store_sk#13, sum#18]
+Arguments: hashpartitioning(sr_customer_sk#12, sr_store_sk#13, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=2]
+
+(20) CometHashAggregate
+Input [3]: [sr_customer_sk#12, sr_store_sk#13, sum#18]
+Keys [2]: [sr_customer_sk#12, sr_store_sk#13]
+Functions [1]: [sum(UnscaledValue(sr_return_amt#14))]
+
+(21) CometHashAggregate
+Input [2]: [ctr_store_sk#19, ctr_total_return#20]
+Keys [1]: [ctr_store_sk#19]
+Functions [1]: [partial_avg(ctr_total_return#20)]
+
+(22) CometExchange
+Input [3]: [ctr_store_sk#19, sum#21, count#22]
+Arguments: hashpartitioning(ctr_store_sk#19, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=3]
+
+(23) CometHashAggregate
+Input [3]: [ctr_store_sk#19, sum#21, count#22]
+Keys [1]: [ctr_store_sk#19]
+Functions [1]: [avg(ctr_total_return#20)]
+
+(24) CometFilter
+Input [2]: [(avg(ctr_total_return) * 1.2)#23, ctr_store_sk#19]
+Condition : isnotnull((avg(ctr_total_return) * 1.2)#23)
+
+(25) CometBroadcastExchange
+Input [2]: [(avg(ctr_total_return) * 1.2)#23, ctr_store_sk#19]
+Arguments: [(avg(ctr_total_return) * 1.2)#23, ctr_store_sk#19]
+
+(26) CometBroadcastHashJoin
+Left output [3]: [ctr_customer_sk#9, ctr_store_sk#10, ctr_total_return#11]
+Right output [2]: [(avg(ctr_total_return) * 1.2)#23, ctr_store_sk#19]
+Arguments: [ctr_store_sk#10], [ctr_store_sk#19], Inner, (cast(ctr_total_return#11 as decimal(24,7)) > (avg(ctr_total_return) * 1.2)#23), BuildRight
+
+(27) CometProject
+Input [5]: [ctr_customer_sk#9, ctr_store_sk#10, ctr_total_return#11, (avg(ctr_total_return) * 1.2)#23, ctr_store_sk#19]
+Arguments: [ctr_customer_sk#9, ctr_store_sk#10], [ctr_customer_sk#9, ctr_store_sk#10]
+
+(28) CometScan [native_iceberg_compat] parquet spark_catalog.default.store
+Output [2]: [s_store_sk#24, s_state#25]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/store]
+PushedFilters: [IsNotNull(s_state), IsNotNull(s_store_sk)]
+ReadSchema: struct
+
+(29) CometFilter
+Input [2]: [s_store_sk#24, s_state#25]
+Condition : ((isnotnull(s_state#25) AND (static_invoke(CharVarcharCodegenUtils.readSidePadding(s_state#25, 2)) = TN)) AND isnotnull(s_store_sk#24))
+
+(30) CometProject
+Input [2]: [s_store_sk#24, s_state#25]
+Arguments: [s_store_sk#24], [s_store_sk#24]
+
+(31) CometBroadcastExchange
+Input [1]: [s_store_sk#24]
+Arguments: [s_store_sk#24]
+
+(32) CometBroadcastHashJoin
+Left output [2]: [ctr_customer_sk#9, ctr_store_sk#10]
+Right output [1]: [s_store_sk#24]
+Arguments: [ctr_store_sk#10], [s_store_sk#24], Inner, BuildRight
+
+(33) CometProject
+Input [3]: [ctr_customer_sk#9, ctr_store_sk#10, s_store_sk#24]
+Arguments: [ctr_customer_sk#9], [ctr_customer_sk#9]
+
+(34) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+Output [2]: [c_customer_sk#26, c_customer_id#27]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk)]
+ReadSchema: struct
+
+(35) CometFilter
+Input [2]: [c_customer_sk#26, c_customer_id#27]
+Condition : isnotnull(c_customer_sk#26)
+
+(36) CometProject
+Input [2]: [c_customer_sk#26, c_customer_id#27]
+Arguments: [c_customer_sk#26, c_customer_id#28], [c_customer_sk#26, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#27, 16)) AS c_customer_id#28]
+
+(37) CometBroadcastExchange
+Input [2]: [c_customer_sk#26, c_customer_id#28]
+Arguments: [c_customer_sk#26, c_customer_id#28]
+
+(38) CometBroadcastHashJoin
+Left output [1]: [ctr_customer_sk#9]
+Right output [2]: [c_customer_sk#26, c_customer_id#28]
+Arguments: [ctr_customer_sk#9], [c_customer_sk#26], Inner, BuildRight
+
+(39) CometProject
+Input [3]: [ctr_customer_sk#9, c_customer_sk#26, c_customer_id#28]
+Arguments: [c_customer_id#28], [c_customer_id#28]
+
+(40) CometTakeOrderedAndProject
+Input [1]: [c_customer_id#28]
+Arguments: TakeOrderedAndProject(limit=100, orderBy=[c_customer_id#28 ASC NULLS FIRST], output=[c_customer_id#28]), [c_customer_id#28], 100, 0, [c_customer_id#28 ASC NULLS FIRST], [c_customer_id#28]
+
+(41) CometColumnarToRow [codegen id : 1]
+Input [1]: [c_customer_id#28]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 1 Hosting Expression = sr_returned_date_sk#4 IN dynamicpruning#5
+BroadcastExchange (46)
++- * CometColumnarToRow (45)
+ +- CometProject (44)
+ +- CometFilter (43)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (42)
+
+
+(42) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#6, d_year#7]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2000), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(43) CometFilter
+Input [2]: [d_date_sk#6, d_year#7]
+Condition : ((isnotnull(d_year#7) AND (d_year#7 = 2000)) AND isnotnull(d_date_sk#6))
+
+(44) CometProject
+Input [2]: [d_date_sk#6, d_year#7]
+Arguments: [d_date_sk#6], [d_date_sk#6]
+
+(45) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#6]
+
+(46) BroadcastExchange
+Input [1]: [d_date_sk#6]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=4]
+
+Subquery:2 Hosting operator id = 13 Hosting Expression = sr_returned_date_sk#15 IN dynamicpruning#5
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1/extended.txt
new file mode 100644
index 0000000000..8aa14c43dd
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1/extended.txt
@@ -0,0 +1,53 @@
+CometColumnarToRow
++- CometTakeOrderedAndProject
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometHashAggregate
+ : : : +- CometExchange
+ : : : +- CometHashAggregate
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometFilter
+ : : +- CometHashAggregate
+ : : +- CometExchange
+ : : +- CometHashAggregate
+ : : +- CometHashAggregate
+ : : +- CometExchange
+ : : +- CometHashAggregate
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns
+ : : : +- ReusedSubquery
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store
+ +- CometBroadcastExchange
+ +- CometProject
+ +- CometFilter
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+
+Comet accelerated 46 out of 49 eligible operators (93%). Final plan contains 2 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1/simplified.txt
new file mode 100644
index 0000000000..3e1d6243f8
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q1/simplified.txt
@@ -0,0 +1,52 @@
+WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometTakeOrderedAndProject [c_customer_id]
+ CometProject [c_customer_id]
+ CometBroadcastHashJoin [ctr_customer_sk,c_customer_sk,c_customer_id]
+ CometProject [ctr_customer_sk]
+ CometBroadcastHashJoin [ctr_customer_sk,ctr_store_sk,s_store_sk]
+ CometProject [ctr_customer_sk,ctr_store_sk]
+ CometBroadcastHashJoin [ctr_customer_sk,ctr_store_sk,ctr_total_return,(avg(ctr_total_return) * 1.2),ctr_store_sk]
+ CometFilter [ctr_customer_sk,ctr_store_sk,ctr_total_return]
+ CometHashAggregate [sum] [ctr_customer_sk,ctr_store_sk,ctr_total_return,sr_customer_sk,sr_store_sk,sum(UnscaledValue(sr_return_amt))]
+ CometExchange [sr_customer_sk,sr_store_sk] #1
+ CometHashAggregate [sr_return_amt] [sr_customer_sk,sr_store_sk,sum]
+ CometProject [sr_customer_sk,sr_store_sk,sr_return_amt]
+ CometBroadcastHashJoin [sr_customer_sk,sr_store_sk,sr_return_amt,sr_returned_date_sk,d_date_sk]
+ CometFilter [sr_customer_sk,sr_store_sk,sr_return_amt,sr_returned_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns [sr_customer_sk,sr_store_sk,sr_return_amt,sr_returned_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #2
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [d_date_sk] #3
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [(avg(ctr_total_return) * 1.2),ctr_store_sk] #4
+ CometFilter [(avg(ctr_total_return) * 1.2),ctr_store_sk]
+ CometHashAggregate [sum,count] [(avg(ctr_total_return) * 1.2),ctr_store_sk,avg(ctr_total_return)]
+ CometExchange [ctr_store_sk] #5
+ CometHashAggregate [ctr_total_return] [ctr_store_sk,sum,count]
+ CometHashAggregate [sr_customer_sk,sum] [ctr_store_sk,ctr_total_return,sr_store_sk,sum(UnscaledValue(sr_return_amt))]
+ CometExchange [sr_customer_sk,sr_store_sk] #6
+ CometHashAggregate [sr_return_amt] [sr_customer_sk,sr_store_sk,sum]
+ CometProject [sr_customer_sk,sr_store_sk,sr_return_amt]
+ CometBroadcastHashJoin [sr_customer_sk,sr_store_sk,sr_return_amt,sr_returned_date_sk,d_date_sk]
+ CometFilter [sr_customer_sk,sr_store_sk,sr_return_amt,sr_returned_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns [sr_customer_sk,sr_store_sk,sr_return_amt,sr_returned_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ ReusedExchange [d_date_sk] #3
+ CometBroadcastExchange [s_store_sk] #7
+ CometProject [s_store_sk]
+ CometFilter [s_store_sk,s_state]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store [s_store_sk,s_state]
+ CometBroadcastExchange [c_customer_sk,c_customer_id] #8
+ CometProject [c_customer_id] [c_customer_sk,c_customer_id]
+ CometFilter [c_customer_sk,c_customer_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer [c_customer_sk,c_customer_id]
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_datafusion/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_datafusion/explain.txt
new file mode 100644
index 0000000000..2c4b495826
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_datafusion/explain.txt
@@ -0,0 +1,295 @@
+== Physical Plan ==
+TakeOrderedAndProject (45)
++- * HashAggregate (44)
+ +- * CometColumnarToRow (43)
+ +- CometColumnarExchange (42)
+ +- * HashAggregate (41)
+ +- * Project (40)
+ +- * BroadcastHashJoin Inner BuildRight (39)
+ :- * Project (33)
+ : +- * BroadcastHashJoin Inner BuildRight (32)
+ : :- * Project (26)
+ : : +- * Filter (25)
+ : : +- * BroadcastHashJoin ExistenceJoin(exists#1) BuildRight (24)
+ : : :- * BroadcastHashJoin ExistenceJoin(exists#2) BuildRight (17)
+ : : : :- * BroadcastHashJoin LeftSemi BuildRight (10)
+ : : : : :- * CometColumnarToRow (3)
+ : : : : : +- CometFilter (2)
+ : : : : : +- CometNativeScan parquet spark_catalog.default.customer (1)
+ : : : : +- BroadcastExchange (9)
+ : : : : +- * Project (8)
+ : : : : +- * BroadcastHashJoin Inner BuildRight (7)
+ : : : : :- * ColumnarToRow (5)
+ : : : : : +- Scan parquet spark_catalog.default.store_sales (4)
+ : : : : +- ReusedExchange (6)
+ : : : +- BroadcastExchange (16)
+ : : : +- * Project (15)
+ : : : +- * BroadcastHashJoin Inner BuildRight (14)
+ : : : :- * ColumnarToRow (12)
+ : : : : +- Scan parquet spark_catalog.default.web_sales (11)
+ : : : +- ReusedExchange (13)
+ : : +- BroadcastExchange (23)
+ : : +- * Project (22)
+ : : +- * BroadcastHashJoin Inner BuildRight (21)
+ : : :- * ColumnarToRow (19)
+ : : : +- Scan parquet spark_catalog.default.catalog_sales (18)
+ : : +- ReusedExchange (20)
+ : +- BroadcastExchange (31)
+ : +- * CometColumnarToRow (30)
+ : +- CometProject (29)
+ : +- CometFilter (28)
+ : +- CometNativeScan parquet spark_catalog.default.customer_address (27)
+ +- BroadcastExchange (38)
+ +- * CometColumnarToRow (37)
+ +- CometProject (36)
+ +- CometFilter (35)
+ +- CometNativeScan parquet spark_catalog.default.customer_demographics (34)
+
+
+(1) CometNativeScan parquet spark_catalog.default.customer
+Output [3]: [c_customer_sk#3, c_current_cdemo_sk#4, c_current_addr_sk#5]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_current_addr_sk), IsNotNull(c_current_cdemo_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [3]: [c_customer_sk#3, c_current_cdemo_sk#4, c_current_addr_sk#5]
+Condition : (isnotnull(c_current_addr_sk#5) AND isnotnull(c_current_cdemo_sk#4))
+
+(3) CometColumnarToRow [codegen id : 9]
+Input [3]: [c_customer_sk#3, c_current_cdemo_sk#4, c_current_addr_sk#5]
+
+(4) Scan parquet spark_catalog.default.store_sales
+Output [2]: [ss_customer_sk#6, ss_sold_date_sk#7]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#7), dynamicpruningexpression(ss_sold_date_sk#7 IN dynamicpruning#8)]
+ReadSchema: struct
+
+(5) ColumnarToRow [codegen id : 2]
+Input [2]: [ss_customer_sk#6, ss_sold_date_sk#7]
+
+(6) ReusedExchange [Reuses operator id: 50]
+Output [1]: [d_date_sk#9]
+
+(7) BroadcastHashJoin [codegen id : 2]
+Left keys [1]: [ss_sold_date_sk#7]
+Right keys [1]: [d_date_sk#9]
+Join type: Inner
+Join condition: None
+
+(8) Project [codegen id : 2]
+Output [1]: [ss_customer_sk#6]
+Input [3]: [ss_customer_sk#6, ss_sold_date_sk#7, d_date_sk#9]
+
+(9) BroadcastExchange
+Input [1]: [ss_customer_sk#6]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=1]
+
+(10) BroadcastHashJoin [codegen id : 9]
+Left keys [1]: [c_customer_sk#3]
+Right keys [1]: [ss_customer_sk#6]
+Join type: LeftSemi
+Join condition: None
+
+(11) Scan parquet spark_catalog.default.web_sales
+Output [2]: [ws_bill_customer_sk#10, ws_sold_date_sk#11]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#11), dynamicpruningexpression(ws_sold_date_sk#11 IN dynamicpruning#8)]
+ReadSchema: struct
+
+(12) ColumnarToRow [codegen id : 4]
+Input [2]: [ws_bill_customer_sk#10, ws_sold_date_sk#11]
+
+(13) ReusedExchange [Reuses operator id: 50]
+Output [1]: [d_date_sk#12]
+
+(14) BroadcastHashJoin [codegen id : 4]
+Left keys [1]: [ws_sold_date_sk#11]
+Right keys [1]: [d_date_sk#12]
+Join type: Inner
+Join condition: None
+
+(15) Project [codegen id : 4]
+Output [1]: [ws_bill_customer_sk#10]
+Input [3]: [ws_bill_customer_sk#10, ws_sold_date_sk#11, d_date_sk#12]
+
+(16) BroadcastExchange
+Input [1]: [ws_bill_customer_sk#10]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=2]
+
+(17) BroadcastHashJoin [codegen id : 9]
+Left keys [1]: [c_customer_sk#3]
+Right keys [1]: [ws_bill_customer_sk#10]
+Join type: ExistenceJoin(exists#2)
+Join condition: None
+
+(18) Scan parquet spark_catalog.default.catalog_sales
+Output [2]: [cs_ship_customer_sk#13, cs_sold_date_sk#14]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#14), dynamicpruningexpression(cs_sold_date_sk#14 IN dynamicpruning#8)]
+ReadSchema: struct
+
+(19) ColumnarToRow [codegen id : 6]
+Input [2]: [cs_ship_customer_sk#13, cs_sold_date_sk#14]
+
+(20) ReusedExchange [Reuses operator id: 50]
+Output [1]: [d_date_sk#15]
+
+(21) BroadcastHashJoin [codegen id : 6]
+Left keys [1]: [cs_sold_date_sk#14]
+Right keys [1]: [d_date_sk#15]
+Join type: Inner
+Join condition: None
+
+(22) Project [codegen id : 6]
+Output [1]: [cs_ship_customer_sk#13]
+Input [3]: [cs_ship_customer_sk#13, cs_sold_date_sk#14, d_date_sk#15]
+
+(23) BroadcastExchange
+Input [1]: [cs_ship_customer_sk#13]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=3]
+
+(24) BroadcastHashJoin [codegen id : 9]
+Left keys [1]: [c_customer_sk#3]
+Right keys [1]: [cs_ship_customer_sk#13]
+Join type: ExistenceJoin(exists#1)
+Join condition: None
+
+(25) Filter [codegen id : 9]
+Input [5]: [c_customer_sk#3, c_current_cdemo_sk#4, c_current_addr_sk#5, exists#2, exists#1]
+Condition : (exists#2 OR exists#1)
+
+(26) Project [codegen id : 9]
+Output [2]: [c_current_cdemo_sk#4, c_current_addr_sk#5]
+Input [5]: [c_customer_sk#3, c_current_cdemo_sk#4, c_current_addr_sk#5, exists#2, exists#1]
+
+(27) CometNativeScan parquet spark_catalog.default.customer_address
+Output [2]: [ca_address_sk#16, ca_county#17]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_address]
+PushedFilters: [In(ca_county, [Dona Ana County,Jefferson County,La Porte County,Rush County,Toole County]), IsNotNull(ca_address_sk)]
+ReadSchema: struct
+
+(28) CometFilter
+Input [2]: [ca_address_sk#16, ca_county#17]
+Condition : (ca_county#17 IN (Rush County,Toole County,Jefferson County,Dona Ana County,La Porte County) AND isnotnull(ca_address_sk#16))
+
+(29) CometProject
+Input [2]: [ca_address_sk#16, ca_county#17]
+Arguments: [ca_address_sk#16], [ca_address_sk#16]
+
+(30) CometColumnarToRow [codegen id : 7]
+Input [1]: [ca_address_sk#16]
+
+(31) BroadcastExchange
+Input [1]: [ca_address_sk#16]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=4]
+
+(32) BroadcastHashJoin [codegen id : 9]
+Left keys [1]: [c_current_addr_sk#5]
+Right keys [1]: [ca_address_sk#16]
+Join type: Inner
+Join condition: None
+
+(33) Project [codegen id : 9]
+Output [1]: [c_current_cdemo_sk#4]
+Input [3]: [c_current_cdemo_sk#4, c_current_addr_sk#5, ca_address_sk#16]
+
+(34) CometNativeScan parquet spark_catalog.default.customer_demographics
+Output [9]: [cd_demo_sk#18, cd_gender#19, cd_marital_status#20, cd_education_status#21, cd_purchase_estimate#22, cd_credit_rating#23, cd_dep_count#24, cd_dep_employed_count#25, cd_dep_college_count#26]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_demographics]
+PushedFilters: [IsNotNull(cd_demo_sk)]
+ReadSchema: struct
+
+(35) CometFilter
+Input [9]: [cd_demo_sk#18, cd_gender#19, cd_marital_status#20, cd_education_status#21, cd_purchase_estimate#22, cd_credit_rating#23, cd_dep_count#24, cd_dep_employed_count#25, cd_dep_college_count#26]
+Condition : isnotnull(cd_demo_sk#18)
+
+(36) CometProject
+Input [9]: [cd_demo_sk#18, cd_gender#19, cd_marital_status#20, cd_education_status#21, cd_purchase_estimate#22, cd_credit_rating#23, cd_dep_count#24, cd_dep_employed_count#25, cd_dep_college_count#26]
+Arguments: [cd_demo_sk#18, cd_gender#27, cd_marital_status#28, cd_education_status#29, cd_purchase_estimate#22, cd_credit_rating#30, cd_dep_count#24, cd_dep_employed_count#25, cd_dep_college_count#26], [cd_demo_sk#18, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_gender#19, 1)) AS cd_gender#27, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_marital_status#20, 1)) AS cd_marital_status#28, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_education_status#21, 20)) AS cd_education_status#29, cd_purchase_estimate#22, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_credit_rating#23, 10)) AS cd_credit_rating#30, cd_dep_count#24, cd_dep_employed_count#25, cd_dep_college_count#26]
+
+(37) CometColumnarToRow [codegen id : 8]
+Input [9]: [cd_demo_sk#18, cd_gender#27, cd_marital_status#28, cd_education_status#29, cd_purchase_estimate#22, cd_credit_rating#30, cd_dep_count#24, cd_dep_employed_count#25, cd_dep_college_count#26]
+
+(38) BroadcastExchange
+Input [9]: [cd_demo_sk#18, cd_gender#27, cd_marital_status#28, cd_education_status#29, cd_purchase_estimate#22, cd_credit_rating#30, cd_dep_count#24, cd_dep_employed_count#25, cd_dep_college_count#26]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=5]
+
+(39) BroadcastHashJoin [codegen id : 9]
+Left keys [1]: [c_current_cdemo_sk#4]
+Right keys [1]: [cd_demo_sk#18]
+Join type: Inner
+Join condition: None
+
+(40) Project [codegen id : 9]
+Output [8]: [cd_gender#27, cd_marital_status#28, cd_education_status#29, cd_purchase_estimate#22, cd_credit_rating#30, cd_dep_count#24, cd_dep_employed_count#25, cd_dep_college_count#26]
+Input [10]: [c_current_cdemo_sk#4, cd_demo_sk#18, cd_gender#27, cd_marital_status#28, cd_education_status#29, cd_purchase_estimate#22, cd_credit_rating#30, cd_dep_count#24, cd_dep_employed_count#25, cd_dep_college_count#26]
+
+(41) HashAggregate [codegen id : 9]
+Input [8]: [cd_gender#27, cd_marital_status#28, cd_education_status#29, cd_purchase_estimate#22, cd_credit_rating#30, cd_dep_count#24, cd_dep_employed_count#25, cd_dep_college_count#26]
+Keys [8]: [cd_gender#27, cd_marital_status#28, cd_education_status#29, cd_purchase_estimate#22, cd_credit_rating#30, cd_dep_count#24, cd_dep_employed_count#25, cd_dep_college_count#26]
+Functions [1]: [partial_count(1)]
+Aggregate Attributes [1]: [count#31]
+Results [9]: [cd_gender#27, cd_marital_status#28, cd_education_status#29, cd_purchase_estimate#22, cd_credit_rating#30, cd_dep_count#24, cd_dep_employed_count#25, cd_dep_college_count#26, count#32]
+
+(42) CometColumnarExchange
+Input [9]: [cd_gender#27, cd_marital_status#28, cd_education_status#29, cd_purchase_estimate#22, cd_credit_rating#30, cd_dep_count#24, cd_dep_employed_count#25, cd_dep_college_count#26, count#32]
+Arguments: hashpartitioning(cd_gender#27, cd_marital_status#28, cd_education_status#29, cd_purchase_estimate#22, cd_credit_rating#30, cd_dep_count#24, cd_dep_employed_count#25, cd_dep_college_count#26, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=6]
+
+(43) CometColumnarToRow [codegen id : 10]
+Input [9]: [cd_gender#27, cd_marital_status#28, cd_education_status#29, cd_purchase_estimate#22, cd_credit_rating#30, cd_dep_count#24, cd_dep_employed_count#25, cd_dep_college_count#26, count#32]
+
+(44) HashAggregate [codegen id : 10]
+Input [9]: [cd_gender#27, cd_marital_status#28, cd_education_status#29, cd_purchase_estimate#22, cd_credit_rating#30, cd_dep_count#24, cd_dep_employed_count#25, cd_dep_college_count#26, count#32]
+Keys [8]: [cd_gender#27, cd_marital_status#28, cd_education_status#29, cd_purchase_estimate#22, cd_credit_rating#30, cd_dep_count#24, cd_dep_employed_count#25, cd_dep_college_count#26]
+Functions [1]: [count(1)]
+Aggregate Attributes [1]: [count(1)#33]
+Results [14]: [cd_gender#27, cd_marital_status#28, cd_education_status#29, count(1)#33 AS cnt1#34, cd_purchase_estimate#22, count(1)#33 AS cnt2#35, cd_credit_rating#30, count(1)#33 AS cnt3#36, cd_dep_count#24, count(1)#33 AS cnt4#37, cd_dep_employed_count#25, count(1)#33 AS cnt5#38, cd_dep_college_count#26, count(1)#33 AS cnt6#39]
+
+(45) TakeOrderedAndProject
+Input [14]: [cd_gender#27, cd_marital_status#28, cd_education_status#29, cnt1#34, cd_purchase_estimate#22, cnt2#35, cd_credit_rating#30, cnt3#36, cd_dep_count#24, cnt4#37, cd_dep_employed_count#25, cnt5#38, cd_dep_college_count#26, cnt6#39]
+Arguments: 100, [cd_gender#27 ASC NULLS FIRST, cd_marital_status#28 ASC NULLS FIRST, cd_education_status#29 ASC NULLS FIRST, cd_purchase_estimate#22 ASC NULLS FIRST, cd_credit_rating#30 ASC NULLS FIRST, cd_dep_count#24 ASC NULLS FIRST, cd_dep_employed_count#25 ASC NULLS FIRST, cd_dep_college_count#26 ASC NULLS FIRST], [cd_gender#27, cd_marital_status#28, cd_education_status#29, cnt1#34, cd_purchase_estimate#22, cnt2#35, cd_credit_rating#30, cnt3#36, cd_dep_count#24, cnt4#37, cd_dep_employed_count#25, cnt5#38, cd_dep_college_count#26, cnt6#39]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 4 Hosting Expression = ss_sold_date_sk#7 IN dynamicpruning#8
+BroadcastExchange (50)
++- * CometColumnarToRow (49)
+ +- CometProject (48)
+ +- CometFilter (47)
+ +- CometNativeScan parquet spark_catalog.default.date_dim (46)
+
+
+(46) CometNativeScan parquet spark_catalog.default.date_dim
+Output [3]: [d_date_sk#9, d_year#40, d_moy#41]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), IsNotNull(d_moy), EqualTo(d_year,2002), GreaterThanOrEqual(d_moy,1), LessThanOrEqual(d_moy,4), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(47) CometFilter
+Input [3]: [d_date_sk#9, d_year#40, d_moy#41]
+Condition : (((((isnotnull(d_year#40) AND isnotnull(d_moy#41)) AND (d_year#40 = 2002)) AND (d_moy#41 >= 1)) AND (d_moy#41 <= 4)) AND isnotnull(d_date_sk#9))
+
+(48) CometProject
+Input [3]: [d_date_sk#9, d_year#40, d_moy#41]
+Arguments: [d_date_sk#9], [d_date_sk#9]
+
+(49) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#9]
+
+(50) BroadcastExchange
+Input [1]: [d_date_sk#9]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=7]
+
+Subquery:2 Hosting operator id = 11 Hosting Expression = ws_sold_date_sk#11 IN dynamicpruning#8
+
+Subquery:3 Hosting operator id = 18 Hosting Expression = cs_sold_date_sk#14 IN dynamicpruning#8
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_datafusion/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_datafusion/extended.txt
new file mode 100644
index 0000000000..8935b6cc13
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_datafusion/extended.txt
@@ -0,0 +1,67 @@
+TakeOrderedAndProject
++- HashAggregate
+ +- CometColumnarToRow
+ +- CometColumnarExchange
+ +- HashAggregate
+ +- Project
+ +- BroadcastHashJoin
+ :- Project
+ : +- BroadcastHashJoin
+ : :- Project
+ : : +- Filter
+ : : +- BroadcastHashJoin
+ : : :- BroadcastHashJoin
+ : : : :- BroadcastHashJoin
+ : : : : :- CometColumnarToRow
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.customer
+ : : : : +- BroadcastExchange
+ : : : : +- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- ColumnarToRow
+ : : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- Project
+ : : : +- BroadcastHashJoin
+ : : : :- ColumnarToRow
+ : : : : +- Scan parquet spark_catalog.default.web_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : +- ReusedSubquery
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- Project
+ : : +- BroadcastHashJoin
+ : : :- ColumnarToRow
+ : : : +- Scan parquet spark_catalog.default.catalog_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : +- ReusedSubquery
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : +- BroadcastExchange
+ : +- CometColumnarToRow
+ : +- CometProject
+ : +- CometFilter
+ : +- CometNativeScan parquet spark_catalog.default.customer_address
+ +- BroadcastExchange
+ +- CometColumnarToRow
+ +- CometProject
+ +- CometFilter
+ +- CometNativeScan parquet spark_catalog.default.customer_demographics
+
+Comet accelerated 21 out of 54 eligible operators (38%). Final plan contains 11 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_datafusion/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_datafusion/simplified.txt
new file mode 100644
index 0000000000..0cc108b0b0
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_datafusion/simplified.txt
@@ -0,0 +1,77 @@
+TakeOrderedAndProject [cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count,cnt1,cnt2,cnt3,cnt4,cnt5,cnt6]
+ WholeStageCodegen (10)
+ HashAggregate [cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count,count] [count(1),cnt1,cnt2,cnt3,cnt4,cnt5,cnt6,count]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count] #1
+ WholeStageCodegen (9)
+ HashAggregate [cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count] [count,count]
+ Project [cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count]
+ BroadcastHashJoin [c_current_cdemo_sk,cd_demo_sk]
+ Project [c_current_cdemo_sk]
+ BroadcastHashJoin [c_current_addr_sk,ca_address_sk]
+ Project [c_current_cdemo_sk,c_current_addr_sk]
+ Filter [exists,exists]
+ BroadcastHashJoin [c_customer_sk,cs_ship_customer_sk]
+ BroadcastHashJoin [c_customer_sk,ws_bill_customer_sk]
+ BroadcastHashJoin [c_customer_sk,ss_customer_sk]
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [c_customer_sk,c_current_cdemo_sk,c_current_addr_sk]
+ CometNativeScan parquet spark_catalog.default.customer [c_customer_sk,c_current_cdemo_sk,c_current_addr_sk]
+ InputAdapter
+ BroadcastExchange #2
+ WholeStageCodegen (2)
+ Project [ss_customer_sk]
+ BroadcastHashJoin [ss_sold_date_sk,d_date_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.store_sales [ss_customer_sk,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #3
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year,d_moy]
+ CometNativeScan parquet spark_catalog.default.date_dim [d_date_sk,d_year,d_moy]
+ InputAdapter
+ ReusedExchange [d_date_sk] #3
+ InputAdapter
+ BroadcastExchange #4
+ WholeStageCodegen (4)
+ Project [ws_bill_customer_sk]
+ BroadcastHashJoin [ws_sold_date_sk,d_date_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.web_sales [ws_bill_customer_sk,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ InputAdapter
+ ReusedExchange [d_date_sk] #3
+ InputAdapter
+ BroadcastExchange #5
+ WholeStageCodegen (6)
+ Project [cs_ship_customer_sk]
+ BroadcastHashJoin [cs_sold_date_sk,d_date_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.catalog_sales [cs_ship_customer_sk,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ InputAdapter
+ ReusedExchange [d_date_sk] #3
+ InputAdapter
+ BroadcastExchange #6
+ WholeStageCodegen (7)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [ca_address_sk]
+ CometFilter [ca_address_sk,ca_county]
+ CometNativeScan parquet spark_catalog.default.customer_address [ca_address_sk,ca_county]
+ InputAdapter
+ BroadcastExchange #7
+ WholeStageCodegen (8)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [cd_gender,cd_marital_status,cd_education_status,cd_credit_rating] [cd_demo_sk,cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count]
+ CometFilter [cd_demo_sk,cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count]
+ CometNativeScan parquet spark_catalog.default.customer_demographics [cd_demo_sk,cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count]
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_iceberg_compat/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_iceberg_compat/explain.txt
new file mode 100644
index 0000000000..e253b8ca7b
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_iceberg_compat/explain.txt
@@ -0,0 +1,306 @@
+== Physical Plan ==
+TakeOrderedAndProject (47)
++- * HashAggregate (46)
+ +- * CometColumnarToRow (45)
+ +- CometColumnarExchange (44)
+ +- * HashAggregate (43)
+ +- * Project (42)
+ +- * BroadcastHashJoin Inner BuildRight (41)
+ :- * Project (35)
+ : +- * BroadcastHashJoin Inner BuildRight (34)
+ : :- * Project (28)
+ : : +- * Filter (27)
+ : : +- * BroadcastHashJoin ExistenceJoin(exists#1) BuildRight (26)
+ : : :- * BroadcastHashJoin ExistenceJoin(exists#2) BuildRight (19)
+ : : : :- * CometColumnarToRow (12)
+ : : : : +- CometBroadcastHashJoin (11)
+ : : : : :- CometFilter (2)
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer (1)
+ : : : : +- CometBroadcastExchange (10)
+ : : : : +- CometProject (9)
+ : : : : +- CometBroadcastHashJoin (8)
+ : : : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (3)
+ : : : : +- CometBroadcastExchange (7)
+ : : : : +- CometProject (6)
+ : : : : +- CometFilter (5)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (4)
+ : : : +- BroadcastExchange (18)
+ : : : +- * CometColumnarToRow (17)
+ : : : +- CometProject (16)
+ : : : +- CometBroadcastHashJoin (15)
+ : : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (13)
+ : : : +- ReusedExchange (14)
+ : : +- BroadcastExchange (25)
+ : : +- * CometColumnarToRow (24)
+ : : +- CometProject (23)
+ : : +- CometBroadcastHashJoin (22)
+ : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (20)
+ : : +- ReusedExchange (21)
+ : +- BroadcastExchange (33)
+ : +- * CometColumnarToRow (32)
+ : +- CometProject (31)
+ : +- CometFilter (30)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address (29)
+ +- BroadcastExchange (40)
+ +- * CometColumnarToRow (39)
+ +- CometProject (38)
+ +- CometFilter (37)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_demographics (36)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+Output [3]: [c_customer_sk#3, c_current_cdemo_sk#4, c_current_addr_sk#5]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_current_addr_sk), IsNotNull(c_current_cdemo_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [3]: [c_customer_sk#3, c_current_cdemo_sk#4, c_current_addr_sk#5]
+Condition : (isnotnull(c_current_addr_sk#5) AND isnotnull(c_current_cdemo_sk#4))
+
+(3) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [2]: [ss_customer_sk#6, ss_sold_date_sk#7]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#7), dynamicpruningexpression(ss_sold_date_sk#7 IN dynamicpruning#8)]
+ReadSchema: struct
+
+(4) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [3]: [d_date_sk#9, d_year#10, d_moy#11]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), IsNotNull(d_moy), EqualTo(d_year,2002), GreaterThanOrEqual(d_moy,1), LessThanOrEqual(d_moy,4), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(5) CometFilter
+Input [3]: [d_date_sk#9, d_year#10, d_moy#11]
+Condition : (((((isnotnull(d_year#10) AND isnotnull(d_moy#11)) AND (d_year#10 = 2002)) AND (d_moy#11 >= 1)) AND (d_moy#11 <= 4)) AND isnotnull(d_date_sk#9))
+
+(6) CometProject
+Input [3]: [d_date_sk#9, d_year#10, d_moy#11]
+Arguments: [d_date_sk#9], [d_date_sk#9]
+
+(7) CometBroadcastExchange
+Input [1]: [d_date_sk#9]
+Arguments: [d_date_sk#9]
+
+(8) CometBroadcastHashJoin
+Left output [2]: [ss_customer_sk#6, ss_sold_date_sk#7]
+Right output [1]: [d_date_sk#9]
+Arguments: [ss_sold_date_sk#7], [d_date_sk#9], Inner, BuildRight
+
+(9) CometProject
+Input [3]: [ss_customer_sk#6, ss_sold_date_sk#7, d_date_sk#9]
+Arguments: [ss_customer_sk#6], [ss_customer_sk#6]
+
+(10) CometBroadcastExchange
+Input [1]: [ss_customer_sk#6]
+Arguments: [ss_customer_sk#6]
+
+(11) CometBroadcastHashJoin
+Left output [3]: [c_customer_sk#3, c_current_cdemo_sk#4, c_current_addr_sk#5]
+Right output [1]: [ss_customer_sk#6]
+Arguments: [c_customer_sk#3], [ss_customer_sk#6], LeftSemi, BuildRight
+
+(12) CometColumnarToRow [codegen id : 5]
+Input [3]: [c_customer_sk#3, c_current_cdemo_sk#4, c_current_addr_sk#5]
+
+(13) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [2]: [ws_bill_customer_sk#12, ws_sold_date_sk#13]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#13), dynamicpruningexpression(ws_sold_date_sk#13 IN dynamicpruning#14)]
+ReadSchema: struct
+
+(14) ReusedExchange [Reuses operator id: 7]
+Output [1]: [d_date_sk#15]
+
+(15) CometBroadcastHashJoin
+Left output [2]: [ws_bill_customer_sk#12, ws_sold_date_sk#13]
+Right output [1]: [d_date_sk#15]
+Arguments: [ws_sold_date_sk#13], [d_date_sk#15], Inner, BuildRight
+
+(16) CometProject
+Input [3]: [ws_bill_customer_sk#12, ws_sold_date_sk#13, d_date_sk#15]
+Arguments: [ws_bill_customer_sk#12], [ws_bill_customer_sk#12]
+
+(17) CometColumnarToRow [codegen id : 1]
+Input [1]: [ws_bill_customer_sk#12]
+
+(18) BroadcastExchange
+Input [1]: [ws_bill_customer_sk#12]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=1]
+
+(19) BroadcastHashJoin [codegen id : 5]
+Left keys [1]: [c_customer_sk#3]
+Right keys [1]: [ws_bill_customer_sk#12]
+Join type: ExistenceJoin(exists#2)
+Join condition: None
+
+(20) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [2]: [cs_ship_customer_sk#16, cs_sold_date_sk#17]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#17), dynamicpruningexpression(cs_sold_date_sk#17 IN dynamicpruning#18)]
+ReadSchema: struct
+
+(21) ReusedExchange [Reuses operator id: 7]
+Output [1]: [d_date_sk#19]
+
+(22) CometBroadcastHashJoin
+Left output [2]: [cs_ship_customer_sk#16, cs_sold_date_sk#17]
+Right output [1]: [d_date_sk#19]
+Arguments: [cs_sold_date_sk#17], [d_date_sk#19], Inner, BuildRight
+
+(23) CometProject
+Input [3]: [cs_ship_customer_sk#16, cs_sold_date_sk#17, d_date_sk#19]
+Arguments: [cs_ship_customer_sk#16], [cs_ship_customer_sk#16]
+
+(24) CometColumnarToRow [codegen id : 2]
+Input [1]: [cs_ship_customer_sk#16]
+
+(25) BroadcastExchange
+Input [1]: [cs_ship_customer_sk#16]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=2]
+
+(26) BroadcastHashJoin [codegen id : 5]
+Left keys [1]: [c_customer_sk#3]
+Right keys [1]: [cs_ship_customer_sk#16]
+Join type: ExistenceJoin(exists#1)
+Join condition: None
+
+(27) Filter [codegen id : 5]
+Input [5]: [c_customer_sk#3, c_current_cdemo_sk#4, c_current_addr_sk#5, exists#2, exists#1]
+Condition : (exists#2 OR exists#1)
+
+(28) Project [codegen id : 5]
+Output [2]: [c_current_cdemo_sk#4, c_current_addr_sk#5]
+Input [5]: [c_customer_sk#3, c_current_cdemo_sk#4, c_current_addr_sk#5, exists#2, exists#1]
+
+(29) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address
+Output [2]: [ca_address_sk#20, ca_county#21]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_address]
+PushedFilters: [In(ca_county, [Dona Ana County,Jefferson County,La Porte County,Rush County,Toole County]), IsNotNull(ca_address_sk)]
+ReadSchema: struct
+
+(30) CometFilter
+Input [2]: [ca_address_sk#20, ca_county#21]
+Condition : (ca_county#21 IN (Rush County,Toole County,Jefferson County,Dona Ana County,La Porte County) AND isnotnull(ca_address_sk#20))
+
+(31) CometProject
+Input [2]: [ca_address_sk#20, ca_county#21]
+Arguments: [ca_address_sk#20], [ca_address_sk#20]
+
+(32) CometColumnarToRow [codegen id : 3]
+Input [1]: [ca_address_sk#20]
+
+(33) BroadcastExchange
+Input [1]: [ca_address_sk#20]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=3]
+
+(34) BroadcastHashJoin [codegen id : 5]
+Left keys [1]: [c_current_addr_sk#5]
+Right keys [1]: [ca_address_sk#20]
+Join type: Inner
+Join condition: None
+
+(35) Project [codegen id : 5]
+Output [1]: [c_current_cdemo_sk#4]
+Input [3]: [c_current_cdemo_sk#4, c_current_addr_sk#5, ca_address_sk#20]
+
+(36) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_demographics
+Output [9]: [cd_demo_sk#22, cd_gender#23, cd_marital_status#24, cd_education_status#25, cd_purchase_estimate#26, cd_credit_rating#27, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_demographics]
+PushedFilters: [IsNotNull(cd_demo_sk)]
+ReadSchema: struct
+
+(37) CometFilter
+Input [9]: [cd_demo_sk#22, cd_gender#23, cd_marital_status#24, cd_education_status#25, cd_purchase_estimate#26, cd_credit_rating#27, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+Condition : isnotnull(cd_demo_sk#22)
+
+(38) CometProject
+Input [9]: [cd_demo_sk#22, cd_gender#23, cd_marital_status#24, cd_education_status#25, cd_purchase_estimate#26, cd_credit_rating#27, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+Arguments: [cd_demo_sk#22, cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30], [cd_demo_sk#22, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_gender#23, 1)) AS cd_gender#31, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_marital_status#24, 1)) AS cd_marital_status#32, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_education_status#25, 20)) AS cd_education_status#33, cd_purchase_estimate#26, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_credit_rating#27, 10)) AS cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+
+(39) CometColumnarToRow [codegen id : 4]
+Input [9]: [cd_demo_sk#22, cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+
+(40) BroadcastExchange
+Input [9]: [cd_demo_sk#22, cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=4]
+
+(41) BroadcastHashJoin [codegen id : 5]
+Left keys [1]: [c_current_cdemo_sk#4]
+Right keys [1]: [cd_demo_sk#22]
+Join type: Inner
+Join condition: None
+
+(42) Project [codegen id : 5]
+Output [8]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+Input [10]: [c_current_cdemo_sk#4, cd_demo_sk#22, cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+
+(43) HashAggregate [codegen id : 5]
+Input [8]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+Keys [8]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+Functions [1]: [partial_count(1)]
+Aggregate Attributes [1]: [count#35]
+Results [9]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30, count#36]
+
+(44) CometColumnarExchange
+Input [9]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30, count#36]
+Arguments: hashpartitioning(cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=5]
+
+(45) CometColumnarToRow [codegen id : 6]
+Input [9]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30, count#36]
+
+(46) HashAggregate [codegen id : 6]
+Input [9]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30, count#36]
+Keys [8]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+Functions [1]: [count(1)]
+Aggregate Attributes [1]: [count(1)#37]
+Results [14]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, count(1)#37 AS cnt1#38, cd_purchase_estimate#26, count(1)#37 AS cnt2#39, cd_credit_rating#34, count(1)#37 AS cnt3#40, cd_dep_count#28, count(1)#37 AS cnt4#41, cd_dep_employed_count#29, count(1)#37 AS cnt5#42, cd_dep_college_count#30, count(1)#37 AS cnt6#43]
+
+(47) TakeOrderedAndProject
+Input [14]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cnt1#38, cd_purchase_estimate#26, cnt2#39, cd_credit_rating#34, cnt3#40, cd_dep_count#28, cnt4#41, cd_dep_employed_count#29, cnt5#42, cd_dep_college_count#30, cnt6#43]
+Arguments: 100, [cd_gender#31 ASC NULLS FIRST, cd_marital_status#32 ASC NULLS FIRST, cd_education_status#33 ASC NULLS FIRST, cd_purchase_estimate#26 ASC NULLS FIRST, cd_credit_rating#34 ASC NULLS FIRST, cd_dep_count#28 ASC NULLS FIRST, cd_dep_employed_count#29 ASC NULLS FIRST, cd_dep_college_count#30 ASC NULLS FIRST], [cd_gender#31, cd_marital_status#32, cd_education_status#33, cnt1#38, cd_purchase_estimate#26, cnt2#39, cd_credit_rating#34, cnt3#40, cd_dep_count#28, cnt4#41, cd_dep_employed_count#29, cnt5#42, cd_dep_college_count#30, cnt6#43]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 3 Hosting Expression = ss_sold_date_sk#7 IN dynamicpruning#8
+BroadcastExchange (52)
++- * CometColumnarToRow (51)
+ +- CometProject (50)
+ +- CometFilter (49)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (48)
+
+
+(48) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [3]: [d_date_sk#9, d_year#10, d_moy#11]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), IsNotNull(d_moy), EqualTo(d_year,2002), GreaterThanOrEqual(d_moy,1), LessThanOrEqual(d_moy,4), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(49) CometFilter
+Input [3]: [d_date_sk#9, d_year#10, d_moy#11]
+Condition : (((((isnotnull(d_year#10) AND isnotnull(d_moy#11)) AND (d_year#10 = 2002)) AND (d_moy#11 >= 1)) AND (d_moy#11 <= 4)) AND isnotnull(d_date_sk#9))
+
+(50) CometProject
+Input [3]: [d_date_sk#9, d_year#10, d_moy#11]
+Arguments: [d_date_sk#9], [d_date_sk#9]
+
+(51) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#9]
+
+(52) BroadcastExchange
+Input [1]: [d_date_sk#9]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=6]
+
+Subquery:2 Hosting operator id = 13 Hosting Expression = ws_sold_date_sk#13 IN dynamicpruning#8
+
+Subquery:3 Hosting operator id = 20 Hosting Expression = cs_sold_date_sk#17 IN dynamicpruning#8
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_iceberg_compat/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_iceberg_compat/extended.txt
new file mode 100644
index 0000000000..a6f33d6f7e
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_iceberg_compat/extended.txt
@@ -0,0 +1,63 @@
+TakeOrderedAndProject
++- HashAggregate
+ +- CometColumnarToRow
+ +- CometColumnarExchange
+ +- HashAggregate
+ +- Project
+ +- BroadcastHashJoin
+ :- Project
+ : +- BroadcastHashJoin
+ : :- Project
+ : : +- Filter
+ : : +- BroadcastHashJoin
+ : : :- BroadcastHashJoin [COMET: Unsupported join type ExistenceJoin(exists#1)]
+ : : : :- CometColumnarToRow
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : +- ReusedSubquery
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- BroadcastExchange
+ : +- CometColumnarToRow
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address
+ +- BroadcastExchange
+ +- CometColumnarToRow
+ +- CometProject
+ +- CometFilter
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_demographics
+
+Comet accelerated 35 out of 54 eligible operators (64%). Final plan contains 7 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_iceberg_compat/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_iceberg_compat/simplified.txt
new file mode 100644
index 0000000000..e7193f87e1
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10.native_iceberg_compat/simplified.txt
@@ -0,0 +1,73 @@
+TakeOrderedAndProject [cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count,cnt1,cnt2,cnt3,cnt4,cnt5,cnt6]
+ WholeStageCodegen (6)
+ HashAggregate [cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count,count] [count(1),cnt1,cnt2,cnt3,cnt4,cnt5,cnt6,count]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count] #1
+ WholeStageCodegen (5)
+ HashAggregate [cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count] [count,count]
+ Project [cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count]
+ BroadcastHashJoin [c_current_cdemo_sk,cd_demo_sk]
+ Project [c_current_cdemo_sk]
+ BroadcastHashJoin [c_current_addr_sk,ca_address_sk]
+ Project [c_current_cdemo_sk,c_current_addr_sk]
+ Filter [exists,exists]
+ BroadcastHashJoin [c_customer_sk,cs_ship_customer_sk]
+ BroadcastHashJoin [c_customer_sk,ws_bill_customer_sk]
+ CometColumnarToRow
+ InputAdapter
+ CometBroadcastHashJoin [c_customer_sk,c_current_cdemo_sk,c_current_addr_sk,ss_customer_sk]
+ CometFilter [c_customer_sk,c_current_cdemo_sk,c_current_addr_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer [c_customer_sk,c_current_cdemo_sk,c_current_addr_sk]
+ CometBroadcastExchange [ss_customer_sk] #2
+ CometProject [ss_customer_sk]
+ CometBroadcastHashJoin [ss_customer_sk,ss_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_customer_sk,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #3
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year,d_moy]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year,d_moy]
+ CometBroadcastExchange [d_date_sk] #4
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year,d_moy]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year,d_moy]
+ InputAdapter
+ BroadcastExchange #5
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [ws_bill_customer_sk]
+ CometBroadcastHashJoin [ws_bill_customer_sk,ws_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_bill_customer_sk,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ ReusedExchange [d_date_sk] #4
+ InputAdapter
+ BroadcastExchange #6
+ WholeStageCodegen (2)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [cs_ship_customer_sk]
+ CometBroadcastHashJoin [cs_ship_customer_sk,cs_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_ship_customer_sk,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ ReusedExchange [d_date_sk] #4
+ InputAdapter
+ BroadcastExchange #7
+ WholeStageCodegen (3)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [ca_address_sk]
+ CometFilter [ca_address_sk,ca_county]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address [ca_address_sk,ca_county]
+ InputAdapter
+ BroadcastExchange #8
+ WholeStageCodegen (4)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [cd_gender,cd_marital_status,cd_education_status,cd_credit_rating] [cd_demo_sk,cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count]
+ CometFilter [cd_demo_sk,cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_demographics [cd_demo_sk,cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count]
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10/explain.txt
new file mode 100644
index 0000000000..e253b8ca7b
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10/explain.txt
@@ -0,0 +1,306 @@
+== Physical Plan ==
+TakeOrderedAndProject (47)
++- * HashAggregate (46)
+ +- * CometColumnarToRow (45)
+ +- CometColumnarExchange (44)
+ +- * HashAggregate (43)
+ +- * Project (42)
+ +- * BroadcastHashJoin Inner BuildRight (41)
+ :- * Project (35)
+ : +- * BroadcastHashJoin Inner BuildRight (34)
+ : :- * Project (28)
+ : : +- * Filter (27)
+ : : +- * BroadcastHashJoin ExistenceJoin(exists#1) BuildRight (26)
+ : : :- * BroadcastHashJoin ExistenceJoin(exists#2) BuildRight (19)
+ : : : :- * CometColumnarToRow (12)
+ : : : : +- CometBroadcastHashJoin (11)
+ : : : : :- CometFilter (2)
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer (1)
+ : : : : +- CometBroadcastExchange (10)
+ : : : : +- CometProject (9)
+ : : : : +- CometBroadcastHashJoin (8)
+ : : : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (3)
+ : : : : +- CometBroadcastExchange (7)
+ : : : : +- CometProject (6)
+ : : : : +- CometFilter (5)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (4)
+ : : : +- BroadcastExchange (18)
+ : : : +- * CometColumnarToRow (17)
+ : : : +- CometProject (16)
+ : : : +- CometBroadcastHashJoin (15)
+ : : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (13)
+ : : : +- ReusedExchange (14)
+ : : +- BroadcastExchange (25)
+ : : +- * CometColumnarToRow (24)
+ : : +- CometProject (23)
+ : : +- CometBroadcastHashJoin (22)
+ : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (20)
+ : : +- ReusedExchange (21)
+ : +- BroadcastExchange (33)
+ : +- * CometColumnarToRow (32)
+ : +- CometProject (31)
+ : +- CometFilter (30)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address (29)
+ +- BroadcastExchange (40)
+ +- * CometColumnarToRow (39)
+ +- CometProject (38)
+ +- CometFilter (37)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_demographics (36)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+Output [3]: [c_customer_sk#3, c_current_cdemo_sk#4, c_current_addr_sk#5]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_current_addr_sk), IsNotNull(c_current_cdemo_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [3]: [c_customer_sk#3, c_current_cdemo_sk#4, c_current_addr_sk#5]
+Condition : (isnotnull(c_current_addr_sk#5) AND isnotnull(c_current_cdemo_sk#4))
+
+(3) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [2]: [ss_customer_sk#6, ss_sold_date_sk#7]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#7), dynamicpruningexpression(ss_sold_date_sk#7 IN dynamicpruning#8)]
+ReadSchema: struct
+
+(4) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [3]: [d_date_sk#9, d_year#10, d_moy#11]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), IsNotNull(d_moy), EqualTo(d_year,2002), GreaterThanOrEqual(d_moy,1), LessThanOrEqual(d_moy,4), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(5) CometFilter
+Input [3]: [d_date_sk#9, d_year#10, d_moy#11]
+Condition : (((((isnotnull(d_year#10) AND isnotnull(d_moy#11)) AND (d_year#10 = 2002)) AND (d_moy#11 >= 1)) AND (d_moy#11 <= 4)) AND isnotnull(d_date_sk#9))
+
+(6) CometProject
+Input [3]: [d_date_sk#9, d_year#10, d_moy#11]
+Arguments: [d_date_sk#9], [d_date_sk#9]
+
+(7) CometBroadcastExchange
+Input [1]: [d_date_sk#9]
+Arguments: [d_date_sk#9]
+
+(8) CometBroadcastHashJoin
+Left output [2]: [ss_customer_sk#6, ss_sold_date_sk#7]
+Right output [1]: [d_date_sk#9]
+Arguments: [ss_sold_date_sk#7], [d_date_sk#9], Inner, BuildRight
+
+(9) CometProject
+Input [3]: [ss_customer_sk#6, ss_sold_date_sk#7, d_date_sk#9]
+Arguments: [ss_customer_sk#6], [ss_customer_sk#6]
+
+(10) CometBroadcastExchange
+Input [1]: [ss_customer_sk#6]
+Arguments: [ss_customer_sk#6]
+
+(11) CometBroadcastHashJoin
+Left output [3]: [c_customer_sk#3, c_current_cdemo_sk#4, c_current_addr_sk#5]
+Right output [1]: [ss_customer_sk#6]
+Arguments: [c_customer_sk#3], [ss_customer_sk#6], LeftSemi, BuildRight
+
+(12) CometColumnarToRow [codegen id : 5]
+Input [3]: [c_customer_sk#3, c_current_cdemo_sk#4, c_current_addr_sk#5]
+
+(13) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [2]: [ws_bill_customer_sk#12, ws_sold_date_sk#13]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#13), dynamicpruningexpression(ws_sold_date_sk#13 IN dynamicpruning#14)]
+ReadSchema: struct
+
+(14) ReusedExchange [Reuses operator id: 7]
+Output [1]: [d_date_sk#15]
+
+(15) CometBroadcastHashJoin
+Left output [2]: [ws_bill_customer_sk#12, ws_sold_date_sk#13]
+Right output [1]: [d_date_sk#15]
+Arguments: [ws_sold_date_sk#13], [d_date_sk#15], Inner, BuildRight
+
+(16) CometProject
+Input [3]: [ws_bill_customer_sk#12, ws_sold_date_sk#13, d_date_sk#15]
+Arguments: [ws_bill_customer_sk#12], [ws_bill_customer_sk#12]
+
+(17) CometColumnarToRow [codegen id : 1]
+Input [1]: [ws_bill_customer_sk#12]
+
+(18) BroadcastExchange
+Input [1]: [ws_bill_customer_sk#12]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=1]
+
+(19) BroadcastHashJoin [codegen id : 5]
+Left keys [1]: [c_customer_sk#3]
+Right keys [1]: [ws_bill_customer_sk#12]
+Join type: ExistenceJoin(exists#2)
+Join condition: None
+
+(20) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [2]: [cs_ship_customer_sk#16, cs_sold_date_sk#17]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#17), dynamicpruningexpression(cs_sold_date_sk#17 IN dynamicpruning#18)]
+ReadSchema: struct
+
+(21) ReusedExchange [Reuses operator id: 7]
+Output [1]: [d_date_sk#19]
+
+(22) CometBroadcastHashJoin
+Left output [2]: [cs_ship_customer_sk#16, cs_sold_date_sk#17]
+Right output [1]: [d_date_sk#19]
+Arguments: [cs_sold_date_sk#17], [d_date_sk#19], Inner, BuildRight
+
+(23) CometProject
+Input [3]: [cs_ship_customer_sk#16, cs_sold_date_sk#17, d_date_sk#19]
+Arguments: [cs_ship_customer_sk#16], [cs_ship_customer_sk#16]
+
+(24) CometColumnarToRow [codegen id : 2]
+Input [1]: [cs_ship_customer_sk#16]
+
+(25) BroadcastExchange
+Input [1]: [cs_ship_customer_sk#16]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=2]
+
+(26) BroadcastHashJoin [codegen id : 5]
+Left keys [1]: [c_customer_sk#3]
+Right keys [1]: [cs_ship_customer_sk#16]
+Join type: ExistenceJoin(exists#1)
+Join condition: None
+
+(27) Filter [codegen id : 5]
+Input [5]: [c_customer_sk#3, c_current_cdemo_sk#4, c_current_addr_sk#5, exists#2, exists#1]
+Condition : (exists#2 OR exists#1)
+
+(28) Project [codegen id : 5]
+Output [2]: [c_current_cdemo_sk#4, c_current_addr_sk#5]
+Input [5]: [c_customer_sk#3, c_current_cdemo_sk#4, c_current_addr_sk#5, exists#2, exists#1]
+
+(29) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address
+Output [2]: [ca_address_sk#20, ca_county#21]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_address]
+PushedFilters: [In(ca_county, [Dona Ana County,Jefferson County,La Porte County,Rush County,Toole County]), IsNotNull(ca_address_sk)]
+ReadSchema: struct
+
+(30) CometFilter
+Input [2]: [ca_address_sk#20, ca_county#21]
+Condition : (ca_county#21 IN (Rush County,Toole County,Jefferson County,Dona Ana County,La Porte County) AND isnotnull(ca_address_sk#20))
+
+(31) CometProject
+Input [2]: [ca_address_sk#20, ca_county#21]
+Arguments: [ca_address_sk#20], [ca_address_sk#20]
+
+(32) CometColumnarToRow [codegen id : 3]
+Input [1]: [ca_address_sk#20]
+
+(33) BroadcastExchange
+Input [1]: [ca_address_sk#20]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=3]
+
+(34) BroadcastHashJoin [codegen id : 5]
+Left keys [1]: [c_current_addr_sk#5]
+Right keys [1]: [ca_address_sk#20]
+Join type: Inner
+Join condition: None
+
+(35) Project [codegen id : 5]
+Output [1]: [c_current_cdemo_sk#4]
+Input [3]: [c_current_cdemo_sk#4, c_current_addr_sk#5, ca_address_sk#20]
+
+(36) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_demographics
+Output [9]: [cd_demo_sk#22, cd_gender#23, cd_marital_status#24, cd_education_status#25, cd_purchase_estimate#26, cd_credit_rating#27, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_demographics]
+PushedFilters: [IsNotNull(cd_demo_sk)]
+ReadSchema: struct
+
+(37) CometFilter
+Input [9]: [cd_demo_sk#22, cd_gender#23, cd_marital_status#24, cd_education_status#25, cd_purchase_estimate#26, cd_credit_rating#27, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+Condition : isnotnull(cd_demo_sk#22)
+
+(38) CometProject
+Input [9]: [cd_demo_sk#22, cd_gender#23, cd_marital_status#24, cd_education_status#25, cd_purchase_estimate#26, cd_credit_rating#27, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+Arguments: [cd_demo_sk#22, cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30], [cd_demo_sk#22, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_gender#23, 1)) AS cd_gender#31, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_marital_status#24, 1)) AS cd_marital_status#32, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_education_status#25, 20)) AS cd_education_status#33, cd_purchase_estimate#26, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_credit_rating#27, 10)) AS cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+
+(39) CometColumnarToRow [codegen id : 4]
+Input [9]: [cd_demo_sk#22, cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+
+(40) BroadcastExchange
+Input [9]: [cd_demo_sk#22, cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=4]
+
+(41) BroadcastHashJoin [codegen id : 5]
+Left keys [1]: [c_current_cdemo_sk#4]
+Right keys [1]: [cd_demo_sk#22]
+Join type: Inner
+Join condition: None
+
+(42) Project [codegen id : 5]
+Output [8]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+Input [10]: [c_current_cdemo_sk#4, cd_demo_sk#22, cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+
+(43) HashAggregate [codegen id : 5]
+Input [8]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+Keys [8]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+Functions [1]: [partial_count(1)]
+Aggregate Attributes [1]: [count#35]
+Results [9]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30, count#36]
+
+(44) CometColumnarExchange
+Input [9]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30, count#36]
+Arguments: hashpartitioning(cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=5]
+
+(45) CometColumnarToRow [codegen id : 6]
+Input [9]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30, count#36]
+
+(46) HashAggregate [codegen id : 6]
+Input [9]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30, count#36]
+Keys [8]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cd_purchase_estimate#26, cd_credit_rating#34, cd_dep_count#28, cd_dep_employed_count#29, cd_dep_college_count#30]
+Functions [1]: [count(1)]
+Aggregate Attributes [1]: [count(1)#37]
+Results [14]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, count(1)#37 AS cnt1#38, cd_purchase_estimate#26, count(1)#37 AS cnt2#39, cd_credit_rating#34, count(1)#37 AS cnt3#40, cd_dep_count#28, count(1)#37 AS cnt4#41, cd_dep_employed_count#29, count(1)#37 AS cnt5#42, cd_dep_college_count#30, count(1)#37 AS cnt6#43]
+
+(47) TakeOrderedAndProject
+Input [14]: [cd_gender#31, cd_marital_status#32, cd_education_status#33, cnt1#38, cd_purchase_estimate#26, cnt2#39, cd_credit_rating#34, cnt3#40, cd_dep_count#28, cnt4#41, cd_dep_employed_count#29, cnt5#42, cd_dep_college_count#30, cnt6#43]
+Arguments: 100, [cd_gender#31 ASC NULLS FIRST, cd_marital_status#32 ASC NULLS FIRST, cd_education_status#33 ASC NULLS FIRST, cd_purchase_estimate#26 ASC NULLS FIRST, cd_credit_rating#34 ASC NULLS FIRST, cd_dep_count#28 ASC NULLS FIRST, cd_dep_employed_count#29 ASC NULLS FIRST, cd_dep_college_count#30 ASC NULLS FIRST], [cd_gender#31, cd_marital_status#32, cd_education_status#33, cnt1#38, cd_purchase_estimate#26, cnt2#39, cd_credit_rating#34, cnt3#40, cd_dep_count#28, cnt4#41, cd_dep_employed_count#29, cnt5#42, cd_dep_college_count#30, cnt6#43]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 3 Hosting Expression = ss_sold_date_sk#7 IN dynamicpruning#8
+BroadcastExchange (52)
++- * CometColumnarToRow (51)
+ +- CometProject (50)
+ +- CometFilter (49)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (48)
+
+
+(48) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [3]: [d_date_sk#9, d_year#10, d_moy#11]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), IsNotNull(d_moy), EqualTo(d_year,2002), GreaterThanOrEqual(d_moy,1), LessThanOrEqual(d_moy,4), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(49) CometFilter
+Input [3]: [d_date_sk#9, d_year#10, d_moy#11]
+Condition : (((((isnotnull(d_year#10) AND isnotnull(d_moy#11)) AND (d_year#10 = 2002)) AND (d_moy#11 >= 1)) AND (d_moy#11 <= 4)) AND isnotnull(d_date_sk#9))
+
+(50) CometProject
+Input [3]: [d_date_sk#9, d_year#10, d_moy#11]
+Arguments: [d_date_sk#9], [d_date_sk#9]
+
+(51) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#9]
+
+(52) BroadcastExchange
+Input [1]: [d_date_sk#9]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=6]
+
+Subquery:2 Hosting operator id = 13 Hosting Expression = ws_sold_date_sk#13 IN dynamicpruning#8
+
+Subquery:3 Hosting operator id = 20 Hosting Expression = cs_sold_date_sk#17 IN dynamicpruning#8
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10/extended.txt
new file mode 100644
index 0000000000..a6f33d6f7e
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10/extended.txt
@@ -0,0 +1,63 @@
+TakeOrderedAndProject
++- HashAggregate
+ +- CometColumnarToRow
+ +- CometColumnarExchange
+ +- HashAggregate
+ +- Project
+ +- BroadcastHashJoin
+ :- Project
+ : +- BroadcastHashJoin
+ : :- Project
+ : : +- Filter
+ : : +- BroadcastHashJoin
+ : : :- BroadcastHashJoin [COMET: Unsupported join type ExistenceJoin(exists#1)]
+ : : : :- CometColumnarToRow
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : +- ReusedSubquery
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- BroadcastExchange
+ : +- CometColumnarToRow
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address
+ +- BroadcastExchange
+ +- CometColumnarToRow
+ +- CometProject
+ +- CometFilter
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_demographics
+
+Comet accelerated 35 out of 54 eligible operators (64%). Final plan contains 7 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10/simplified.txt
new file mode 100644
index 0000000000..e7193f87e1
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q10/simplified.txt
@@ -0,0 +1,73 @@
+TakeOrderedAndProject [cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count,cnt1,cnt2,cnt3,cnt4,cnt5,cnt6]
+ WholeStageCodegen (6)
+ HashAggregate [cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count,count] [count(1),cnt1,cnt2,cnt3,cnt4,cnt5,cnt6,count]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count] #1
+ WholeStageCodegen (5)
+ HashAggregate [cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count] [count,count]
+ Project [cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count]
+ BroadcastHashJoin [c_current_cdemo_sk,cd_demo_sk]
+ Project [c_current_cdemo_sk]
+ BroadcastHashJoin [c_current_addr_sk,ca_address_sk]
+ Project [c_current_cdemo_sk,c_current_addr_sk]
+ Filter [exists,exists]
+ BroadcastHashJoin [c_customer_sk,cs_ship_customer_sk]
+ BroadcastHashJoin [c_customer_sk,ws_bill_customer_sk]
+ CometColumnarToRow
+ InputAdapter
+ CometBroadcastHashJoin [c_customer_sk,c_current_cdemo_sk,c_current_addr_sk,ss_customer_sk]
+ CometFilter [c_customer_sk,c_current_cdemo_sk,c_current_addr_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer [c_customer_sk,c_current_cdemo_sk,c_current_addr_sk]
+ CometBroadcastExchange [ss_customer_sk] #2
+ CometProject [ss_customer_sk]
+ CometBroadcastHashJoin [ss_customer_sk,ss_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_customer_sk,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #3
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year,d_moy]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year,d_moy]
+ CometBroadcastExchange [d_date_sk] #4
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year,d_moy]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year,d_moy]
+ InputAdapter
+ BroadcastExchange #5
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [ws_bill_customer_sk]
+ CometBroadcastHashJoin [ws_bill_customer_sk,ws_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_bill_customer_sk,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ ReusedExchange [d_date_sk] #4
+ InputAdapter
+ BroadcastExchange #6
+ WholeStageCodegen (2)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [cs_ship_customer_sk]
+ CometBroadcastHashJoin [cs_ship_customer_sk,cs_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_ship_customer_sk,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ ReusedExchange [d_date_sk] #4
+ InputAdapter
+ BroadcastExchange #7
+ WholeStageCodegen (3)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [ca_address_sk]
+ CometFilter [ca_address_sk,ca_county]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address [ca_address_sk,ca_county]
+ InputAdapter
+ BroadcastExchange #8
+ WholeStageCodegen (4)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [cd_gender,cd_marital_status,cd_education_status,cd_credit_rating] [cd_demo_sk,cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count]
+ CometFilter [cd_demo_sk,cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_demographics [cd_demo_sk,cd_gender,cd_marital_status,cd_education_status,cd_purchase_estimate,cd_credit_rating,cd_dep_count,cd_dep_employed_count,cd_dep_college_count]
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_datafusion/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_datafusion/explain.txt
new file mode 100644
index 0000000000..0b7aa0c883
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_datafusion/explain.txt
@@ -0,0 +1,518 @@
+== Physical Plan ==
+TakeOrderedAndProject (80)
++- * Project (79)
+ +- * BroadcastHashJoin Inner BuildRight (78)
+ :- * Project (59)
+ : +- * BroadcastHashJoin Inner BuildRight (58)
+ : :- * Project (38)
+ : : +- * BroadcastHashJoin Inner BuildRight (37)
+ : : :- * Filter (18)
+ : : : +- * HashAggregate (17)
+ : : : +- * CometColumnarToRow (16)
+ : : : +- CometColumnarExchange (15)
+ : : : +- * HashAggregate (14)
+ : : : +- * Project (13)
+ : : : +- * BroadcastHashJoin Inner BuildRight (12)
+ : : : :- * Project (10)
+ : : : : +- * BroadcastHashJoin Inner BuildRight (9)
+ : : : : :- * CometColumnarToRow (4)
+ : : : : : +- CometProject (3)
+ : : : : : +- CometFilter (2)
+ : : : : : +- CometNativeScan parquet spark_catalog.default.customer (1)
+ : : : : +- BroadcastExchange (8)
+ : : : : +- * Filter (7)
+ : : : : +- * ColumnarToRow (6)
+ : : : : +- Scan parquet spark_catalog.default.store_sales (5)
+ : : : +- ReusedExchange (11)
+ : : +- BroadcastExchange (36)
+ : : +- * HashAggregate (35)
+ : : +- * CometColumnarToRow (34)
+ : : +- CometColumnarExchange (33)
+ : : +- * HashAggregate (32)
+ : : +- * Project (31)
+ : : +- * BroadcastHashJoin Inner BuildRight (30)
+ : : :- * Project (28)
+ : : : +- * BroadcastHashJoin Inner BuildRight (27)
+ : : : :- * CometColumnarToRow (22)
+ : : : : +- CometProject (21)
+ : : : : +- CometFilter (20)
+ : : : : +- CometNativeScan parquet spark_catalog.default.customer (19)
+ : : : +- BroadcastExchange (26)
+ : : : +- * Filter (25)
+ : : : +- * ColumnarToRow (24)
+ : : : +- Scan parquet spark_catalog.default.store_sales (23)
+ : : +- ReusedExchange (29)
+ : +- BroadcastExchange (57)
+ : +- * Filter (56)
+ : +- * HashAggregate (55)
+ : +- * CometColumnarToRow (54)
+ : +- CometColumnarExchange (53)
+ : +- * HashAggregate (52)
+ : +- * Project (51)
+ : +- * BroadcastHashJoin Inner BuildRight (50)
+ : :- * Project (48)
+ : : +- * BroadcastHashJoin Inner BuildRight (47)
+ : : :- * CometColumnarToRow (42)
+ : : : +- CometProject (41)
+ : : : +- CometFilter (40)
+ : : : +- CometNativeScan parquet spark_catalog.default.customer (39)
+ : : +- BroadcastExchange (46)
+ : : +- * Filter (45)
+ : : +- * ColumnarToRow (44)
+ : : +- Scan parquet spark_catalog.default.web_sales (43)
+ : +- ReusedExchange (49)
+ +- BroadcastExchange (77)
+ +- * HashAggregate (76)
+ +- * CometColumnarToRow (75)
+ +- CometColumnarExchange (74)
+ +- * HashAggregate (73)
+ +- * Project (72)
+ +- * BroadcastHashJoin Inner BuildRight (71)
+ :- * Project (69)
+ : +- * BroadcastHashJoin Inner BuildRight (68)
+ : :- * CometColumnarToRow (63)
+ : : +- CometProject (62)
+ : : +- CometFilter (61)
+ : : +- CometNativeScan parquet spark_catalog.default.customer (60)
+ : +- BroadcastExchange (67)
+ : +- * Filter (66)
+ : +- * ColumnarToRow (65)
+ : +- Scan parquet spark_catalog.default.web_sales (64)
+ +- ReusedExchange (70)
+
+
+(1) CometNativeScan parquet spark_catalog.default.customer
+Output [8]: [c_customer_sk#1, c_customer_id#2, c_first_name#3, c_last_name#4, c_preferred_cust_flag#5, c_birth_country#6, c_login#7, c_email_address#8]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [8]: [c_customer_sk#1, c_customer_id#2, c_first_name#3, c_last_name#4, c_preferred_cust_flag#5, c_birth_country#6, c_login#7, c_email_address#8]
+Condition : (isnotnull(c_customer_sk#1) AND isnotnull(static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#2, 16))))
+
+(3) CometProject
+Input [8]: [c_customer_sk#1, c_customer_id#2, c_first_name#3, c_last_name#4, c_preferred_cust_flag#5, c_birth_country#6, c_login#7, c_email_address#8]
+Arguments: [c_customer_sk#1, c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14], [c_customer_sk#1, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#2, 16)) AS c_customer_id#9, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_first_name#3, 20)) AS c_first_name#10, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_last_name#4, 30)) AS c_last_name#11, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_preferred_cust_flag#5, 1)) AS c_preferred_cust_flag#12, c_birth_country#6, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_login#7, 13)) AS c_login#13, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_email_address#8, 50)) AS c_email_address#14]
+
+(4) CometColumnarToRow [codegen id : 3]
+Input [8]: [c_customer_sk#1, c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14]
+
+(5) Scan parquet spark_catalog.default.store_sales
+Output [4]: [ss_customer_sk#15, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#18), dynamicpruningexpression(ss_sold_date_sk#18 IN dynamicpruning#19)]
+PushedFilters: [IsNotNull(ss_customer_sk)]
+ReadSchema: struct
+
+(6) ColumnarToRow [codegen id : 1]
+Input [4]: [ss_customer_sk#15, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+
+(7) Filter [codegen id : 1]
+Input [4]: [ss_customer_sk#15, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+Condition : isnotnull(ss_customer_sk#15)
+
+(8) BroadcastExchange
+Input [4]: [ss_customer_sk#15, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=1]
+
+(9) BroadcastHashJoin [codegen id : 3]
+Left keys [1]: [c_customer_sk#1]
+Right keys [1]: [ss_customer_sk#15]
+Join type: Inner
+Join condition: None
+
+(10) Project [codegen id : 3]
+Output [10]: [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+Input [12]: [c_customer_sk#1, c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_customer_sk#15, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+
+(11) ReusedExchange [Reuses operator id: 84]
+Output [2]: [d_date_sk#20, d_year#21]
+
+(12) BroadcastHashJoin [codegen id : 3]
+Left keys [1]: [ss_sold_date_sk#18]
+Right keys [1]: [d_date_sk#20]
+Join type: Inner
+Join condition: None
+
+(13) Project [codegen id : 3]
+Output [10]: [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, d_year#21]
+Input [12]: [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18, d_date_sk#20, d_year#21]
+
+(14) HashAggregate [codegen id : 3]
+Input [10]: [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, d_year#21]
+Keys [8]: [c_customer_id#9, c_first_name#10, c_last_name#11, d_year#21, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14]
+Functions [1]: [partial_sum(UnscaledValue((ss_ext_list_price#17 - ss_ext_discount_amt#16)))]
+Aggregate Attributes [1]: [sum#22]
+Results [9]: [c_customer_id#9, c_first_name#10, c_last_name#11, d_year#21, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, sum#23]
+
+(15) CometColumnarExchange
+Input [9]: [c_customer_id#9, c_first_name#10, c_last_name#11, d_year#21, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, sum#23]
+Arguments: hashpartitioning(c_customer_id#9, c_first_name#10, c_last_name#11, d_year#21, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=2]
+
+(16) CometColumnarToRow [codegen id : 16]
+Input [9]: [c_customer_id#9, c_first_name#10, c_last_name#11, d_year#21, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, sum#23]
+
+(17) HashAggregate [codegen id : 16]
+Input [9]: [c_customer_id#9, c_first_name#10, c_last_name#11, d_year#21, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, sum#23]
+Keys [8]: [c_customer_id#9, c_first_name#10, c_last_name#11, d_year#21, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14]
+Functions [1]: [sum(UnscaledValue((ss_ext_list_price#17 - ss_ext_discount_amt#16)))]
+Aggregate Attributes [1]: [sum(UnscaledValue((ss_ext_list_price#17 - ss_ext_discount_amt#16)))#24]
+Results [2]: [c_customer_id#9 AS customer_id#25, MakeDecimal(sum(UnscaledValue((ss_ext_list_price#17 - ss_ext_discount_amt#16)))#24,18,2) AS year_total#26]
+
+(18) Filter [codegen id : 16]
+Input [2]: [customer_id#25, year_total#26]
+Condition : (isnotnull(year_total#26) AND (year_total#26 > 0.00))
+
+(19) CometNativeScan parquet spark_catalog.default.customer
+Output [8]: [c_customer_sk#27, c_customer_id#28, c_first_name#29, c_last_name#30, c_preferred_cust_flag#31, c_birth_country#32, c_login#33, c_email_address#34]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk)]
+ReadSchema: struct
+
+(20) CometFilter
+Input [8]: [c_customer_sk#27, c_customer_id#28, c_first_name#29, c_last_name#30, c_preferred_cust_flag#31, c_birth_country#32, c_login#33, c_email_address#34]
+Condition : (isnotnull(c_customer_sk#27) AND isnotnull(static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#28, 16))))
+
+(21) CometProject
+Input [8]: [c_customer_sk#27, c_customer_id#28, c_first_name#29, c_last_name#30, c_preferred_cust_flag#31, c_birth_country#32, c_login#33, c_email_address#34]
+Arguments: [c_customer_sk#27, c_customer_id#35, c_first_name#36, c_last_name#37, c_preferred_cust_flag#38, c_birth_country#32, c_login#39, c_email_address#40], [c_customer_sk#27, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#28, 16)) AS c_customer_id#35, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_first_name#29, 20)) AS c_first_name#36, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_last_name#30, 30)) AS c_last_name#37, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_preferred_cust_flag#31, 1)) AS c_preferred_cust_flag#38, c_birth_country#32, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_login#33, 13)) AS c_login#39, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_email_address#34, 50)) AS c_email_address#40]
+
+(22) CometColumnarToRow [codegen id : 6]
+Input [8]: [c_customer_sk#27, c_customer_id#35, c_first_name#36, c_last_name#37, c_preferred_cust_flag#38, c_birth_country#32, c_login#39, c_email_address#40]
+
+(23) Scan parquet spark_catalog.default.store_sales
+Output [4]: [ss_customer_sk#41, ss_ext_discount_amt#42, ss_ext_list_price#43, ss_sold_date_sk#44]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#44), dynamicpruningexpression(ss_sold_date_sk#44 IN dynamicpruning#45)]
+PushedFilters: [IsNotNull(ss_customer_sk)]
+ReadSchema: struct
+
+(24) ColumnarToRow [codegen id : 4]
+Input [4]: [ss_customer_sk#41, ss_ext_discount_amt#42, ss_ext_list_price#43, ss_sold_date_sk#44]
+
+(25) Filter [codegen id : 4]
+Input [4]: [ss_customer_sk#41, ss_ext_discount_amt#42, ss_ext_list_price#43, ss_sold_date_sk#44]
+Condition : isnotnull(ss_customer_sk#41)
+
+(26) BroadcastExchange
+Input [4]: [ss_customer_sk#41, ss_ext_discount_amt#42, ss_ext_list_price#43, ss_sold_date_sk#44]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=3]
+
+(27) BroadcastHashJoin [codegen id : 6]
+Left keys [1]: [c_customer_sk#27]
+Right keys [1]: [ss_customer_sk#41]
+Join type: Inner
+Join condition: None
+
+(28) Project [codegen id : 6]
+Output [10]: [c_customer_id#35, c_first_name#36, c_last_name#37, c_preferred_cust_flag#38, c_birth_country#32, c_login#39, c_email_address#40, ss_ext_discount_amt#42, ss_ext_list_price#43, ss_sold_date_sk#44]
+Input [12]: [c_customer_sk#27, c_customer_id#35, c_first_name#36, c_last_name#37, c_preferred_cust_flag#38, c_birth_country#32, c_login#39, c_email_address#40, ss_customer_sk#41, ss_ext_discount_amt#42, ss_ext_list_price#43, ss_sold_date_sk#44]
+
+(29) ReusedExchange [Reuses operator id: 88]
+Output [2]: [d_date_sk#46, d_year#47]
+
+(30) BroadcastHashJoin [codegen id : 6]
+Left keys [1]: [ss_sold_date_sk#44]
+Right keys [1]: [d_date_sk#46]
+Join type: Inner
+Join condition: None
+
+(31) Project [codegen id : 6]
+Output [10]: [c_customer_id#35, c_first_name#36, c_last_name#37, c_preferred_cust_flag#38, c_birth_country#32, c_login#39, c_email_address#40, ss_ext_discount_amt#42, ss_ext_list_price#43, d_year#47]
+Input [12]: [c_customer_id#35, c_first_name#36, c_last_name#37, c_preferred_cust_flag#38, c_birth_country#32, c_login#39, c_email_address#40, ss_ext_discount_amt#42, ss_ext_list_price#43, ss_sold_date_sk#44, d_date_sk#46, d_year#47]
+
+(32) HashAggregate [codegen id : 6]
+Input [10]: [c_customer_id#35, c_first_name#36, c_last_name#37, c_preferred_cust_flag#38, c_birth_country#32, c_login#39, c_email_address#40, ss_ext_discount_amt#42, ss_ext_list_price#43, d_year#47]
+Keys [8]: [c_customer_id#35, c_first_name#36, c_last_name#37, d_year#47, c_preferred_cust_flag#38, c_birth_country#32, c_login#39, c_email_address#40]
+Functions [1]: [partial_sum(UnscaledValue((ss_ext_list_price#43 - ss_ext_discount_amt#42)))]
+Aggregate Attributes [1]: [sum#48]
+Results [9]: [c_customer_id#35, c_first_name#36, c_last_name#37, d_year#47, c_preferred_cust_flag#38, c_birth_country#32, c_login#39, c_email_address#40, sum#49]
+
+(33) CometColumnarExchange
+Input [9]: [c_customer_id#35, c_first_name#36, c_last_name#37, d_year#47, c_preferred_cust_flag#38, c_birth_country#32, c_login#39, c_email_address#40, sum#49]
+Arguments: hashpartitioning(c_customer_id#35, c_first_name#36, c_last_name#37, d_year#47, c_preferred_cust_flag#38, c_birth_country#32, c_login#39, c_email_address#40, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=4]
+
+(34) CometColumnarToRow [codegen id : 7]
+Input [9]: [c_customer_id#35, c_first_name#36, c_last_name#37, d_year#47, c_preferred_cust_flag#38, c_birth_country#32, c_login#39, c_email_address#40, sum#49]
+
+(35) HashAggregate [codegen id : 7]
+Input [9]: [c_customer_id#35, c_first_name#36, c_last_name#37, d_year#47, c_preferred_cust_flag#38, c_birth_country#32, c_login#39, c_email_address#40, sum#49]
+Keys [8]: [c_customer_id#35, c_first_name#36, c_last_name#37, d_year#47, c_preferred_cust_flag#38, c_birth_country#32, c_login#39, c_email_address#40]
+Functions [1]: [sum(UnscaledValue((ss_ext_list_price#43 - ss_ext_discount_amt#42)))]
+Aggregate Attributes [1]: [sum(UnscaledValue((ss_ext_list_price#43 - ss_ext_discount_amt#42)))#24]
+Results [3]: [c_customer_id#35 AS customer_id#50, c_preferred_cust_flag#38 AS customer_preferred_cust_flag#51, MakeDecimal(sum(UnscaledValue((ss_ext_list_price#43 - ss_ext_discount_amt#42)))#24,18,2) AS year_total#52]
+
+(36) BroadcastExchange
+Input [3]: [customer_id#50, customer_preferred_cust_flag#51, year_total#52]
+Arguments: HashedRelationBroadcastMode(List(input[0, string, true]),false), [plan_id=5]
+
+(37) BroadcastHashJoin [codegen id : 16]
+Left keys [1]: [customer_id#25]
+Right keys [1]: [customer_id#50]
+Join type: Inner
+Join condition: None
+
+(38) Project [codegen id : 16]
+Output [4]: [customer_id#25, year_total#26, customer_preferred_cust_flag#51, year_total#52]
+Input [5]: [customer_id#25, year_total#26, customer_id#50, customer_preferred_cust_flag#51, year_total#52]
+
+(39) CometNativeScan parquet spark_catalog.default.customer
+Output [8]: [c_customer_sk#53, c_customer_id#54, c_first_name#55, c_last_name#56, c_preferred_cust_flag#57, c_birth_country#58, c_login#59, c_email_address#60]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk)]
+ReadSchema: struct
+
+(40) CometFilter
+Input [8]: [c_customer_sk#53, c_customer_id#54, c_first_name#55, c_last_name#56, c_preferred_cust_flag#57, c_birth_country#58, c_login#59, c_email_address#60]
+Condition : (isnotnull(c_customer_sk#53) AND isnotnull(static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#54, 16))))
+
+(41) CometProject
+Input [8]: [c_customer_sk#53, c_customer_id#54, c_first_name#55, c_last_name#56, c_preferred_cust_flag#57, c_birth_country#58, c_login#59, c_email_address#60]
+Arguments: [c_customer_sk#53, c_customer_id#61, c_first_name#62, c_last_name#63, c_preferred_cust_flag#64, c_birth_country#58, c_login#65, c_email_address#66], [c_customer_sk#53, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#54, 16)) AS c_customer_id#61, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_first_name#55, 20)) AS c_first_name#62, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_last_name#56, 30)) AS c_last_name#63, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_preferred_cust_flag#57, 1)) AS c_preferred_cust_flag#64, c_birth_country#58, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_login#59, 13)) AS c_login#65, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_email_address#60, 50)) AS c_email_address#66]
+
+(42) CometColumnarToRow [codegen id : 10]
+Input [8]: [c_customer_sk#53, c_customer_id#61, c_first_name#62, c_last_name#63, c_preferred_cust_flag#64, c_birth_country#58, c_login#65, c_email_address#66]
+
+(43) Scan parquet spark_catalog.default.web_sales
+Output [4]: [ws_bill_customer_sk#67, ws_ext_discount_amt#68, ws_ext_list_price#69, ws_sold_date_sk#70]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#70), dynamicpruningexpression(ws_sold_date_sk#70 IN dynamicpruning#19)]
+PushedFilters: [IsNotNull(ws_bill_customer_sk)]
+ReadSchema: struct
+
+(44) ColumnarToRow [codegen id : 8]
+Input [4]: [ws_bill_customer_sk#67, ws_ext_discount_amt#68, ws_ext_list_price#69, ws_sold_date_sk#70]
+
+(45) Filter [codegen id : 8]
+Input [4]: [ws_bill_customer_sk#67, ws_ext_discount_amt#68, ws_ext_list_price#69, ws_sold_date_sk#70]
+Condition : isnotnull(ws_bill_customer_sk#67)
+
+(46) BroadcastExchange
+Input [4]: [ws_bill_customer_sk#67, ws_ext_discount_amt#68, ws_ext_list_price#69, ws_sold_date_sk#70]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=6]
+
+(47) BroadcastHashJoin [codegen id : 10]
+Left keys [1]: [c_customer_sk#53]
+Right keys [1]: [ws_bill_customer_sk#67]
+Join type: Inner
+Join condition: None
+
+(48) Project [codegen id : 10]
+Output [10]: [c_customer_id#61, c_first_name#62, c_last_name#63, c_preferred_cust_flag#64, c_birth_country#58, c_login#65, c_email_address#66, ws_ext_discount_amt#68, ws_ext_list_price#69, ws_sold_date_sk#70]
+Input [12]: [c_customer_sk#53, c_customer_id#61, c_first_name#62, c_last_name#63, c_preferred_cust_flag#64, c_birth_country#58, c_login#65, c_email_address#66, ws_bill_customer_sk#67, ws_ext_discount_amt#68, ws_ext_list_price#69, ws_sold_date_sk#70]
+
+(49) ReusedExchange [Reuses operator id: 84]
+Output [2]: [d_date_sk#71, d_year#72]
+
+(50) BroadcastHashJoin [codegen id : 10]
+Left keys [1]: [ws_sold_date_sk#70]
+Right keys [1]: [d_date_sk#71]
+Join type: Inner
+Join condition: None
+
+(51) Project [codegen id : 10]
+Output [10]: [c_customer_id#61, c_first_name#62, c_last_name#63, c_preferred_cust_flag#64, c_birth_country#58, c_login#65, c_email_address#66, ws_ext_discount_amt#68, ws_ext_list_price#69, d_year#72]
+Input [12]: [c_customer_id#61, c_first_name#62, c_last_name#63, c_preferred_cust_flag#64, c_birth_country#58, c_login#65, c_email_address#66, ws_ext_discount_amt#68, ws_ext_list_price#69, ws_sold_date_sk#70, d_date_sk#71, d_year#72]
+
+(52) HashAggregate [codegen id : 10]
+Input [10]: [c_customer_id#61, c_first_name#62, c_last_name#63, c_preferred_cust_flag#64, c_birth_country#58, c_login#65, c_email_address#66, ws_ext_discount_amt#68, ws_ext_list_price#69, d_year#72]
+Keys [8]: [c_customer_id#61, c_first_name#62, c_last_name#63, c_preferred_cust_flag#64, c_birth_country#58, c_login#65, c_email_address#66, d_year#72]
+Functions [1]: [partial_sum(UnscaledValue((ws_ext_list_price#69 - ws_ext_discount_amt#68)))]
+Aggregate Attributes [1]: [sum#73]
+Results [9]: [c_customer_id#61, c_first_name#62, c_last_name#63, c_preferred_cust_flag#64, c_birth_country#58, c_login#65, c_email_address#66, d_year#72, sum#74]
+
+(53) CometColumnarExchange
+Input [9]: [c_customer_id#61, c_first_name#62, c_last_name#63, c_preferred_cust_flag#64, c_birth_country#58, c_login#65, c_email_address#66, d_year#72, sum#74]
+Arguments: hashpartitioning(c_customer_id#61, c_first_name#62, c_last_name#63, c_preferred_cust_flag#64, c_birth_country#58, c_login#65, c_email_address#66, d_year#72, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=7]
+
+(54) CometColumnarToRow [codegen id : 11]
+Input [9]: [c_customer_id#61, c_first_name#62, c_last_name#63, c_preferred_cust_flag#64, c_birth_country#58, c_login#65, c_email_address#66, d_year#72, sum#74]
+
+(55) HashAggregate [codegen id : 11]
+Input [9]: [c_customer_id#61, c_first_name#62, c_last_name#63, c_preferred_cust_flag#64, c_birth_country#58, c_login#65, c_email_address#66, d_year#72, sum#74]
+Keys [8]: [c_customer_id#61, c_first_name#62, c_last_name#63, c_preferred_cust_flag#64, c_birth_country#58, c_login#65, c_email_address#66, d_year#72]
+Functions [1]: [sum(UnscaledValue((ws_ext_list_price#69 - ws_ext_discount_amt#68)))]
+Aggregate Attributes [1]: [sum(UnscaledValue((ws_ext_list_price#69 - ws_ext_discount_amt#68)))#75]
+Results [2]: [c_customer_id#61 AS customer_id#76, MakeDecimal(sum(UnscaledValue((ws_ext_list_price#69 - ws_ext_discount_amt#68)))#75,18,2) AS year_total#77]
+
+(56) Filter [codegen id : 11]
+Input [2]: [customer_id#76, year_total#77]
+Condition : (isnotnull(year_total#77) AND (year_total#77 > 0.00))
+
+(57) BroadcastExchange
+Input [2]: [customer_id#76, year_total#77]
+Arguments: HashedRelationBroadcastMode(List(input[0, string, true]),false), [plan_id=8]
+
+(58) BroadcastHashJoin [codegen id : 16]
+Left keys [1]: [customer_id#25]
+Right keys [1]: [customer_id#76]
+Join type: Inner
+Join condition: None
+
+(59) Project [codegen id : 16]
+Output [5]: [customer_id#25, year_total#26, customer_preferred_cust_flag#51, year_total#52, year_total#77]
+Input [6]: [customer_id#25, year_total#26, customer_preferred_cust_flag#51, year_total#52, customer_id#76, year_total#77]
+
+(60) CometNativeScan parquet spark_catalog.default.customer
+Output [8]: [c_customer_sk#78, c_customer_id#79, c_first_name#80, c_last_name#81, c_preferred_cust_flag#82, c_birth_country#83, c_login#84, c_email_address#85]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk)]
+ReadSchema: struct
+
+(61) CometFilter
+Input [8]: [c_customer_sk#78, c_customer_id#79, c_first_name#80, c_last_name#81, c_preferred_cust_flag#82, c_birth_country#83, c_login#84, c_email_address#85]
+Condition : (isnotnull(c_customer_sk#78) AND isnotnull(static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#79, 16))))
+
+(62) CometProject
+Input [8]: [c_customer_sk#78, c_customer_id#79, c_first_name#80, c_last_name#81, c_preferred_cust_flag#82, c_birth_country#83, c_login#84, c_email_address#85]
+Arguments: [c_customer_sk#78, c_customer_id#86, c_first_name#87, c_last_name#88, c_preferred_cust_flag#89, c_birth_country#83, c_login#90, c_email_address#91], [c_customer_sk#78, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#79, 16)) AS c_customer_id#86, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_first_name#80, 20)) AS c_first_name#87, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_last_name#81, 30)) AS c_last_name#88, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_preferred_cust_flag#82, 1)) AS c_preferred_cust_flag#89, c_birth_country#83, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_login#84, 13)) AS c_login#90, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_email_address#85, 50)) AS c_email_address#91]
+
+(63) CometColumnarToRow [codegen id : 14]
+Input [8]: [c_customer_sk#78, c_customer_id#86, c_first_name#87, c_last_name#88, c_preferred_cust_flag#89, c_birth_country#83, c_login#90, c_email_address#91]
+
+(64) Scan parquet spark_catalog.default.web_sales
+Output [4]: [ws_bill_customer_sk#92, ws_ext_discount_amt#93, ws_ext_list_price#94, ws_sold_date_sk#95]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#95), dynamicpruningexpression(ws_sold_date_sk#95 IN dynamicpruning#45)]
+PushedFilters: [IsNotNull(ws_bill_customer_sk)]
+ReadSchema: struct
+
+(65) ColumnarToRow [codegen id : 12]
+Input [4]: [ws_bill_customer_sk#92, ws_ext_discount_amt#93, ws_ext_list_price#94, ws_sold_date_sk#95]
+
+(66) Filter [codegen id : 12]
+Input [4]: [ws_bill_customer_sk#92, ws_ext_discount_amt#93, ws_ext_list_price#94, ws_sold_date_sk#95]
+Condition : isnotnull(ws_bill_customer_sk#92)
+
+(67) BroadcastExchange
+Input [4]: [ws_bill_customer_sk#92, ws_ext_discount_amt#93, ws_ext_list_price#94, ws_sold_date_sk#95]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=9]
+
+(68) BroadcastHashJoin [codegen id : 14]
+Left keys [1]: [c_customer_sk#78]
+Right keys [1]: [ws_bill_customer_sk#92]
+Join type: Inner
+Join condition: None
+
+(69) Project [codegen id : 14]
+Output [10]: [c_customer_id#86, c_first_name#87, c_last_name#88, c_preferred_cust_flag#89, c_birth_country#83, c_login#90, c_email_address#91, ws_ext_discount_amt#93, ws_ext_list_price#94, ws_sold_date_sk#95]
+Input [12]: [c_customer_sk#78, c_customer_id#86, c_first_name#87, c_last_name#88, c_preferred_cust_flag#89, c_birth_country#83, c_login#90, c_email_address#91, ws_bill_customer_sk#92, ws_ext_discount_amt#93, ws_ext_list_price#94, ws_sold_date_sk#95]
+
+(70) ReusedExchange [Reuses operator id: 88]
+Output [2]: [d_date_sk#96, d_year#97]
+
+(71) BroadcastHashJoin [codegen id : 14]
+Left keys [1]: [ws_sold_date_sk#95]
+Right keys [1]: [d_date_sk#96]
+Join type: Inner
+Join condition: None
+
+(72) Project [codegen id : 14]
+Output [10]: [c_customer_id#86, c_first_name#87, c_last_name#88, c_preferred_cust_flag#89, c_birth_country#83, c_login#90, c_email_address#91, ws_ext_discount_amt#93, ws_ext_list_price#94, d_year#97]
+Input [12]: [c_customer_id#86, c_first_name#87, c_last_name#88, c_preferred_cust_flag#89, c_birth_country#83, c_login#90, c_email_address#91, ws_ext_discount_amt#93, ws_ext_list_price#94, ws_sold_date_sk#95, d_date_sk#96, d_year#97]
+
+(73) HashAggregate [codegen id : 14]
+Input [10]: [c_customer_id#86, c_first_name#87, c_last_name#88, c_preferred_cust_flag#89, c_birth_country#83, c_login#90, c_email_address#91, ws_ext_discount_amt#93, ws_ext_list_price#94, d_year#97]
+Keys [8]: [c_customer_id#86, c_first_name#87, c_last_name#88, c_preferred_cust_flag#89, c_birth_country#83, c_login#90, c_email_address#91, d_year#97]
+Functions [1]: [partial_sum(UnscaledValue((ws_ext_list_price#94 - ws_ext_discount_amt#93)))]
+Aggregate Attributes [1]: [sum#98]
+Results [9]: [c_customer_id#86, c_first_name#87, c_last_name#88, c_preferred_cust_flag#89, c_birth_country#83, c_login#90, c_email_address#91, d_year#97, sum#99]
+
+(74) CometColumnarExchange
+Input [9]: [c_customer_id#86, c_first_name#87, c_last_name#88, c_preferred_cust_flag#89, c_birth_country#83, c_login#90, c_email_address#91, d_year#97, sum#99]
+Arguments: hashpartitioning(c_customer_id#86, c_first_name#87, c_last_name#88, c_preferred_cust_flag#89, c_birth_country#83, c_login#90, c_email_address#91, d_year#97, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=10]
+
+(75) CometColumnarToRow [codegen id : 15]
+Input [9]: [c_customer_id#86, c_first_name#87, c_last_name#88, c_preferred_cust_flag#89, c_birth_country#83, c_login#90, c_email_address#91, d_year#97, sum#99]
+
+(76) HashAggregate [codegen id : 15]
+Input [9]: [c_customer_id#86, c_first_name#87, c_last_name#88, c_preferred_cust_flag#89, c_birth_country#83, c_login#90, c_email_address#91, d_year#97, sum#99]
+Keys [8]: [c_customer_id#86, c_first_name#87, c_last_name#88, c_preferred_cust_flag#89, c_birth_country#83, c_login#90, c_email_address#91, d_year#97]
+Functions [1]: [sum(UnscaledValue((ws_ext_list_price#94 - ws_ext_discount_amt#93)))]
+Aggregate Attributes [1]: [sum(UnscaledValue((ws_ext_list_price#94 - ws_ext_discount_amt#93)))#75]
+Results [2]: [c_customer_id#86 AS customer_id#100, MakeDecimal(sum(UnscaledValue((ws_ext_list_price#94 - ws_ext_discount_amt#93)))#75,18,2) AS year_total#101]
+
+(77) BroadcastExchange
+Input [2]: [customer_id#100, year_total#101]
+Arguments: HashedRelationBroadcastMode(List(input[0, string, true]),false), [plan_id=11]
+
+(78) BroadcastHashJoin [codegen id : 16]
+Left keys [1]: [customer_id#25]
+Right keys [1]: [customer_id#100]
+Join type: Inner
+Join condition: (CASE WHEN (year_total#77 > 0.00) THEN (year_total#101 / year_total#77) END > CASE WHEN (year_total#26 > 0.00) THEN (year_total#52 / year_total#26) END)
+
+(79) Project [codegen id : 16]
+Output [1]: [customer_preferred_cust_flag#51]
+Input [7]: [customer_id#25, year_total#26, customer_preferred_cust_flag#51, year_total#52, year_total#77, customer_id#100, year_total#101]
+
+(80) TakeOrderedAndProject
+Input [1]: [customer_preferred_cust_flag#51]
+Arguments: 100, [customer_preferred_cust_flag#51 ASC NULLS FIRST], [customer_preferred_cust_flag#51]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 5 Hosting Expression = ss_sold_date_sk#18 IN dynamicpruning#19
+BroadcastExchange (84)
++- * CometColumnarToRow (83)
+ +- CometFilter (82)
+ +- CometNativeScan parquet spark_catalog.default.date_dim (81)
+
+
+(81) CometNativeScan parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#20, d_year#21]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(82) CometFilter
+Input [2]: [d_date_sk#20, d_year#21]
+Condition : ((isnotnull(d_year#21) AND (d_year#21 = 2001)) AND isnotnull(d_date_sk#20))
+
+(83) CometColumnarToRow [codegen id : 1]
+Input [2]: [d_date_sk#20, d_year#21]
+
+(84) BroadcastExchange
+Input [2]: [d_date_sk#20, d_year#21]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=12]
+
+Subquery:2 Hosting operator id = 23 Hosting Expression = ss_sold_date_sk#44 IN dynamicpruning#45
+BroadcastExchange (88)
++- * CometColumnarToRow (87)
+ +- CometFilter (86)
+ +- CometNativeScan parquet spark_catalog.default.date_dim (85)
+
+
+(85) CometNativeScan parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#46, d_year#47]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2002), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(86) CometFilter
+Input [2]: [d_date_sk#46, d_year#47]
+Condition : ((isnotnull(d_year#47) AND (d_year#47 = 2002)) AND isnotnull(d_date_sk#46))
+
+(87) CometColumnarToRow [codegen id : 1]
+Input [2]: [d_date_sk#46, d_year#47]
+
+(88) BroadcastExchange
+Input [2]: [d_date_sk#46, d_year#47]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=13]
+
+Subquery:3 Hosting operator id = 43 Hosting Expression = ws_sold_date_sk#70 IN dynamicpruning#19
+
+Subquery:4 Hosting operator id = 64 Hosting Expression = ws_sold_date_sk#95 IN dynamicpruning#45
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_datafusion/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_datafusion/extended.txt
new file mode 100644
index 0000000000..0f9f19de77
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_datafusion/extended.txt
@@ -0,0 +1,106 @@
+TakeOrderedAndProject
++- Project
+ +- BroadcastHashJoin
+ :- Project
+ : +- BroadcastHashJoin
+ : :- Project
+ : : +- BroadcastHashJoin
+ : : :- Filter
+ : : : +- HashAggregate
+ : : : +- CometColumnarToRow
+ : : : +- CometColumnarExchange
+ : : : +- HashAggregate
+ : : : +- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.customer
+ : : : : +- BroadcastExchange
+ : : : : +- Filter
+ : : : : +- ColumnarToRow
+ : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- HashAggregate
+ : : +- CometColumnarToRow
+ : : +- CometColumnarExchange
+ : : +- HashAggregate
+ : : +- Project
+ : : +- BroadcastHashJoin
+ : : :- Project
+ : : : +- BroadcastHashJoin
+ : : : :- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.customer
+ : : : +- BroadcastExchange
+ : : : +- Filter
+ : : : +- ColumnarToRow
+ : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : +- SubqueryBroadcast
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : +- BroadcastExchange
+ : +- Filter
+ : +- HashAggregate
+ : +- CometColumnarToRow
+ : +- CometColumnarExchange
+ : +- HashAggregate
+ : +- Project
+ : +- BroadcastHashJoin
+ : :- Project
+ : : +- BroadcastHashJoin
+ : : :- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.customer
+ : : +- BroadcastExchange
+ : : +- Filter
+ : : +- ColumnarToRow
+ : : +- Scan parquet spark_catalog.default.web_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : +- ReusedSubquery
+ : +- BroadcastExchange
+ : +- CometColumnarToRow
+ : +- CometFilter
+ : +- CometNativeScan parquet spark_catalog.default.date_dim
+ +- BroadcastExchange
+ +- HashAggregate
+ +- CometColumnarToRow
+ +- CometColumnarExchange
+ +- HashAggregate
+ +- Project
+ +- BroadcastHashJoin
+ :- Project
+ : +- BroadcastHashJoin
+ : :- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.customer
+ : +- BroadcastExchange
+ : +- Filter
+ : +- ColumnarToRow
+ : +- Scan parquet spark_catalog.default.web_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : +- ReusedSubquery
+ +- BroadcastExchange
+ +- CometColumnarToRow
+ +- CometFilter
+ +- CometNativeScan parquet spark_catalog.default.date_dim
+
+Comet accelerated 28 out of 86 eligible operators (32%). Final plan contains 18 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_datafusion/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_datafusion/simplified.txt
new file mode 100644
index 0000000000..6c9e276c01
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_datafusion/simplified.txt
@@ -0,0 +1,131 @@
+TakeOrderedAndProject [customer_preferred_cust_flag]
+ WholeStageCodegen (16)
+ Project [customer_preferred_cust_flag]
+ BroadcastHashJoin [customer_id,customer_id,year_total,year_total,year_total,year_total]
+ Project [customer_id,year_total,customer_preferred_cust_flag,year_total,year_total]
+ BroadcastHashJoin [customer_id,customer_id]
+ Project [customer_id,year_total,customer_preferred_cust_flag,year_total]
+ BroadcastHashJoin [customer_id,customer_id]
+ Filter [year_total]
+ HashAggregate [c_customer_id,c_first_name,c_last_name,d_year,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,sum] [sum(UnscaledValue((ss_ext_list_price - ss_ext_discount_amt))),customer_id,year_total,sum]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [c_customer_id,c_first_name,c_last_name,d_year,c_preferred_cust_flag,c_birth_country,c_login,c_email_address] #1
+ WholeStageCodegen (3)
+ HashAggregate [c_customer_id,c_first_name,c_last_name,d_year,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_list_price,ss_ext_discount_amt] [sum,sum]
+ Project [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_discount_amt,ss_ext_list_price,d_year]
+ BroadcastHashJoin [ss_sold_date_sk,d_date_sk]
+ Project [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ BroadcastHashJoin [c_customer_sk,ss_customer_sk]
+ CometColumnarToRow
+ InputAdapter
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_login,c_email_address] [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometFilter [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometNativeScan parquet spark_catalog.default.customer [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ InputAdapter
+ BroadcastExchange #2
+ WholeStageCodegen (1)
+ Filter [ss_customer_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.store_sales [ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #3
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [d_date_sk,d_year]
+ CometNativeScan parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ InputAdapter
+ ReusedExchange [d_date_sk,d_year] #3
+ InputAdapter
+ BroadcastExchange #4
+ WholeStageCodegen (7)
+ HashAggregate [c_customer_id,c_first_name,c_last_name,d_year,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,sum] [sum(UnscaledValue((ss_ext_list_price - ss_ext_discount_amt))),customer_id,customer_preferred_cust_flag,year_total,sum]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [c_customer_id,c_first_name,c_last_name,d_year,c_preferred_cust_flag,c_birth_country,c_login,c_email_address] #5
+ WholeStageCodegen (6)
+ HashAggregate [c_customer_id,c_first_name,c_last_name,d_year,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_list_price,ss_ext_discount_amt] [sum,sum]
+ Project [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_discount_amt,ss_ext_list_price,d_year]
+ BroadcastHashJoin [ss_sold_date_sk,d_date_sk]
+ Project [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ BroadcastHashJoin [c_customer_sk,ss_customer_sk]
+ CometColumnarToRow
+ InputAdapter
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_login,c_email_address] [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometFilter [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometNativeScan parquet spark_catalog.default.customer [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ InputAdapter
+ BroadcastExchange #6
+ WholeStageCodegen (4)
+ Filter [ss_customer_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.store_sales [ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #2
+ BroadcastExchange #7
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [d_date_sk,d_year]
+ CometNativeScan parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ InputAdapter
+ ReusedExchange [d_date_sk,d_year] #7
+ InputAdapter
+ BroadcastExchange #8
+ WholeStageCodegen (11)
+ Filter [year_total]
+ HashAggregate [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year,sum] [sum(UnscaledValue((ws_ext_list_price - ws_ext_discount_amt))),customer_id,year_total,sum]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year] #9
+ WholeStageCodegen (10)
+ HashAggregate [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year,ws_ext_list_price,ws_ext_discount_amt] [sum,sum]
+ Project [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_ext_discount_amt,ws_ext_list_price,d_year]
+ BroadcastHashJoin [ws_sold_date_sk,d_date_sk]
+ Project [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ BroadcastHashJoin [c_customer_sk,ws_bill_customer_sk]
+ CometColumnarToRow
+ InputAdapter
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_login,c_email_address] [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometFilter [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometNativeScan parquet spark_catalog.default.customer [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ InputAdapter
+ BroadcastExchange #10
+ WholeStageCodegen (8)
+ Filter [ws_bill_customer_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.web_sales [ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ InputAdapter
+ ReusedExchange [d_date_sk,d_year] #3
+ InputAdapter
+ BroadcastExchange #11
+ WholeStageCodegen (15)
+ HashAggregate [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year,sum] [sum(UnscaledValue((ws_ext_list_price - ws_ext_discount_amt))),customer_id,year_total,sum]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year] #12
+ WholeStageCodegen (14)
+ HashAggregate [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year,ws_ext_list_price,ws_ext_discount_amt] [sum,sum]
+ Project [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_ext_discount_amt,ws_ext_list_price,d_year]
+ BroadcastHashJoin [ws_sold_date_sk,d_date_sk]
+ Project [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ BroadcastHashJoin [c_customer_sk,ws_bill_customer_sk]
+ CometColumnarToRow
+ InputAdapter
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_login,c_email_address] [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometFilter [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometNativeScan parquet spark_catalog.default.customer [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ InputAdapter
+ BroadcastExchange #13
+ WholeStageCodegen (12)
+ Filter [ws_bill_customer_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.web_sales [ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ InputAdapter
+ ReusedExchange [d_date_sk,d_year] #7
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_iceberg_compat/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_iceberg_compat/explain.txt
new file mode 100644
index 0000000000..b6edfa8800
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_iceberg_compat/explain.txt
@@ -0,0 +1,475 @@
+== Physical Plan ==
+* CometColumnarToRow (73)
++- CometTakeOrderedAndProject (72)
+ +- CometProject (71)
+ +- CometBroadcastHashJoin (70)
+ :- CometProject (54)
+ : +- CometBroadcastHashJoin (53)
+ : :- CometProject (36)
+ : : +- CometBroadcastHashJoin (35)
+ : : :- CometFilter (17)
+ : : : +- CometHashAggregate (16)
+ : : : +- CometExchange (15)
+ : : : +- CometHashAggregate (14)
+ : : : +- CometProject (13)
+ : : : +- CometBroadcastHashJoin (12)
+ : : : :- CometProject (8)
+ : : : : +- CometBroadcastHashJoin (7)
+ : : : : :- CometProject (3)
+ : : : : : +- CometFilter (2)
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer (1)
+ : : : : +- CometBroadcastExchange (6)
+ : : : : +- CometFilter (5)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (4)
+ : : : +- CometBroadcastExchange (11)
+ : : : +- CometFilter (10)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (9)
+ : : +- CometBroadcastExchange (34)
+ : : +- CometHashAggregate (33)
+ : : +- CometExchange (32)
+ : : +- CometHashAggregate (31)
+ : : +- CometProject (30)
+ : : +- CometBroadcastHashJoin (29)
+ : : :- CometProject (25)
+ : : : +- CometBroadcastHashJoin (24)
+ : : : :- CometProject (20)
+ : : : : +- CometFilter (19)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer (18)
+ : : : +- CometBroadcastExchange (23)
+ : : : +- CometFilter (22)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (21)
+ : : +- CometBroadcastExchange (28)
+ : : +- CometFilter (27)
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (26)
+ : +- CometBroadcastExchange (52)
+ : +- CometFilter (51)
+ : +- CometHashAggregate (50)
+ : +- CometExchange (49)
+ : +- CometHashAggregate (48)
+ : +- CometProject (47)
+ : +- CometBroadcastHashJoin (46)
+ : :- CometProject (44)
+ : : +- CometBroadcastHashJoin (43)
+ : : :- CometProject (39)
+ : : : +- CometFilter (38)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer (37)
+ : : +- CometBroadcastExchange (42)
+ : : +- CometFilter (41)
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (40)
+ : +- ReusedExchange (45)
+ +- CometBroadcastExchange (69)
+ +- CometHashAggregate (68)
+ +- CometExchange (67)
+ +- CometHashAggregate (66)
+ +- CometProject (65)
+ +- CometBroadcastHashJoin (64)
+ :- CometProject (62)
+ : +- CometBroadcastHashJoin (61)
+ : :- CometProject (57)
+ : : +- CometFilter (56)
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer (55)
+ : +- CometBroadcastExchange (60)
+ : +- CometFilter (59)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (58)
+ +- ReusedExchange (63)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+Output [8]: [c_customer_sk#1, c_customer_id#2, c_first_name#3, c_last_name#4, c_preferred_cust_flag#5, c_birth_country#6, c_login#7, c_email_address#8]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [8]: [c_customer_sk#1, c_customer_id#2, c_first_name#3, c_last_name#4, c_preferred_cust_flag#5, c_birth_country#6, c_login#7, c_email_address#8]
+Condition : (isnotnull(c_customer_sk#1) AND isnotnull(static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#2, 16))))
+
+(3) CometProject
+Input [8]: [c_customer_sk#1, c_customer_id#2, c_first_name#3, c_last_name#4, c_preferred_cust_flag#5, c_birth_country#6, c_login#7, c_email_address#8]
+Arguments: [c_customer_sk#1, c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14], [c_customer_sk#1, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#2, 16)) AS c_customer_id#9, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_first_name#3, 20)) AS c_first_name#10, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_last_name#4, 30)) AS c_last_name#11, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_preferred_cust_flag#5, 1)) AS c_preferred_cust_flag#12, c_birth_country#6, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_login#7, 13)) AS c_login#13, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_email_address#8, 50)) AS c_email_address#14]
+
+(4) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [4]: [ss_customer_sk#15, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#18), dynamicpruningexpression(ss_sold_date_sk#18 IN dynamicpruning#19)]
+PushedFilters: [IsNotNull(ss_customer_sk)]
+ReadSchema: struct
+
+(5) CometFilter
+Input [4]: [ss_customer_sk#15, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+Condition : isnotnull(ss_customer_sk#15)
+
+(6) CometBroadcastExchange
+Input [4]: [ss_customer_sk#15, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+Arguments: [ss_customer_sk#15, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+
+(7) CometBroadcastHashJoin
+Left output [8]: [c_customer_sk#1, c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14]
+Right output [4]: [ss_customer_sk#15, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+Arguments: [c_customer_sk#1], [ss_customer_sk#15], Inner, BuildRight
+
+(8) CometProject
+Input [12]: [c_customer_sk#1, c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_customer_sk#15, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+Arguments: [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18], [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+
+(9) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#20, d_year#21]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(10) CometFilter
+Input [2]: [d_date_sk#20, d_year#21]
+Condition : ((isnotnull(d_year#21) AND (d_year#21 = 2001)) AND isnotnull(d_date_sk#20))
+
+(11) CometBroadcastExchange
+Input [2]: [d_date_sk#20, d_year#21]
+Arguments: [d_date_sk#20, d_year#21]
+
+(12) CometBroadcastHashJoin
+Left output [10]: [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+Right output [2]: [d_date_sk#20, d_year#21]
+Arguments: [ss_sold_date_sk#18], [d_date_sk#20], Inner, BuildRight
+
+(13) CometProject
+Input [12]: [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18, d_date_sk#20, d_year#21]
+Arguments: [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, d_year#21], [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, d_year#21]
+
+(14) CometHashAggregate
+Input [10]: [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, d_year#21]
+Keys [8]: [c_customer_id#9, c_first_name#10, c_last_name#11, d_year#21, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14]
+Functions [1]: [partial_sum(UnscaledValue((ss_ext_list_price#17 - ss_ext_discount_amt#16)))]
+
+(15) CometExchange
+Input [9]: [c_customer_id#9, c_first_name#10, c_last_name#11, d_year#21, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, sum#22]
+Arguments: hashpartitioning(c_customer_id#9, c_first_name#10, c_last_name#11, d_year#21, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=1]
+
+(16) CometHashAggregate
+Input [9]: [c_customer_id#9, c_first_name#10, c_last_name#11, d_year#21, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, sum#22]
+Keys [8]: [c_customer_id#9, c_first_name#10, c_last_name#11, d_year#21, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14]
+Functions [1]: [sum(UnscaledValue((ss_ext_list_price#17 - ss_ext_discount_amt#16)))]
+
+(17) CometFilter
+Input [2]: [customer_id#23, year_total#24]
+Condition : (isnotnull(year_total#24) AND (year_total#24 > 0.00))
+
+(18) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+Output [8]: [c_customer_sk#25, c_customer_id#26, c_first_name#27, c_last_name#28, c_preferred_cust_flag#29, c_birth_country#30, c_login#31, c_email_address#32]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk)]
+ReadSchema: struct
+
+(19) CometFilter
+Input [8]: [c_customer_sk#25, c_customer_id#26, c_first_name#27, c_last_name#28, c_preferred_cust_flag#29, c_birth_country#30, c_login#31, c_email_address#32]
+Condition : (isnotnull(c_customer_sk#25) AND isnotnull(static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#26, 16))))
+
+(20) CometProject
+Input [8]: [c_customer_sk#25, c_customer_id#26, c_first_name#27, c_last_name#28, c_preferred_cust_flag#29, c_birth_country#30, c_login#31, c_email_address#32]
+Arguments: [c_customer_sk#25, c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38], [c_customer_sk#25, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#26, 16)) AS c_customer_id#33, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_first_name#27, 20)) AS c_first_name#34, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_last_name#28, 30)) AS c_last_name#35, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_preferred_cust_flag#29, 1)) AS c_preferred_cust_flag#36, c_birth_country#30, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_login#31, 13)) AS c_login#37, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_email_address#32, 50)) AS c_email_address#38]
+
+(21) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [4]: [ss_customer_sk#39, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#42), dynamicpruningexpression(ss_sold_date_sk#42 IN dynamicpruning#43)]
+PushedFilters: [IsNotNull(ss_customer_sk)]
+ReadSchema: struct
+
+(22) CometFilter
+Input [4]: [ss_customer_sk#39, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42]
+Condition : isnotnull(ss_customer_sk#39)
+
+(23) CometBroadcastExchange
+Input [4]: [ss_customer_sk#39, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42]
+Arguments: [ss_customer_sk#39, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42]
+
+(24) CometBroadcastHashJoin
+Left output [8]: [c_customer_sk#25, c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38]
+Right output [4]: [ss_customer_sk#39, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42]
+Arguments: [c_customer_sk#25], [ss_customer_sk#39], Inner, BuildRight
+
+(25) CometProject
+Input [12]: [c_customer_sk#25, c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, ss_customer_sk#39, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42]
+Arguments: [c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42], [c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42]
+
+(26) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#44, d_year#45]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2002), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(27) CometFilter
+Input [2]: [d_date_sk#44, d_year#45]
+Condition : ((isnotnull(d_year#45) AND (d_year#45 = 2002)) AND isnotnull(d_date_sk#44))
+
+(28) CometBroadcastExchange
+Input [2]: [d_date_sk#44, d_year#45]
+Arguments: [d_date_sk#44, d_year#45]
+
+(29) CometBroadcastHashJoin
+Left output [10]: [c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42]
+Right output [2]: [d_date_sk#44, d_year#45]
+Arguments: [ss_sold_date_sk#42], [d_date_sk#44], Inner, BuildRight
+
+(30) CometProject
+Input [12]: [c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42, d_date_sk#44, d_year#45]
+Arguments: [c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, ss_ext_discount_amt#40, ss_ext_list_price#41, d_year#45], [c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, ss_ext_discount_amt#40, ss_ext_list_price#41, d_year#45]
+
+(31) CometHashAggregate
+Input [10]: [c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, ss_ext_discount_amt#40, ss_ext_list_price#41, d_year#45]
+Keys [8]: [c_customer_id#33, c_first_name#34, c_last_name#35, d_year#45, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38]
+Functions [1]: [partial_sum(UnscaledValue((ss_ext_list_price#41 - ss_ext_discount_amt#40)))]
+
+(32) CometExchange
+Input [9]: [c_customer_id#33, c_first_name#34, c_last_name#35, d_year#45, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, sum#46]
+Arguments: hashpartitioning(c_customer_id#33, c_first_name#34, c_last_name#35, d_year#45, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=2]
+
+(33) CometHashAggregate
+Input [9]: [c_customer_id#33, c_first_name#34, c_last_name#35, d_year#45, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, sum#46]
+Keys [8]: [c_customer_id#33, c_first_name#34, c_last_name#35, d_year#45, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38]
+Functions [1]: [sum(UnscaledValue((ss_ext_list_price#41 - ss_ext_discount_amt#40)))]
+
+(34) CometBroadcastExchange
+Input [3]: [customer_id#47, customer_preferred_cust_flag#48, year_total#49]
+Arguments: [customer_id#47, customer_preferred_cust_flag#48, year_total#49]
+
+(35) CometBroadcastHashJoin
+Left output [2]: [customer_id#23, year_total#24]
+Right output [3]: [customer_id#47, customer_preferred_cust_flag#48, year_total#49]
+Arguments: [customer_id#23], [customer_id#47], Inner, BuildRight
+
+(36) CometProject
+Input [5]: [customer_id#23, year_total#24, customer_id#47, customer_preferred_cust_flag#48, year_total#49]
+Arguments: [customer_id#23, year_total#24, customer_preferred_cust_flag#48, year_total#49], [customer_id#23, year_total#24, customer_preferred_cust_flag#48, year_total#49]
+
+(37) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+Output [8]: [c_customer_sk#50, c_customer_id#51, c_first_name#52, c_last_name#53, c_preferred_cust_flag#54, c_birth_country#55, c_login#56, c_email_address#57]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk)]
+ReadSchema: struct
+
+(38) CometFilter
+Input [8]: [c_customer_sk#50, c_customer_id#51, c_first_name#52, c_last_name#53, c_preferred_cust_flag#54, c_birth_country#55, c_login#56, c_email_address#57]
+Condition : (isnotnull(c_customer_sk#50) AND isnotnull(static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#51, 16))))
+
+(39) CometProject
+Input [8]: [c_customer_sk#50, c_customer_id#51, c_first_name#52, c_last_name#53, c_preferred_cust_flag#54, c_birth_country#55, c_login#56, c_email_address#57]
+Arguments: [c_customer_sk#50, c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63], [c_customer_sk#50, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#51, 16)) AS c_customer_id#58, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_first_name#52, 20)) AS c_first_name#59, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_last_name#53, 30)) AS c_last_name#60, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_preferred_cust_flag#54, 1)) AS c_preferred_cust_flag#61, c_birth_country#55, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_login#56, 13)) AS c_login#62, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_email_address#57, 50)) AS c_email_address#63]
+
+(40) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [4]: [ws_bill_customer_sk#64, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#67), dynamicpruningexpression(ws_sold_date_sk#67 IN dynamicpruning#68)]
+PushedFilters: [IsNotNull(ws_bill_customer_sk)]
+ReadSchema: struct
+
+(41) CometFilter
+Input [4]: [ws_bill_customer_sk#64, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67]
+Condition : isnotnull(ws_bill_customer_sk#64)
+
+(42) CometBroadcastExchange
+Input [4]: [ws_bill_customer_sk#64, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67]
+Arguments: [ws_bill_customer_sk#64, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67]
+
+(43) CometBroadcastHashJoin
+Left output [8]: [c_customer_sk#50, c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63]
+Right output [4]: [ws_bill_customer_sk#64, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67]
+Arguments: [c_customer_sk#50], [ws_bill_customer_sk#64], Inner, BuildRight
+
+(44) CometProject
+Input [12]: [c_customer_sk#50, c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, ws_bill_customer_sk#64, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67]
+Arguments: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67], [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67]
+
+(45) ReusedExchange [Reuses operator id: 11]
+Output [2]: [d_date_sk#69, d_year#70]
+
+(46) CometBroadcastHashJoin
+Left output [10]: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67]
+Right output [2]: [d_date_sk#69, d_year#70]
+Arguments: [ws_sold_date_sk#67], [d_date_sk#69], Inner, BuildRight
+
+(47) CometProject
+Input [12]: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67, d_date_sk#69, d_year#70]
+Arguments: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, ws_ext_discount_amt#65, ws_ext_list_price#66, d_year#70], [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, ws_ext_discount_amt#65, ws_ext_list_price#66, d_year#70]
+
+(48) CometHashAggregate
+Input [10]: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, ws_ext_discount_amt#65, ws_ext_list_price#66, d_year#70]
+Keys [8]: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, d_year#70]
+Functions [1]: [partial_sum(UnscaledValue((ws_ext_list_price#66 - ws_ext_discount_amt#65)))]
+
+(49) CometExchange
+Input [9]: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, d_year#70, sum#71]
+Arguments: hashpartitioning(c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, d_year#70, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=3]
+
+(50) CometHashAggregate
+Input [9]: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, d_year#70, sum#71]
+Keys [8]: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, d_year#70]
+Functions [1]: [sum(UnscaledValue((ws_ext_list_price#66 - ws_ext_discount_amt#65)))]
+
+(51) CometFilter
+Input [2]: [customer_id#72, year_total#73]
+Condition : (isnotnull(year_total#73) AND (year_total#73 > 0.00))
+
+(52) CometBroadcastExchange
+Input [2]: [customer_id#72, year_total#73]
+Arguments: [customer_id#72, year_total#73]
+
+(53) CometBroadcastHashJoin
+Left output [4]: [customer_id#23, year_total#24, customer_preferred_cust_flag#48, year_total#49]
+Right output [2]: [customer_id#72, year_total#73]
+Arguments: [customer_id#23], [customer_id#72], Inner, BuildRight
+
+(54) CometProject
+Input [6]: [customer_id#23, year_total#24, customer_preferred_cust_flag#48, year_total#49, customer_id#72, year_total#73]
+Arguments: [customer_id#23, year_total#24, customer_preferred_cust_flag#48, year_total#49, year_total#73], [customer_id#23, year_total#24, customer_preferred_cust_flag#48, year_total#49, year_total#73]
+
+(55) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+Output [8]: [c_customer_sk#74, c_customer_id#75, c_first_name#76, c_last_name#77, c_preferred_cust_flag#78, c_birth_country#79, c_login#80, c_email_address#81]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk)]
+ReadSchema: struct
+
+(56) CometFilter
+Input [8]: [c_customer_sk#74, c_customer_id#75, c_first_name#76, c_last_name#77, c_preferred_cust_flag#78, c_birth_country#79, c_login#80, c_email_address#81]
+Condition : (isnotnull(c_customer_sk#74) AND isnotnull(static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#75, 16))))
+
+(57) CometProject
+Input [8]: [c_customer_sk#74, c_customer_id#75, c_first_name#76, c_last_name#77, c_preferred_cust_flag#78, c_birth_country#79, c_login#80, c_email_address#81]
+Arguments: [c_customer_sk#74, c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87], [c_customer_sk#74, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#75, 16)) AS c_customer_id#82, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_first_name#76, 20)) AS c_first_name#83, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_last_name#77, 30)) AS c_last_name#84, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_preferred_cust_flag#78, 1)) AS c_preferred_cust_flag#85, c_birth_country#79, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_login#80, 13)) AS c_login#86, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_email_address#81, 50)) AS c_email_address#87]
+
+(58) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [4]: [ws_bill_customer_sk#88, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#91), dynamicpruningexpression(ws_sold_date_sk#91 IN dynamicpruning#92)]
+PushedFilters: [IsNotNull(ws_bill_customer_sk)]
+ReadSchema: struct
+
+(59) CometFilter
+Input [4]: [ws_bill_customer_sk#88, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91]
+Condition : isnotnull(ws_bill_customer_sk#88)
+
+(60) CometBroadcastExchange
+Input [4]: [ws_bill_customer_sk#88, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91]
+Arguments: [ws_bill_customer_sk#88, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91]
+
+(61) CometBroadcastHashJoin
+Left output [8]: [c_customer_sk#74, c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87]
+Right output [4]: [ws_bill_customer_sk#88, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91]
+Arguments: [c_customer_sk#74], [ws_bill_customer_sk#88], Inner, BuildRight
+
+(62) CometProject
+Input [12]: [c_customer_sk#74, c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, ws_bill_customer_sk#88, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91]
+Arguments: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91], [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91]
+
+(63) ReusedExchange [Reuses operator id: 28]
+Output [2]: [d_date_sk#93, d_year#94]
+
+(64) CometBroadcastHashJoin
+Left output [10]: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91]
+Right output [2]: [d_date_sk#93, d_year#94]
+Arguments: [ws_sold_date_sk#91], [d_date_sk#93], Inner, BuildRight
+
+(65) CometProject
+Input [12]: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91, d_date_sk#93, d_year#94]
+Arguments: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, ws_ext_discount_amt#89, ws_ext_list_price#90, d_year#94], [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, ws_ext_discount_amt#89, ws_ext_list_price#90, d_year#94]
+
+(66) CometHashAggregate
+Input [10]: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, ws_ext_discount_amt#89, ws_ext_list_price#90, d_year#94]
+Keys [8]: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, d_year#94]
+Functions [1]: [partial_sum(UnscaledValue((ws_ext_list_price#90 - ws_ext_discount_amt#89)))]
+
+(67) CometExchange
+Input [9]: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, d_year#94, sum#95]
+Arguments: hashpartitioning(c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, d_year#94, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=4]
+
+(68) CometHashAggregate
+Input [9]: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, d_year#94, sum#95]
+Keys [8]: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, d_year#94]
+Functions [1]: [sum(UnscaledValue((ws_ext_list_price#90 - ws_ext_discount_amt#89)))]
+
+(69) CometBroadcastExchange
+Input [2]: [customer_id#96, year_total#97]
+Arguments: [customer_id#96, year_total#97]
+
+(70) CometBroadcastHashJoin
+Left output [5]: [customer_id#23, year_total#24, customer_preferred_cust_flag#48, year_total#49, year_total#73]
+Right output [2]: [customer_id#96, year_total#97]
+Arguments: [customer_id#23], [customer_id#96], Inner, (CASE WHEN (year_total#73 > 0.00) THEN (year_total#97 / year_total#73) END > CASE WHEN (year_total#24 > 0.00) THEN (year_total#49 / year_total#24) END), BuildRight
+
+(71) CometProject
+Input [7]: [customer_id#23, year_total#24, customer_preferred_cust_flag#48, year_total#49, year_total#73, customer_id#96, year_total#97]
+Arguments: [customer_preferred_cust_flag#48], [customer_preferred_cust_flag#48]
+
+(72) CometTakeOrderedAndProject
+Input [1]: [customer_preferred_cust_flag#48]
+Arguments: TakeOrderedAndProject(limit=100, orderBy=[customer_preferred_cust_flag#48 ASC NULLS FIRST], output=[customer_preferred_cust_flag#48]), [customer_preferred_cust_flag#48], 100, 0, [customer_preferred_cust_flag#48 ASC NULLS FIRST], [customer_preferred_cust_flag#48]
+
+(73) CometColumnarToRow [codegen id : 1]
+Input [1]: [customer_preferred_cust_flag#48]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 4 Hosting Expression = ss_sold_date_sk#18 IN dynamicpruning#19
+BroadcastExchange (77)
++- * CometColumnarToRow (76)
+ +- CometFilter (75)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (74)
+
+
+(74) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#20, d_year#21]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(75) CometFilter
+Input [2]: [d_date_sk#20, d_year#21]
+Condition : ((isnotnull(d_year#21) AND (d_year#21 = 2001)) AND isnotnull(d_date_sk#20))
+
+(76) CometColumnarToRow [codegen id : 1]
+Input [2]: [d_date_sk#20, d_year#21]
+
+(77) BroadcastExchange
+Input [2]: [d_date_sk#20, d_year#21]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=5]
+
+Subquery:2 Hosting operator id = 21 Hosting Expression = ss_sold_date_sk#42 IN dynamicpruning#43
+BroadcastExchange (81)
++- * CometColumnarToRow (80)
+ +- CometFilter (79)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (78)
+
+
+(78) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#44, d_year#45]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2002), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(79) CometFilter
+Input [2]: [d_date_sk#44, d_year#45]
+Condition : ((isnotnull(d_year#45) AND (d_year#45 = 2002)) AND isnotnull(d_date_sk#44))
+
+(80) CometColumnarToRow [codegen id : 1]
+Input [2]: [d_date_sk#44, d_year#45]
+
+(81) BroadcastExchange
+Input [2]: [d_date_sk#44, d_year#45]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=6]
+
+Subquery:3 Hosting operator id = 40 Hosting Expression = ws_sold_date_sk#67 IN dynamicpruning#19
+
+Subquery:4 Hosting operator id = 58 Hosting Expression = ws_sold_date_sk#91 IN dynamicpruning#43
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_iceberg_compat/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_iceberg_compat/extended.txt
new file mode 100644
index 0000000000..781eae9054
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_iceberg_compat/extended.txt
@@ -0,0 +1,91 @@
+CometColumnarToRow
++- CometTakeOrderedAndProject
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometHashAggregate
+ : : : +- CometExchange
+ : : : +- CometHashAggregate
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometHashAggregate
+ : : +- CometExchange
+ : : +- CometHashAggregate
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+ : : : +- CometBroadcastExchange
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : +- SubqueryBroadcast
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometFilter
+ : +- CometHashAggregate
+ : +- CometExchange
+ : +- CometHashAggregate
+ : +- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+ : : +- CometBroadcastExchange
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : +- ReusedSubquery
+ : +- CometBroadcastExchange
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ +- CometBroadcastExchange
+ +- CometHashAggregate
+ +- CometExchange
+ +- CometHashAggregate
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+ : +- CometBroadcastExchange
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : +- ReusedSubquery
+ +- CometBroadcastExchange
+ +- CometFilter
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+
+Comet accelerated 80 out of 86 eligible operators (93%). Final plan contains 3 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_iceberg_compat/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_iceberg_compat/simplified.txt
new file mode 100644
index 0000000000..4599ecf539
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11.native_iceberg_compat/simplified.txt
@@ -0,0 +1,91 @@
+WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometTakeOrderedAndProject [customer_preferred_cust_flag]
+ CometProject [customer_preferred_cust_flag]
+ CometBroadcastHashJoin [customer_id,year_total,customer_preferred_cust_flag,year_total,year_total,customer_id,year_total]
+ CometProject [customer_id,year_total,customer_preferred_cust_flag,year_total,year_total]
+ CometBroadcastHashJoin [customer_id,year_total,customer_preferred_cust_flag,year_total,customer_id,year_total]
+ CometProject [customer_id,year_total,customer_preferred_cust_flag,year_total]
+ CometBroadcastHashJoin [customer_id,year_total,customer_id,customer_preferred_cust_flag,year_total]
+ CometFilter [customer_id,year_total]
+ CometHashAggregate [c_first_name,c_last_name,d_year,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,sum] [customer_id,year_total,c_customer_id,sum(UnscaledValue((ss_ext_list_price - ss_ext_discount_amt)))]
+ CometExchange [c_customer_id,c_first_name,c_last_name,d_year,c_preferred_cust_flag,c_birth_country,c_login,c_email_address] #1
+ CometHashAggregate [ss_ext_list_price,ss_ext_discount_amt] [c_customer_id,c_first_name,c_last_name,d_year,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,sum]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_discount_amt,ss_ext_list_price,d_year]
+ CometBroadcastHashJoin [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk,d_date_sk,d_year]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ CometBroadcastHashJoin [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_login,c_email_address] [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometFilter [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometBroadcastExchange [ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk] #2
+ CometFilter [ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #3
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [d_date_sk,d_year] #4
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [customer_id,customer_preferred_cust_flag,year_total] #5
+ CometHashAggregate [c_first_name,c_last_name,d_year,c_birth_country,c_login,c_email_address,sum] [customer_id,customer_preferred_cust_flag,year_total,c_customer_id,c_preferred_cust_flag,sum(UnscaledValue((ss_ext_list_price - ss_ext_discount_amt)))]
+ CometExchange [c_customer_id,c_first_name,c_last_name,d_year,c_preferred_cust_flag,c_birth_country,c_login,c_email_address] #6
+ CometHashAggregate [ss_ext_list_price,ss_ext_discount_amt] [c_customer_id,c_first_name,c_last_name,d_year,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,sum]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_discount_amt,ss_ext_list_price,d_year]
+ CometBroadcastHashJoin [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk,d_date_sk,d_year]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ CometBroadcastHashJoin [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_login,c_email_address] [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometFilter [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometBroadcastExchange [ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk] #7
+ CometFilter [ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #2
+ BroadcastExchange #8
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [d_date_sk,d_year] #9
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [customer_id,year_total] #10
+ CometFilter [customer_id,year_total]
+ CometHashAggregate [c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year,sum] [customer_id,year_total,c_customer_id,sum(UnscaledValue((ws_ext_list_price - ws_ext_discount_amt)))]
+ CometExchange [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year] #11
+ CometHashAggregate [ws_ext_list_price,ws_ext_discount_amt] [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year,sum]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_ext_discount_amt,ws_ext_list_price,d_year]
+ CometBroadcastHashJoin [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk,d_date_sk,d_year]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ CometBroadcastHashJoin [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_login,c_email_address] [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometFilter [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometBroadcastExchange [ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk] #12
+ CometFilter [ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ ReusedExchange [d_date_sk,d_year] #4
+ CometBroadcastExchange [customer_id,year_total] #13
+ CometHashAggregate [c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year,sum] [customer_id,year_total,c_customer_id,sum(UnscaledValue((ws_ext_list_price - ws_ext_discount_amt)))]
+ CometExchange [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year] #14
+ CometHashAggregate [ws_ext_list_price,ws_ext_discount_amt] [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year,sum]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_ext_discount_amt,ws_ext_list_price,d_year]
+ CometBroadcastHashJoin [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk,d_date_sk,d_year]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ CometBroadcastHashJoin [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_login,c_email_address] [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometFilter [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometBroadcastExchange [ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk] #15
+ CometFilter [ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ ReusedExchange [d_date_sk,d_year] #9
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11/explain.txt
new file mode 100644
index 0000000000..b6edfa8800
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11/explain.txt
@@ -0,0 +1,475 @@
+== Physical Plan ==
+* CometColumnarToRow (73)
++- CometTakeOrderedAndProject (72)
+ +- CometProject (71)
+ +- CometBroadcastHashJoin (70)
+ :- CometProject (54)
+ : +- CometBroadcastHashJoin (53)
+ : :- CometProject (36)
+ : : +- CometBroadcastHashJoin (35)
+ : : :- CometFilter (17)
+ : : : +- CometHashAggregate (16)
+ : : : +- CometExchange (15)
+ : : : +- CometHashAggregate (14)
+ : : : +- CometProject (13)
+ : : : +- CometBroadcastHashJoin (12)
+ : : : :- CometProject (8)
+ : : : : +- CometBroadcastHashJoin (7)
+ : : : : :- CometProject (3)
+ : : : : : +- CometFilter (2)
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer (1)
+ : : : : +- CometBroadcastExchange (6)
+ : : : : +- CometFilter (5)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (4)
+ : : : +- CometBroadcastExchange (11)
+ : : : +- CometFilter (10)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (9)
+ : : +- CometBroadcastExchange (34)
+ : : +- CometHashAggregate (33)
+ : : +- CometExchange (32)
+ : : +- CometHashAggregate (31)
+ : : +- CometProject (30)
+ : : +- CometBroadcastHashJoin (29)
+ : : :- CometProject (25)
+ : : : +- CometBroadcastHashJoin (24)
+ : : : :- CometProject (20)
+ : : : : +- CometFilter (19)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer (18)
+ : : : +- CometBroadcastExchange (23)
+ : : : +- CometFilter (22)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (21)
+ : : +- CometBroadcastExchange (28)
+ : : +- CometFilter (27)
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (26)
+ : +- CometBroadcastExchange (52)
+ : +- CometFilter (51)
+ : +- CometHashAggregate (50)
+ : +- CometExchange (49)
+ : +- CometHashAggregate (48)
+ : +- CometProject (47)
+ : +- CometBroadcastHashJoin (46)
+ : :- CometProject (44)
+ : : +- CometBroadcastHashJoin (43)
+ : : :- CometProject (39)
+ : : : +- CometFilter (38)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer (37)
+ : : +- CometBroadcastExchange (42)
+ : : +- CometFilter (41)
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (40)
+ : +- ReusedExchange (45)
+ +- CometBroadcastExchange (69)
+ +- CometHashAggregate (68)
+ +- CometExchange (67)
+ +- CometHashAggregate (66)
+ +- CometProject (65)
+ +- CometBroadcastHashJoin (64)
+ :- CometProject (62)
+ : +- CometBroadcastHashJoin (61)
+ : :- CometProject (57)
+ : : +- CometFilter (56)
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer (55)
+ : +- CometBroadcastExchange (60)
+ : +- CometFilter (59)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (58)
+ +- ReusedExchange (63)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+Output [8]: [c_customer_sk#1, c_customer_id#2, c_first_name#3, c_last_name#4, c_preferred_cust_flag#5, c_birth_country#6, c_login#7, c_email_address#8]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [8]: [c_customer_sk#1, c_customer_id#2, c_first_name#3, c_last_name#4, c_preferred_cust_flag#5, c_birth_country#6, c_login#7, c_email_address#8]
+Condition : (isnotnull(c_customer_sk#1) AND isnotnull(static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#2, 16))))
+
+(3) CometProject
+Input [8]: [c_customer_sk#1, c_customer_id#2, c_first_name#3, c_last_name#4, c_preferred_cust_flag#5, c_birth_country#6, c_login#7, c_email_address#8]
+Arguments: [c_customer_sk#1, c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14], [c_customer_sk#1, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#2, 16)) AS c_customer_id#9, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_first_name#3, 20)) AS c_first_name#10, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_last_name#4, 30)) AS c_last_name#11, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_preferred_cust_flag#5, 1)) AS c_preferred_cust_flag#12, c_birth_country#6, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_login#7, 13)) AS c_login#13, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_email_address#8, 50)) AS c_email_address#14]
+
+(4) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [4]: [ss_customer_sk#15, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#18), dynamicpruningexpression(ss_sold_date_sk#18 IN dynamicpruning#19)]
+PushedFilters: [IsNotNull(ss_customer_sk)]
+ReadSchema: struct
+
+(5) CometFilter
+Input [4]: [ss_customer_sk#15, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+Condition : isnotnull(ss_customer_sk#15)
+
+(6) CometBroadcastExchange
+Input [4]: [ss_customer_sk#15, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+Arguments: [ss_customer_sk#15, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+
+(7) CometBroadcastHashJoin
+Left output [8]: [c_customer_sk#1, c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14]
+Right output [4]: [ss_customer_sk#15, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+Arguments: [c_customer_sk#1], [ss_customer_sk#15], Inner, BuildRight
+
+(8) CometProject
+Input [12]: [c_customer_sk#1, c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_customer_sk#15, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+Arguments: [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18], [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+
+(9) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#20, d_year#21]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(10) CometFilter
+Input [2]: [d_date_sk#20, d_year#21]
+Condition : ((isnotnull(d_year#21) AND (d_year#21 = 2001)) AND isnotnull(d_date_sk#20))
+
+(11) CometBroadcastExchange
+Input [2]: [d_date_sk#20, d_year#21]
+Arguments: [d_date_sk#20, d_year#21]
+
+(12) CometBroadcastHashJoin
+Left output [10]: [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18]
+Right output [2]: [d_date_sk#20, d_year#21]
+Arguments: [ss_sold_date_sk#18], [d_date_sk#20], Inner, BuildRight
+
+(13) CometProject
+Input [12]: [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, ss_sold_date_sk#18, d_date_sk#20, d_year#21]
+Arguments: [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, d_year#21], [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, d_year#21]
+
+(14) CometHashAggregate
+Input [10]: [c_customer_id#9, c_first_name#10, c_last_name#11, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, ss_ext_discount_amt#16, ss_ext_list_price#17, d_year#21]
+Keys [8]: [c_customer_id#9, c_first_name#10, c_last_name#11, d_year#21, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14]
+Functions [1]: [partial_sum(UnscaledValue((ss_ext_list_price#17 - ss_ext_discount_amt#16)))]
+
+(15) CometExchange
+Input [9]: [c_customer_id#9, c_first_name#10, c_last_name#11, d_year#21, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, sum#22]
+Arguments: hashpartitioning(c_customer_id#9, c_first_name#10, c_last_name#11, d_year#21, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=1]
+
+(16) CometHashAggregate
+Input [9]: [c_customer_id#9, c_first_name#10, c_last_name#11, d_year#21, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14, sum#22]
+Keys [8]: [c_customer_id#9, c_first_name#10, c_last_name#11, d_year#21, c_preferred_cust_flag#12, c_birth_country#6, c_login#13, c_email_address#14]
+Functions [1]: [sum(UnscaledValue((ss_ext_list_price#17 - ss_ext_discount_amt#16)))]
+
+(17) CometFilter
+Input [2]: [customer_id#23, year_total#24]
+Condition : (isnotnull(year_total#24) AND (year_total#24 > 0.00))
+
+(18) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+Output [8]: [c_customer_sk#25, c_customer_id#26, c_first_name#27, c_last_name#28, c_preferred_cust_flag#29, c_birth_country#30, c_login#31, c_email_address#32]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk)]
+ReadSchema: struct
+
+(19) CometFilter
+Input [8]: [c_customer_sk#25, c_customer_id#26, c_first_name#27, c_last_name#28, c_preferred_cust_flag#29, c_birth_country#30, c_login#31, c_email_address#32]
+Condition : (isnotnull(c_customer_sk#25) AND isnotnull(static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#26, 16))))
+
+(20) CometProject
+Input [8]: [c_customer_sk#25, c_customer_id#26, c_first_name#27, c_last_name#28, c_preferred_cust_flag#29, c_birth_country#30, c_login#31, c_email_address#32]
+Arguments: [c_customer_sk#25, c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38], [c_customer_sk#25, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#26, 16)) AS c_customer_id#33, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_first_name#27, 20)) AS c_first_name#34, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_last_name#28, 30)) AS c_last_name#35, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_preferred_cust_flag#29, 1)) AS c_preferred_cust_flag#36, c_birth_country#30, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_login#31, 13)) AS c_login#37, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_email_address#32, 50)) AS c_email_address#38]
+
+(21) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [4]: [ss_customer_sk#39, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#42), dynamicpruningexpression(ss_sold_date_sk#42 IN dynamicpruning#43)]
+PushedFilters: [IsNotNull(ss_customer_sk)]
+ReadSchema: struct
+
+(22) CometFilter
+Input [4]: [ss_customer_sk#39, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42]
+Condition : isnotnull(ss_customer_sk#39)
+
+(23) CometBroadcastExchange
+Input [4]: [ss_customer_sk#39, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42]
+Arguments: [ss_customer_sk#39, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42]
+
+(24) CometBroadcastHashJoin
+Left output [8]: [c_customer_sk#25, c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38]
+Right output [4]: [ss_customer_sk#39, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42]
+Arguments: [c_customer_sk#25], [ss_customer_sk#39], Inner, BuildRight
+
+(25) CometProject
+Input [12]: [c_customer_sk#25, c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, ss_customer_sk#39, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42]
+Arguments: [c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42], [c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42]
+
+(26) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#44, d_year#45]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2002), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(27) CometFilter
+Input [2]: [d_date_sk#44, d_year#45]
+Condition : ((isnotnull(d_year#45) AND (d_year#45 = 2002)) AND isnotnull(d_date_sk#44))
+
+(28) CometBroadcastExchange
+Input [2]: [d_date_sk#44, d_year#45]
+Arguments: [d_date_sk#44, d_year#45]
+
+(29) CometBroadcastHashJoin
+Left output [10]: [c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42]
+Right output [2]: [d_date_sk#44, d_year#45]
+Arguments: [ss_sold_date_sk#42], [d_date_sk#44], Inner, BuildRight
+
+(30) CometProject
+Input [12]: [c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, ss_ext_discount_amt#40, ss_ext_list_price#41, ss_sold_date_sk#42, d_date_sk#44, d_year#45]
+Arguments: [c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, ss_ext_discount_amt#40, ss_ext_list_price#41, d_year#45], [c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, ss_ext_discount_amt#40, ss_ext_list_price#41, d_year#45]
+
+(31) CometHashAggregate
+Input [10]: [c_customer_id#33, c_first_name#34, c_last_name#35, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, ss_ext_discount_amt#40, ss_ext_list_price#41, d_year#45]
+Keys [8]: [c_customer_id#33, c_first_name#34, c_last_name#35, d_year#45, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38]
+Functions [1]: [partial_sum(UnscaledValue((ss_ext_list_price#41 - ss_ext_discount_amt#40)))]
+
+(32) CometExchange
+Input [9]: [c_customer_id#33, c_first_name#34, c_last_name#35, d_year#45, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, sum#46]
+Arguments: hashpartitioning(c_customer_id#33, c_first_name#34, c_last_name#35, d_year#45, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=2]
+
+(33) CometHashAggregate
+Input [9]: [c_customer_id#33, c_first_name#34, c_last_name#35, d_year#45, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38, sum#46]
+Keys [8]: [c_customer_id#33, c_first_name#34, c_last_name#35, d_year#45, c_preferred_cust_flag#36, c_birth_country#30, c_login#37, c_email_address#38]
+Functions [1]: [sum(UnscaledValue((ss_ext_list_price#41 - ss_ext_discount_amt#40)))]
+
+(34) CometBroadcastExchange
+Input [3]: [customer_id#47, customer_preferred_cust_flag#48, year_total#49]
+Arguments: [customer_id#47, customer_preferred_cust_flag#48, year_total#49]
+
+(35) CometBroadcastHashJoin
+Left output [2]: [customer_id#23, year_total#24]
+Right output [3]: [customer_id#47, customer_preferred_cust_flag#48, year_total#49]
+Arguments: [customer_id#23], [customer_id#47], Inner, BuildRight
+
+(36) CometProject
+Input [5]: [customer_id#23, year_total#24, customer_id#47, customer_preferred_cust_flag#48, year_total#49]
+Arguments: [customer_id#23, year_total#24, customer_preferred_cust_flag#48, year_total#49], [customer_id#23, year_total#24, customer_preferred_cust_flag#48, year_total#49]
+
+(37) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+Output [8]: [c_customer_sk#50, c_customer_id#51, c_first_name#52, c_last_name#53, c_preferred_cust_flag#54, c_birth_country#55, c_login#56, c_email_address#57]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk)]
+ReadSchema: struct
+
+(38) CometFilter
+Input [8]: [c_customer_sk#50, c_customer_id#51, c_first_name#52, c_last_name#53, c_preferred_cust_flag#54, c_birth_country#55, c_login#56, c_email_address#57]
+Condition : (isnotnull(c_customer_sk#50) AND isnotnull(static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#51, 16))))
+
+(39) CometProject
+Input [8]: [c_customer_sk#50, c_customer_id#51, c_first_name#52, c_last_name#53, c_preferred_cust_flag#54, c_birth_country#55, c_login#56, c_email_address#57]
+Arguments: [c_customer_sk#50, c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63], [c_customer_sk#50, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#51, 16)) AS c_customer_id#58, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_first_name#52, 20)) AS c_first_name#59, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_last_name#53, 30)) AS c_last_name#60, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_preferred_cust_flag#54, 1)) AS c_preferred_cust_flag#61, c_birth_country#55, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_login#56, 13)) AS c_login#62, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_email_address#57, 50)) AS c_email_address#63]
+
+(40) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [4]: [ws_bill_customer_sk#64, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#67), dynamicpruningexpression(ws_sold_date_sk#67 IN dynamicpruning#68)]
+PushedFilters: [IsNotNull(ws_bill_customer_sk)]
+ReadSchema: struct
+
+(41) CometFilter
+Input [4]: [ws_bill_customer_sk#64, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67]
+Condition : isnotnull(ws_bill_customer_sk#64)
+
+(42) CometBroadcastExchange
+Input [4]: [ws_bill_customer_sk#64, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67]
+Arguments: [ws_bill_customer_sk#64, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67]
+
+(43) CometBroadcastHashJoin
+Left output [8]: [c_customer_sk#50, c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63]
+Right output [4]: [ws_bill_customer_sk#64, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67]
+Arguments: [c_customer_sk#50], [ws_bill_customer_sk#64], Inner, BuildRight
+
+(44) CometProject
+Input [12]: [c_customer_sk#50, c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, ws_bill_customer_sk#64, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67]
+Arguments: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67], [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67]
+
+(45) ReusedExchange [Reuses operator id: 11]
+Output [2]: [d_date_sk#69, d_year#70]
+
+(46) CometBroadcastHashJoin
+Left output [10]: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67]
+Right output [2]: [d_date_sk#69, d_year#70]
+Arguments: [ws_sold_date_sk#67], [d_date_sk#69], Inner, BuildRight
+
+(47) CometProject
+Input [12]: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, ws_ext_discount_amt#65, ws_ext_list_price#66, ws_sold_date_sk#67, d_date_sk#69, d_year#70]
+Arguments: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, ws_ext_discount_amt#65, ws_ext_list_price#66, d_year#70], [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, ws_ext_discount_amt#65, ws_ext_list_price#66, d_year#70]
+
+(48) CometHashAggregate
+Input [10]: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, ws_ext_discount_amt#65, ws_ext_list_price#66, d_year#70]
+Keys [8]: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, d_year#70]
+Functions [1]: [partial_sum(UnscaledValue((ws_ext_list_price#66 - ws_ext_discount_amt#65)))]
+
+(49) CometExchange
+Input [9]: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, d_year#70, sum#71]
+Arguments: hashpartitioning(c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, d_year#70, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=3]
+
+(50) CometHashAggregate
+Input [9]: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, d_year#70, sum#71]
+Keys [8]: [c_customer_id#58, c_first_name#59, c_last_name#60, c_preferred_cust_flag#61, c_birth_country#55, c_login#62, c_email_address#63, d_year#70]
+Functions [1]: [sum(UnscaledValue((ws_ext_list_price#66 - ws_ext_discount_amt#65)))]
+
+(51) CometFilter
+Input [2]: [customer_id#72, year_total#73]
+Condition : (isnotnull(year_total#73) AND (year_total#73 > 0.00))
+
+(52) CometBroadcastExchange
+Input [2]: [customer_id#72, year_total#73]
+Arguments: [customer_id#72, year_total#73]
+
+(53) CometBroadcastHashJoin
+Left output [4]: [customer_id#23, year_total#24, customer_preferred_cust_flag#48, year_total#49]
+Right output [2]: [customer_id#72, year_total#73]
+Arguments: [customer_id#23], [customer_id#72], Inner, BuildRight
+
+(54) CometProject
+Input [6]: [customer_id#23, year_total#24, customer_preferred_cust_flag#48, year_total#49, customer_id#72, year_total#73]
+Arguments: [customer_id#23, year_total#24, customer_preferred_cust_flag#48, year_total#49, year_total#73], [customer_id#23, year_total#24, customer_preferred_cust_flag#48, year_total#49, year_total#73]
+
+(55) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+Output [8]: [c_customer_sk#74, c_customer_id#75, c_first_name#76, c_last_name#77, c_preferred_cust_flag#78, c_birth_country#79, c_login#80, c_email_address#81]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk)]
+ReadSchema: struct
+
+(56) CometFilter
+Input [8]: [c_customer_sk#74, c_customer_id#75, c_first_name#76, c_last_name#77, c_preferred_cust_flag#78, c_birth_country#79, c_login#80, c_email_address#81]
+Condition : (isnotnull(c_customer_sk#74) AND isnotnull(static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#75, 16))))
+
+(57) CometProject
+Input [8]: [c_customer_sk#74, c_customer_id#75, c_first_name#76, c_last_name#77, c_preferred_cust_flag#78, c_birth_country#79, c_login#80, c_email_address#81]
+Arguments: [c_customer_sk#74, c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87], [c_customer_sk#74, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_customer_id#75, 16)) AS c_customer_id#82, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_first_name#76, 20)) AS c_first_name#83, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_last_name#77, 30)) AS c_last_name#84, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_preferred_cust_flag#78, 1)) AS c_preferred_cust_flag#85, c_birth_country#79, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_login#80, 13)) AS c_login#86, static_invoke(CharVarcharCodegenUtils.readSidePadding(c_email_address#81, 50)) AS c_email_address#87]
+
+(58) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [4]: [ws_bill_customer_sk#88, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#91), dynamicpruningexpression(ws_sold_date_sk#91 IN dynamicpruning#92)]
+PushedFilters: [IsNotNull(ws_bill_customer_sk)]
+ReadSchema: struct
+
+(59) CometFilter
+Input [4]: [ws_bill_customer_sk#88, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91]
+Condition : isnotnull(ws_bill_customer_sk#88)
+
+(60) CometBroadcastExchange
+Input [4]: [ws_bill_customer_sk#88, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91]
+Arguments: [ws_bill_customer_sk#88, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91]
+
+(61) CometBroadcastHashJoin
+Left output [8]: [c_customer_sk#74, c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87]
+Right output [4]: [ws_bill_customer_sk#88, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91]
+Arguments: [c_customer_sk#74], [ws_bill_customer_sk#88], Inner, BuildRight
+
+(62) CometProject
+Input [12]: [c_customer_sk#74, c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, ws_bill_customer_sk#88, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91]
+Arguments: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91], [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91]
+
+(63) ReusedExchange [Reuses operator id: 28]
+Output [2]: [d_date_sk#93, d_year#94]
+
+(64) CometBroadcastHashJoin
+Left output [10]: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91]
+Right output [2]: [d_date_sk#93, d_year#94]
+Arguments: [ws_sold_date_sk#91], [d_date_sk#93], Inner, BuildRight
+
+(65) CometProject
+Input [12]: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, ws_ext_discount_amt#89, ws_ext_list_price#90, ws_sold_date_sk#91, d_date_sk#93, d_year#94]
+Arguments: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, ws_ext_discount_amt#89, ws_ext_list_price#90, d_year#94], [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, ws_ext_discount_amt#89, ws_ext_list_price#90, d_year#94]
+
+(66) CometHashAggregate
+Input [10]: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, ws_ext_discount_amt#89, ws_ext_list_price#90, d_year#94]
+Keys [8]: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, d_year#94]
+Functions [1]: [partial_sum(UnscaledValue((ws_ext_list_price#90 - ws_ext_discount_amt#89)))]
+
+(67) CometExchange
+Input [9]: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, d_year#94, sum#95]
+Arguments: hashpartitioning(c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, d_year#94, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=4]
+
+(68) CometHashAggregate
+Input [9]: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, d_year#94, sum#95]
+Keys [8]: [c_customer_id#82, c_first_name#83, c_last_name#84, c_preferred_cust_flag#85, c_birth_country#79, c_login#86, c_email_address#87, d_year#94]
+Functions [1]: [sum(UnscaledValue((ws_ext_list_price#90 - ws_ext_discount_amt#89)))]
+
+(69) CometBroadcastExchange
+Input [2]: [customer_id#96, year_total#97]
+Arguments: [customer_id#96, year_total#97]
+
+(70) CometBroadcastHashJoin
+Left output [5]: [customer_id#23, year_total#24, customer_preferred_cust_flag#48, year_total#49, year_total#73]
+Right output [2]: [customer_id#96, year_total#97]
+Arguments: [customer_id#23], [customer_id#96], Inner, (CASE WHEN (year_total#73 > 0.00) THEN (year_total#97 / year_total#73) END > CASE WHEN (year_total#24 > 0.00) THEN (year_total#49 / year_total#24) END), BuildRight
+
+(71) CometProject
+Input [7]: [customer_id#23, year_total#24, customer_preferred_cust_flag#48, year_total#49, year_total#73, customer_id#96, year_total#97]
+Arguments: [customer_preferred_cust_flag#48], [customer_preferred_cust_flag#48]
+
+(72) CometTakeOrderedAndProject
+Input [1]: [customer_preferred_cust_flag#48]
+Arguments: TakeOrderedAndProject(limit=100, orderBy=[customer_preferred_cust_flag#48 ASC NULLS FIRST], output=[customer_preferred_cust_flag#48]), [customer_preferred_cust_flag#48], 100, 0, [customer_preferred_cust_flag#48 ASC NULLS FIRST], [customer_preferred_cust_flag#48]
+
+(73) CometColumnarToRow [codegen id : 1]
+Input [1]: [customer_preferred_cust_flag#48]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 4 Hosting Expression = ss_sold_date_sk#18 IN dynamicpruning#19
+BroadcastExchange (77)
++- * CometColumnarToRow (76)
+ +- CometFilter (75)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (74)
+
+
+(74) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#20, d_year#21]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(75) CometFilter
+Input [2]: [d_date_sk#20, d_year#21]
+Condition : ((isnotnull(d_year#21) AND (d_year#21 = 2001)) AND isnotnull(d_date_sk#20))
+
+(76) CometColumnarToRow [codegen id : 1]
+Input [2]: [d_date_sk#20, d_year#21]
+
+(77) BroadcastExchange
+Input [2]: [d_date_sk#20, d_year#21]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=5]
+
+Subquery:2 Hosting operator id = 21 Hosting Expression = ss_sold_date_sk#42 IN dynamicpruning#43
+BroadcastExchange (81)
++- * CometColumnarToRow (80)
+ +- CometFilter (79)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (78)
+
+
+(78) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#44, d_year#45]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2002), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(79) CometFilter
+Input [2]: [d_date_sk#44, d_year#45]
+Condition : ((isnotnull(d_year#45) AND (d_year#45 = 2002)) AND isnotnull(d_date_sk#44))
+
+(80) CometColumnarToRow [codegen id : 1]
+Input [2]: [d_date_sk#44, d_year#45]
+
+(81) BroadcastExchange
+Input [2]: [d_date_sk#44, d_year#45]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=6]
+
+Subquery:3 Hosting operator id = 40 Hosting Expression = ws_sold_date_sk#67 IN dynamicpruning#19
+
+Subquery:4 Hosting operator id = 58 Hosting Expression = ws_sold_date_sk#91 IN dynamicpruning#43
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11/extended.txt
new file mode 100644
index 0000000000..781eae9054
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11/extended.txt
@@ -0,0 +1,91 @@
+CometColumnarToRow
++- CometTakeOrderedAndProject
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometHashAggregate
+ : : : +- CometExchange
+ : : : +- CometHashAggregate
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometHashAggregate
+ : : +- CometExchange
+ : : +- CometHashAggregate
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+ : : : +- CometBroadcastExchange
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : +- SubqueryBroadcast
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometFilter
+ : +- CometHashAggregate
+ : +- CometExchange
+ : +- CometHashAggregate
+ : +- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+ : : +- CometBroadcastExchange
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : +- ReusedSubquery
+ : +- CometBroadcastExchange
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ +- CometBroadcastExchange
+ +- CometHashAggregate
+ +- CometExchange
+ +- CometHashAggregate
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+ : +- CometBroadcastExchange
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : +- ReusedSubquery
+ +- CometBroadcastExchange
+ +- CometFilter
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+
+Comet accelerated 80 out of 86 eligible operators (93%). Final plan contains 3 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11/simplified.txt
new file mode 100644
index 0000000000..4599ecf539
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q11/simplified.txt
@@ -0,0 +1,91 @@
+WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometTakeOrderedAndProject [customer_preferred_cust_flag]
+ CometProject [customer_preferred_cust_flag]
+ CometBroadcastHashJoin [customer_id,year_total,customer_preferred_cust_flag,year_total,year_total,customer_id,year_total]
+ CometProject [customer_id,year_total,customer_preferred_cust_flag,year_total,year_total]
+ CometBroadcastHashJoin [customer_id,year_total,customer_preferred_cust_flag,year_total,customer_id,year_total]
+ CometProject [customer_id,year_total,customer_preferred_cust_flag,year_total]
+ CometBroadcastHashJoin [customer_id,year_total,customer_id,customer_preferred_cust_flag,year_total]
+ CometFilter [customer_id,year_total]
+ CometHashAggregate [c_first_name,c_last_name,d_year,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,sum] [customer_id,year_total,c_customer_id,sum(UnscaledValue((ss_ext_list_price - ss_ext_discount_amt)))]
+ CometExchange [c_customer_id,c_first_name,c_last_name,d_year,c_preferred_cust_flag,c_birth_country,c_login,c_email_address] #1
+ CometHashAggregate [ss_ext_list_price,ss_ext_discount_amt] [c_customer_id,c_first_name,c_last_name,d_year,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,sum]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_discount_amt,ss_ext_list_price,d_year]
+ CometBroadcastHashJoin [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk,d_date_sk,d_year]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ CometBroadcastHashJoin [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_login,c_email_address] [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometFilter [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometBroadcastExchange [ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk] #2
+ CometFilter [ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #3
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [d_date_sk,d_year] #4
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [customer_id,customer_preferred_cust_flag,year_total] #5
+ CometHashAggregate [c_first_name,c_last_name,d_year,c_birth_country,c_login,c_email_address,sum] [customer_id,customer_preferred_cust_flag,year_total,c_customer_id,c_preferred_cust_flag,sum(UnscaledValue((ss_ext_list_price - ss_ext_discount_amt)))]
+ CometExchange [c_customer_id,c_first_name,c_last_name,d_year,c_preferred_cust_flag,c_birth_country,c_login,c_email_address] #6
+ CometHashAggregate [ss_ext_list_price,ss_ext_discount_amt] [c_customer_id,c_first_name,c_last_name,d_year,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,sum]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_discount_amt,ss_ext_list_price,d_year]
+ CometBroadcastHashJoin [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk,d_date_sk,d_year]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ CometBroadcastHashJoin [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_login,c_email_address] [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometFilter [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometBroadcastExchange [ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk] #7
+ CometFilter [ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_customer_sk,ss_ext_discount_amt,ss_ext_list_price,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #2
+ BroadcastExchange #8
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [d_date_sk,d_year] #9
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [customer_id,year_total] #10
+ CometFilter [customer_id,year_total]
+ CometHashAggregate [c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year,sum] [customer_id,year_total,c_customer_id,sum(UnscaledValue((ws_ext_list_price - ws_ext_discount_amt)))]
+ CometExchange [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year] #11
+ CometHashAggregate [ws_ext_list_price,ws_ext_discount_amt] [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year,sum]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_ext_discount_amt,ws_ext_list_price,d_year]
+ CometBroadcastHashJoin [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk,d_date_sk,d_year]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ CometBroadcastHashJoin [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_login,c_email_address] [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometFilter [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometBroadcastExchange [ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk] #12
+ CometFilter [ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ ReusedExchange [d_date_sk,d_year] #4
+ CometBroadcastExchange [customer_id,year_total] #13
+ CometHashAggregate [c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year,sum] [customer_id,year_total,c_customer_id,sum(UnscaledValue((ws_ext_list_price - ws_ext_discount_amt)))]
+ CometExchange [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year] #14
+ CometHashAggregate [ws_ext_list_price,ws_ext_discount_amt] [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,d_year,sum]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_ext_discount_amt,ws_ext_list_price,d_year]
+ CometBroadcastHashJoin [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk,d_date_sk,d_year]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ CometBroadcastHashJoin [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address,ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ CometProject [c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_login,c_email_address] [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometFilter [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer [c_customer_sk,c_customer_id,c_first_name,c_last_name,c_preferred_cust_flag,c_birth_country,c_login,c_email_address]
+ CometBroadcastExchange [ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk] #15
+ CometFilter [ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_bill_customer_sk,ws_ext_discount_amt,ws_ext_list_price,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ ReusedExchange [d_date_sk,d_year] #9
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_datafusion/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_datafusion/explain.txt
new file mode 100644
index 0000000000..409078c363
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_datafusion/explain.txt
@@ -0,0 +1,163 @@
+== Physical Plan ==
+TakeOrderedAndProject (23)
++- * Project (22)
+ +- Window (21)
+ +- * CometColumnarToRow (20)
+ +- CometSort (19)
+ +- CometColumnarExchange (18)
+ +- * HashAggregate (17)
+ +- * CometColumnarToRow (16)
+ +- CometColumnarExchange (15)
+ +- * HashAggregate (14)
+ +- * Project (13)
+ +- * BroadcastHashJoin Inner BuildRight (12)
+ :- * Project (10)
+ : +- * BroadcastHashJoin Inner BuildRight (9)
+ : :- * Filter (3)
+ : : +- * ColumnarToRow (2)
+ : : +- Scan parquet spark_catalog.default.web_sales (1)
+ : +- BroadcastExchange (8)
+ : +- * CometColumnarToRow (7)
+ : +- CometProject (6)
+ : +- CometFilter (5)
+ : +- CometNativeScan parquet spark_catalog.default.item (4)
+ +- ReusedExchange (11)
+
+
+(1) Scan parquet spark_catalog.default.web_sales
+Output [3]: [ws_item_sk#1, ws_ext_sales_price#2, ws_sold_date_sk#3]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#3), dynamicpruningexpression(ws_sold_date_sk#3 IN dynamicpruning#4)]
+PushedFilters: [IsNotNull(ws_item_sk)]
+ReadSchema: struct
+
+(2) ColumnarToRow [codegen id : 3]
+Input [3]: [ws_item_sk#1, ws_ext_sales_price#2, ws_sold_date_sk#3]
+
+(3) Filter [codegen id : 3]
+Input [3]: [ws_item_sk#1, ws_ext_sales_price#2, ws_sold_date_sk#3]
+Condition : isnotnull(ws_item_sk#1)
+
+(4) CometNativeScan parquet spark_catalog.default.item
+Output [6]: [i_item_sk#5, i_item_id#6, i_item_desc#7, i_current_price#8, i_class#9, i_category#10]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk)]
+ReadSchema: struct
+
+(5) CometFilter
+Input [6]: [i_item_sk#5, i_item_id#6, i_item_desc#7, i_current_price#8, i_class#9, i_category#10]
+Condition : (static_invoke(CharVarcharCodegenUtils.readSidePadding(i_category#10, 50)) IN (Sports ,Books ,Home ) AND isnotnull(i_item_sk#5))
+
+(6) CometProject
+Input [6]: [i_item_sk#5, i_item_id#6, i_item_desc#7, i_current_price#8, i_class#9, i_category#10]
+Arguments: [i_item_sk#5, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13], [i_item_sk#5, static_invoke(CharVarcharCodegenUtils.readSidePadding(i_item_id#6, 16)) AS i_item_id#11, i_item_desc#7, i_current_price#8, static_invoke(CharVarcharCodegenUtils.readSidePadding(i_class#9, 50)) AS i_class#12, static_invoke(CharVarcharCodegenUtils.readSidePadding(i_category#10, 50)) AS i_category#13]
+
+(7) CometColumnarToRow [codegen id : 1]
+Input [6]: [i_item_sk#5, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+
+(8) BroadcastExchange
+Input [6]: [i_item_sk#5, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=1]
+
+(9) BroadcastHashJoin [codegen id : 3]
+Left keys [1]: [ws_item_sk#1]
+Right keys [1]: [i_item_sk#5]
+Join type: Inner
+Join condition: None
+
+(10) Project [codegen id : 3]
+Output [7]: [ws_ext_sales_price#2, ws_sold_date_sk#3, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+Input [9]: [ws_item_sk#1, ws_ext_sales_price#2, ws_sold_date_sk#3, i_item_sk#5, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+
+(11) ReusedExchange [Reuses operator id: 28]
+Output [1]: [d_date_sk#14]
+
+(12) BroadcastHashJoin [codegen id : 3]
+Left keys [1]: [ws_sold_date_sk#3]
+Right keys [1]: [d_date_sk#14]
+Join type: Inner
+Join condition: None
+
+(13) Project [codegen id : 3]
+Output [6]: [ws_ext_sales_price#2, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+Input [8]: [ws_ext_sales_price#2, ws_sold_date_sk#3, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13, d_date_sk#14]
+
+(14) HashAggregate [codegen id : 3]
+Input [6]: [ws_ext_sales_price#2, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+Keys [5]: [i_item_id#11, i_item_desc#7, i_category#13, i_class#12, i_current_price#8]
+Functions [1]: [partial_sum(UnscaledValue(ws_ext_sales_price#2))]
+Aggregate Attributes [1]: [sum#15]
+Results [6]: [i_item_id#11, i_item_desc#7, i_category#13, i_class#12, i_current_price#8, sum#16]
+
+(15) CometColumnarExchange
+Input [6]: [i_item_id#11, i_item_desc#7, i_category#13, i_class#12, i_current_price#8, sum#16]
+Arguments: hashpartitioning(i_item_id#11, i_item_desc#7, i_category#13, i_class#12, i_current_price#8, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=2]
+
+(16) CometColumnarToRow [codegen id : 4]
+Input [6]: [i_item_id#11, i_item_desc#7, i_category#13, i_class#12, i_current_price#8, sum#16]
+
+(17) HashAggregate [codegen id : 4]
+Input [6]: [i_item_id#11, i_item_desc#7, i_category#13, i_class#12, i_current_price#8, sum#16]
+Keys [5]: [i_item_id#11, i_item_desc#7, i_category#13, i_class#12, i_current_price#8]
+Functions [1]: [sum(UnscaledValue(ws_ext_sales_price#2))]
+Aggregate Attributes [1]: [sum(UnscaledValue(ws_ext_sales_price#2))#17]
+Results [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, MakeDecimal(sum(UnscaledValue(ws_ext_sales_price#2))#17,17,2) AS itemrevenue#18, MakeDecimal(sum(UnscaledValue(ws_ext_sales_price#2))#17,17,2) AS _w0#19, i_item_id#11]
+
+(18) CometColumnarExchange
+Input [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#18, _w0#19, i_item_id#11]
+Arguments: hashpartitioning(i_class#12, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=3]
+
+(19) CometSort
+Input [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#18, _w0#19, i_item_id#11]
+Arguments: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#18, _w0#19, i_item_id#11], [i_class#12 ASC NULLS FIRST]
+
+(20) CometColumnarToRow [codegen id : 5]
+Input [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#18, _w0#19, i_item_id#11]
+
+(21) Window
+Input [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#18, _w0#19, i_item_id#11]
+Arguments: [sum(_w0#19) windowspecdefinition(i_class#12, specifiedwindowframe(RowFrame, unboundedpreceding$(), unboundedfollowing$())) AS _we0#20], [i_class#12]
+
+(22) Project [codegen id : 6]
+Output [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#18, ((_w0#19 * 100) / _we0#20) AS revenueratio#21, i_item_id#11]
+Input [8]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#18, _w0#19, i_item_id#11, _we0#20]
+
+(23) TakeOrderedAndProject
+Input [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#18, revenueratio#21, i_item_id#11]
+Arguments: 100, [i_category#13 ASC NULLS FIRST, i_class#12 ASC NULLS FIRST, i_item_id#11 ASC NULLS FIRST, i_item_desc#7 ASC NULLS FIRST, revenueratio#21 ASC NULLS FIRST], [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#18, revenueratio#21]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 1 Hosting Expression = ws_sold_date_sk#3 IN dynamicpruning#4
+BroadcastExchange (28)
++- * CometColumnarToRow (27)
+ +- CometProject (26)
+ +- CometFilter (25)
+ +- CometNativeScan parquet spark_catalog.default.date_dim (24)
+
+
+(24) CometNativeScan parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#14, d_date#22]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_date), GreaterThanOrEqual(d_date,1999-02-22), LessThanOrEqual(d_date,1999-03-24), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(25) CometFilter
+Input [2]: [d_date_sk#14, d_date#22]
+Condition : (((isnotnull(d_date#22) AND (d_date#22 >= 1999-02-22)) AND (d_date#22 <= 1999-03-24)) AND isnotnull(d_date_sk#14))
+
+(26) CometProject
+Input [2]: [d_date_sk#14, d_date#22]
+Arguments: [d_date_sk#14], [d_date_sk#14]
+
+(27) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#14]
+
+(28) BroadcastExchange
+Input [1]: [d_date_sk#14]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=4]
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_datafusion/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_datafusion/extended.txt
new file mode 100644
index 0000000000..6c2a775097
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_datafusion/extended.txt
@@ -0,0 +1,35 @@
+TakeOrderedAndProject
++- Project
+ +- Window [COMET: WindowExec is not fully compatible with Spark (Native WindowExec has known correctness issues). To enable it anyway, set spark.comet.operator.WindowExec.allowIncompatible=true. For more information, refer to the Comet Compatibility Guide (https://datafusion.apache.org/comet/user-guide/compatibility.html).]
+ +- CometColumnarToRow
+ +- CometSort
+ +- CometColumnarExchange
+ +- HashAggregate
+ +- CometColumnarToRow
+ +- CometColumnarExchange
+ +- HashAggregate
+ +- Project
+ +- BroadcastHashJoin
+ :- Project
+ : +- BroadcastHashJoin
+ : :- Filter
+ : : +- ColumnarToRow
+ : : +- Scan parquet spark_catalog.default.web_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : +- SubqueryBroadcast
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : +- BroadcastExchange
+ : +- CometColumnarToRow
+ : +- CometProject
+ : +- CometFilter
+ : +- CometNativeScan parquet spark_catalog.default.item
+ +- BroadcastExchange
+ +- CometColumnarToRow
+ +- CometProject
+ +- CometFilter
+ +- CometNativeScan parquet spark_catalog.default.date_dim
+
+Comet accelerated 12 out of 27 eligible operators (44%). Final plan contains 6 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_datafusion/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_datafusion/simplified.txt
new file mode 100644
index 0000000000..b7b0a89774
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_datafusion/simplified.txt
@@ -0,0 +1,43 @@
+TakeOrderedAndProject [i_category,i_class,i_item_id,i_item_desc,revenueratio,i_current_price,itemrevenue]
+ WholeStageCodegen (6)
+ Project [i_item_desc,i_category,i_class,i_current_price,itemrevenue,_w0,_we0,i_item_id]
+ InputAdapter
+ Window [_w0,i_class]
+ WholeStageCodegen (5)
+ CometColumnarToRow
+ InputAdapter
+ CometSort [i_item_desc,i_category,i_class,i_current_price,itemrevenue,_w0,i_item_id]
+ CometColumnarExchange [i_class] #1
+ WholeStageCodegen (4)
+ HashAggregate [i_item_id,i_item_desc,i_category,i_class,i_current_price,sum] [sum(UnscaledValue(ws_ext_sales_price)),itemrevenue,_w0,sum]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [i_item_id,i_item_desc,i_category,i_class,i_current_price] #2
+ WholeStageCodegen (3)
+ HashAggregate [i_item_id,i_item_desc,i_category,i_class,i_current_price,ws_ext_sales_price] [sum,sum]
+ Project [ws_ext_sales_price,i_item_id,i_item_desc,i_current_price,i_class,i_category]
+ BroadcastHashJoin [ws_sold_date_sk,d_date_sk]
+ Project [ws_ext_sales_price,ws_sold_date_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category]
+ BroadcastHashJoin [ws_item_sk,i_item_sk]
+ Filter [ws_item_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.web_sales [ws_item_sk,ws_ext_sales_price,ws_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #3
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_date]
+ CometNativeScan parquet spark_catalog.default.date_dim [d_date_sk,d_date]
+ InputAdapter
+ BroadcastExchange #4
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [i_item_id,i_class,i_category] [i_item_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category]
+ CometFilter [i_item_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category]
+ CometNativeScan parquet spark_catalog.default.item [i_item_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category]
+ InputAdapter
+ ReusedExchange [d_date_sk] #3
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_iceberg_compat/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_iceberg_compat/explain.txt
new file mode 100644
index 0000000000..8811d04e59
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_iceberg_compat/explain.txt
@@ -0,0 +1,164 @@
+== Physical Plan ==
+TakeOrderedAndProject (23)
++- * Project (22)
+ +- Window (21)
+ +- * CometColumnarToRow (20)
+ +- CometSort (19)
+ +- CometExchange (18)
+ +- CometHashAggregate (17)
+ +- CometExchange (16)
+ +- CometHashAggregate (15)
+ +- CometProject (14)
+ +- CometBroadcastHashJoin (13)
+ :- CometProject (8)
+ : +- CometBroadcastHashJoin (7)
+ : :- CometFilter (2)
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (1)
+ : +- CometBroadcastExchange (6)
+ : +- CometProject (5)
+ : +- CometFilter (4)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (3)
+ +- CometBroadcastExchange (12)
+ +- CometProject (11)
+ +- CometFilter (10)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (9)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [3]: [ws_item_sk#1, ws_ext_sales_price#2, ws_sold_date_sk#3]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#3), dynamicpruningexpression(ws_sold_date_sk#3 IN dynamicpruning#4)]
+PushedFilters: [IsNotNull(ws_item_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [3]: [ws_item_sk#1, ws_ext_sales_price#2, ws_sold_date_sk#3]
+Condition : isnotnull(ws_item_sk#1)
+
+(3) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [6]: [i_item_sk#5, i_item_id#6, i_item_desc#7, i_current_price#8, i_class#9, i_category#10]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk)]
+ReadSchema: struct
+
+(4) CometFilter
+Input [6]: [i_item_sk#5, i_item_id#6, i_item_desc#7, i_current_price#8, i_class#9, i_category#10]
+Condition : (static_invoke(CharVarcharCodegenUtils.readSidePadding(i_category#10, 50)) IN (Sports ,Books ,Home ) AND isnotnull(i_item_sk#5))
+
+(5) CometProject
+Input [6]: [i_item_sk#5, i_item_id#6, i_item_desc#7, i_current_price#8, i_class#9, i_category#10]
+Arguments: [i_item_sk#5, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13], [i_item_sk#5, static_invoke(CharVarcharCodegenUtils.readSidePadding(i_item_id#6, 16)) AS i_item_id#11, i_item_desc#7, i_current_price#8, static_invoke(CharVarcharCodegenUtils.readSidePadding(i_class#9, 50)) AS i_class#12, static_invoke(CharVarcharCodegenUtils.readSidePadding(i_category#10, 50)) AS i_category#13]
+
+(6) CometBroadcastExchange
+Input [6]: [i_item_sk#5, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+Arguments: [i_item_sk#5, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+
+(7) CometBroadcastHashJoin
+Left output [3]: [ws_item_sk#1, ws_ext_sales_price#2, ws_sold_date_sk#3]
+Right output [6]: [i_item_sk#5, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+Arguments: [ws_item_sk#1], [i_item_sk#5], Inner, BuildRight
+
+(8) CometProject
+Input [9]: [ws_item_sk#1, ws_ext_sales_price#2, ws_sold_date_sk#3, i_item_sk#5, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+Arguments: [ws_ext_sales_price#2, ws_sold_date_sk#3, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13], [ws_ext_sales_price#2, ws_sold_date_sk#3, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+
+(9) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#14, d_date#15]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_date), GreaterThanOrEqual(d_date,1999-02-22), LessThanOrEqual(d_date,1999-03-24), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(10) CometFilter
+Input [2]: [d_date_sk#14, d_date#15]
+Condition : (((isnotnull(d_date#15) AND (d_date#15 >= 1999-02-22)) AND (d_date#15 <= 1999-03-24)) AND isnotnull(d_date_sk#14))
+
+(11) CometProject
+Input [2]: [d_date_sk#14, d_date#15]
+Arguments: [d_date_sk#14], [d_date_sk#14]
+
+(12) CometBroadcastExchange
+Input [1]: [d_date_sk#14]
+Arguments: [d_date_sk#14]
+
+(13) CometBroadcastHashJoin
+Left output [7]: [ws_ext_sales_price#2, ws_sold_date_sk#3, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+Right output [1]: [d_date_sk#14]
+Arguments: [ws_sold_date_sk#3], [d_date_sk#14], Inner, BuildRight
+
+(14) CometProject
+Input [8]: [ws_ext_sales_price#2, ws_sold_date_sk#3, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13, d_date_sk#14]
+Arguments: [ws_ext_sales_price#2, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13], [ws_ext_sales_price#2, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+
+(15) CometHashAggregate
+Input [6]: [ws_ext_sales_price#2, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+Keys [5]: [i_item_id#11, i_item_desc#7, i_category#13, i_class#12, i_current_price#8]
+Functions [1]: [partial_sum(UnscaledValue(ws_ext_sales_price#2))]
+
+(16) CometExchange
+Input [6]: [i_item_id#11, i_item_desc#7, i_category#13, i_class#12, i_current_price#8, sum#16]
+Arguments: hashpartitioning(i_item_id#11, i_item_desc#7, i_category#13, i_class#12, i_current_price#8, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=1]
+
+(17) CometHashAggregate
+Input [6]: [i_item_id#11, i_item_desc#7, i_category#13, i_class#12, i_current_price#8, sum#16]
+Keys [5]: [i_item_id#11, i_item_desc#7, i_category#13, i_class#12, i_current_price#8]
+Functions [1]: [sum(UnscaledValue(ws_ext_sales_price#2))]
+
+(18) CometExchange
+Input [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, _w0#18, i_item_id#11]
+Arguments: hashpartitioning(i_class#12, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=2]
+
+(19) CometSort
+Input [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, _w0#18, i_item_id#11]
+Arguments: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, _w0#18, i_item_id#11], [i_class#12 ASC NULLS FIRST]
+
+(20) CometColumnarToRow [codegen id : 1]
+Input [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, _w0#18, i_item_id#11]
+
+(21) Window
+Input [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, _w0#18, i_item_id#11]
+Arguments: [sum(_w0#18) windowspecdefinition(i_class#12, specifiedwindowframe(RowFrame, unboundedpreceding$(), unboundedfollowing$())) AS _we0#19], [i_class#12]
+
+(22) Project [codegen id : 2]
+Output [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, ((_w0#18 * 100) / _we0#19) AS revenueratio#20, i_item_id#11]
+Input [8]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, _w0#18, i_item_id#11, _we0#19]
+
+(23) TakeOrderedAndProject
+Input [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, revenueratio#20, i_item_id#11]
+Arguments: 100, [i_category#13 ASC NULLS FIRST, i_class#12 ASC NULLS FIRST, i_item_id#11 ASC NULLS FIRST, i_item_desc#7 ASC NULLS FIRST, revenueratio#20 ASC NULLS FIRST], [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, revenueratio#20]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 1 Hosting Expression = ws_sold_date_sk#3 IN dynamicpruning#4
+BroadcastExchange (28)
++- * CometColumnarToRow (27)
+ +- CometProject (26)
+ +- CometFilter (25)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (24)
+
+
+(24) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#14, d_date#15]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_date), GreaterThanOrEqual(d_date,1999-02-22), LessThanOrEqual(d_date,1999-03-24), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(25) CometFilter
+Input [2]: [d_date_sk#14, d_date#15]
+Condition : (((isnotnull(d_date#15) AND (d_date#15 >= 1999-02-22)) AND (d_date#15 <= 1999-03-24)) AND isnotnull(d_date_sk#14))
+
+(26) CometProject
+Input [2]: [d_date_sk#14, d_date#15]
+Arguments: [d_date_sk#14], [d_date_sk#14]
+
+(27) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#14]
+
+(28) BroadcastExchange
+Input [1]: [d_date_sk#14]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=3]
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_iceberg_compat/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_iceberg_compat/extended.txt
new file mode 100644
index 0000000000..3f41c97ff5
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_iceberg_compat/extended.txt
@@ -0,0 +1,31 @@
+TakeOrderedAndProject
++- Project
+ +- Window [COMET: WindowExec is not fully compatible with Spark (Native WindowExec has known correctness issues). To enable it anyway, set spark.comet.operator.WindowExec.allowIncompatible=true. For more information, refer to the Comet Compatibility Guide (https://datafusion.apache.org/comet/user-guide/compatibility.html).]
+ +- CometColumnarToRow
+ +- CometSort
+ +- CometExchange
+ +- CometHashAggregate
+ +- CometExchange
+ +- CometHashAggregate
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : +- SubqueryBroadcast
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ +- CometBroadcastExchange
+ +- CometProject
+ +- CometFilter
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+
+Comet accelerated 22 out of 27 eligible operators (81%). Final plan contains 2 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_iceberg_compat/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_iceberg_compat/simplified.txt
new file mode 100644
index 0000000000..fb83fd2f9a
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12.native_iceberg_compat/simplified.txt
@@ -0,0 +1,35 @@
+TakeOrderedAndProject [i_category,i_class,i_item_id,i_item_desc,revenueratio,i_current_price,itemrevenue]
+ WholeStageCodegen (2)
+ Project [i_item_desc,i_category,i_class,i_current_price,itemrevenue,_w0,_we0,i_item_id]
+ InputAdapter
+ Window [_w0,i_class]
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometSort [i_item_desc,i_category,i_class,i_current_price,itemrevenue,_w0,i_item_id]
+ CometExchange [i_class] #1
+ CometHashAggregate [sum] [i_item_desc,i_category,i_class,i_current_price,itemrevenue,_w0,i_item_id,sum(UnscaledValue(ws_ext_sales_price))]
+ CometExchange [i_item_id,i_item_desc,i_category,i_class,i_current_price] #2
+ CometHashAggregate [ws_ext_sales_price] [i_item_id,i_item_desc,i_category,i_class,i_current_price,sum]
+ CometProject [ws_ext_sales_price,i_item_id,i_item_desc,i_current_price,i_class,i_category]
+ CometBroadcastHashJoin [ws_ext_sales_price,ws_sold_date_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category,d_date_sk]
+ CometProject [ws_ext_sales_price,ws_sold_date_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category]
+ CometBroadcastHashJoin [ws_item_sk,ws_ext_sales_price,ws_sold_date_sk,i_item_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category]
+ CometFilter [ws_item_sk,ws_ext_sales_price,ws_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_item_sk,ws_ext_sales_price,ws_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #3
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_date]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_date]
+ CometBroadcastExchange [i_item_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category] #4
+ CometProject [i_item_id,i_class,i_category] [i_item_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category]
+ CometFilter [i_item_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category]
+ CometBroadcastExchange [d_date_sk] #5
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_date]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_date]
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12/explain.txt
new file mode 100644
index 0000000000..8811d04e59
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12/explain.txt
@@ -0,0 +1,164 @@
+== Physical Plan ==
+TakeOrderedAndProject (23)
++- * Project (22)
+ +- Window (21)
+ +- * CometColumnarToRow (20)
+ +- CometSort (19)
+ +- CometExchange (18)
+ +- CometHashAggregate (17)
+ +- CometExchange (16)
+ +- CometHashAggregate (15)
+ +- CometProject (14)
+ +- CometBroadcastHashJoin (13)
+ :- CometProject (8)
+ : +- CometBroadcastHashJoin (7)
+ : :- CometFilter (2)
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (1)
+ : +- CometBroadcastExchange (6)
+ : +- CometProject (5)
+ : +- CometFilter (4)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (3)
+ +- CometBroadcastExchange (12)
+ +- CometProject (11)
+ +- CometFilter (10)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (9)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [3]: [ws_item_sk#1, ws_ext_sales_price#2, ws_sold_date_sk#3]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#3), dynamicpruningexpression(ws_sold_date_sk#3 IN dynamicpruning#4)]
+PushedFilters: [IsNotNull(ws_item_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [3]: [ws_item_sk#1, ws_ext_sales_price#2, ws_sold_date_sk#3]
+Condition : isnotnull(ws_item_sk#1)
+
+(3) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [6]: [i_item_sk#5, i_item_id#6, i_item_desc#7, i_current_price#8, i_class#9, i_category#10]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk)]
+ReadSchema: struct
+
+(4) CometFilter
+Input [6]: [i_item_sk#5, i_item_id#6, i_item_desc#7, i_current_price#8, i_class#9, i_category#10]
+Condition : (static_invoke(CharVarcharCodegenUtils.readSidePadding(i_category#10, 50)) IN (Sports ,Books ,Home ) AND isnotnull(i_item_sk#5))
+
+(5) CometProject
+Input [6]: [i_item_sk#5, i_item_id#6, i_item_desc#7, i_current_price#8, i_class#9, i_category#10]
+Arguments: [i_item_sk#5, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13], [i_item_sk#5, static_invoke(CharVarcharCodegenUtils.readSidePadding(i_item_id#6, 16)) AS i_item_id#11, i_item_desc#7, i_current_price#8, static_invoke(CharVarcharCodegenUtils.readSidePadding(i_class#9, 50)) AS i_class#12, static_invoke(CharVarcharCodegenUtils.readSidePadding(i_category#10, 50)) AS i_category#13]
+
+(6) CometBroadcastExchange
+Input [6]: [i_item_sk#5, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+Arguments: [i_item_sk#5, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+
+(7) CometBroadcastHashJoin
+Left output [3]: [ws_item_sk#1, ws_ext_sales_price#2, ws_sold_date_sk#3]
+Right output [6]: [i_item_sk#5, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+Arguments: [ws_item_sk#1], [i_item_sk#5], Inner, BuildRight
+
+(8) CometProject
+Input [9]: [ws_item_sk#1, ws_ext_sales_price#2, ws_sold_date_sk#3, i_item_sk#5, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+Arguments: [ws_ext_sales_price#2, ws_sold_date_sk#3, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13], [ws_ext_sales_price#2, ws_sold_date_sk#3, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+
+(9) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#14, d_date#15]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_date), GreaterThanOrEqual(d_date,1999-02-22), LessThanOrEqual(d_date,1999-03-24), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(10) CometFilter
+Input [2]: [d_date_sk#14, d_date#15]
+Condition : (((isnotnull(d_date#15) AND (d_date#15 >= 1999-02-22)) AND (d_date#15 <= 1999-03-24)) AND isnotnull(d_date_sk#14))
+
+(11) CometProject
+Input [2]: [d_date_sk#14, d_date#15]
+Arguments: [d_date_sk#14], [d_date_sk#14]
+
+(12) CometBroadcastExchange
+Input [1]: [d_date_sk#14]
+Arguments: [d_date_sk#14]
+
+(13) CometBroadcastHashJoin
+Left output [7]: [ws_ext_sales_price#2, ws_sold_date_sk#3, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+Right output [1]: [d_date_sk#14]
+Arguments: [ws_sold_date_sk#3], [d_date_sk#14], Inner, BuildRight
+
+(14) CometProject
+Input [8]: [ws_ext_sales_price#2, ws_sold_date_sk#3, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13, d_date_sk#14]
+Arguments: [ws_ext_sales_price#2, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13], [ws_ext_sales_price#2, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+
+(15) CometHashAggregate
+Input [6]: [ws_ext_sales_price#2, i_item_id#11, i_item_desc#7, i_current_price#8, i_class#12, i_category#13]
+Keys [5]: [i_item_id#11, i_item_desc#7, i_category#13, i_class#12, i_current_price#8]
+Functions [1]: [partial_sum(UnscaledValue(ws_ext_sales_price#2))]
+
+(16) CometExchange
+Input [6]: [i_item_id#11, i_item_desc#7, i_category#13, i_class#12, i_current_price#8, sum#16]
+Arguments: hashpartitioning(i_item_id#11, i_item_desc#7, i_category#13, i_class#12, i_current_price#8, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=1]
+
+(17) CometHashAggregate
+Input [6]: [i_item_id#11, i_item_desc#7, i_category#13, i_class#12, i_current_price#8, sum#16]
+Keys [5]: [i_item_id#11, i_item_desc#7, i_category#13, i_class#12, i_current_price#8]
+Functions [1]: [sum(UnscaledValue(ws_ext_sales_price#2))]
+
+(18) CometExchange
+Input [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, _w0#18, i_item_id#11]
+Arguments: hashpartitioning(i_class#12, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=2]
+
+(19) CometSort
+Input [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, _w0#18, i_item_id#11]
+Arguments: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, _w0#18, i_item_id#11], [i_class#12 ASC NULLS FIRST]
+
+(20) CometColumnarToRow [codegen id : 1]
+Input [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, _w0#18, i_item_id#11]
+
+(21) Window
+Input [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, _w0#18, i_item_id#11]
+Arguments: [sum(_w0#18) windowspecdefinition(i_class#12, specifiedwindowframe(RowFrame, unboundedpreceding$(), unboundedfollowing$())) AS _we0#19], [i_class#12]
+
+(22) Project [codegen id : 2]
+Output [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, ((_w0#18 * 100) / _we0#19) AS revenueratio#20, i_item_id#11]
+Input [8]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, _w0#18, i_item_id#11, _we0#19]
+
+(23) TakeOrderedAndProject
+Input [7]: [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, revenueratio#20, i_item_id#11]
+Arguments: 100, [i_category#13 ASC NULLS FIRST, i_class#12 ASC NULLS FIRST, i_item_id#11 ASC NULLS FIRST, i_item_desc#7 ASC NULLS FIRST, revenueratio#20 ASC NULLS FIRST], [i_item_desc#7, i_category#13, i_class#12, i_current_price#8, itemrevenue#17, revenueratio#20]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 1 Hosting Expression = ws_sold_date_sk#3 IN dynamicpruning#4
+BroadcastExchange (28)
++- * CometColumnarToRow (27)
+ +- CometProject (26)
+ +- CometFilter (25)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (24)
+
+
+(24) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#14, d_date#15]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_date), GreaterThanOrEqual(d_date,1999-02-22), LessThanOrEqual(d_date,1999-03-24), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(25) CometFilter
+Input [2]: [d_date_sk#14, d_date#15]
+Condition : (((isnotnull(d_date#15) AND (d_date#15 >= 1999-02-22)) AND (d_date#15 <= 1999-03-24)) AND isnotnull(d_date_sk#14))
+
+(26) CometProject
+Input [2]: [d_date_sk#14, d_date#15]
+Arguments: [d_date_sk#14], [d_date_sk#14]
+
+(27) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#14]
+
+(28) BroadcastExchange
+Input [1]: [d_date_sk#14]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=3]
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12/extended.txt
new file mode 100644
index 0000000000..3f41c97ff5
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12/extended.txt
@@ -0,0 +1,31 @@
+TakeOrderedAndProject
++- Project
+ +- Window [COMET: WindowExec is not fully compatible with Spark (Native WindowExec has known correctness issues). To enable it anyway, set spark.comet.operator.WindowExec.allowIncompatible=true. For more information, refer to the Comet Compatibility Guide (https://datafusion.apache.org/comet/user-guide/compatibility.html).]
+ +- CometColumnarToRow
+ +- CometSort
+ +- CometExchange
+ +- CometHashAggregate
+ +- CometExchange
+ +- CometHashAggregate
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : +- SubqueryBroadcast
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ +- CometBroadcastExchange
+ +- CometProject
+ +- CometFilter
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+
+Comet accelerated 22 out of 27 eligible operators (81%). Final plan contains 2 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12/simplified.txt
new file mode 100644
index 0000000000..fb83fd2f9a
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q12/simplified.txt
@@ -0,0 +1,35 @@
+TakeOrderedAndProject [i_category,i_class,i_item_id,i_item_desc,revenueratio,i_current_price,itemrevenue]
+ WholeStageCodegen (2)
+ Project [i_item_desc,i_category,i_class,i_current_price,itemrevenue,_w0,_we0,i_item_id]
+ InputAdapter
+ Window [_w0,i_class]
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometSort [i_item_desc,i_category,i_class,i_current_price,itemrevenue,_w0,i_item_id]
+ CometExchange [i_class] #1
+ CometHashAggregate [sum] [i_item_desc,i_category,i_class,i_current_price,itemrevenue,_w0,i_item_id,sum(UnscaledValue(ws_ext_sales_price))]
+ CometExchange [i_item_id,i_item_desc,i_category,i_class,i_current_price] #2
+ CometHashAggregate [ws_ext_sales_price] [i_item_id,i_item_desc,i_category,i_class,i_current_price,sum]
+ CometProject [ws_ext_sales_price,i_item_id,i_item_desc,i_current_price,i_class,i_category]
+ CometBroadcastHashJoin [ws_ext_sales_price,ws_sold_date_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category,d_date_sk]
+ CometProject [ws_ext_sales_price,ws_sold_date_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category]
+ CometBroadcastHashJoin [ws_item_sk,ws_ext_sales_price,ws_sold_date_sk,i_item_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category]
+ CometFilter [ws_item_sk,ws_ext_sales_price,ws_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_item_sk,ws_ext_sales_price,ws_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #3
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_date]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_date]
+ CometBroadcastExchange [i_item_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category] #4
+ CometProject [i_item_id,i_class,i_category] [i_item_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category]
+ CometFilter [i_item_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_item_id,i_item_desc,i_current_price,i_class,i_category]
+ CometBroadcastExchange [d_date_sk] #5
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_date]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_date]
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_datafusion/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_datafusion/explain.txt
new file mode 100644
index 0000000000..613d0cb7b2
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_datafusion/explain.txt
@@ -0,0 +1,241 @@
+== Physical Plan ==
+* HashAggregate (36)
++- * CometColumnarToRow (35)
+ +- CometColumnarExchange (34)
+ +- * HashAggregate (33)
+ +- * Project (32)
+ +- * BroadcastHashJoin Inner BuildRight (31)
+ :- * Project (26)
+ : +- * BroadcastHashJoin Inner BuildRight (25)
+ : :- * Project (19)
+ : : +- * BroadcastHashJoin Inner BuildRight (18)
+ : : :- * Project (16)
+ : : : +- * BroadcastHashJoin Inner BuildRight (15)
+ : : : :- * Project (9)
+ : : : : +- * BroadcastHashJoin Inner BuildRight (8)
+ : : : : :- * Filter (3)
+ : : : : : +- * ColumnarToRow (2)
+ : : : : : +- Scan parquet spark_catalog.default.store_sales (1)
+ : : : : +- BroadcastExchange (7)
+ : : : : +- * CometColumnarToRow (6)
+ : : : : +- CometFilter (5)
+ : : : : +- CometNativeScan parquet spark_catalog.default.store (4)
+ : : : +- BroadcastExchange (14)
+ : : : +- * CometColumnarToRow (13)
+ : : : +- CometProject (12)
+ : : : +- CometFilter (11)
+ : : : +- CometNativeScan parquet spark_catalog.default.customer_address (10)
+ : : +- ReusedExchange (17)
+ : +- BroadcastExchange (24)
+ : +- * CometColumnarToRow (23)
+ : +- CometProject (22)
+ : +- CometFilter (21)
+ : +- CometNativeScan parquet spark_catalog.default.customer_demographics (20)
+ +- BroadcastExchange (30)
+ +- * CometColumnarToRow (29)
+ +- CometFilter (28)
+ +- CometNativeScan parquet spark_catalog.default.household_demographics (27)
+
+
+(1) Scan parquet spark_catalog.default.store_sales
+Output [10]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_store_sk#4, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#10), dynamicpruningexpression(ss_sold_date_sk#10 IN dynamicpruning#11)]
+PushedFilters: [IsNotNull(ss_store_sk), IsNotNull(ss_addr_sk), IsNotNull(ss_cdemo_sk), IsNotNull(ss_hdemo_sk), Or(Or(And(GreaterThanOrEqual(ss_net_profit,100.00),LessThanOrEqual(ss_net_profit,200.00)),And(GreaterThanOrEqual(ss_net_profit,150.00),LessThanOrEqual(ss_net_profit,300.00))),And(GreaterThanOrEqual(ss_net_profit,50.00),LessThanOrEqual(ss_net_profit,250.00))), Or(Or(And(GreaterThanOrEqual(ss_sales_price,100.00),LessThanOrEqual(ss_sales_price,150.00)),And(GreaterThanOrEqual(ss_sales_price,50.00),LessThanOrEqual(ss_sales_price,100.00))),And(GreaterThanOrEqual(ss_sales_price,150.00),LessThanOrEqual(ss_sales_price,200.00)))]
+ReadSchema: struct
+
+(2) ColumnarToRow [codegen id : 6]
+Input [10]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_store_sk#4, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10]
+
+(3) Filter [codegen id : 6]
+Input [10]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_store_sk#4, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10]
+Condition : (((((isnotnull(ss_store_sk#4) AND isnotnull(ss_addr_sk#3)) AND isnotnull(ss_cdemo_sk#1)) AND isnotnull(ss_hdemo_sk#2)) AND ((((ss_net_profit#9 >= 100.00) AND (ss_net_profit#9 <= 200.00)) OR ((ss_net_profit#9 >= 150.00) AND (ss_net_profit#9 <= 300.00))) OR ((ss_net_profit#9 >= 50.00) AND (ss_net_profit#9 <= 250.00)))) AND ((((ss_sales_price#6 >= 100.00) AND (ss_sales_price#6 <= 150.00)) OR ((ss_sales_price#6 >= 50.00) AND (ss_sales_price#6 <= 100.00))) OR ((ss_sales_price#6 >= 150.00) AND (ss_sales_price#6 <= 200.00))))
+
+(4) CometNativeScan parquet spark_catalog.default.store
+Output [1]: [s_store_sk#12]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/store]
+PushedFilters: [IsNotNull(s_store_sk)]
+ReadSchema: struct
+
+(5) CometFilter
+Input [1]: [s_store_sk#12]
+Condition : isnotnull(s_store_sk#12)
+
+(6) CometColumnarToRow [codegen id : 1]
+Input [1]: [s_store_sk#12]
+
+(7) BroadcastExchange
+Input [1]: [s_store_sk#12]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=1]
+
+(8) BroadcastHashJoin [codegen id : 6]
+Left keys [1]: [ss_store_sk#4]
+Right keys [1]: [s_store_sk#12]
+Join type: Inner
+Join condition: None
+
+(9) Project [codegen id : 6]
+Output [9]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10]
+Input [11]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_store_sk#4, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10, s_store_sk#12]
+
+(10) CometNativeScan parquet spark_catalog.default.customer_address
+Output [3]: [ca_address_sk#13, ca_state#14, ca_country#15]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_address]
+PushedFilters: [IsNotNull(ca_country), EqualTo(ca_country,United States), IsNotNull(ca_address_sk)]
+ReadSchema: struct
+
+(11) CometFilter
+Input [3]: [ca_address_sk#13, ca_state#14, ca_country#15]
+Condition : (((isnotnull(ca_country#15) AND (ca_country#15 = United States)) AND isnotnull(ca_address_sk#13)) AND ((static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#14, 2)) IN (TX,OH) OR static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#14, 2)) IN (OR,NM,KY)) OR static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#14, 2)) IN (VA,TX,MS)))
+
+(12) CometProject
+Input [3]: [ca_address_sk#13, ca_state#14, ca_country#15]
+Arguments: [ca_address_sk#13, ca_state#16], [ca_address_sk#13, static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#14, 2)) AS ca_state#16]
+
+(13) CometColumnarToRow [codegen id : 2]
+Input [2]: [ca_address_sk#13, ca_state#16]
+
+(14) BroadcastExchange
+Input [2]: [ca_address_sk#13, ca_state#16]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=2]
+
+(15) BroadcastHashJoin [codegen id : 6]
+Left keys [1]: [ss_addr_sk#3]
+Right keys [1]: [ca_address_sk#13]
+Join type: Inner
+Join condition: ((((ca_state#16 IN (TX,OH) AND (ss_net_profit#9 >= 100.00)) AND (ss_net_profit#9 <= 200.00)) OR ((ca_state#16 IN (OR,NM,KY) AND (ss_net_profit#9 >= 150.00)) AND (ss_net_profit#9 <= 300.00))) OR ((ca_state#16 IN (VA,TX,MS) AND (ss_net_profit#9 >= 50.00)) AND (ss_net_profit#9 <= 250.00)))
+
+(16) Project [codegen id : 6]
+Output [7]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_sold_date_sk#10]
+Input [11]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10, ca_address_sk#13, ca_state#16]
+
+(17) ReusedExchange [Reuses operator id: 41]
+Output [1]: [d_date_sk#17]
+
+(18) BroadcastHashJoin [codegen id : 6]
+Left keys [1]: [ss_sold_date_sk#10]
+Right keys [1]: [d_date_sk#17]
+Join type: Inner
+Join condition: None
+
+(19) Project [codegen id : 6]
+Output [6]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8]
+Input [8]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_sold_date_sk#10, d_date_sk#17]
+
+(20) CometNativeScan parquet spark_catalog.default.customer_demographics
+Output [3]: [cd_demo_sk#18, cd_marital_status#19, cd_education_status#20]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_demographics]
+PushedFilters: [IsNotNull(cd_demo_sk)]
+ReadSchema: struct
+
+(21) CometFilter
+Input [3]: [cd_demo_sk#18, cd_marital_status#19, cd_education_status#20]
+Condition : (isnotnull(cd_demo_sk#18) AND ((((static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_marital_status#19, 1)) = M) AND (static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_education_status#20, 20)) = Advanced Degree )) OR ((static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_marital_status#19, 1)) = S) AND (static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_education_status#20, 20)) = College ))) OR ((static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_marital_status#19, 1)) = W) AND (static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_education_status#20, 20)) = 2 yr Degree ))))
+
+(22) CometProject
+Input [3]: [cd_demo_sk#18, cd_marital_status#19, cd_education_status#20]
+Arguments: [cd_demo_sk#18, cd_marital_status#21, cd_education_status#22], [cd_demo_sk#18, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_marital_status#19, 1)) AS cd_marital_status#21, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_education_status#20, 20)) AS cd_education_status#22]
+
+(23) CometColumnarToRow [codegen id : 4]
+Input [3]: [cd_demo_sk#18, cd_marital_status#21, cd_education_status#22]
+
+(24) BroadcastExchange
+Input [3]: [cd_demo_sk#18, cd_marital_status#21, cd_education_status#22]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=3]
+
+(25) BroadcastHashJoin [codegen id : 6]
+Left keys [1]: [ss_cdemo_sk#1]
+Right keys [1]: [cd_demo_sk#18]
+Join type: Inner
+Join condition: ((((((cd_marital_status#21 = M) AND (cd_education_status#22 = Advanced Degree )) AND (ss_sales_price#6 >= 100.00)) AND (ss_sales_price#6 <= 150.00)) OR ((((cd_marital_status#21 = S) AND (cd_education_status#22 = College )) AND (ss_sales_price#6 >= 50.00)) AND (ss_sales_price#6 <= 100.00))) OR ((((cd_marital_status#21 = W) AND (cd_education_status#22 = 2 yr Degree )) AND (ss_sales_price#6 >= 150.00)) AND (ss_sales_price#6 <= 200.00)))
+
+(26) Project [codegen id : 6]
+Output [7]: [ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, cd_marital_status#21, cd_education_status#22]
+Input [9]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, cd_demo_sk#18, cd_marital_status#21, cd_education_status#22]
+
+(27) CometNativeScan parquet spark_catalog.default.household_demographics
+Output [2]: [hd_demo_sk#23, hd_dep_count#24]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/household_demographics]
+PushedFilters: [IsNotNull(hd_demo_sk), Or(EqualTo(hd_dep_count,3),EqualTo(hd_dep_count,1))]
+ReadSchema: struct
+
+(28) CometFilter
+Input [2]: [hd_demo_sk#23, hd_dep_count#24]
+Condition : (isnotnull(hd_demo_sk#23) AND ((hd_dep_count#24 = 3) OR (hd_dep_count#24 = 1)))
+
+(29) CometColumnarToRow [codegen id : 5]
+Input [2]: [hd_demo_sk#23, hd_dep_count#24]
+
+(30) BroadcastExchange
+Input [2]: [hd_demo_sk#23, hd_dep_count#24]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=4]
+
+(31) BroadcastHashJoin [codegen id : 6]
+Left keys [1]: [ss_hdemo_sk#2]
+Right keys [1]: [hd_demo_sk#23]
+Join type: Inner
+Join condition: (((((((cd_marital_status#21 = M) AND (cd_education_status#22 = Advanced Degree )) AND (ss_sales_price#6 >= 100.00)) AND (ss_sales_price#6 <= 150.00)) AND (hd_dep_count#24 = 3)) OR (((((cd_marital_status#21 = S) AND (cd_education_status#22 = College )) AND (ss_sales_price#6 >= 50.00)) AND (ss_sales_price#6 <= 100.00)) AND (hd_dep_count#24 = 1))) OR (((((cd_marital_status#21 = W) AND (cd_education_status#22 = 2 yr Degree )) AND (ss_sales_price#6 >= 150.00)) AND (ss_sales_price#6 <= 200.00)) AND (hd_dep_count#24 = 1)))
+
+(32) Project [codegen id : 6]
+Output [3]: [ss_quantity#5, ss_ext_sales_price#7, ss_ext_wholesale_cost#8]
+Input [9]: [ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, cd_marital_status#21, cd_education_status#22, hd_demo_sk#23, hd_dep_count#24]
+
+(33) HashAggregate [codegen id : 6]
+Input [3]: [ss_quantity#5, ss_ext_sales_price#7, ss_ext_wholesale_cost#8]
+Keys: []
+Functions [4]: [partial_avg(ss_quantity#5), partial_avg(UnscaledValue(ss_ext_sales_price#7)), partial_avg(UnscaledValue(ss_ext_wholesale_cost#8)), partial_sum(UnscaledValue(ss_ext_wholesale_cost#8))]
+Aggregate Attributes [7]: [sum#25, count#26, sum#27, count#28, sum#29, count#30, sum#31]
+Results [7]: [sum#32, count#33, sum#34, count#35, sum#36, count#37, sum#38]
+
+(34) CometColumnarExchange
+Input [7]: [sum#32, count#33, sum#34, count#35, sum#36, count#37, sum#38]
+Arguments: SinglePartition, ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=5]
+
+(35) CometColumnarToRow [codegen id : 7]
+Input [7]: [sum#32, count#33, sum#34, count#35, sum#36, count#37, sum#38]
+
+(36) HashAggregate [codegen id : 7]
+Input [7]: [sum#32, count#33, sum#34, count#35, sum#36, count#37, sum#38]
+Keys: []
+Functions [4]: [avg(ss_quantity#5), avg(UnscaledValue(ss_ext_sales_price#7)), avg(UnscaledValue(ss_ext_wholesale_cost#8)), sum(UnscaledValue(ss_ext_wholesale_cost#8))]
+Aggregate Attributes [4]: [avg(ss_quantity#5)#39, avg(UnscaledValue(ss_ext_sales_price#7))#40, avg(UnscaledValue(ss_ext_wholesale_cost#8))#41, sum(UnscaledValue(ss_ext_wholesale_cost#8))#42]
+Results [4]: [avg(ss_quantity#5)#39 AS avg(ss_quantity)#43, cast((avg(UnscaledValue(ss_ext_sales_price#7))#40 / 100.0) as decimal(11,6)) AS avg(ss_ext_sales_price)#44, cast((avg(UnscaledValue(ss_ext_wholesale_cost#8))#41 / 100.0) as decimal(11,6)) AS avg(ss_ext_wholesale_cost)#45, MakeDecimal(sum(UnscaledValue(ss_ext_wholesale_cost#8))#42,17,2) AS sum(ss_ext_wholesale_cost)#46]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 1 Hosting Expression = ss_sold_date_sk#10 IN dynamicpruning#11
+BroadcastExchange (41)
++- * CometColumnarToRow (40)
+ +- CometProject (39)
+ +- CometFilter (38)
+ +- CometNativeScan parquet spark_catalog.default.date_dim (37)
+
+
+(37) CometNativeScan parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#17, d_year#47]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(38) CometFilter
+Input [2]: [d_date_sk#17, d_year#47]
+Condition : ((isnotnull(d_year#47) AND (d_year#47 = 2001)) AND isnotnull(d_date_sk#17))
+
+(39) CometProject
+Input [2]: [d_date_sk#17, d_year#47]
+Arguments: [d_date_sk#17], [d_date_sk#17]
+
+(40) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#17]
+
+(41) BroadcastExchange
+Input [1]: [d_date_sk#17]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=6]
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_datafusion/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_datafusion/extended.txt
new file mode 100644
index 0000000000..4c0d0b7a33
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_datafusion/extended.txt
@@ -0,0 +1,48 @@
+HashAggregate
++- CometColumnarToRow
+ +- CometColumnarExchange
+ +- HashAggregate
+ +- Project
+ +- BroadcastHashJoin
+ :- Project
+ : +- BroadcastHashJoin
+ : :- Project
+ : : +- BroadcastHashJoin
+ : : :- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Filter
+ : : : : : +- ColumnarToRow
+ : : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.store
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.customer_address
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : +- BroadcastExchange
+ : +- CometColumnarToRow
+ : +- CometProject
+ : +- CometFilter
+ : +- CometNativeScan parquet spark_catalog.default.customer_demographics
+ +- BroadcastExchange
+ +- CometColumnarToRow
+ +- CometFilter
+ +- CometNativeScan parquet spark_catalog.default.household_demographics
+
+Comet accelerated 17 out of 38 eligible operators (44%). Final plan contains 8 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_datafusion/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_datafusion/simplified.txt
new file mode 100644
index 0000000000..a33ae5a161
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_datafusion/simplified.txt
@@ -0,0 +1,61 @@
+WholeStageCodegen (7)
+ HashAggregate [sum,count,sum,count,sum,count,sum] [avg(ss_quantity),avg(UnscaledValue(ss_ext_sales_price)),avg(UnscaledValue(ss_ext_wholesale_cost)),sum(UnscaledValue(ss_ext_wholesale_cost)),avg(ss_quantity),avg(ss_ext_sales_price),avg(ss_ext_wholesale_cost),sum(ss_ext_wholesale_cost),sum,count,sum,count,sum,count,sum]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange #1
+ WholeStageCodegen (6)
+ HashAggregate [ss_quantity,ss_ext_sales_price,ss_ext_wholesale_cost] [sum,count,sum,count,sum,count,sum,sum,count,sum,count,sum,count,sum]
+ Project [ss_quantity,ss_ext_sales_price,ss_ext_wholesale_cost]
+ BroadcastHashJoin [ss_hdemo_sk,hd_demo_sk,cd_marital_status,cd_education_status,ss_sales_price,hd_dep_count]
+ Project [ss_hdemo_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,cd_marital_status,cd_education_status]
+ BroadcastHashJoin [ss_cdemo_sk,cd_demo_sk,cd_marital_status,cd_education_status,ss_sales_price]
+ Project [ss_cdemo_sk,ss_hdemo_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost]
+ BroadcastHashJoin [ss_sold_date_sk,d_date_sk]
+ Project [ss_cdemo_sk,ss_hdemo_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,ss_sold_date_sk]
+ BroadcastHashJoin [ss_addr_sk,ca_address_sk,ca_state,ss_net_profit]
+ Project [ss_cdemo_sk,ss_hdemo_sk,ss_addr_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,ss_net_profit,ss_sold_date_sk]
+ BroadcastHashJoin [ss_store_sk,s_store_sk]
+ Filter [ss_store_sk,ss_addr_sk,ss_cdemo_sk,ss_hdemo_sk,ss_net_profit,ss_sales_price]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.store_sales [ss_cdemo_sk,ss_hdemo_sk,ss_addr_sk,ss_store_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,ss_net_profit,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #2
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometNativeScan parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ InputAdapter
+ BroadcastExchange #3
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [s_store_sk]
+ CometNativeScan parquet spark_catalog.default.store [s_store_sk]
+ InputAdapter
+ BroadcastExchange #4
+ WholeStageCodegen (2)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [ca_state] [ca_address_sk,ca_state]
+ CometFilter [ca_address_sk,ca_state,ca_country]
+ CometNativeScan parquet spark_catalog.default.customer_address [ca_address_sk,ca_state,ca_country]
+ InputAdapter
+ ReusedExchange [d_date_sk] #2
+ InputAdapter
+ BroadcastExchange #5
+ WholeStageCodegen (4)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [cd_marital_status,cd_education_status] [cd_demo_sk,cd_marital_status,cd_education_status]
+ CometFilter [cd_demo_sk,cd_marital_status,cd_education_status]
+ CometNativeScan parquet spark_catalog.default.customer_demographics [cd_demo_sk,cd_marital_status,cd_education_status]
+ InputAdapter
+ BroadcastExchange #6
+ WholeStageCodegen (5)
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [hd_demo_sk,hd_dep_count]
+ CometNativeScan parquet spark_catalog.default.household_demographics [hd_demo_sk,hd_dep_count]
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_iceberg_compat/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_iceberg_compat/explain.txt
new file mode 100644
index 0000000000..027d679419
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_iceberg_compat/explain.txt
@@ -0,0 +1,231 @@
+== Physical Plan ==
+* CometColumnarToRow (34)
++- CometHashAggregate (33)
+ +- CometExchange (32)
+ +- CometHashAggregate (31)
+ +- CometProject (30)
+ +- CometBroadcastHashJoin (29)
+ :- CometProject (25)
+ : +- CometBroadcastHashJoin (24)
+ : :- CometProject (19)
+ : : +- CometBroadcastHashJoin (18)
+ : : :- CometProject (13)
+ : : : +- CometBroadcastHashJoin (12)
+ : : : :- CometProject (7)
+ : : : : +- CometBroadcastHashJoin (6)
+ : : : : :- CometFilter (2)
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (1)
+ : : : : +- CometBroadcastExchange (5)
+ : : : : +- CometFilter (4)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store (3)
+ : : : +- CometBroadcastExchange (11)
+ : : : +- CometProject (10)
+ : : : +- CometFilter (9)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address (8)
+ : : +- CometBroadcastExchange (17)
+ : : +- CometProject (16)
+ : : +- CometFilter (15)
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (14)
+ : +- CometBroadcastExchange (23)
+ : +- CometProject (22)
+ : +- CometFilter (21)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_demographics (20)
+ +- CometBroadcastExchange (28)
+ +- CometFilter (27)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.household_demographics (26)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [10]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_store_sk#4, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#10), dynamicpruningexpression(ss_sold_date_sk#10 IN dynamicpruning#11)]
+PushedFilters: [IsNotNull(ss_store_sk), IsNotNull(ss_addr_sk), IsNotNull(ss_cdemo_sk), IsNotNull(ss_hdemo_sk), Or(Or(And(GreaterThanOrEqual(ss_net_profit,100.00),LessThanOrEqual(ss_net_profit,200.00)),And(GreaterThanOrEqual(ss_net_profit,150.00),LessThanOrEqual(ss_net_profit,300.00))),And(GreaterThanOrEqual(ss_net_profit,50.00),LessThanOrEqual(ss_net_profit,250.00))), Or(Or(And(GreaterThanOrEqual(ss_sales_price,100.00),LessThanOrEqual(ss_sales_price,150.00)),And(GreaterThanOrEqual(ss_sales_price,50.00),LessThanOrEqual(ss_sales_price,100.00))),And(GreaterThanOrEqual(ss_sales_price,150.00),LessThanOrEqual(ss_sales_price,200.00)))]
+ReadSchema: struct
+
+(2) CometFilter
+Input [10]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_store_sk#4, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10]
+Condition : (((((isnotnull(ss_store_sk#4) AND isnotnull(ss_addr_sk#3)) AND isnotnull(ss_cdemo_sk#1)) AND isnotnull(ss_hdemo_sk#2)) AND ((((ss_net_profit#9 >= 100.00) AND (ss_net_profit#9 <= 200.00)) OR ((ss_net_profit#9 >= 150.00) AND (ss_net_profit#9 <= 300.00))) OR ((ss_net_profit#9 >= 50.00) AND (ss_net_profit#9 <= 250.00)))) AND ((((ss_sales_price#6 >= 100.00) AND (ss_sales_price#6 <= 150.00)) OR ((ss_sales_price#6 >= 50.00) AND (ss_sales_price#6 <= 100.00))) OR ((ss_sales_price#6 >= 150.00) AND (ss_sales_price#6 <= 200.00))))
+
+(3) CometScan [native_iceberg_compat] parquet spark_catalog.default.store
+Output [1]: [s_store_sk#12]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/store]
+PushedFilters: [IsNotNull(s_store_sk)]
+ReadSchema: struct
+
+(4) CometFilter
+Input [1]: [s_store_sk#12]
+Condition : isnotnull(s_store_sk#12)
+
+(5) CometBroadcastExchange
+Input [1]: [s_store_sk#12]
+Arguments: [s_store_sk#12]
+
+(6) CometBroadcastHashJoin
+Left output [10]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_store_sk#4, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10]
+Right output [1]: [s_store_sk#12]
+Arguments: [ss_store_sk#4], [s_store_sk#12], Inner, BuildRight
+
+(7) CometProject
+Input [11]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_store_sk#4, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10, s_store_sk#12]
+Arguments: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10], [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10]
+
+(8) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address
+Output [3]: [ca_address_sk#13, ca_state#14, ca_country#15]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_address]
+PushedFilters: [IsNotNull(ca_country), EqualTo(ca_country,United States), IsNotNull(ca_address_sk)]
+ReadSchema: struct
+
+(9) CometFilter
+Input [3]: [ca_address_sk#13, ca_state#14, ca_country#15]
+Condition : (((isnotnull(ca_country#15) AND (ca_country#15 = United States)) AND isnotnull(ca_address_sk#13)) AND ((static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#14, 2)) IN (TX,OH) OR static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#14, 2)) IN (OR,NM,KY)) OR static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#14, 2)) IN (VA,TX,MS)))
+
+(10) CometProject
+Input [3]: [ca_address_sk#13, ca_state#14, ca_country#15]
+Arguments: [ca_address_sk#13, ca_state#16], [ca_address_sk#13, static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#14, 2)) AS ca_state#16]
+
+(11) CometBroadcastExchange
+Input [2]: [ca_address_sk#13, ca_state#16]
+Arguments: [ca_address_sk#13, ca_state#16]
+
+(12) CometBroadcastHashJoin
+Left output [9]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10]
+Right output [2]: [ca_address_sk#13, ca_state#16]
+Arguments: [ss_addr_sk#3], [ca_address_sk#13], Inner, ((((ca_state#16 IN (TX,OH) AND (ss_net_profit#9 >= 100.00)) AND (ss_net_profit#9 <= 200.00)) OR ((ca_state#16 IN (OR,NM,KY) AND (ss_net_profit#9 >= 150.00)) AND (ss_net_profit#9 <= 300.00))) OR ((ca_state#16 IN (VA,TX,MS) AND (ss_net_profit#9 >= 50.00)) AND (ss_net_profit#9 <= 250.00))), BuildRight
+
+(13) CometProject
+Input [11]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10, ca_address_sk#13, ca_state#16]
+Arguments: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_sold_date_sk#10], [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_sold_date_sk#10]
+
+(14) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#17, d_year#18]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(15) CometFilter
+Input [2]: [d_date_sk#17, d_year#18]
+Condition : ((isnotnull(d_year#18) AND (d_year#18 = 2001)) AND isnotnull(d_date_sk#17))
+
+(16) CometProject
+Input [2]: [d_date_sk#17, d_year#18]
+Arguments: [d_date_sk#17], [d_date_sk#17]
+
+(17) CometBroadcastExchange
+Input [1]: [d_date_sk#17]
+Arguments: [d_date_sk#17]
+
+(18) CometBroadcastHashJoin
+Left output [7]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_sold_date_sk#10]
+Right output [1]: [d_date_sk#17]
+Arguments: [ss_sold_date_sk#10], [d_date_sk#17], Inner, BuildRight
+
+(19) CometProject
+Input [8]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_sold_date_sk#10, d_date_sk#17]
+Arguments: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8], [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8]
+
+(20) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_demographics
+Output [3]: [cd_demo_sk#19, cd_marital_status#20, cd_education_status#21]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_demographics]
+PushedFilters: [IsNotNull(cd_demo_sk)]
+ReadSchema: struct
+
+(21) CometFilter
+Input [3]: [cd_demo_sk#19, cd_marital_status#20, cd_education_status#21]
+Condition : (isnotnull(cd_demo_sk#19) AND ((((static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_marital_status#20, 1)) = M) AND (static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_education_status#21, 20)) = Advanced Degree )) OR ((static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_marital_status#20, 1)) = S) AND (static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_education_status#21, 20)) = College ))) OR ((static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_marital_status#20, 1)) = W) AND (static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_education_status#21, 20)) = 2 yr Degree ))))
+
+(22) CometProject
+Input [3]: [cd_demo_sk#19, cd_marital_status#20, cd_education_status#21]
+Arguments: [cd_demo_sk#19, cd_marital_status#22, cd_education_status#23], [cd_demo_sk#19, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_marital_status#20, 1)) AS cd_marital_status#22, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_education_status#21, 20)) AS cd_education_status#23]
+
+(23) CometBroadcastExchange
+Input [3]: [cd_demo_sk#19, cd_marital_status#22, cd_education_status#23]
+Arguments: [cd_demo_sk#19, cd_marital_status#22, cd_education_status#23]
+
+(24) CometBroadcastHashJoin
+Left output [6]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8]
+Right output [3]: [cd_demo_sk#19, cd_marital_status#22, cd_education_status#23]
+Arguments: [ss_cdemo_sk#1], [cd_demo_sk#19], Inner, ((((((cd_marital_status#22 = M) AND (cd_education_status#23 = Advanced Degree )) AND (ss_sales_price#6 >= 100.00)) AND (ss_sales_price#6 <= 150.00)) OR ((((cd_marital_status#22 = S) AND (cd_education_status#23 = College )) AND (ss_sales_price#6 >= 50.00)) AND (ss_sales_price#6 <= 100.00))) OR ((((cd_marital_status#22 = W) AND (cd_education_status#23 = 2 yr Degree )) AND (ss_sales_price#6 >= 150.00)) AND (ss_sales_price#6 <= 200.00))), BuildRight
+
+(25) CometProject
+Input [9]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, cd_demo_sk#19, cd_marital_status#22, cd_education_status#23]
+Arguments: [ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, cd_marital_status#22, cd_education_status#23], [ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, cd_marital_status#22, cd_education_status#23]
+
+(26) CometScan [native_iceberg_compat] parquet spark_catalog.default.household_demographics
+Output [2]: [hd_demo_sk#24, hd_dep_count#25]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/household_demographics]
+PushedFilters: [IsNotNull(hd_demo_sk), Or(EqualTo(hd_dep_count,3),EqualTo(hd_dep_count,1))]
+ReadSchema: struct
+
+(27) CometFilter
+Input [2]: [hd_demo_sk#24, hd_dep_count#25]
+Condition : (isnotnull(hd_demo_sk#24) AND ((hd_dep_count#25 = 3) OR (hd_dep_count#25 = 1)))
+
+(28) CometBroadcastExchange
+Input [2]: [hd_demo_sk#24, hd_dep_count#25]
+Arguments: [hd_demo_sk#24, hd_dep_count#25]
+
+(29) CometBroadcastHashJoin
+Left output [7]: [ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, cd_marital_status#22, cd_education_status#23]
+Right output [2]: [hd_demo_sk#24, hd_dep_count#25]
+Arguments: [ss_hdemo_sk#2], [hd_demo_sk#24], Inner, (((((((cd_marital_status#22 = M) AND (cd_education_status#23 = Advanced Degree )) AND (ss_sales_price#6 >= 100.00)) AND (ss_sales_price#6 <= 150.00)) AND (hd_dep_count#25 = 3)) OR (((((cd_marital_status#22 = S) AND (cd_education_status#23 = College )) AND (ss_sales_price#6 >= 50.00)) AND (ss_sales_price#6 <= 100.00)) AND (hd_dep_count#25 = 1))) OR (((((cd_marital_status#22 = W) AND (cd_education_status#23 = 2 yr Degree )) AND (ss_sales_price#6 >= 150.00)) AND (ss_sales_price#6 <= 200.00)) AND (hd_dep_count#25 = 1))), BuildRight
+
+(30) CometProject
+Input [9]: [ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, cd_marital_status#22, cd_education_status#23, hd_demo_sk#24, hd_dep_count#25]
+Arguments: [ss_quantity#5, ss_ext_sales_price#7, ss_ext_wholesale_cost#8], [ss_quantity#5, ss_ext_sales_price#7, ss_ext_wholesale_cost#8]
+
+(31) CometHashAggregate
+Input [3]: [ss_quantity#5, ss_ext_sales_price#7, ss_ext_wholesale_cost#8]
+Keys: []
+Functions [4]: [partial_avg(ss_quantity#5), partial_avg(UnscaledValue(ss_ext_sales_price#7)), partial_avg(UnscaledValue(ss_ext_wholesale_cost#8)), partial_sum(UnscaledValue(ss_ext_wholesale_cost#8))]
+
+(32) CometExchange
+Input [7]: [sum#26, count#27, sum#28, count#29, sum#30, count#31, sum#32]
+Arguments: SinglePartition, ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=1]
+
+(33) CometHashAggregate
+Input [7]: [sum#26, count#27, sum#28, count#29, sum#30, count#31, sum#32]
+Keys: []
+Functions [4]: [avg(ss_quantity#5), avg(UnscaledValue(ss_ext_sales_price#7)), avg(UnscaledValue(ss_ext_wholesale_cost#8)), sum(UnscaledValue(ss_ext_wholesale_cost#8))]
+
+(34) CometColumnarToRow [codegen id : 1]
+Input [4]: [avg(ss_quantity)#33, avg(ss_ext_sales_price)#34, avg(ss_ext_wholesale_cost)#35, sum(ss_ext_wholesale_cost)#36]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 1 Hosting Expression = ss_sold_date_sk#10 IN dynamicpruning#11
+BroadcastExchange (39)
++- * CometColumnarToRow (38)
+ +- CometProject (37)
+ +- CometFilter (36)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (35)
+
+
+(35) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#17, d_year#18]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(36) CometFilter
+Input [2]: [d_date_sk#17, d_year#18]
+Condition : ((isnotnull(d_year#18) AND (d_year#18 = 2001)) AND isnotnull(d_date_sk#17))
+
+(37) CometProject
+Input [2]: [d_date_sk#17, d_year#18]
+Arguments: [d_date_sk#17], [d_date_sk#17]
+
+(38) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#17]
+
+(39) BroadcastExchange
+Input [1]: [d_date_sk#17]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=2]
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_iceberg_compat/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_iceberg_compat/extended.txt
new file mode 100644
index 0000000000..08e9beb692
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_iceberg_compat/extended.txt
@@ -0,0 +1,42 @@
+CometColumnarToRow
++- CometHashAggregate
+ +- CometExchange
+ +- CometHashAggregate
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_demographics
+ +- CometBroadcastExchange
+ +- CometFilter
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.household_demographics
+
+Comet accelerated 36 out of 38 eligible operators (94%). Final plan contains 2 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_iceberg_compat/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_iceberg_compat/simplified.txt
new file mode 100644
index 0000000000..8ef882a435
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13.native_iceberg_compat/simplified.txt
@@ -0,0 +1,44 @@
+WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometHashAggregate [sum,count,sum,count,sum,count,sum] [avg(ss_quantity),avg(ss_ext_sales_price),avg(ss_ext_wholesale_cost),sum(ss_ext_wholesale_cost),avg(ss_quantity),avg(UnscaledValue(ss_ext_sales_price)),avg(UnscaledValue(ss_ext_wholesale_cost)),sum(UnscaledValue(ss_ext_wholesale_cost))]
+ CometExchange #1
+ CometHashAggregate [ss_quantity,ss_ext_sales_price,ss_ext_wholesale_cost] [sum,count,sum,count,sum,count,sum]
+ CometProject [ss_quantity,ss_ext_sales_price,ss_ext_wholesale_cost]
+ CometBroadcastHashJoin [ss_hdemo_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,cd_marital_status,cd_education_status,hd_demo_sk,hd_dep_count]
+ CometProject [ss_hdemo_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,cd_marital_status,cd_education_status]
+ CometBroadcastHashJoin [ss_cdemo_sk,ss_hdemo_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,cd_demo_sk,cd_marital_status,cd_education_status]
+ CometProject [ss_cdemo_sk,ss_hdemo_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost]
+ CometBroadcastHashJoin [ss_cdemo_sk,ss_hdemo_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,ss_sold_date_sk,d_date_sk]
+ CometProject [ss_cdemo_sk,ss_hdemo_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,ss_sold_date_sk]
+ CometBroadcastHashJoin [ss_cdemo_sk,ss_hdemo_sk,ss_addr_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,ss_net_profit,ss_sold_date_sk,ca_address_sk,ca_state]
+ CometProject [ss_cdemo_sk,ss_hdemo_sk,ss_addr_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,ss_net_profit,ss_sold_date_sk]
+ CometBroadcastHashJoin [ss_cdemo_sk,ss_hdemo_sk,ss_addr_sk,ss_store_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,ss_net_profit,ss_sold_date_sk,s_store_sk]
+ CometFilter [ss_cdemo_sk,ss_hdemo_sk,ss_addr_sk,ss_store_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,ss_net_profit,ss_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_cdemo_sk,ss_hdemo_sk,ss_addr_sk,ss_store_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,ss_net_profit,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #2
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [s_store_sk] #3
+ CometFilter [s_store_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store [s_store_sk]
+ CometBroadcastExchange [ca_address_sk,ca_state] #4
+ CometProject [ca_state] [ca_address_sk,ca_state]
+ CometFilter [ca_address_sk,ca_state,ca_country]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address [ca_address_sk,ca_state,ca_country]
+ CometBroadcastExchange [d_date_sk] #5
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [cd_demo_sk,cd_marital_status,cd_education_status] #6
+ CometProject [cd_marital_status,cd_education_status] [cd_demo_sk,cd_marital_status,cd_education_status]
+ CometFilter [cd_demo_sk,cd_marital_status,cd_education_status]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_demographics [cd_demo_sk,cd_marital_status,cd_education_status]
+ CometBroadcastExchange [hd_demo_sk,hd_dep_count] #7
+ CometFilter [hd_demo_sk,hd_dep_count]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.household_demographics [hd_demo_sk,hd_dep_count]
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13/explain.txt
new file mode 100644
index 0000000000..027d679419
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13/explain.txt
@@ -0,0 +1,231 @@
+== Physical Plan ==
+* CometColumnarToRow (34)
++- CometHashAggregate (33)
+ +- CometExchange (32)
+ +- CometHashAggregate (31)
+ +- CometProject (30)
+ +- CometBroadcastHashJoin (29)
+ :- CometProject (25)
+ : +- CometBroadcastHashJoin (24)
+ : :- CometProject (19)
+ : : +- CometBroadcastHashJoin (18)
+ : : :- CometProject (13)
+ : : : +- CometBroadcastHashJoin (12)
+ : : : :- CometProject (7)
+ : : : : +- CometBroadcastHashJoin (6)
+ : : : : :- CometFilter (2)
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (1)
+ : : : : +- CometBroadcastExchange (5)
+ : : : : +- CometFilter (4)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store (3)
+ : : : +- CometBroadcastExchange (11)
+ : : : +- CometProject (10)
+ : : : +- CometFilter (9)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address (8)
+ : : +- CometBroadcastExchange (17)
+ : : +- CometProject (16)
+ : : +- CometFilter (15)
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (14)
+ : +- CometBroadcastExchange (23)
+ : +- CometProject (22)
+ : +- CometFilter (21)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_demographics (20)
+ +- CometBroadcastExchange (28)
+ +- CometFilter (27)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.household_demographics (26)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [10]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_store_sk#4, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#10), dynamicpruningexpression(ss_sold_date_sk#10 IN dynamicpruning#11)]
+PushedFilters: [IsNotNull(ss_store_sk), IsNotNull(ss_addr_sk), IsNotNull(ss_cdemo_sk), IsNotNull(ss_hdemo_sk), Or(Or(And(GreaterThanOrEqual(ss_net_profit,100.00),LessThanOrEqual(ss_net_profit,200.00)),And(GreaterThanOrEqual(ss_net_profit,150.00),LessThanOrEqual(ss_net_profit,300.00))),And(GreaterThanOrEqual(ss_net_profit,50.00),LessThanOrEqual(ss_net_profit,250.00))), Or(Or(And(GreaterThanOrEqual(ss_sales_price,100.00),LessThanOrEqual(ss_sales_price,150.00)),And(GreaterThanOrEqual(ss_sales_price,50.00),LessThanOrEqual(ss_sales_price,100.00))),And(GreaterThanOrEqual(ss_sales_price,150.00),LessThanOrEqual(ss_sales_price,200.00)))]
+ReadSchema: struct
+
+(2) CometFilter
+Input [10]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_store_sk#4, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10]
+Condition : (((((isnotnull(ss_store_sk#4) AND isnotnull(ss_addr_sk#3)) AND isnotnull(ss_cdemo_sk#1)) AND isnotnull(ss_hdemo_sk#2)) AND ((((ss_net_profit#9 >= 100.00) AND (ss_net_profit#9 <= 200.00)) OR ((ss_net_profit#9 >= 150.00) AND (ss_net_profit#9 <= 300.00))) OR ((ss_net_profit#9 >= 50.00) AND (ss_net_profit#9 <= 250.00)))) AND ((((ss_sales_price#6 >= 100.00) AND (ss_sales_price#6 <= 150.00)) OR ((ss_sales_price#6 >= 50.00) AND (ss_sales_price#6 <= 100.00))) OR ((ss_sales_price#6 >= 150.00) AND (ss_sales_price#6 <= 200.00))))
+
+(3) CometScan [native_iceberg_compat] parquet spark_catalog.default.store
+Output [1]: [s_store_sk#12]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/store]
+PushedFilters: [IsNotNull(s_store_sk)]
+ReadSchema: struct
+
+(4) CometFilter
+Input [1]: [s_store_sk#12]
+Condition : isnotnull(s_store_sk#12)
+
+(5) CometBroadcastExchange
+Input [1]: [s_store_sk#12]
+Arguments: [s_store_sk#12]
+
+(6) CometBroadcastHashJoin
+Left output [10]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_store_sk#4, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10]
+Right output [1]: [s_store_sk#12]
+Arguments: [ss_store_sk#4], [s_store_sk#12], Inner, BuildRight
+
+(7) CometProject
+Input [11]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_store_sk#4, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10, s_store_sk#12]
+Arguments: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10], [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10]
+
+(8) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address
+Output [3]: [ca_address_sk#13, ca_state#14, ca_country#15]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_address]
+PushedFilters: [IsNotNull(ca_country), EqualTo(ca_country,United States), IsNotNull(ca_address_sk)]
+ReadSchema: struct
+
+(9) CometFilter
+Input [3]: [ca_address_sk#13, ca_state#14, ca_country#15]
+Condition : (((isnotnull(ca_country#15) AND (ca_country#15 = United States)) AND isnotnull(ca_address_sk#13)) AND ((static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#14, 2)) IN (TX,OH) OR static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#14, 2)) IN (OR,NM,KY)) OR static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#14, 2)) IN (VA,TX,MS)))
+
+(10) CometProject
+Input [3]: [ca_address_sk#13, ca_state#14, ca_country#15]
+Arguments: [ca_address_sk#13, ca_state#16], [ca_address_sk#13, static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#14, 2)) AS ca_state#16]
+
+(11) CometBroadcastExchange
+Input [2]: [ca_address_sk#13, ca_state#16]
+Arguments: [ca_address_sk#13, ca_state#16]
+
+(12) CometBroadcastHashJoin
+Left output [9]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10]
+Right output [2]: [ca_address_sk#13, ca_state#16]
+Arguments: [ss_addr_sk#3], [ca_address_sk#13], Inner, ((((ca_state#16 IN (TX,OH) AND (ss_net_profit#9 >= 100.00)) AND (ss_net_profit#9 <= 200.00)) OR ((ca_state#16 IN (OR,NM,KY) AND (ss_net_profit#9 >= 150.00)) AND (ss_net_profit#9 <= 300.00))) OR ((ca_state#16 IN (VA,TX,MS) AND (ss_net_profit#9 >= 50.00)) AND (ss_net_profit#9 <= 250.00))), BuildRight
+
+(13) CometProject
+Input [11]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_addr_sk#3, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_net_profit#9, ss_sold_date_sk#10, ca_address_sk#13, ca_state#16]
+Arguments: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_sold_date_sk#10], [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_sold_date_sk#10]
+
+(14) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#17, d_year#18]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(15) CometFilter
+Input [2]: [d_date_sk#17, d_year#18]
+Condition : ((isnotnull(d_year#18) AND (d_year#18 = 2001)) AND isnotnull(d_date_sk#17))
+
+(16) CometProject
+Input [2]: [d_date_sk#17, d_year#18]
+Arguments: [d_date_sk#17], [d_date_sk#17]
+
+(17) CometBroadcastExchange
+Input [1]: [d_date_sk#17]
+Arguments: [d_date_sk#17]
+
+(18) CometBroadcastHashJoin
+Left output [7]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_sold_date_sk#10]
+Right output [1]: [d_date_sk#17]
+Arguments: [ss_sold_date_sk#10], [d_date_sk#17], Inner, BuildRight
+
+(19) CometProject
+Input [8]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, ss_sold_date_sk#10, d_date_sk#17]
+Arguments: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8], [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8]
+
+(20) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_demographics
+Output [3]: [cd_demo_sk#19, cd_marital_status#20, cd_education_status#21]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_demographics]
+PushedFilters: [IsNotNull(cd_demo_sk)]
+ReadSchema: struct
+
+(21) CometFilter
+Input [3]: [cd_demo_sk#19, cd_marital_status#20, cd_education_status#21]
+Condition : (isnotnull(cd_demo_sk#19) AND ((((static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_marital_status#20, 1)) = M) AND (static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_education_status#21, 20)) = Advanced Degree )) OR ((static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_marital_status#20, 1)) = S) AND (static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_education_status#21, 20)) = College ))) OR ((static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_marital_status#20, 1)) = W) AND (static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_education_status#21, 20)) = 2 yr Degree ))))
+
+(22) CometProject
+Input [3]: [cd_demo_sk#19, cd_marital_status#20, cd_education_status#21]
+Arguments: [cd_demo_sk#19, cd_marital_status#22, cd_education_status#23], [cd_demo_sk#19, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_marital_status#20, 1)) AS cd_marital_status#22, static_invoke(CharVarcharCodegenUtils.readSidePadding(cd_education_status#21, 20)) AS cd_education_status#23]
+
+(23) CometBroadcastExchange
+Input [3]: [cd_demo_sk#19, cd_marital_status#22, cd_education_status#23]
+Arguments: [cd_demo_sk#19, cd_marital_status#22, cd_education_status#23]
+
+(24) CometBroadcastHashJoin
+Left output [6]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8]
+Right output [3]: [cd_demo_sk#19, cd_marital_status#22, cd_education_status#23]
+Arguments: [ss_cdemo_sk#1], [cd_demo_sk#19], Inner, ((((((cd_marital_status#22 = M) AND (cd_education_status#23 = Advanced Degree )) AND (ss_sales_price#6 >= 100.00)) AND (ss_sales_price#6 <= 150.00)) OR ((((cd_marital_status#22 = S) AND (cd_education_status#23 = College )) AND (ss_sales_price#6 >= 50.00)) AND (ss_sales_price#6 <= 100.00))) OR ((((cd_marital_status#22 = W) AND (cd_education_status#23 = 2 yr Degree )) AND (ss_sales_price#6 >= 150.00)) AND (ss_sales_price#6 <= 200.00))), BuildRight
+
+(25) CometProject
+Input [9]: [ss_cdemo_sk#1, ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, cd_demo_sk#19, cd_marital_status#22, cd_education_status#23]
+Arguments: [ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, cd_marital_status#22, cd_education_status#23], [ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, cd_marital_status#22, cd_education_status#23]
+
+(26) CometScan [native_iceberg_compat] parquet spark_catalog.default.household_demographics
+Output [2]: [hd_demo_sk#24, hd_dep_count#25]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/household_demographics]
+PushedFilters: [IsNotNull(hd_demo_sk), Or(EqualTo(hd_dep_count,3),EqualTo(hd_dep_count,1))]
+ReadSchema: struct
+
+(27) CometFilter
+Input [2]: [hd_demo_sk#24, hd_dep_count#25]
+Condition : (isnotnull(hd_demo_sk#24) AND ((hd_dep_count#25 = 3) OR (hd_dep_count#25 = 1)))
+
+(28) CometBroadcastExchange
+Input [2]: [hd_demo_sk#24, hd_dep_count#25]
+Arguments: [hd_demo_sk#24, hd_dep_count#25]
+
+(29) CometBroadcastHashJoin
+Left output [7]: [ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, cd_marital_status#22, cd_education_status#23]
+Right output [2]: [hd_demo_sk#24, hd_dep_count#25]
+Arguments: [ss_hdemo_sk#2], [hd_demo_sk#24], Inner, (((((((cd_marital_status#22 = M) AND (cd_education_status#23 = Advanced Degree )) AND (ss_sales_price#6 >= 100.00)) AND (ss_sales_price#6 <= 150.00)) AND (hd_dep_count#25 = 3)) OR (((((cd_marital_status#22 = S) AND (cd_education_status#23 = College )) AND (ss_sales_price#6 >= 50.00)) AND (ss_sales_price#6 <= 100.00)) AND (hd_dep_count#25 = 1))) OR (((((cd_marital_status#22 = W) AND (cd_education_status#23 = 2 yr Degree )) AND (ss_sales_price#6 >= 150.00)) AND (ss_sales_price#6 <= 200.00)) AND (hd_dep_count#25 = 1))), BuildRight
+
+(30) CometProject
+Input [9]: [ss_hdemo_sk#2, ss_quantity#5, ss_sales_price#6, ss_ext_sales_price#7, ss_ext_wholesale_cost#8, cd_marital_status#22, cd_education_status#23, hd_demo_sk#24, hd_dep_count#25]
+Arguments: [ss_quantity#5, ss_ext_sales_price#7, ss_ext_wholesale_cost#8], [ss_quantity#5, ss_ext_sales_price#7, ss_ext_wholesale_cost#8]
+
+(31) CometHashAggregate
+Input [3]: [ss_quantity#5, ss_ext_sales_price#7, ss_ext_wholesale_cost#8]
+Keys: []
+Functions [4]: [partial_avg(ss_quantity#5), partial_avg(UnscaledValue(ss_ext_sales_price#7)), partial_avg(UnscaledValue(ss_ext_wholesale_cost#8)), partial_sum(UnscaledValue(ss_ext_wholesale_cost#8))]
+
+(32) CometExchange
+Input [7]: [sum#26, count#27, sum#28, count#29, sum#30, count#31, sum#32]
+Arguments: SinglePartition, ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=1]
+
+(33) CometHashAggregate
+Input [7]: [sum#26, count#27, sum#28, count#29, sum#30, count#31, sum#32]
+Keys: []
+Functions [4]: [avg(ss_quantity#5), avg(UnscaledValue(ss_ext_sales_price#7)), avg(UnscaledValue(ss_ext_wholesale_cost#8)), sum(UnscaledValue(ss_ext_wholesale_cost#8))]
+
+(34) CometColumnarToRow [codegen id : 1]
+Input [4]: [avg(ss_quantity)#33, avg(ss_ext_sales_price)#34, avg(ss_ext_wholesale_cost)#35, sum(ss_ext_wholesale_cost)#36]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 1 Hosting Expression = ss_sold_date_sk#10 IN dynamicpruning#11
+BroadcastExchange (39)
++- * CometColumnarToRow (38)
+ +- CometProject (37)
+ +- CometFilter (36)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (35)
+
+
+(35) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#17, d_year#18]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), EqualTo(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(36) CometFilter
+Input [2]: [d_date_sk#17, d_year#18]
+Condition : ((isnotnull(d_year#18) AND (d_year#18 = 2001)) AND isnotnull(d_date_sk#17))
+
+(37) CometProject
+Input [2]: [d_date_sk#17, d_year#18]
+Arguments: [d_date_sk#17], [d_date_sk#17]
+
+(38) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#17]
+
+(39) BroadcastExchange
+Input [1]: [d_date_sk#17]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=2]
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13/extended.txt
new file mode 100644
index 0000000000..08e9beb692
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13/extended.txt
@@ -0,0 +1,42 @@
+CometColumnarToRow
++- CometHashAggregate
+ +- CometExchange
+ +- CometHashAggregate
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_demographics
+ +- CometBroadcastExchange
+ +- CometFilter
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.household_demographics
+
+Comet accelerated 36 out of 38 eligible operators (94%). Final plan contains 2 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13/simplified.txt
new file mode 100644
index 0000000000..8ef882a435
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q13/simplified.txt
@@ -0,0 +1,44 @@
+WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometHashAggregate [sum,count,sum,count,sum,count,sum] [avg(ss_quantity),avg(ss_ext_sales_price),avg(ss_ext_wholesale_cost),sum(ss_ext_wholesale_cost),avg(ss_quantity),avg(UnscaledValue(ss_ext_sales_price)),avg(UnscaledValue(ss_ext_wholesale_cost)),sum(UnscaledValue(ss_ext_wholesale_cost))]
+ CometExchange #1
+ CometHashAggregate [ss_quantity,ss_ext_sales_price,ss_ext_wholesale_cost] [sum,count,sum,count,sum,count,sum]
+ CometProject [ss_quantity,ss_ext_sales_price,ss_ext_wholesale_cost]
+ CometBroadcastHashJoin [ss_hdemo_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,cd_marital_status,cd_education_status,hd_demo_sk,hd_dep_count]
+ CometProject [ss_hdemo_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,cd_marital_status,cd_education_status]
+ CometBroadcastHashJoin [ss_cdemo_sk,ss_hdemo_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,cd_demo_sk,cd_marital_status,cd_education_status]
+ CometProject [ss_cdemo_sk,ss_hdemo_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost]
+ CometBroadcastHashJoin [ss_cdemo_sk,ss_hdemo_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,ss_sold_date_sk,d_date_sk]
+ CometProject [ss_cdemo_sk,ss_hdemo_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,ss_sold_date_sk]
+ CometBroadcastHashJoin [ss_cdemo_sk,ss_hdemo_sk,ss_addr_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,ss_net_profit,ss_sold_date_sk,ca_address_sk,ca_state]
+ CometProject [ss_cdemo_sk,ss_hdemo_sk,ss_addr_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,ss_net_profit,ss_sold_date_sk]
+ CometBroadcastHashJoin [ss_cdemo_sk,ss_hdemo_sk,ss_addr_sk,ss_store_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,ss_net_profit,ss_sold_date_sk,s_store_sk]
+ CometFilter [ss_cdemo_sk,ss_hdemo_sk,ss_addr_sk,ss_store_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,ss_net_profit,ss_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_cdemo_sk,ss_hdemo_sk,ss_addr_sk,ss_store_sk,ss_quantity,ss_sales_price,ss_ext_sales_price,ss_ext_wholesale_cost,ss_net_profit,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #2
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [s_store_sk] #3
+ CometFilter [s_store_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store [s_store_sk]
+ CometBroadcastExchange [ca_address_sk,ca_state] #4
+ CometProject [ca_state] [ca_address_sk,ca_state]
+ CometFilter [ca_address_sk,ca_state,ca_country]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address [ca_address_sk,ca_state,ca_country]
+ CometBroadcastExchange [d_date_sk] #5
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [cd_demo_sk,cd_marital_status,cd_education_status] #6
+ CometProject [cd_marital_status,cd_education_status] [cd_demo_sk,cd_marital_status,cd_education_status]
+ CometFilter [cd_demo_sk,cd_marital_status,cd_education_status]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_demographics [cd_demo_sk,cd_marital_status,cd_education_status]
+ CometBroadcastExchange [hd_demo_sk,hd_dep_count] #7
+ CometFilter [hd_demo_sk,hd_dep_count]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.household_demographics [hd_demo_sk,hd_dep_count]
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_datafusion/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_datafusion/explain.txt
new file mode 100644
index 0000000000..f7377ccf8a
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_datafusion/explain.txt
@@ -0,0 +1,822 @@
+== Physical Plan ==
+TakeOrderedAndProject (110)
++- * HashAggregate (109)
+ +- * CometColumnarToRow (108)
+ +- CometColumnarExchange (107)
+ +- * HashAggregate (106)
+ +- * Expand (105)
+ +- Union (104)
+ :- * Project (69)
+ : +- * Filter (68)
+ : +- * HashAggregate (67)
+ : +- * CometColumnarToRow (66)
+ : +- CometColumnarExchange (65)
+ : +- * HashAggregate (64)
+ : +- * Project (63)
+ : +- * BroadcastHashJoin Inner BuildRight (62)
+ : :- * Project (60)
+ : : +- * BroadcastHashJoin Inner BuildRight (59)
+ : : :- * BroadcastHashJoin LeftSemi BuildRight (52)
+ : : : :- * Filter (3)
+ : : : : +- * ColumnarToRow (2)
+ : : : : +- Scan parquet spark_catalog.default.store_sales (1)
+ : : : +- BroadcastExchange (51)
+ : : : +- * Project (50)
+ : : : +- * BroadcastHashJoin Inner BuildRight (49)
+ : : : :- * CometColumnarToRow (6)
+ : : : : +- CometFilter (5)
+ : : : : +- CometNativeScan parquet spark_catalog.default.item (4)
+ : : : +- BroadcastExchange (48)
+ : : : +- * BroadcastHashJoin LeftSemi BuildRight (47)
+ : : : :- * CometColumnarToRow (36)
+ : : : : +- CometHashAggregate (35)
+ : : : : +- CometColumnarExchange (34)
+ : : : : +- * HashAggregate (33)
+ : : : : +- * Project (32)
+ : : : : +- * BroadcastHashJoin Inner BuildRight (31)
+ : : : : :- * Project (29)
+ : : : : : +- * BroadcastHashJoin Inner BuildRight (28)
+ : : : : : :- * Filter (9)
+ : : : : : : +- * ColumnarToRow (8)
+ : : : : : : +- Scan parquet spark_catalog.default.store_sales (7)
+ : : : : : +- BroadcastExchange (27)
+ : : : : : +- * BroadcastHashJoin LeftSemi BuildRight (26)
+ : : : : : :- * CometColumnarToRow (12)
+ : : : : : : +- CometFilter (11)
+ : : : : : : +- CometNativeScan parquet spark_catalog.default.item (10)
+ : : : : : +- BroadcastExchange (25)
+ : : : : : +- * Project (24)
+ : : : : : +- * BroadcastHashJoin Inner BuildRight (23)
+ : : : : : :- * Project (21)
+ : : : : : : +- * BroadcastHashJoin Inner BuildRight (20)
+ : : : : : : :- * Filter (15)
+ : : : : : : : +- * ColumnarToRow (14)
+ : : : : : : : +- Scan parquet spark_catalog.default.catalog_sales (13)
+ : : : : : : +- BroadcastExchange (19)
+ : : : : : : +- * CometColumnarToRow (18)
+ : : : : : : +- CometFilter (17)
+ : : : : : : +- CometNativeScan parquet spark_catalog.default.item (16)
+ : : : : : +- ReusedExchange (22)
+ : : : : +- ReusedExchange (30)
+ : : : +- BroadcastExchange (46)
+ : : : +- * Project (45)
+ : : : +- * BroadcastHashJoin Inner BuildRight (44)
+ : : : :- * Project (42)
+ : : : : +- * BroadcastHashJoin Inner BuildRight (41)
+ : : : : :- * Filter (39)
+ : : : : : +- * ColumnarToRow (38)
+ : : : : : +- Scan parquet spark_catalog.default.web_sales (37)
+ : : : : +- ReusedExchange (40)
+ : : : +- ReusedExchange (43)
+ : : +- BroadcastExchange (58)
+ : : +- * BroadcastHashJoin LeftSemi BuildRight (57)
+ : : :- * CometColumnarToRow (55)
+ : : : +- CometFilter (54)
+ : : : +- CometNativeScan parquet spark_catalog.default.item (53)
+ : : +- ReusedExchange (56)
+ : +- ReusedExchange (61)
+ :- * Project (86)
+ : +- * Filter (85)
+ : +- * HashAggregate (84)
+ : +- * CometColumnarToRow (83)
+ : +- CometColumnarExchange (82)
+ : +- * HashAggregate (81)
+ : +- * Project (80)
+ : +- * BroadcastHashJoin Inner BuildRight (79)
+ : :- * Project (77)
+ : : +- * BroadcastHashJoin Inner BuildRight (76)
+ : : :- * BroadcastHashJoin LeftSemi BuildRight (74)
+ : : : :- * Filter (72)
+ : : : : +- * ColumnarToRow (71)
+ : : : : +- Scan parquet spark_catalog.default.catalog_sales (70)
+ : : : +- ReusedExchange (73)
+ : : +- ReusedExchange (75)
+ : +- ReusedExchange (78)
+ +- * Project (103)
+ +- * Filter (102)
+ +- * HashAggregate (101)
+ +- * CometColumnarToRow (100)
+ +- CometColumnarExchange (99)
+ +- * HashAggregate (98)
+ +- * Project (97)
+ +- * BroadcastHashJoin Inner BuildRight (96)
+ :- * Project (94)
+ : +- * BroadcastHashJoin Inner BuildRight (93)
+ : :- * BroadcastHashJoin LeftSemi BuildRight (91)
+ : : :- * Filter (89)
+ : : : +- * ColumnarToRow (88)
+ : : : +- Scan parquet spark_catalog.default.web_sales (87)
+ : : +- ReusedExchange (90)
+ : +- ReusedExchange (92)
+ +- ReusedExchange (95)
+
+
+(1) Scan parquet spark_catalog.default.store_sales
+Output [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#4), dynamicpruningexpression(ss_sold_date_sk#4 IN dynamicpruning#5)]
+PushedFilters: [IsNotNull(ss_item_sk)]
+ReadSchema: struct
+
+(2) ColumnarToRow [codegen id : 25]
+Input [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+
+(3) Filter [codegen id : 25]
+Input [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Condition : isnotnull(ss_item_sk#1)
+
+(4) CometNativeScan parquet spark_catalog.default.item
+Output [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_brand_id), IsNotNull(i_class_id), IsNotNull(i_category_id)]
+ReadSchema: struct
+
+(5) CometFilter
+Input [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+Condition : ((isnotnull(i_brand_id#7) AND isnotnull(i_class_id#8)) AND isnotnull(i_category_id#9))
+
+(6) CometColumnarToRow [codegen id : 11]
+Input [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+
+(7) Scan parquet spark_catalog.default.store_sales
+Output [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#11), dynamicpruningexpression(ss_sold_date_sk#11 IN dynamicpruning#12)]
+PushedFilters: [IsNotNull(ss_item_sk)]
+ReadSchema: struct
+
+(8) ColumnarToRow [codegen id : 6]
+Input [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+
+(9) Filter [codegen id : 6]
+Input [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+Condition : isnotnull(ss_item_sk#10)
+
+(10) CometNativeScan parquet spark_catalog.default.item
+Output [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk), IsNotNull(i_brand_id), IsNotNull(i_class_id), IsNotNull(i_category_id)]
+ReadSchema: struct
+
+(11) CometFilter
+Input [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Condition : (((isnotnull(i_item_sk#13) AND isnotnull(i_brand_id#14)) AND isnotnull(i_class_id#15)) AND isnotnull(i_category_id#16))
+
+(12) CometColumnarToRow [codegen id : 4]
+Input [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+
+(13) Scan parquet spark_catalog.default.catalog_sales
+Output [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#18), dynamicpruningexpression(cs_sold_date_sk#18 IN dynamicpruning#12)]
+PushedFilters: [IsNotNull(cs_item_sk)]
+ReadSchema: struct
+
+(14) ColumnarToRow [codegen id : 3]
+Input [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+
+(15) Filter [codegen id : 3]
+Input [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+Condition : isnotnull(cs_item_sk#17)
+
+(16) CometNativeScan parquet spark_catalog.default.item
+Output [4]: [i_item_sk#19, i_brand_id#20, i_class_id#21, i_category_id#22]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk)]
+ReadSchema: struct
+
+(17) CometFilter
+Input [4]: [i_item_sk#19, i_brand_id#20, i_class_id#21, i_category_id#22]
+Condition : isnotnull(i_item_sk#19)
+
+(18) CometColumnarToRow [codegen id : 1]
+Input [4]: [i_item_sk#19, i_brand_id#20, i_class_id#21, i_category_id#22]
+
+(19) BroadcastExchange
+Input [4]: [i_item_sk#19, i_brand_id#20, i_class_id#21, i_category_id#22]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=1]
+
+(20) BroadcastHashJoin [codegen id : 3]
+Left keys [1]: [cs_item_sk#17]
+Right keys [1]: [i_item_sk#19]
+Join type: Inner
+Join condition: None
+
+(21) Project [codegen id : 3]
+Output [4]: [cs_sold_date_sk#18, i_brand_id#20, i_class_id#21, i_category_id#22]
+Input [6]: [cs_item_sk#17, cs_sold_date_sk#18, i_item_sk#19, i_brand_id#20, i_class_id#21, i_category_id#22]
+
+(22) ReusedExchange [Reuses operator id: 140]
+Output [1]: [d_date_sk#23]
+
+(23) BroadcastHashJoin [codegen id : 3]
+Left keys [1]: [cs_sold_date_sk#18]
+Right keys [1]: [d_date_sk#23]
+Join type: Inner
+Join condition: None
+
+(24) Project [codegen id : 3]
+Output [3]: [i_brand_id#20, i_class_id#21, i_category_id#22]
+Input [5]: [cs_sold_date_sk#18, i_brand_id#20, i_class_id#21, i_category_id#22, d_date_sk#23]
+
+(25) BroadcastExchange
+Input [3]: [i_brand_id#20, i_class_id#21, i_category_id#22]
+Arguments: HashedRelationBroadcastMode(List(coalesce(input[0, int, true], 0), isnull(input[0, int, true]), coalesce(input[1, int, true], 0), isnull(input[1, int, true]), coalesce(input[2, int, true], 0), isnull(input[2, int, true])),false), [plan_id=2]
+
+(26) BroadcastHashJoin [codegen id : 4]
+Left keys [6]: [coalesce(i_brand_id#14, 0), isnull(i_brand_id#14), coalesce(i_class_id#15, 0), isnull(i_class_id#15), coalesce(i_category_id#16, 0), isnull(i_category_id#16)]
+Right keys [6]: [coalesce(i_brand_id#20, 0), isnull(i_brand_id#20), coalesce(i_class_id#21, 0), isnull(i_class_id#21), coalesce(i_category_id#22, 0), isnull(i_category_id#22)]
+Join type: LeftSemi
+Join condition: None
+
+(27) BroadcastExchange
+Input [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=3]
+
+(28) BroadcastHashJoin [codegen id : 6]
+Left keys [1]: [ss_item_sk#10]
+Right keys [1]: [i_item_sk#13]
+Join type: Inner
+Join condition: None
+
+(29) Project [codegen id : 6]
+Output [4]: [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16]
+Input [6]: [ss_item_sk#10, ss_sold_date_sk#11, i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+
+(30) ReusedExchange [Reuses operator id: 140]
+Output [1]: [d_date_sk#24]
+
+(31) BroadcastHashJoin [codegen id : 6]
+Left keys [1]: [ss_sold_date_sk#11]
+Right keys [1]: [d_date_sk#24]
+Join type: Inner
+Join condition: None
+
+(32) Project [codegen id : 6]
+Output [3]: [i_brand_id#14 AS brand_id#25, i_class_id#15 AS class_id#26, i_category_id#16 AS category_id#27]
+Input [5]: [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16, d_date_sk#24]
+
+(33) HashAggregate [codegen id : 6]
+Input [3]: [brand_id#25, class_id#26, category_id#27]
+Keys [3]: [brand_id#25, class_id#26, category_id#27]
+Functions: []
+Aggregate Attributes: []
+Results [3]: [brand_id#25, class_id#26, category_id#27]
+
+(34) CometColumnarExchange
+Input [3]: [brand_id#25, class_id#26, category_id#27]
+Arguments: hashpartitioning(brand_id#25, class_id#26, category_id#27, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=4]
+
+(35) CometHashAggregate
+Input [3]: [brand_id#25, class_id#26, category_id#27]
+Keys [3]: [brand_id#25, class_id#26, category_id#27]
+Functions: []
+
+(36) CometColumnarToRow [codegen id : 10]
+Input [3]: [brand_id#25, class_id#26, category_id#27]
+
+(37) Scan parquet spark_catalog.default.web_sales
+Output [2]: [ws_item_sk#28, ws_sold_date_sk#29]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#29), dynamicpruningexpression(ws_sold_date_sk#29 IN dynamicpruning#12)]
+PushedFilters: [IsNotNull(ws_item_sk)]
+ReadSchema: struct
+
+(38) ColumnarToRow [codegen id : 9]
+Input [2]: [ws_item_sk#28, ws_sold_date_sk#29]
+
+(39) Filter [codegen id : 9]
+Input [2]: [ws_item_sk#28, ws_sold_date_sk#29]
+Condition : isnotnull(ws_item_sk#28)
+
+(40) ReusedExchange [Reuses operator id: 19]
+Output [4]: [i_item_sk#30, i_brand_id#31, i_class_id#32, i_category_id#33]
+
+(41) BroadcastHashJoin [codegen id : 9]
+Left keys [1]: [ws_item_sk#28]
+Right keys [1]: [i_item_sk#30]
+Join type: Inner
+Join condition: None
+
+(42) Project [codegen id : 9]
+Output [4]: [ws_sold_date_sk#29, i_brand_id#31, i_class_id#32, i_category_id#33]
+Input [6]: [ws_item_sk#28, ws_sold_date_sk#29, i_item_sk#30, i_brand_id#31, i_class_id#32, i_category_id#33]
+
+(43) ReusedExchange [Reuses operator id: 140]
+Output [1]: [d_date_sk#34]
+
+(44) BroadcastHashJoin [codegen id : 9]
+Left keys [1]: [ws_sold_date_sk#29]
+Right keys [1]: [d_date_sk#34]
+Join type: Inner
+Join condition: None
+
+(45) Project [codegen id : 9]
+Output [3]: [i_brand_id#31, i_class_id#32, i_category_id#33]
+Input [5]: [ws_sold_date_sk#29, i_brand_id#31, i_class_id#32, i_category_id#33, d_date_sk#34]
+
+(46) BroadcastExchange
+Input [3]: [i_brand_id#31, i_class_id#32, i_category_id#33]
+Arguments: HashedRelationBroadcastMode(List(coalesce(input[0, int, true], 0), isnull(input[0, int, true]), coalesce(input[1, int, true], 0), isnull(input[1, int, true]), coalesce(input[2, int, true], 0), isnull(input[2, int, true])),false), [plan_id=5]
+
+(47) BroadcastHashJoin [codegen id : 10]
+Left keys [6]: [coalesce(brand_id#25, 0), isnull(brand_id#25), coalesce(class_id#26, 0), isnull(class_id#26), coalesce(category_id#27, 0), isnull(category_id#27)]
+Right keys [6]: [coalesce(i_brand_id#31, 0), isnull(i_brand_id#31), coalesce(i_class_id#32, 0), isnull(i_class_id#32), coalesce(i_category_id#33, 0), isnull(i_category_id#33)]
+Join type: LeftSemi
+Join condition: None
+
+(48) BroadcastExchange
+Input [3]: [brand_id#25, class_id#26, category_id#27]
+Arguments: HashedRelationBroadcastMode(List(input[0, int, true], input[1, int, true], input[2, int, true]),false), [plan_id=6]
+
+(49) BroadcastHashJoin [codegen id : 11]
+Left keys [3]: [i_brand_id#7, i_class_id#8, i_category_id#9]
+Right keys [3]: [brand_id#25, class_id#26, category_id#27]
+Join type: Inner
+Join condition: None
+
+(50) Project [codegen id : 11]
+Output [1]: [i_item_sk#6 AS ss_item_sk#35]
+Input [7]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9, brand_id#25, class_id#26, category_id#27]
+
+(51) BroadcastExchange
+Input [1]: [ss_item_sk#35]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=7]
+
+(52) BroadcastHashJoin [codegen id : 25]
+Left keys [1]: [ss_item_sk#1]
+Right keys [1]: [ss_item_sk#35]
+Join type: LeftSemi
+Join condition: None
+
+(53) CometNativeScan parquet spark_catalog.default.item
+Output [4]: [i_item_sk#36, i_brand_id#37, i_class_id#38, i_category_id#39]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk)]
+ReadSchema: struct
+
+(54) CometFilter
+Input [4]: [i_item_sk#36, i_brand_id#37, i_class_id#38, i_category_id#39]
+Condition : isnotnull(i_item_sk#36)
+
+(55) CometColumnarToRow [codegen id : 23]
+Input [4]: [i_item_sk#36, i_brand_id#37, i_class_id#38, i_category_id#39]
+
+(56) ReusedExchange [Reuses operator id: 51]
+Output [1]: [ss_item_sk#35]
+
+(57) BroadcastHashJoin [codegen id : 23]
+Left keys [1]: [i_item_sk#36]
+Right keys [1]: [ss_item_sk#35]
+Join type: LeftSemi
+Join condition: None
+
+(58) BroadcastExchange
+Input [4]: [i_item_sk#36, i_brand_id#37, i_class_id#38, i_category_id#39]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=8]
+
+(59) BroadcastHashJoin [codegen id : 25]
+Left keys [1]: [ss_item_sk#1]
+Right keys [1]: [i_item_sk#36]
+Join type: Inner
+Join condition: None
+
+(60) Project [codegen id : 25]
+Output [6]: [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#37, i_class_id#38, i_category_id#39]
+Input [8]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_item_sk#36, i_brand_id#37, i_class_id#38, i_category_id#39]
+
+(61) ReusedExchange [Reuses operator id: 135]
+Output [1]: [d_date_sk#40]
+
+(62) BroadcastHashJoin [codegen id : 25]
+Left keys [1]: [ss_sold_date_sk#4]
+Right keys [1]: [d_date_sk#40]
+Join type: Inner
+Join condition: None
+
+(63) Project [codegen id : 25]
+Output [5]: [ss_quantity#2, ss_list_price#3, i_brand_id#37, i_class_id#38, i_category_id#39]
+Input [7]: [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#37, i_class_id#38, i_category_id#39, d_date_sk#40]
+
+(64) HashAggregate [codegen id : 25]
+Input [5]: [ss_quantity#2, ss_list_price#3, i_brand_id#37, i_class_id#38, i_category_id#39]
+Keys [3]: [i_brand_id#37, i_class_id#38, i_category_id#39]
+Functions [2]: [partial_sum((cast(ss_quantity#2 as decimal(10,0)) * ss_list_price#3)), partial_count(1)]
+Aggregate Attributes [3]: [sum#41, isEmpty#42, count#43]
+Results [6]: [i_brand_id#37, i_class_id#38, i_category_id#39, sum#44, isEmpty#45, count#46]
+
+(65) CometColumnarExchange
+Input [6]: [i_brand_id#37, i_class_id#38, i_category_id#39, sum#44, isEmpty#45, count#46]
+Arguments: hashpartitioning(i_brand_id#37, i_class_id#38, i_category_id#39, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=9]
+
+(66) CometColumnarToRow [codegen id : 26]
+Input [6]: [i_brand_id#37, i_class_id#38, i_category_id#39, sum#44, isEmpty#45, count#46]
+
+(67) HashAggregate [codegen id : 26]
+Input [6]: [i_brand_id#37, i_class_id#38, i_category_id#39, sum#44, isEmpty#45, count#46]
+Keys [3]: [i_brand_id#37, i_class_id#38, i_category_id#39]
+Functions [2]: [sum((cast(ss_quantity#2 as decimal(10,0)) * ss_list_price#3)), count(1)]
+Aggregate Attributes [2]: [sum((cast(ss_quantity#2 as decimal(10,0)) * ss_list_price#3))#47, count(1)#48]
+Results [5]: [i_brand_id#37, i_class_id#38, i_category_id#39, sum((cast(ss_quantity#2 as decimal(10,0)) * ss_list_price#3))#47 AS sales#49, count(1)#48 AS number_sales#50]
+
+(68) Filter [codegen id : 26]
+Input [5]: [i_brand_id#37, i_class_id#38, i_category_id#39, sales#49, number_sales#50]
+Condition : (isnotnull(sales#49) AND (cast(sales#49 as decimal(32,6)) > cast(Subquery scalar-subquery#51, [id=#52] as decimal(32,6))))
+
+(69) Project [codegen id : 26]
+Output [6]: [sales#49, number_sales#50, store AS channel#53, i_brand_id#37 AS i_brand_id#54, i_class_id#38 AS i_class_id#55, i_category_id#39 AS i_category_id#56]
+Input [5]: [i_brand_id#37, i_class_id#38, i_category_id#39, sales#49, number_sales#50]
+
+(70) Scan parquet spark_catalog.default.catalog_sales
+Output [4]: [cs_item_sk#57, cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#60), dynamicpruningexpression(cs_sold_date_sk#60 IN dynamicpruning#5)]
+PushedFilters: [IsNotNull(cs_item_sk)]
+ReadSchema: struct
+
+(71) ColumnarToRow [codegen id : 51]
+Input [4]: [cs_item_sk#57, cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60]
+
+(72) Filter [codegen id : 51]
+Input [4]: [cs_item_sk#57, cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60]
+Condition : isnotnull(cs_item_sk#57)
+
+(73) ReusedExchange [Reuses operator id: 51]
+Output [1]: [ss_item_sk#61]
+
+(74) BroadcastHashJoin [codegen id : 51]
+Left keys [1]: [cs_item_sk#57]
+Right keys [1]: [ss_item_sk#61]
+Join type: LeftSemi
+Join condition: None
+
+(75) ReusedExchange [Reuses operator id: 58]
+Output [4]: [i_item_sk#62, i_brand_id#63, i_class_id#64, i_category_id#65]
+
+(76) BroadcastHashJoin [codegen id : 51]
+Left keys [1]: [cs_item_sk#57]
+Right keys [1]: [i_item_sk#62]
+Join type: Inner
+Join condition: None
+
+(77) Project [codegen id : 51]
+Output [6]: [cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60, i_brand_id#63, i_class_id#64, i_category_id#65]
+Input [8]: [cs_item_sk#57, cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60, i_item_sk#62, i_brand_id#63, i_class_id#64, i_category_id#65]
+
+(78) ReusedExchange [Reuses operator id: 135]
+Output [1]: [d_date_sk#66]
+
+(79) BroadcastHashJoin [codegen id : 51]
+Left keys [1]: [cs_sold_date_sk#60]
+Right keys [1]: [d_date_sk#66]
+Join type: Inner
+Join condition: None
+
+(80) Project [codegen id : 51]
+Output [5]: [cs_quantity#58, cs_list_price#59, i_brand_id#63, i_class_id#64, i_category_id#65]
+Input [7]: [cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60, i_brand_id#63, i_class_id#64, i_category_id#65, d_date_sk#66]
+
+(81) HashAggregate [codegen id : 51]
+Input [5]: [cs_quantity#58, cs_list_price#59, i_brand_id#63, i_class_id#64, i_category_id#65]
+Keys [3]: [i_brand_id#63, i_class_id#64, i_category_id#65]
+Functions [2]: [partial_sum((cast(cs_quantity#58 as decimal(10,0)) * cs_list_price#59)), partial_count(1)]
+Aggregate Attributes [3]: [sum#67, isEmpty#68, count#69]
+Results [6]: [i_brand_id#63, i_class_id#64, i_category_id#65, sum#70, isEmpty#71, count#72]
+
+(82) CometColumnarExchange
+Input [6]: [i_brand_id#63, i_class_id#64, i_category_id#65, sum#70, isEmpty#71, count#72]
+Arguments: hashpartitioning(i_brand_id#63, i_class_id#64, i_category_id#65, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=10]
+
+(83) CometColumnarToRow [codegen id : 52]
+Input [6]: [i_brand_id#63, i_class_id#64, i_category_id#65, sum#70, isEmpty#71, count#72]
+
+(84) HashAggregate [codegen id : 52]
+Input [6]: [i_brand_id#63, i_class_id#64, i_category_id#65, sum#70, isEmpty#71, count#72]
+Keys [3]: [i_brand_id#63, i_class_id#64, i_category_id#65]
+Functions [2]: [sum((cast(cs_quantity#58 as decimal(10,0)) * cs_list_price#59)), count(1)]
+Aggregate Attributes [2]: [sum((cast(cs_quantity#58 as decimal(10,0)) * cs_list_price#59))#73, count(1)#74]
+Results [5]: [i_brand_id#63, i_class_id#64, i_category_id#65, sum((cast(cs_quantity#58 as decimal(10,0)) * cs_list_price#59))#73 AS sales#75, count(1)#74 AS number_sales#76]
+
+(85) Filter [codegen id : 52]
+Input [5]: [i_brand_id#63, i_class_id#64, i_category_id#65, sales#75, number_sales#76]
+Condition : (isnotnull(sales#75) AND (cast(sales#75 as decimal(32,6)) > cast(ReusedSubquery Subquery scalar-subquery#51, [id=#52] as decimal(32,6))))
+
+(86) Project [codegen id : 52]
+Output [6]: [sales#75, number_sales#76, catalog AS channel#77, i_brand_id#63, i_class_id#64, i_category_id#65]
+Input [5]: [i_brand_id#63, i_class_id#64, i_category_id#65, sales#75, number_sales#76]
+
+(87) Scan parquet spark_catalog.default.web_sales
+Output [4]: [ws_item_sk#78, ws_quantity#79, ws_list_price#80, ws_sold_date_sk#81]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#81), dynamicpruningexpression(ws_sold_date_sk#81 IN dynamicpruning#5)]
+PushedFilters: [IsNotNull(ws_item_sk)]
+ReadSchema: struct
+
+(88) ColumnarToRow [codegen id : 77]
+Input [4]: [ws_item_sk#78, ws_quantity#79, ws_list_price#80, ws_sold_date_sk#81]
+
+(89) Filter [codegen id : 77]
+Input [4]: [ws_item_sk#78, ws_quantity#79, ws_list_price#80, ws_sold_date_sk#81]
+Condition : isnotnull(ws_item_sk#78)
+
+(90) ReusedExchange [Reuses operator id: 51]
+Output [1]: [ss_item_sk#82]
+
+(91) BroadcastHashJoin [codegen id : 77]
+Left keys [1]: [ws_item_sk#78]
+Right keys [1]: [ss_item_sk#82]
+Join type: LeftSemi
+Join condition: None
+
+(92) ReusedExchange [Reuses operator id: 58]
+Output [4]: [i_item_sk#83, i_brand_id#84, i_class_id#85, i_category_id#86]
+
+(93) BroadcastHashJoin [codegen id : 77]
+Left keys [1]: [ws_item_sk#78]
+Right keys [1]: [i_item_sk#83]
+Join type: Inner
+Join condition: None
+
+(94) Project [codegen id : 77]
+Output [6]: [ws_quantity#79, ws_list_price#80, ws_sold_date_sk#81, i_brand_id#84, i_class_id#85, i_category_id#86]
+Input [8]: [ws_item_sk#78, ws_quantity#79, ws_list_price#80, ws_sold_date_sk#81, i_item_sk#83, i_brand_id#84, i_class_id#85, i_category_id#86]
+
+(95) ReusedExchange [Reuses operator id: 135]
+Output [1]: [d_date_sk#87]
+
+(96) BroadcastHashJoin [codegen id : 77]
+Left keys [1]: [ws_sold_date_sk#81]
+Right keys [1]: [d_date_sk#87]
+Join type: Inner
+Join condition: None
+
+(97) Project [codegen id : 77]
+Output [5]: [ws_quantity#79, ws_list_price#80, i_brand_id#84, i_class_id#85, i_category_id#86]
+Input [7]: [ws_quantity#79, ws_list_price#80, ws_sold_date_sk#81, i_brand_id#84, i_class_id#85, i_category_id#86, d_date_sk#87]
+
+(98) HashAggregate [codegen id : 77]
+Input [5]: [ws_quantity#79, ws_list_price#80, i_brand_id#84, i_class_id#85, i_category_id#86]
+Keys [3]: [i_brand_id#84, i_class_id#85, i_category_id#86]
+Functions [2]: [partial_sum((cast(ws_quantity#79 as decimal(10,0)) * ws_list_price#80)), partial_count(1)]
+Aggregate Attributes [3]: [sum#88, isEmpty#89, count#90]
+Results [6]: [i_brand_id#84, i_class_id#85, i_category_id#86, sum#91, isEmpty#92, count#93]
+
+(99) CometColumnarExchange
+Input [6]: [i_brand_id#84, i_class_id#85, i_category_id#86, sum#91, isEmpty#92, count#93]
+Arguments: hashpartitioning(i_brand_id#84, i_class_id#85, i_category_id#86, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=11]
+
+(100) CometColumnarToRow [codegen id : 78]
+Input [6]: [i_brand_id#84, i_class_id#85, i_category_id#86, sum#91, isEmpty#92, count#93]
+
+(101) HashAggregate [codegen id : 78]
+Input [6]: [i_brand_id#84, i_class_id#85, i_category_id#86, sum#91, isEmpty#92, count#93]
+Keys [3]: [i_brand_id#84, i_class_id#85, i_category_id#86]
+Functions [2]: [sum((cast(ws_quantity#79 as decimal(10,0)) * ws_list_price#80)), count(1)]
+Aggregate Attributes [2]: [sum((cast(ws_quantity#79 as decimal(10,0)) * ws_list_price#80))#94, count(1)#95]
+Results [5]: [i_brand_id#84, i_class_id#85, i_category_id#86, sum((cast(ws_quantity#79 as decimal(10,0)) * ws_list_price#80))#94 AS sales#96, count(1)#95 AS number_sales#97]
+
+(102) Filter [codegen id : 78]
+Input [5]: [i_brand_id#84, i_class_id#85, i_category_id#86, sales#96, number_sales#97]
+Condition : (isnotnull(sales#96) AND (cast(sales#96 as decimal(32,6)) > cast(ReusedSubquery Subquery scalar-subquery#51, [id=#52] as decimal(32,6))))
+
+(103) Project [codegen id : 78]
+Output [6]: [sales#96, number_sales#97, web AS channel#98, i_brand_id#84, i_class_id#85, i_category_id#86]
+Input [5]: [i_brand_id#84, i_class_id#85, i_category_id#86, sales#96, number_sales#97]
+
+(104) Union
+
+(105) Expand [codegen id : 79]
+Input [6]: [sales#49, number_sales#50, channel#53, i_brand_id#54, i_class_id#55, i_category_id#56]
+Arguments: [[sales#49, number_sales#50, channel#53, i_brand_id#54, i_class_id#55, i_category_id#56, 0], [sales#49, number_sales#50, channel#53, i_brand_id#54, i_class_id#55, null, 1], [sales#49, number_sales#50, channel#53, i_brand_id#54, null, null, 3], [sales#49, number_sales#50, channel#53, null, null, null, 7], [sales#49, number_sales#50, null, null, null, null, 15]], [sales#49, number_sales#50, channel#99, i_brand_id#100, i_class_id#101, i_category_id#102, spark_grouping_id#103]
+
+(106) HashAggregate [codegen id : 79]
+Input [7]: [sales#49, number_sales#50, channel#99, i_brand_id#100, i_class_id#101, i_category_id#102, spark_grouping_id#103]
+Keys [5]: [channel#99, i_brand_id#100, i_class_id#101, i_category_id#102, spark_grouping_id#103]
+Functions [2]: [partial_sum(sales#49), partial_sum(number_sales#50)]
+Aggregate Attributes [3]: [sum#104, isEmpty#105, sum#106]
+Results [8]: [channel#99, i_brand_id#100, i_class_id#101, i_category_id#102, spark_grouping_id#103, sum#107, isEmpty#108, sum#109]
+
+(107) CometColumnarExchange
+Input [8]: [channel#99, i_brand_id#100, i_class_id#101, i_category_id#102, spark_grouping_id#103, sum#107, isEmpty#108, sum#109]
+Arguments: hashpartitioning(channel#99, i_brand_id#100, i_class_id#101, i_category_id#102, spark_grouping_id#103, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=12]
+
+(108) CometColumnarToRow [codegen id : 80]
+Input [8]: [channel#99, i_brand_id#100, i_class_id#101, i_category_id#102, spark_grouping_id#103, sum#107, isEmpty#108, sum#109]
+
+(109) HashAggregate [codegen id : 80]
+Input [8]: [channel#99, i_brand_id#100, i_class_id#101, i_category_id#102, spark_grouping_id#103, sum#107, isEmpty#108, sum#109]
+Keys [5]: [channel#99, i_brand_id#100, i_class_id#101, i_category_id#102, spark_grouping_id#103]
+Functions [2]: [sum(sales#49), sum(number_sales#50)]
+Aggregate Attributes [2]: [sum(sales#49)#110, sum(number_sales#50)#111]
+Results [6]: [channel#99, i_brand_id#100, i_class_id#101, i_category_id#102, sum(sales#49)#110 AS sum(sales)#112, sum(number_sales#50)#111 AS sum(number_sales)#113]
+
+(110) TakeOrderedAndProject
+Input [6]: [channel#99, i_brand_id#100, i_class_id#101, i_category_id#102, sum(sales)#112, sum(number_sales)#113]
+Arguments: 100, [channel#99 ASC NULLS FIRST, i_brand_id#100 ASC NULLS FIRST, i_class_id#101 ASC NULLS FIRST, i_category_id#102 ASC NULLS FIRST], [channel#99, i_brand_id#100, i_class_id#101, i_category_id#102, sum(sales)#112, sum(number_sales)#113]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 68 Hosting Expression = Subquery scalar-subquery#51, [id=#52]
+* HashAggregate (130)
++- * CometColumnarToRow (129)
+ +- CometColumnarExchange (128)
+ +- * HashAggregate (127)
+ +- Union (126)
+ :- * Project (115)
+ : +- * BroadcastHashJoin Inner BuildRight (114)
+ : :- * ColumnarToRow (112)
+ : : +- Scan parquet spark_catalog.default.store_sales (111)
+ : +- ReusedExchange (113)
+ :- * Project (120)
+ : +- * BroadcastHashJoin Inner BuildRight (119)
+ : :- * ColumnarToRow (117)
+ : : +- Scan parquet spark_catalog.default.catalog_sales (116)
+ : +- ReusedExchange (118)
+ +- * Project (125)
+ +- * BroadcastHashJoin Inner BuildRight (124)
+ :- * ColumnarToRow (122)
+ : +- Scan parquet spark_catalog.default.web_sales (121)
+ +- ReusedExchange (123)
+
+
+(111) Scan parquet spark_catalog.default.store_sales
+Output [3]: [ss_quantity#114, ss_list_price#115, ss_sold_date_sk#116]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#116), dynamicpruningexpression(ss_sold_date_sk#116 IN dynamicpruning#12)]
+ReadSchema: struct
+
+(112) ColumnarToRow [codegen id : 2]
+Input [3]: [ss_quantity#114, ss_list_price#115, ss_sold_date_sk#116]
+
+(113) ReusedExchange [Reuses operator id: 140]
+Output [1]: [d_date_sk#117]
+
+(114) BroadcastHashJoin [codegen id : 2]
+Left keys [1]: [ss_sold_date_sk#116]
+Right keys [1]: [d_date_sk#117]
+Join type: Inner
+Join condition: None
+
+(115) Project [codegen id : 2]
+Output [2]: [ss_quantity#114 AS quantity#118, ss_list_price#115 AS list_price#119]
+Input [4]: [ss_quantity#114, ss_list_price#115, ss_sold_date_sk#116, d_date_sk#117]
+
+(116) Scan parquet spark_catalog.default.catalog_sales
+Output [3]: [cs_quantity#120, cs_list_price#121, cs_sold_date_sk#122]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#122), dynamicpruningexpression(cs_sold_date_sk#122 IN dynamicpruning#12)]
+ReadSchema: struct
+
+(117) ColumnarToRow [codegen id : 4]
+Input [3]: [cs_quantity#120, cs_list_price#121, cs_sold_date_sk#122]
+
+(118) ReusedExchange [Reuses operator id: 140]
+Output [1]: [d_date_sk#123]
+
+(119) BroadcastHashJoin [codegen id : 4]
+Left keys [1]: [cs_sold_date_sk#122]
+Right keys [1]: [d_date_sk#123]
+Join type: Inner
+Join condition: None
+
+(120) Project [codegen id : 4]
+Output [2]: [cs_quantity#120 AS quantity#124, cs_list_price#121 AS list_price#125]
+Input [4]: [cs_quantity#120, cs_list_price#121, cs_sold_date_sk#122, d_date_sk#123]
+
+(121) Scan parquet spark_catalog.default.web_sales
+Output [3]: [ws_quantity#126, ws_list_price#127, ws_sold_date_sk#128]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#128), dynamicpruningexpression(ws_sold_date_sk#128 IN dynamicpruning#12)]
+ReadSchema: struct
+
+(122) ColumnarToRow [codegen id : 6]
+Input [3]: [ws_quantity#126, ws_list_price#127, ws_sold_date_sk#128]
+
+(123) ReusedExchange [Reuses operator id: 140]
+Output [1]: [d_date_sk#129]
+
+(124) BroadcastHashJoin [codegen id : 6]
+Left keys [1]: [ws_sold_date_sk#128]
+Right keys [1]: [d_date_sk#129]
+Join type: Inner
+Join condition: None
+
+(125) Project [codegen id : 6]
+Output [2]: [ws_quantity#126 AS quantity#130, ws_list_price#127 AS list_price#131]
+Input [4]: [ws_quantity#126, ws_list_price#127, ws_sold_date_sk#128, d_date_sk#129]
+
+(126) Union
+
+(127) HashAggregate [codegen id : 7]
+Input [2]: [quantity#118, list_price#119]
+Keys: []
+Functions [1]: [partial_avg((cast(quantity#118 as decimal(10,0)) * list_price#119))]
+Aggregate Attributes [2]: [sum#132, count#133]
+Results [2]: [sum#134, count#135]
+
+(128) CometColumnarExchange
+Input [2]: [sum#134, count#135]
+Arguments: SinglePartition, ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=13]
+
+(129) CometColumnarToRow [codegen id : 8]
+Input [2]: [sum#134, count#135]
+
+(130) HashAggregate [codegen id : 8]
+Input [2]: [sum#134, count#135]
+Keys: []
+Functions [1]: [avg((cast(quantity#118 as decimal(10,0)) * list_price#119))]
+Aggregate Attributes [1]: [avg((cast(quantity#118 as decimal(10,0)) * list_price#119))#136]
+Results [1]: [avg((cast(quantity#118 as decimal(10,0)) * list_price#119))#136 AS average_sales#137]
+
+Subquery:2 Hosting operator id = 111 Hosting Expression = ss_sold_date_sk#116 IN dynamicpruning#12
+
+Subquery:3 Hosting operator id = 116 Hosting Expression = cs_sold_date_sk#122 IN dynamicpruning#12
+
+Subquery:4 Hosting operator id = 121 Hosting Expression = ws_sold_date_sk#128 IN dynamicpruning#12
+
+Subquery:5 Hosting operator id = 1 Hosting Expression = ss_sold_date_sk#4 IN dynamicpruning#5
+BroadcastExchange (135)
++- * CometColumnarToRow (134)
+ +- CometProject (133)
+ +- CometFilter (132)
+ +- CometNativeScan parquet spark_catalog.default.date_dim (131)
+
+
+(131) CometNativeScan parquet spark_catalog.default.date_dim
+Output [3]: [d_date_sk#40, d_year#138, d_moy#139]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), IsNotNull(d_moy), EqualTo(d_year,2001), EqualTo(d_moy,11), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(132) CometFilter
+Input [3]: [d_date_sk#40, d_year#138, d_moy#139]
+Condition : ((((isnotnull(d_year#138) AND isnotnull(d_moy#139)) AND (d_year#138 = 2001)) AND (d_moy#139 = 11)) AND isnotnull(d_date_sk#40))
+
+(133) CometProject
+Input [3]: [d_date_sk#40, d_year#138, d_moy#139]
+Arguments: [d_date_sk#40], [d_date_sk#40]
+
+(134) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#40]
+
+(135) BroadcastExchange
+Input [1]: [d_date_sk#40]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=14]
+
+Subquery:6 Hosting operator id = 7 Hosting Expression = ss_sold_date_sk#11 IN dynamicpruning#12
+BroadcastExchange (140)
++- * CometColumnarToRow (139)
+ +- CometProject (138)
+ +- CometFilter (137)
+ +- CometNativeScan parquet spark_catalog.default.date_dim (136)
+
+
+(136) CometNativeScan parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#24, d_year#140]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), GreaterThanOrEqual(d_year,1999), LessThanOrEqual(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(137) CometFilter
+Input [2]: [d_date_sk#24, d_year#140]
+Condition : (((isnotnull(d_year#140) AND (d_year#140 >= 1999)) AND (d_year#140 <= 2001)) AND isnotnull(d_date_sk#24))
+
+(138) CometProject
+Input [2]: [d_date_sk#24, d_year#140]
+Arguments: [d_date_sk#24], [d_date_sk#24]
+
+(139) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#24]
+
+(140) BroadcastExchange
+Input [1]: [d_date_sk#24]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=15]
+
+Subquery:7 Hosting operator id = 13 Hosting Expression = cs_sold_date_sk#18 IN dynamicpruning#12
+
+Subquery:8 Hosting operator id = 37 Hosting Expression = ws_sold_date_sk#29 IN dynamicpruning#12
+
+Subquery:9 Hosting operator id = 85 Hosting Expression = ReusedSubquery Subquery scalar-subquery#51, [id=#52]
+
+Subquery:10 Hosting operator id = 70 Hosting Expression = cs_sold_date_sk#60 IN dynamicpruning#5
+
+Subquery:11 Hosting operator id = 102 Hosting Expression = ReusedSubquery Subquery scalar-subquery#51, [id=#52]
+
+Subquery:12 Hosting operator id = 87 Hosting Expression = ws_sold_date_sk#81 IN dynamicpruning#5
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_datafusion/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_datafusion/extended.txt
new file mode 100644
index 0000000000..dfd3434d90
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_datafusion/extended.txt
@@ -0,0 +1,553 @@
+TakeOrderedAndProject
++- HashAggregate
+ +- CometColumnarToRow
+ +- CometColumnarExchange
+ +- HashAggregate
+ +- Expand
+ +- Union
+ :- Project
+ : +- Filter
+ : : +- Subquery
+ : : +- HashAggregate
+ : : +- CometColumnarToRow
+ : : +- CometColumnarExchange
+ : : +- HashAggregate
+ : : +- Union
+ : : :- Project
+ : : : +- BroadcastHashJoin
+ : : : :- ColumnarToRow
+ : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : +- ReusedSubquery
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : :- Project
+ : : : +- BroadcastHashJoin
+ : : : :- ColumnarToRow
+ : : : : +- Scan parquet spark_catalog.default.catalog_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : +- ReusedSubquery
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- Project
+ : : +- BroadcastHashJoin
+ : : :- ColumnarToRow
+ : : : +- Scan parquet spark_catalog.default.web_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : +- ReusedSubquery
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : +- HashAggregate
+ : +- CometColumnarToRow
+ : +- CometColumnarExchange
+ : +- HashAggregate
+ : +- Project
+ : +- BroadcastHashJoin
+ : :- Project
+ : : +- BroadcastHashJoin
+ : : :- BroadcastHashJoin
+ : : : :- Filter
+ : : : : +- ColumnarToRow
+ : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- Project
+ : : : +- BroadcastHashJoin
+ : : : :- CometColumnarToRow
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : +- BroadcastExchange
+ : : : +- BroadcastHashJoin
+ : : : :- CometColumnarToRow
+ : : : : +- CometHashAggregate
+ : : : : +- CometColumnarExchange
+ : : : : +- HashAggregate
+ : : : : +- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Project
+ : : : : : +- BroadcastHashJoin
+ : : : : : :- Filter
+ : : : : : : +- ColumnarToRow
+ : : : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : : +- SubqueryBroadcast
+ : : : : : : +- BroadcastExchange
+ : : : : : : +- CometColumnarToRow
+ : : : : : : +- CometProject
+ : : : : : : +- CometFilter
+ : : : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : : : +- BroadcastExchange
+ : : : : : +- BroadcastHashJoin
+ : : : : : :- CometColumnarToRow
+ : : : : : : +- CometFilter
+ : : : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : : : +- BroadcastExchange
+ : : : : : +- Project
+ : : : : : +- BroadcastHashJoin
+ : : : : : :- Project
+ : : : : : : +- BroadcastHashJoin
+ : : : : : : :- Filter
+ : : : : : : : +- ColumnarToRow
+ : : : : : : : +- Scan parquet spark_catalog.default.catalog_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : : : +- ReusedSubquery
+ : : : : : : +- BroadcastExchange
+ : : : : : : +- CometColumnarToRow
+ : : : : : : +- CometFilter
+ : : : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Filter
+ : : : : : +- ColumnarToRow
+ : : : : : +- Scan parquet spark_catalog.default.web_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : +- ReusedSubquery
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- BroadcastHashJoin
+ : : :- CometColumnarToRow
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : +- BroadcastExchange
+ : : +- Project
+ : : +- BroadcastHashJoin
+ : : :- CometColumnarToRow
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : +- BroadcastExchange
+ : : +- BroadcastHashJoin
+ : : :- CometColumnarToRow
+ : : : +- CometHashAggregate
+ : : : +- CometColumnarExchange
+ : : : +- HashAggregate
+ : : : +- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Filter
+ : : : : : +- ColumnarToRow
+ : : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : : +- BroadcastExchange
+ : : : : +- BroadcastHashJoin
+ : : : : :- CometColumnarToRow
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : : +- BroadcastExchange
+ : : : : +- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Project
+ : : : : : +- BroadcastHashJoin
+ : : : : : :- Filter
+ : : : : : : +- ColumnarToRow
+ : : : : : : +- Scan parquet spark_catalog.default.catalog_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : : +- ReusedSubquery
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- Project
+ : : +- BroadcastHashJoin
+ : : :- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Filter
+ : : : : +- ColumnarToRow
+ : : : : +- Scan parquet spark_catalog.default.web_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : +- ReusedSubquery
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : +- BroadcastExchange
+ : +- CometColumnarToRow
+ : +- CometProject
+ : +- CometFilter
+ : +- CometNativeScan parquet spark_catalog.default.date_dim
+ :- Project
+ : +- Filter
+ : : +- ReusedSubquery
+ : +- HashAggregate
+ : +- CometColumnarToRow
+ : +- CometColumnarExchange
+ : +- HashAggregate
+ : +- Project
+ : +- BroadcastHashJoin
+ : :- Project
+ : : +- BroadcastHashJoin
+ : : :- BroadcastHashJoin
+ : : : :- Filter
+ : : : : +- ColumnarToRow
+ : : : : +- Scan parquet spark_catalog.default.catalog_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : +- ReusedSubquery
+ : : : +- BroadcastExchange
+ : : : +- Project
+ : : : +- BroadcastHashJoin
+ : : : :- CometColumnarToRow
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : +- BroadcastExchange
+ : : : +- BroadcastHashJoin
+ : : : :- CometColumnarToRow
+ : : : : +- CometHashAggregate
+ : : : : +- CometColumnarExchange
+ : : : : +- HashAggregate
+ : : : : +- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Project
+ : : : : : +- BroadcastHashJoin
+ : : : : : :- Filter
+ : : : : : : +- ColumnarToRow
+ : : : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : : +- SubqueryBroadcast
+ : : : : : : +- BroadcastExchange
+ : : : : : : +- CometColumnarToRow
+ : : : : : : +- CometProject
+ : : : : : : +- CometFilter
+ : : : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : : : +- BroadcastExchange
+ : : : : : +- BroadcastHashJoin
+ : : : : : :- CometColumnarToRow
+ : : : : : : +- CometFilter
+ : : : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : : : +- BroadcastExchange
+ : : : : : +- Project
+ : : : : : +- BroadcastHashJoin
+ : : : : : :- Project
+ : : : : : : +- BroadcastHashJoin
+ : : : : : : :- Filter
+ : : : : : : : +- ColumnarToRow
+ : : : : : : : +- Scan parquet spark_catalog.default.catalog_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : : : +- ReusedSubquery
+ : : : : : : +- BroadcastExchange
+ : : : : : : +- CometColumnarToRow
+ : : : : : : +- CometFilter
+ : : : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Filter
+ : : : : : +- ColumnarToRow
+ : : : : : +- Scan parquet spark_catalog.default.web_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : +- ReusedSubquery
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- BroadcastHashJoin
+ : : :- CometColumnarToRow
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : +- BroadcastExchange
+ : : +- Project
+ : : +- BroadcastHashJoin
+ : : :- CometColumnarToRow
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : +- BroadcastExchange
+ : : +- BroadcastHashJoin
+ : : :- CometColumnarToRow
+ : : : +- CometHashAggregate
+ : : : +- CometColumnarExchange
+ : : : +- HashAggregate
+ : : : +- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Filter
+ : : : : : +- ColumnarToRow
+ : : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : : +- BroadcastExchange
+ : : : : +- BroadcastHashJoin
+ : : : : :- CometColumnarToRow
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : : +- BroadcastExchange
+ : : : : +- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Project
+ : : : : : +- BroadcastHashJoin
+ : : : : : :- Filter
+ : : : : : : +- ColumnarToRow
+ : : : : : : +- Scan parquet spark_catalog.default.catalog_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : : +- ReusedSubquery
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- Project
+ : : +- BroadcastHashJoin
+ : : :- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Filter
+ : : : : +- ColumnarToRow
+ : : : : +- Scan parquet spark_catalog.default.web_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : +- ReusedSubquery
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : +- BroadcastExchange
+ : +- CometColumnarToRow
+ : +- CometProject
+ : +- CometFilter
+ : +- CometNativeScan parquet spark_catalog.default.date_dim
+ +- Project
+ +- Filter
+ : +- ReusedSubquery
+ +- HashAggregate
+ +- CometColumnarToRow
+ +- CometColumnarExchange
+ +- HashAggregate
+ +- Project
+ +- BroadcastHashJoin
+ :- Project
+ : +- BroadcastHashJoin
+ : :- BroadcastHashJoin
+ : : :- Filter
+ : : : +- ColumnarToRow
+ : : : +- Scan parquet spark_catalog.default.web_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : +- ReusedSubquery
+ : : +- BroadcastExchange
+ : : +- Project
+ : : +- BroadcastHashJoin
+ : : :- CometColumnarToRow
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : +- BroadcastExchange
+ : : +- BroadcastHashJoin
+ : : :- CometColumnarToRow
+ : : : +- CometHashAggregate
+ : : : +- CometColumnarExchange
+ : : : +- HashAggregate
+ : : : +- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Filter
+ : : : : : +- ColumnarToRow
+ : : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : : +- BroadcastExchange
+ : : : : +- BroadcastHashJoin
+ : : : : :- CometColumnarToRow
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : : +- BroadcastExchange
+ : : : : +- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Project
+ : : : : : +- BroadcastHashJoin
+ : : : : : :- Filter
+ : : : : : : +- ColumnarToRow
+ : : : : : : +- Scan parquet spark_catalog.default.catalog_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : : +- ReusedSubquery
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- Project
+ : : +- BroadcastHashJoin
+ : : :- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Filter
+ : : : : +- ColumnarToRow
+ : : : : +- Scan parquet spark_catalog.default.web_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : +- ReusedSubquery
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : +- BroadcastExchange
+ : +- BroadcastHashJoin
+ : :- CometColumnarToRow
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.item
+ : +- BroadcastExchange
+ : +- Project
+ : +- BroadcastHashJoin
+ : :- CometColumnarToRow
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.item
+ : +- BroadcastExchange
+ : +- BroadcastHashJoin
+ : :- CometColumnarToRow
+ : : +- CometHashAggregate
+ : : +- CometColumnarExchange
+ : : +- HashAggregate
+ : : +- Project
+ : : +- BroadcastHashJoin
+ : : :- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Filter
+ : : : : +- ColumnarToRow
+ : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- BroadcastHashJoin
+ : : : :- CometColumnarToRow
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : +- BroadcastExchange
+ : : : +- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Filter
+ : : : : : +- ColumnarToRow
+ : : : : : +- Scan parquet spark_catalog.default.catalog_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : +- ReusedSubquery
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : +- BroadcastExchange
+ : +- Project
+ : +- BroadcastHashJoin
+ : :- Project
+ : : +- BroadcastHashJoin
+ : : :- Filter
+ : : : +- ColumnarToRow
+ : : : +- Scan parquet spark_catalog.default.web_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : +- ReusedSubquery
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.item
+ : +- BroadcastExchange
+ : +- CometColumnarToRow
+ : +- CometProject
+ : +- CometFilter
+ : +- CometNativeScan parquet spark_catalog.default.date_dim
+ +- BroadcastExchange
+ +- CometColumnarToRow
+ +- CometProject
+ +- CometFilter
+ +- CometNativeScan parquet spark_catalog.default.date_dim
+
+Comet accelerated 164 out of 458 eligible operators (35%). Final plan contains 93 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_datafusion/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_datafusion/simplified.txt
new file mode 100644
index 0000000000..c989fe9a81
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_datafusion/simplified.txt
@@ -0,0 +1,220 @@
+TakeOrderedAndProject [channel,i_brand_id,i_class_id,i_category_id,sum(sales),sum(number_sales)]
+ WholeStageCodegen (80)
+ HashAggregate [channel,i_brand_id,i_class_id,i_category_id,spark_grouping_id,sum,isEmpty,sum] [sum(sales),sum(number_salesL),sum(sales),sum(number_sales),sum,isEmpty,sum]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [channel,i_brand_id,i_class_id,i_category_id,spark_grouping_id] #1
+ WholeStageCodegen (79)
+ HashAggregate [channel,i_brand_id,i_class_id,i_category_id,spark_grouping_id,sales,number_sales] [sum,isEmpty,sum,sum,isEmpty,sum]
+ Expand [sales,number_sales,channel,i_brand_id,i_class_id,i_category_id]
+ InputAdapter
+ Union
+ WholeStageCodegen (26)
+ Project [sales,number_sales,i_brand_id,i_class_id,i_category_id]
+ Filter [sales]
+ Subquery #3
+ WholeStageCodegen (8)
+ HashAggregate [sum,count] [avg((cast(quantity as decimal(10,0)) * list_price)),average_sales,sum,count]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange #13
+ WholeStageCodegen (7)
+ HashAggregate [quantity,list_price] [sum,count,sum,count]
+ InputAdapter
+ Union
+ WholeStageCodegen (2)
+ Project [ss_quantity,ss_list_price]
+ BroadcastHashJoin [ss_sold_date_sk,d_date_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.store_sales [ss_quantity,ss_list_price,ss_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ InputAdapter
+ ReusedExchange [d_date_sk] #7
+ WholeStageCodegen (4)
+ Project [cs_quantity,cs_list_price]
+ BroadcastHashJoin [cs_sold_date_sk,d_date_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.catalog_sales [cs_quantity,cs_list_price,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ InputAdapter
+ ReusedExchange [d_date_sk] #7
+ WholeStageCodegen (6)
+ Project [ws_quantity,ws_list_price]
+ BroadcastHashJoin [ws_sold_date_sk,d_date_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.web_sales [ws_quantity,ws_list_price,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ InputAdapter
+ ReusedExchange [d_date_sk] #7
+ HashAggregate [i_brand_id,i_class_id,i_category_id,sum,isEmpty,count] [sum((cast(ss_quantity as decimal(10,0)) * ss_list_price)),count(1),sales,number_sales,sum,isEmpty,count]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [i_brand_id,i_class_id,i_category_id] #2
+ WholeStageCodegen (25)
+ HashAggregate [i_brand_id,i_class_id,i_category_id,ss_quantity,ss_list_price] [sum,isEmpty,count,sum,isEmpty,count]
+ Project [ss_quantity,ss_list_price,i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [ss_sold_date_sk,d_date_sk]
+ Project [ss_quantity,ss_list_price,ss_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [ss_item_sk,i_item_sk]
+ BroadcastHashJoin [ss_item_sk,ss_item_sk]
+ Filter [ss_item_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.store_sales [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #3
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year,d_moy]
+ CometNativeScan parquet spark_catalog.default.date_dim [d_date_sk,d_year,d_moy]
+ InputAdapter
+ BroadcastExchange #4
+ WholeStageCodegen (11)
+ Project [i_item_sk]
+ BroadcastHashJoin [i_brand_id,i_class_id,i_category_id,brand_id,class_id,category_id]
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometNativeScan parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ InputAdapter
+ BroadcastExchange #5
+ WholeStageCodegen (10)
+ BroadcastHashJoin [brand_id,class_id,category_id,i_brand_id,i_class_id,i_category_id]
+ CometColumnarToRow
+ InputAdapter
+ CometHashAggregate [brand_id,class_id,category_id]
+ CometColumnarExchange [brand_id,class_id,category_id] #6
+ WholeStageCodegen (6)
+ HashAggregate [brand_id,class_id,category_id]
+ Project [i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [ss_sold_date_sk,d_date_sk]
+ Project [ss_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [ss_item_sk,i_item_sk]
+ Filter [ss_item_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.store_sales [ss_item_sk,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #2
+ BroadcastExchange #7
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometNativeScan parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ InputAdapter
+ BroadcastExchange #8
+ WholeStageCodegen (4)
+ BroadcastHashJoin [i_brand_id,i_class_id,i_category_id,i_brand_id,i_class_id,i_category_id]
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometNativeScan parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ InputAdapter
+ BroadcastExchange #9
+ WholeStageCodegen (3)
+ Project [i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [cs_sold_date_sk,d_date_sk]
+ Project [cs_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [cs_item_sk,i_item_sk]
+ Filter [cs_item_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.catalog_sales [cs_item_sk,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ InputAdapter
+ BroadcastExchange #10
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometNativeScan parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ InputAdapter
+ ReusedExchange [d_date_sk] #7
+ InputAdapter
+ ReusedExchange [d_date_sk] #7
+ InputAdapter
+ BroadcastExchange #11
+ WholeStageCodegen (9)
+ Project [i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [ws_sold_date_sk,d_date_sk]
+ Project [ws_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [ws_item_sk,i_item_sk]
+ Filter [ws_item_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.web_sales [ws_item_sk,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ InputAdapter
+ ReusedExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #10
+ InputAdapter
+ ReusedExchange [d_date_sk] #7
+ InputAdapter
+ BroadcastExchange #12
+ WholeStageCodegen (23)
+ BroadcastHashJoin [i_item_sk,ss_item_sk]
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometNativeScan parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ InputAdapter
+ ReusedExchange [ss_item_sk] #4
+ InputAdapter
+ ReusedExchange [d_date_sk] #3
+ WholeStageCodegen (52)
+ Project [sales,number_sales,i_brand_id,i_class_id,i_category_id]
+ Filter [sales]
+ ReusedSubquery [average_sales] #3
+ HashAggregate [i_brand_id,i_class_id,i_category_id,sum,isEmpty,count] [sum((cast(cs_quantity as decimal(10,0)) * cs_list_price)),count(1),sales,number_sales,sum,isEmpty,count]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [i_brand_id,i_class_id,i_category_id] #14
+ WholeStageCodegen (51)
+ HashAggregate [i_brand_id,i_class_id,i_category_id,cs_quantity,cs_list_price] [sum,isEmpty,count,sum,isEmpty,count]
+ Project [cs_quantity,cs_list_price,i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [cs_sold_date_sk,d_date_sk]
+ Project [cs_quantity,cs_list_price,cs_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [cs_item_sk,i_item_sk]
+ BroadcastHashJoin [cs_item_sk,ss_item_sk]
+ Filter [cs_item_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.catalog_sales [cs_item_sk,cs_quantity,cs_list_price,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ InputAdapter
+ ReusedExchange [ss_item_sk] #4
+ InputAdapter
+ ReusedExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #12
+ InputAdapter
+ ReusedExchange [d_date_sk] #3
+ WholeStageCodegen (78)
+ Project [sales,number_sales,i_brand_id,i_class_id,i_category_id]
+ Filter [sales]
+ ReusedSubquery [average_sales] #3
+ HashAggregate [i_brand_id,i_class_id,i_category_id,sum,isEmpty,count] [sum((cast(ws_quantity as decimal(10,0)) * ws_list_price)),count(1),sales,number_sales,sum,isEmpty,count]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [i_brand_id,i_class_id,i_category_id] #15
+ WholeStageCodegen (77)
+ HashAggregate [i_brand_id,i_class_id,i_category_id,ws_quantity,ws_list_price] [sum,isEmpty,count,sum,isEmpty,count]
+ Project [ws_quantity,ws_list_price,i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [ws_sold_date_sk,d_date_sk]
+ Project [ws_quantity,ws_list_price,ws_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [ws_item_sk,i_item_sk]
+ BroadcastHashJoin [ws_item_sk,ss_item_sk]
+ Filter [ws_item_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.web_sales [ws_item_sk,ws_quantity,ws_list_price,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ InputAdapter
+ ReusedExchange [ss_item_sk] #4
+ InputAdapter
+ ReusedExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #12
+ InputAdapter
+ ReusedExchange [d_date_sk] #3
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_iceberg_compat/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_iceberg_compat/explain.txt
new file mode 100644
index 0000000000..22f1896b63
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_iceberg_compat/explain.txt
@@ -0,0 +1,754 @@
+== Physical Plan ==
+* CometColumnarToRow (102)
++- CometTakeOrderedAndProject (101)
+ +- CometHashAggregate (100)
+ +- CometExchange (99)
+ +- CometHashAggregate (98)
+ +- CometExpand (97)
+ +- CometUnion (96)
+ :- CometProject (65)
+ : +- CometFilter (64)
+ : +- CometHashAggregate (63)
+ : +- CometExchange (62)
+ : +- CometHashAggregate (61)
+ : +- CometProject (60)
+ : +- CometBroadcastHashJoin (59)
+ : :- CometProject (54)
+ : : +- CometBroadcastHashJoin (53)
+ : : :- CometBroadcastHashJoin (47)
+ : : : :- CometFilter (2)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (1)
+ : : : +- CometBroadcastExchange (46)
+ : : : +- CometProject (45)
+ : : : +- CometBroadcastHashJoin (44)
+ : : : :- CometFilter (4)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (3)
+ : : : +- CometBroadcastExchange (43)
+ : : : +- CometBroadcastHashJoin (42)
+ : : : :- CometHashAggregate (32)
+ : : : : +- CometExchange (31)
+ : : : : +- CometHashAggregate (30)
+ : : : : +- CometProject (29)
+ : : : : +- CometBroadcastHashJoin (28)
+ : : : : :- CometProject (26)
+ : : : : : +- CometBroadcastHashJoin (25)
+ : : : : : :- CometFilter (6)
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (5)
+ : : : : : +- CometBroadcastExchange (24)
+ : : : : : +- CometBroadcastHashJoin (23)
+ : : : : : :- CometFilter (8)
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (7)
+ : : : : : +- CometBroadcastExchange (22)
+ : : : : : +- CometProject (21)
+ : : : : : +- CometBroadcastHashJoin (20)
+ : : : : : :- CometProject (15)
+ : : : : : : +- CometBroadcastHashJoin (14)
+ : : : : : : :- CometFilter (10)
+ : : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (9)
+ : : : : : : +- CometBroadcastExchange (13)
+ : : : : : : +- CometFilter (12)
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (11)
+ : : : : : +- CometBroadcastExchange (19)
+ : : : : : +- CometProject (18)
+ : : : : : +- CometFilter (17)
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (16)
+ : : : : +- ReusedExchange (27)
+ : : : +- CometBroadcastExchange (41)
+ : : : +- CometProject (40)
+ : : : +- CometBroadcastHashJoin (39)
+ : : : :- CometProject (37)
+ : : : : +- CometBroadcastHashJoin (36)
+ : : : : :- CometFilter (34)
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (33)
+ : : : : +- ReusedExchange (35)
+ : : : +- ReusedExchange (38)
+ : : +- CometBroadcastExchange (52)
+ : : +- CometBroadcastHashJoin (51)
+ : : :- CometFilter (49)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (48)
+ : : +- ReusedExchange (50)
+ : +- CometBroadcastExchange (58)
+ : +- CometProject (57)
+ : +- CometFilter (56)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (55)
+ :- CometProject (80)
+ : +- CometFilter (79)
+ : +- CometHashAggregate (78)
+ : +- CometExchange (77)
+ : +- CometHashAggregate (76)
+ : +- CometProject (75)
+ : +- CometBroadcastHashJoin (74)
+ : :- CometProject (72)
+ : : +- CometBroadcastHashJoin (71)
+ : : :- CometBroadcastHashJoin (69)
+ : : : :- CometFilter (67)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (66)
+ : : : +- ReusedExchange (68)
+ : : +- ReusedExchange (70)
+ : +- ReusedExchange (73)
+ +- CometProject (95)
+ +- CometFilter (94)
+ +- CometHashAggregate (93)
+ +- CometExchange (92)
+ +- CometHashAggregate (91)
+ +- CometProject (90)
+ +- CometBroadcastHashJoin (89)
+ :- CometProject (87)
+ : +- CometBroadcastHashJoin (86)
+ : :- CometBroadcastHashJoin (84)
+ : : :- CometFilter (82)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (81)
+ : : +- ReusedExchange (83)
+ : +- ReusedExchange (85)
+ +- ReusedExchange (88)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#4), dynamicpruningexpression(ss_sold_date_sk#4 IN dynamicpruning#5)]
+PushedFilters: [IsNotNull(ss_item_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Condition : isnotnull(ss_item_sk#1)
+
+(3) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_brand_id), IsNotNull(i_class_id), IsNotNull(i_category_id)]
+ReadSchema: struct
+
+(4) CometFilter
+Input [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+Condition : ((isnotnull(i_brand_id#7) AND isnotnull(i_class_id#8)) AND isnotnull(i_category_id#9))
+
+(5) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#11), dynamicpruningexpression(ss_sold_date_sk#11 IN dynamicpruning#12)]
+PushedFilters: [IsNotNull(ss_item_sk)]
+ReadSchema: struct
+
+(6) CometFilter
+Input [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+Condition : isnotnull(ss_item_sk#10)
+
+(7) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk), IsNotNull(i_brand_id), IsNotNull(i_class_id), IsNotNull(i_category_id)]
+ReadSchema: struct
+
+(8) CometFilter
+Input [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Condition : (((isnotnull(i_item_sk#13) AND isnotnull(i_brand_id#14)) AND isnotnull(i_class_id#15)) AND isnotnull(i_category_id#16))
+
+(9) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#18), dynamicpruningexpression(cs_sold_date_sk#18 IN dynamicpruning#19)]
+PushedFilters: [IsNotNull(cs_item_sk)]
+ReadSchema: struct
+
+(10) CometFilter
+Input [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+Condition : isnotnull(cs_item_sk#17)
+
+(11) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [4]: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk)]
+ReadSchema: struct
+
+(12) CometFilter
+Input [4]: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Condition : isnotnull(i_item_sk#20)
+
+(13) CometBroadcastExchange
+Input [4]: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+
+(14) CometBroadcastHashJoin
+Left output [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+Right output [4]: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [cs_item_sk#17], [i_item_sk#20], Inner, BuildRight
+
+(15) CometProject
+Input [6]: [cs_item_sk#17, cs_sold_date_sk#18, i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [cs_sold_date_sk#18, i_brand_id#21, i_class_id#22, i_category_id#23], [cs_sold_date_sk#18, i_brand_id#21, i_class_id#22, i_category_id#23]
+
+(16) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#24, d_year#25]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), GreaterThanOrEqual(d_year,1999), LessThanOrEqual(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(17) CometFilter
+Input [2]: [d_date_sk#24, d_year#25]
+Condition : (((isnotnull(d_year#25) AND (d_year#25 >= 1999)) AND (d_year#25 <= 2001)) AND isnotnull(d_date_sk#24))
+
+(18) CometProject
+Input [2]: [d_date_sk#24, d_year#25]
+Arguments: [d_date_sk#24], [d_date_sk#24]
+
+(19) CometBroadcastExchange
+Input [1]: [d_date_sk#24]
+Arguments: [d_date_sk#24]
+
+(20) CometBroadcastHashJoin
+Left output [4]: [cs_sold_date_sk#18, i_brand_id#21, i_class_id#22, i_category_id#23]
+Right output [1]: [d_date_sk#24]
+Arguments: [cs_sold_date_sk#18], [d_date_sk#24], Inner, BuildRight
+
+(21) CometProject
+Input [5]: [cs_sold_date_sk#18, i_brand_id#21, i_class_id#22, i_category_id#23, d_date_sk#24]
+Arguments: [i_brand_id#21, i_class_id#22, i_category_id#23], [i_brand_id#21, i_class_id#22, i_category_id#23]
+
+(22) CometBroadcastExchange
+Input [3]: [i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [i_brand_id#21, i_class_id#22, i_category_id#23]
+
+(23) CometBroadcastHashJoin
+Left output [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Right output [3]: [i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [coalesce(i_brand_id#14, 0), isnull(i_brand_id#14), coalesce(i_class_id#15, 0), isnull(i_class_id#15), coalesce(i_category_id#16, 0), isnull(i_category_id#16)], [coalesce(i_brand_id#21, 0), isnull(i_brand_id#21), coalesce(i_class_id#22, 0), isnull(i_class_id#22), coalesce(i_category_id#23, 0), isnull(i_category_id#23)], LeftSemi, BuildRight
+
+(24) CometBroadcastExchange
+Input [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Arguments: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+
+(25) CometBroadcastHashJoin
+Left output [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+Right output [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Arguments: [ss_item_sk#10], [i_item_sk#13], Inner, BuildRight
+
+(26) CometProject
+Input [6]: [ss_item_sk#10, ss_sold_date_sk#11, i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Arguments: [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16], [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16]
+
+(27) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#26]
+
+(28) CometBroadcastHashJoin
+Left output [4]: [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16]
+Right output [1]: [d_date_sk#26]
+Arguments: [ss_sold_date_sk#11], [d_date_sk#26], Inner, BuildRight
+
+(29) CometProject
+Input [5]: [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16, d_date_sk#26]
+Arguments: [brand_id#27, class_id#28, category_id#29], [i_brand_id#14 AS brand_id#27, i_class_id#15 AS class_id#28, i_category_id#16 AS category_id#29]
+
+(30) CometHashAggregate
+Input [3]: [brand_id#27, class_id#28, category_id#29]
+Keys [3]: [brand_id#27, class_id#28, category_id#29]
+Functions: []
+
+(31) CometExchange
+Input [3]: [brand_id#27, class_id#28, category_id#29]
+Arguments: hashpartitioning(brand_id#27, class_id#28, category_id#29, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=1]
+
+(32) CometHashAggregate
+Input [3]: [brand_id#27, class_id#28, category_id#29]
+Keys [3]: [brand_id#27, class_id#28, category_id#29]
+Functions: []
+
+(33) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [2]: [ws_item_sk#30, ws_sold_date_sk#31]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#31), dynamicpruningexpression(ws_sold_date_sk#31 IN dynamicpruning#32)]
+PushedFilters: [IsNotNull(ws_item_sk)]
+ReadSchema: struct
+
+(34) CometFilter
+Input [2]: [ws_item_sk#30, ws_sold_date_sk#31]
+Condition : isnotnull(ws_item_sk#30)
+
+(35) ReusedExchange [Reuses operator id: 13]
+Output [4]: [i_item_sk#33, i_brand_id#34, i_class_id#35, i_category_id#36]
+
+(36) CometBroadcastHashJoin
+Left output [2]: [ws_item_sk#30, ws_sold_date_sk#31]
+Right output [4]: [i_item_sk#33, i_brand_id#34, i_class_id#35, i_category_id#36]
+Arguments: [ws_item_sk#30], [i_item_sk#33], Inner, BuildRight
+
+(37) CometProject
+Input [6]: [ws_item_sk#30, ws_sold_date_sk#31, i_item_sk#33, i_brand_id#34, i_class_id#35, i_category_id#36]
+Arguments: [ws_sold_date_sk#31, i_brand_id#34, i_class_id#35, i_category_id#36], [ws_sold_date_sk#31, i_brand_id#34, i_class_id#35, i_category_id#36]
+
+(38) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#37]
+
+(39) CometBroadcastHashJoin
+Left output [4]: [ws_sold_date_sk#31, i_brand_id#34, i_class_id#35, i_category_id#36]
+Right output [1]: [d_date_sk#37]
+Arguments: [ws_sold_date_sk#31], [d_date_sk#37], Inner, BuildRight
+
+(40) CometProject
+Input [5]: [ws_sold_date_sk#31, i_brand_id#34, i_class_id#35, i_category_id#36, d_date_sk#37]
+Arguments: [i_brand_id#34, i_class_id#35, i_category_id#36], [i_brand_id#34, i_class_id#35, i_category_id#36]
+
+(41) CometBroadcastExchange
+Input [3]: [i_brand_id#34, i_class_id#35, i_category_id#36]
+Arguments: [i_brand_id#34, i_class_id#35, i_category_id#36]
+
+(42) CometBroadcastHashJoin
+Left output [3]: [brand_id#27, class_id#28, category_id#29]
+Right output [3]: [i_brand_id#34, i_class_id#35, i_category_id#36]
+Arguments: [coalesce(brand_id#27, 0), isnull(brand_id#27), coalesce(class_id#28, 0), isnull(class_id#28), coalesce(category_id#29, 0), isnull(category_id#29)], [coalesce(i_brand_id#34, 0), isnull(i_brand_id#34), coalesce(i_class_id#35, 0), isnull(i_class_id#35), coalesce(i_category_id#36, 0), isnull(i_category_id#36)], LeftSemi, BuildRight
+
+(43) CometBroadcastExchange
+Input [3]: [brand_id#27, class_id#28, category_id#29]
+Arguments: [brand_id#27, class_id#28, category_id#29]
+
+(44) CometBroadcastHashJoin
+Left output [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+Right output [3]: [brand_id#27, class_id#28, category_id#29]
+Arguments: [i_brand_id#7, i_class_id#8, i_category_id#9], [brand_id#27, class_id#28, category_id#29], Inner, BuildRight
+
+(45) CometProject
+Input [7]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9, brand_id#27, class_id#28, category_id#29]
+Arguments: [ss_item_sk#38], [i_item_sk#6 AS ss_item_sk#38]
+
+(46) CometBroadcastExchange
+Input [1]: [ss_item_sk#38]
+Arguments: [ss_item_sk#38]
+
+(47) CometBroadcastHashJoin
+Left output [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Right output [1]: [ss_item_sk#38]
+Arguments: [ss_item_sk#1], [ss_item_sk#38], LeftSemi, BuildRight
+
+(48) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk)]
+ReadSchema: struct
+
+(49) CometFilter
+Input [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Condition : isnotnull(i_item_sk#39)
+
+(50) ReusedExchange [Reuses operator id: 46]
+Output [1]: [ss_item_sk#38]
+
+(51) CometBroadcastHashJoin
+Left output [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Right output [1]: [ss_item_sk#38]
+Arguments: [i_item_sk#39], [ss_item_sk#38], LeftSemi, BuildRight
+
+(52) CometBroadcastExchange
+Input [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Arguments: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+
+(53) CometBroadcastHashJoin
+Left output [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Right output [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Arguments: [ss_item_sk#1], [i_item_sk#39], Inner, BuildRight
+
+(54) CometProject
+Input [8]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Arguments: [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#40, i_class_id#41, i_category_id#42], [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#40, i_class_id#41, i_category_id#42]
+
+(55) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [3]: [d_date_sk#43, d_year#44, d_moy#45]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), IsNotNull(d_moy), EqualTo(d_year,2001), EqualTo(d_moy,11), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(56) CometFilter
+Input [3]: [d_date_sk#43, d_year#44, d_moy#45]
+Condition : ((((isnotnull(d_year#44) AND isnotnull(d_moy#45)) AND (d_year#44 = 2001)) AND (d_moy#45 = 11)) AND isnotnull(d_date_sk#43))
+
+(57) CometProject
+Input [3]: [d_date_sk#43, d_year#44, d_moy#45]
+Arguments: [d_date_sk#43], [d_date_sk#43]
+
+(58) CometBroadcastExchange
+Input [1]: [d_date_sk#43]
+Arguments: [d_date_sk#43]
+
+(59) CometBroadcastHashJoin
+Left output [6]: [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#40, i_class_id#41, i_category_id#42]
+Right output [1]: [d_date_sk#43]
+Arguments: [ss_sold_date_sk#4], [d_date_sk#43], Inner, BuildRight
+
+(60) CometProject
+Input [7]: [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#40, i_class_id#41, i_category_id#42, d_date_sk#43]
+Arguments: [ss_quantity#2, ss_list_price#3, i_brand_id#40, i_class_id#41, i_category_id#42], [ss_quantity#2, ss_list_price#3, i_brand_id#40, i_class_id#41, i_category_id#42]
+
+(61) CometHashAggregate
+Input [5]: [ss_quantity#2, ss_list_price#3, i_brand_id#40, i_class_id#41, i_category_id#42]
+Keys [3]: [i_brand_id#40, i_class_id#41, i_category_id#42]
+Functions [2]: [partial_sum((cast(ss_quantity#2 as decimal(10,0)) * ss_list_price#3)), partial_count(1)]
+
+(62) CometExchange
+Input [6]: [i_brand_id#40, i_class_id#41, i_category_id#42, sum#46, isEmpty#47, count#48]
+Arguments: hashpartitioning(i_brand_id#40, i_class_id#41, i_category_id#42, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=2]
+
+(63) CometHashAggregate
+Input [6]: [i_brand_id#40, i_class_id#41, i_category_id#42, sum#46, isEmpty#47, count#48]
+Keys [3]: [i_brand_id#40, i_class_id#41, i_category_id#42]
+Functions [2]: [sum((cast(ss_quantity#2 as decimal(10,0)) * ss_list_price#3)), count(1)]
+
+(64) CometFilter
+Input [5]: [i_brand_id#40, i_class_id#41, i_category_id#42, sales#49, number_sales#50]
+Condition : (isnotnull(sales#49) AND (cast(sales#49 as decimal(32,6)) > cast(Subquery scalar-subquery#51, [id=#52] as decimal(32,6))))
+
+(65) CometProject
+Input [5]: [i_brand_id#40, i_class_id#41, i_category_id#42, sales#49, number_sales#50]
+Arguments: [sales#49, number_sales#50, channel#53, i_brand_id#54, i_class_id#55, i_category_id#56], [sales#49, number_sales#50, store AS channel#53, i_brand_id#40 AS i_brand_id#54, i_class_id#41 AS i_class_id#55, i_category_id#42 AS i_category_id#56]
+
+(66) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [4]: [cs_item_sk#57, cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#60), dynamicpruningexpression(cs_sold_date_sk#60 IN dynamicpruning#61)]
+PushedFilters: [IsNotNull(cs_item_sk)]
+ReadSchema: struct
+
+(67) CometFilter
+Input [4]: [cs_item_sk#57, cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60]
+Condition : isnotnull(cs_item_sk#57)
+
+(68) ReusedExchange [Reuses operator id: 46]
+Output [1]: [ss_item_sk#62]
+
+(69) CometBroadcastHashJoin
+Left output [4]: [cs_item_sk#57, cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60]
+Right output [1]: [ss_item_sk#62]
+Arguments: [cs_item_sk#57], [ss_item_sk#62], LeftSemi, BuildRight
+
+(70) ReusedExchange [Reuses operator id: 52]
+Output [4]: [i_item_sk#63, i_brand_id#64, i_class_id#65, i_category_id#66]
+
+(71) CometBroadcastHashJoin
+Left output [4]: [cs_item_sk#57, cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60]
+Right output [4]: [i_item_sk#63, i_brand_id#64, i_class_id#65, i_category_id#66]
+Arguments: [cs_item_sk#57], [i_item_sk#63], Inner, BuildRight
+
+(72) CometProject
+Input [8]: [cs_item_sk#57, cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60, i_item_sk#63, i_brand_id#64, i_class_id#65, i_category_id#66]
+Arguments: [cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60, i_brand_id#64, i_class_id#65, i_category_id#66], [cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60, i_brand_id#64, i_class_id#65, i_category_id#66]
+
+(73) ReusedExchange [Reuses operator id: 58]
+Output [1]: [d_date_sk#67]
+
+(74) CometBroadcastHashJoin
+Left output [6]: [cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60, i_brand_id#64, i_class_id#65, i_category_id#66]
+Right output [1]: [d_date_sk#67]
+Arguments: [cs_sold_date_sk#60], [d_date_sk#67], Inner, BuildRight
+
+(75) CometProject
+Input [7]: [cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60, i_brand_id#64, i_class_id#65, i_category_id#66, d_date_sk#67]
+Arguments: [cs_quantity#58, cs_list_price#59, i_brand_id#64, i_class_id#65, i_category_id#66], [cs_quantity#58, cs_list_price#59, i_brand_id#64, i_class_id#65, i_category_id#66]
+
+(76) CometHashAggregate
+Input [5]: [cs_quantity#58, cs_list_price#59, i_brand_id#64, i_class_id#65, i_category_id#66]
+Keys [3]: [i_brand_id#64, i_class_id#65, i_category_id#66]
+Functions [2]: [partial_sum((cast(cs_quantity#58 as decimal(10,0)) * cs_list_price#59)), partial_count(1)]
+
+(77) CometExchange
+Input [6]: [i_brand_id#64, i_class_id#65, i_category_id#66, sum#68, isEmpty#69, count#70]
+Arguments: hashpartitioning(i_brand_id#64, i_class_id#65, i_category_id#66, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=3]
+
+(78) CometHashAggregate
+Input [6]: [i_brand_id#64, i_class_id#65, i_category_id#66, sum#68, isEmpty#69, count#70]
+Keys [3]: [i_brand_id#64, i_class_id#65, i_category_id#66]
+Functions [2]: [sum((cast(cs_quantity#58 as decimal(10,0)) * cs_list_price#59)), count(1)]
+
+(79) CometFilter
+Input [5]: [i_brand_id#64, i_class_id#65, i_category_id#66, sales#71, number_sales#72]
+Condition : (isnotnull(sales#71) AND (cast(sales#71 as decimal(32,6)) > cast(ReusedSubquery Subquery scalar-subquery#51, [id=#52] as decimal(32,6))))
+
+(80) CometProject
+Input [5]: [i_brand_id#64, i_class_id#65, i_category_id#66, sales#71, number_sales#72]
+Arguments: [sales#71, number_sales#72, channel#73, i_brand_id#64, i_class_id#65, i_category_id#66], [sales#71, number_sales#72, catalog AS channel#73, i_brand_id#64, i_class_id#65, i_category_id#66]
+
+(81) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [4]: [ws_item_sk#74, ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#77), dynamicpruningexpression(ws_sold_date_sk#77 IN dynamicpruning#78)]
+PushedFilters: [IsNotNull(ws_item_sk)]
+ReadSchema: struct
+
+(82) CometFilter
+Input [4]: [ws_item_sk#74, ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77]
+Condition : isnotnull(ws_item_sk#74)
+
+(83) ReusedExchange [Reuses operator id: 46]
+Output [1]: [ss_item_sk#79]
+
+(84) CometBroadcastHashJoin
+Left output [4]: [ws_item_sk#74, ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77]
+Right output [1]: [ss_item_sk#79]
+Arguments: [ws_item_sk#74], [ss_item_sk#79], LeftSemi, BuildRight
+
+(85) ReusedExchange [Reuses operator id: 52]
+Output [4]: [i_item_sk#80, i_brand_id#81, i_class_id#82, i_category_id#83]
+
+(86) CometBroadcastHashJoin
+Left output [4]: [ws_item_sk#74, ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77]
+Right output [4]: [i_item_sk#80, i_brand_id#81, i_class_id#82, i_category_id#83]
+Arguments: [ws_item_sk#74], [i_item_sk#80], Inner, BuildRight
+
+(87) CometProject
+Input [8]: [ws_item_sk#74, ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77, i_item_sk#80, i_brand_id#81, i_class_id#82, i_category_id#83]
+Arguments: [ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77, i_brand_id#81, i_class_id#82, i_category_id#83], [ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77, i_brand_id#81, i_class_id#82, i_category_id#83]
+
+(88) ReusedExchange [Reuses operator id: 58]
+Output [1]: [d_date_sk#84]
+
+(89) CometBroadcastHashJoin
+Left output [6]: [ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77, i_brand_id#81, i_class_id#82, i_category_id#83]
+Right output [1]: [d_date_sk#84]
+Arguments: [ws_sold_date_sk#77], [d_date_sk#84], Inner, BuildRight
+
+(90) CometProject
+Input [7]: [ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77, i_brand_id#81, i_class_id#82, i_category_id#83, d_date_sk#84]
+Arguments: [ws_quantity#75, ws_list_price#76, i_brand_id#81, i_class_id#82, i_category_id#83], [ws_quantity#75, ws_list_price#76, i_brand_id#81, i_class_id#82, i_category_id#83]
+
+(91) CometHashAggregate
+Input [5]: [ws_quantity#75, ws_list_price#76, i_brand_id#81, i_class_id#82, i_category_id#83]
+Keys [3]: [i_brand_id#81, i_class_id#82, i_category_id#83]
+Functions [2]: [partial_sum((cast(ws_quantity#75 as decimal(10,0)) * ws_list_price#76)), partial_count(1)]
+
+(92) CometExchange
+Input [6]: [i_brand_id#81, i_class_id#82, i_category_id#83, sum#85, isEmpty#86, count#87]
+Arguments: hashpartitioning(i_brand_id#81, i_class_id#82, i_category_id#83, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=4]
+
+(93) CometHashAggregate
+Input [6]: [i_brand_id#81, i_class_id#82, i_category_id#83, sum#85, isEmpty#86, count#87]
+Keys [3]: [i_brand_id#81, i_class_id#82, i_category_id#83]
+Functions [2]: [sum((cast(ws_quantity#75 as decimal(10,0)) * ws_list_price#76)), count(1)]
+
+(94) CometFilter
+Input [5]: [i_brand_id#81, i_class_id#82, i_category_id#83, sales#88, number_sales#89]
+Condition : (isnotnull(sales#88) AND (cast(sales#88 as decimal(32,6)) > cast(ReusedSubquery Subquery scalar-subquery#51, [id=#52] as decimal(32,6))))
+
+(95) CometProject
+Input [5]: [i_brand_id#81, i_class_id#82, i_category_id#83, sales#88, number_sales#89]
+Arguments: [sales#88, number_sales#89, channel#90, i_brand_id#81, i_class_id#82, i_category_id#83], [sales#88, number_sales#89, web AS channel#90, i_brand_id#81, i_class_id#82, i_category_id#83]
+
+(96) CometUnion
+Child 0 Input [6]: [sales#49, number_sales#50, channel#53, i_brand_id#54, i_class_id#55, i_category_id#56]
+Child 1 Input [6]: [sales#71, number_sales#72, channel#73, i_brand_id#64, i_class_id#65, i_category_id#66]
+Child 2 Input [6]: [sales#88, number_sales#89, channel#90, i_brand_id#81, i_class_id#82, i_category_id#83]
+
+(97) CometExpand
+Input [6]: [sales#49, number_sales#50, channel#53, i_brand_id#54, i_class_id#55, i_category_id#56]
+Arguments: [[sales#49, number_sales#50, channel#53, i_brand_id#54, i_class_id#55, i_category_id#56, 0], [sales#49, number_sales#50, channel#53, i_brand_id#54, i_class_id#55, null, 1], [sales#49, number_sales#50, channel#53, i_brand_id#54, null, null, 3], [sales#49, number_sales#50, channel#53, null, null, null, 7], [sales#49, number_sales#50, null, null, null, null, 15]], [sales#49, number_sales#50, channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, spark_grouping_id#95]
+
+(98) CometHashAggregate
+Input [7]: [sales#49, number_sales#50, channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, spark_grouping_id#95]
+Keys [5]: [channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, spark_grouping_id#95]
+Functions [2]: [partial_sum(sales#49), partial_sum(number_sales#50)]
+
+(99) CometExchange
+Input [8]: [channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, spark_grouping_id#95, sum#96, isEmpty#97, sum#98]
+Arguments: hashpartitioning(channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, spark_grouping_id#95, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=5]
+
+(100) CometHashAggregate
+Input [8]: [channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, spark_grouping_id#95, sum#96, isEmpty#97, sum#98]
+Keys [5]: [channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, spark_grouping_id#95]
+Functions [2]: [sum(sales#49), sum(number_sales#50)]
+
+(101) CometTakeOrderedAndProject
+Input [6]: [channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, sum(sales)#99, sum(number_sales)#100]
+Arguments: TakeOrderedAndProject(limit=100, orderBy=[channel#91 ASC NULLS FIRST,i_brand_id#92 ASC NULLS FIRST,i_class_id#93 ASC NULLS FIRST,i_category_id#94 ASC NULLS FIRST], output=[channel#91,i_brand_id#92,i_class_id#93,i_category_id#94,sum(sales)#99,sum(number_sales)#100]), [channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, sum(sales)#99, sum(number_sales)#100], 100, 0, [channel#91 ASC NULLS FIRST, i_brand_id#92 ASC NULLS FIRST, i_class_id#93 ASC NULLS FIRST, i_category_id#94 ASC NULLS FIRST], [channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, sum(sales)#99, sum(number_sales)#100]
+
+(102) CometColumnarToRow [codegen id : 1]
+Input [6]: [channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, sum(sales)#99, sum(number_sales)#100]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 64 Hosting Expression = Subquery scalar-subquery#51, [id=#52]
+* CometColumnarToRow (119)
++- CometHashAggregate (118)
+ +- CometExchange (117)
+ +- CometHashAggregate (116)
+ +- CometUnion (115)
+ :- CometProject (106)
+ : +- CometBroadcastHashJoin (105)
+ : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (103)
+ : +- ReusedExchange (104)
+ :- CometProject (110)
+ : +- CometBroadcastHashJoin (109)
+ : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (107)
+ : +- ReusedExchange (108)
+ +- CometProject (114)
+ +- CometBroadcastHashJoin (113)
+ :- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (111)
+ +- ReusedExchange (112)
+
+
+(103) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [3]: [ss_quantity#101, ss_list_price#102, ss_sold_date_sk#103]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#103), dynamicpruningexpression(ss_sold_date_sk#103 IN dynamicpruning#104)]
+ReadSchema: struct
+
+(104) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#105]
+
+(105) CometBroadcastHashJoin
+Left output [3]: [ss_quantity#101, ss_list_price#102, ss_sold_date_sk#103]
+Right output [1]: [d_date_sk#105]
+Arguments: [ss_sold_date_sk#103], [d_date_sk#105], Inner, BuildRight
+
+(106) CometProject
+Input [4]: [ss_quantity#101, ss_list_price#102, ss_sold_date_sk#103, d_date_sk#105]
+Arguments: [quantity#106, list_price#107], [ss_quantity#101 AS quantity#106, ss_list_price#102 AS list_price#107]
+
+(107) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [3]: [cs_quantity#108, cs_list_price#109, cs_sold_date_sk#110]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#110), dynamicpruningexpression(cs_sold_date_sk#110 IN dynamicpruning#111)]
+ReadSchema: struct
+
+(108) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#112]
+
+(109) CometBroadcastHashJoin
+Left output [3]: [cs_quantity#108, cs_list_price#109, cs_sold_date_sk#110]
+Right output [1]: [d_date_sk#112]
+Arguments: [cs_sold_date_sk#110], [d_date_sk#112], Inner, BuildRight
+
+(110) CometProject
+Input [4]: [cs_quantity#108, cs_list_price#109, cs_sold_date_sk#110, d_date_sk#112]
+Arguments: [quantity#113, list_price#114], [cs_quantity#108 AS quantity#113, cs_list_price#109 AS list_price#114]
+
+(111) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [3]: [ws_quantity#115, ws_list_price#116, ws_sold_date_sk#117]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#117), dynamicpruningexpression(ws_sold_date_sk#117 IN dynamicpruning#118)]
+ReadSchema: struct
+
+(112) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#119]
+
+(113) CometBroadcastHashJoin
+Left output [3]: [ws_quantity#115, ws_list_price#116, ws_sold_date_sk#117]
+Right output [1]: [d_date_sk#119]
+Arguments: [ws_sold_date_sk#117], [d_date_sk#119], Inner, BuildRight
+
+(114) CometProject
+Input [4]: [ws_quantity#115, ws_list_price#116, ws_sold_date_sk#117, d_date_sk#119]
+Arguments: [quantity#120, list_price#121], [ws_quantity#115 AS quantity#120, ws_list_price#116 AS list_price#121]
+
+(115) CometUnion
+Child 0 Input [2]: [quantity#106, list_price#107]
+Child 1 Input [2]: [quantity#113, list_price#114]
+Child 2 Input [2]: [quantity#120, list_price#121]
+
+(116) CometHashAggregate
+Input [2]: [quantity#106, list_price#107]
+Keys: []
+Functions [1]: [partial_avg((cast(quantity#106 as decimal(10,0)) * list_price#107))]
+
+(117) CometExchange
+Input [2]: [sum#122, count#123]
+Arguments: SinglePartition, ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=6]
+
+(118) CometHashAggregate
+Input [2]: [sum#122, count#123]
+Keys: []
+Functions [1]: [avg((cast(quantity#106 as decimal(10,0)) * list_price#107))]
+
+(119) CometColumnarToRow [codegen id : 1]
+Input [1]: [average_sales#124]
+
+Subquery:2 Hosting operator id = 103 Hosting Expression = ss_sold_date_sk#103 IN dynamicpruning#12
+
+Subquery:3 Hosting operator id = 107 Hosting Expression = cs_sold_date_sk#110 IN dynamicpruning#12
+
+Subquery:4 Hosting operator id = 111 Hosting Expression = ws_sold_date_sk#117 IN dynamicpruning#12
+
+Subquery:5 Hosting operator id = 1 Hosting Expression = ss_sold_date_sk#4 IN dynamicpruning#5
+BroadcastExchange (124)
++- * CometColumnarToRow (123)
+ +- CometProject (122)
+ +- CometFilter (121)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (120)
+
+
+(120) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [3]: [d_date_sk#43, d_year#44, d_moy#45]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), IsNotNull(d_moy), EqualTo(d_year,2001), EqualTo(d_moy,11), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(121) CometFilter
+Input [3]: [d_date_sk#43, d_year#44, d_moy#45]
+Condition : ((((isnotnull(d_year#44) AND isnotnull(d_moy#45)) AND (d_year#44 = 2001)) AND (d_moy#45 = 11)) AND isnotnull(d_date_sk#43))
+
+(122) CometProject
+Input [3]: [d_date_sk#43, d_year#44, d_moy#45]
+Arguments: [d_date_sk#43], [d_date_sk#43]
+
+(123) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#43]
+
+(124) BroadcastExchange
+Input [1]: [d_date_sk#43]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=7]
+
+Subquery:6 Hosting operator id = 5 Hosting Expression = ss_sold_date_sk#11 IN dynamicpruning#12
+BroadcastExchange (129)
++- * CometColumnarToRow (128)
+ +- CometProject (127)
+ +- CometFilter (126)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (125)
+
+
+(125) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#26, d_year#125]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), GreaterThanOrEqual(d_year,1999), LessThanOrEqual(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(126) CometFilter
+Input [2]: [d_date_sk#26, d_year#125]
+Condition : (((isnotnull(d_year#125) AND (d_year#125 >= 1999)) AND (d_year#125 <= 2001)) AND isnotnull(d_date_sk#26))
+
+(127) CometProject
+Input [2]: [d_date_sk#26, d_year#125]
+Arguments: [d_date_sk#26], [d_date_sk#26]
+
+(128) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#26]
+
+(129) BroadcastExchange
+Input [1]: [d_date_sk#26]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=8]
+
+Subquery:7 Hosting operator id = 9 Hosting Expression = cs_sold_date_sk#18 IN dynamicpruning#12
+
+Subquery:8 Hosting operator id = 33 Hosting Expression = ws_sold_date_sk#31 IN dynamicpruning#12
+
+Subquery:9 Hosting operator id = 79 Hosting Expression = ReusedSubquery Subquery scalar-subquery#51, [id=#52]
+
+Subquery:10 Hosting operator id = 66 Hosting Expression = cs_sold_date_sk#60 IN dynamicpruning#5
+
+Subquery:11 Hosting operator id = 94 Hosting Expression = ReusedSubquery Subquery scalar-subquery#51, [id=#52]
+
+Subquery:12 Hosting operator id = 81 Hosting Expression = ws_sold_date_sk#77 IN dynamicpruning#5
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_iceberg_compat/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_iceberg_compat/extended.txt
new file mode 100644
index 0000000000..4af04a7846
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_iceberg_compat/extended.txt
@@ -0,0 +1,469 @@
+CometColumnarToRow
++- CometTakeOrderedAndProject
+ +- CometHashAggregate
+ +- CometExchange
+ +- CometHashAggregate
+ +- CometExpand
+ +- CometUnion
+ :- CometProject
+ : +- CometFilter
+ : : +- Subquery
+ : : +- CometColumnarToRow
+ : : +- CometHashAggregate
+ : : +- CometExchange
+ : : +- CometHashAggregate
+ : : +- CometUnion
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : +- ReusedSubquery
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometHashAggregate
+ : +- CometExchange
+ : +- CometHashAggregate
+ : +- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometHashAggregate
+ : : : : +- CometExchange
+ : : : : +- CometHashAggregate
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : : +- SubqueryBroadcast
+ : : : : : : +- BroadcastExchange
+ : : : : : : +- CometColumnarToRow
+ : : : : : : +- CometProject
+ : : : : : : +- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometProject
+ : : : : : : +- CometBroadcastHashJoin
+ : : : : : : :- CometFilter
+ : : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : : : +- ReusedSubquery
+ : : : : : : +- CometBroadcastExchange
+ : : : : : : +- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : : +- ReusedSubquery
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometBroadcastHashJoin
+ : : :- CometHashAggregate
+ : : : +- CometExchange
+ : : : +- CometHashAggregate
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : : +- ReusedSubquery
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ :- CometProject
+ : +- CometFilter
+ : : +- ReusedSubquery
+ : +- CometHashAggregate
+ : +- CometExchange
+ : +- CometHashAggregate
+ : +- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometHashAggregate
+ : : : : +- CometExchange
+ : : : : +- CometHashAggregate
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : : +- SubqueryBroadcast
+ : : : : : : +- BroadcastExchange
+ : : : : : : +- CometColumnarToRow
+ : : : : : : +- CometProject
+ : : : : : : +- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometProject
+ : : : : : : +- CometBroadcastHashJoin
+ : : : : : : :- CometFilter
+ : : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : : : +- ReusedSubquery
+ : : : : : : +- CometBroadcastExchange
+ : : : : : : +- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : : +- ReusedSubquery
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometBroadcastHashJoin
+ : : :- CometHashAggregate
+ : : : +- CometExchange
+ : : : +- CometHashAggregate
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : : +- ReusedSubquery
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ +- CometProject
+ +- CometFilter
+ : +- ReusedSubquery
+ +- CometHashAggregate
+ +- CometExchange
+ +- CometHashAggregate
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : +- ReusedSubquery
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometBroadcastHashJoin
+ : : :- CometHashAggregate
+ : : : +- CometExchange
+ : : : +- CometHashAggregate
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : : +- ReusedSubquery
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometBroadcastHashJoin
+ : :- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : +- CometBroadcastExchange
+ : +- CometBroadcastHashJoin
+ : :- CometHashAggregate
+ : : +- CometExchange
+ : : +- CometHashAggregate
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : +- ReusedSubquery
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : +- ReusedSubquery
+ : : +- CometBroadcastExchange
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ +- CometBroadcastExchange
+ +- CometProject
+ +- CometFilter
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+
+Comet accelerated 424 out of 458 eligible operators (92%). Final plan contains 9 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_iceberg_compat/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_iceberg_compat/simplified.txt
new file mode 100644
index 0000000000..79c782f2ca
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a.native_iceberg_compat/simplified.txt
@@ -0,0 +1,149 @@
+WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometTakeOrderedAndProject [channel,i_brand_id,i_class_id,i_category_id,sum(sales),sum(number_sales)]
+ CometHashAggregate [spark_grouping_id,sum,isEmpty,sum] [channel,i_brand_id,i_class_id,i_category_id,sum(sales),sum(number_sales),sum(sales),sum(number_salesL)]
+ CometExchange [channel,i_brand_id,i_class_id,i_category_id,spark_grouping_id] #1
+ CometHashAggregate [sales,number_sales] [channel,i_brand_id,i_class_id,i_category_id,spark_grouping_id,sum,isEmpty,sum]
+ CometExpand [channel,i_brand_id,i_class_id,i_category_id] [sales,number_sales,channel,i_brand_id,i_class_id,i_category_id,spark_grouping_id]
+ CometUnion [sales,number_sales,channel,i_brand_id,i_class_id,i_category_id]
+ CometProject [i_brand_id,i_class_id,i_category_id] [sales,number_sales,channel,i_brand_id,i_class_id,i_category_id]
+ CometFilter [i_brand_id,i_class_id,i_category_id,sales,number_sales]
+ Subquery #3
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometHashAggregate [sum,count] [average_sales,avg((cast(quantity as decimal(10,0)) * list_price))]
+ CometExchange #15
+ CometHashAggregate [quantity,list_price] [sum,count]
+ CometUnion [quantity,list_price]
+ CometProject [ss_quantity,ss_list_price] [quantity,list_price]
+ CometBroadcastHashJoin [ss_quantity,ss_list_price,ss_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_quantity,ss_list_price,ss_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ ReusedExchange [d_date_sk] #11
+ CometProject [cs_quantity,cs_list_price] [quantity,list_price]
+ CometBroadcastHashJoin [cs_quantity,cs_list_price,cs_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_quantity,cs_list_price,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ ReusedExchange [d_date_sk] #11
+ CometProject [ws_quantity,ws_list_price] [quantity,list_price]
+ CometBroadcastHashJoin [ws_quantity,ws_list_price,ws_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_quantity,ws_list_price,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ ReusedExchange [d_date_sk] #11
+ CometHashAggregate [sum,isEmpty,count] [i_brand_id,i_class_id,i_category_id,sales,number_sales,sum((cast(ss_quantity as decimal(10,0)) * ss_list_price)),count(1)]
+ CometExchange [i_brand_id,i_class_id,i_category_id] #2
+ CometHashAggregate [ss_quantity,ss_list_price] [i_brand_id,i_class_id,i_category_id,sum,isEmpty,count]
+ CometProject [ss_quantity,ss_list_price,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_quantity,ss_list_price,ss_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [ss_quantity,ss_list_price,ss_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk,ss_item_sk]
+ CometFilter [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #3
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year,d_moy]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year,d_moy]
+ CometBroadcastExchange [ss_item_sk] #4
+ CometProject [i_item_sk] [ss_item_sk]
+ CometBroadcastHashJoin [i_item_sk,i_brand_id,i_class_id,i_category_id,brand_id,class_id,category_id]
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastExchange [brand_id,class_id,category_id] #5
+ CometBroadcastHashJoin [brand_id,class_id,category_id,i_brand_id,i_class_id,i_category_id]
+ CometHashAggregate [brand_id,class_id,category_id]
+ CometExchange [brand_id,class_id,category_id] #6
+ CometHashAggregate [brand_id,class_id,category_id]
+ CometProject [i_brand_id,i_class_id,i_category_id] [brand_id,class_id,category_id]
+ CometBroadcastHashJoin [ss_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [ss_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_item_sk,ss_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometFilter [ss_item_sk,ss_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_item_sk,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #2
+ BroadcastExchange #7
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #8
+ CometBroadcastHashJoin [i_item_sk,i_brand_id,i_class_id,i_category_id,i_brand_id,i_class_id,i_category_id]
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastExchange [i_brand_id,i_class_id,i_category_id] #9
+ CometProject [i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [cs_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [cs_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [cs_item_sk,cs_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometFilter [cs_item_sk,cs_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_item_sk,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ CometBroadcastExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #10
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastExchange [d_date_sk] #11
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ ReusedExchange [d_date_sk] #11
+ CometBroadcastExchange [i_brand_id,i_class_id,i_category_id] #12
+ CometProject [i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ws_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [ws_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ws_item_sk,ws_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometFilter [ws_item_sk,ws_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_item_sk,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ ReusedExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #10
+ ReusedExchange [d_date_sk] #11
+ CometBroadcastExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #13
+ CometBroadcastHashJoin [i_item_sk,i_brand_id,i_class_id,i_category_id,ss_item_sk]
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ ReusedExchange [ss_item_sk] #4
+ CometBroadcastExchange [d_date_sk] #14
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year,d_moy]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year,d_moy]
+ CometProject [sales,number_sales,channel,i_brand_id,i_class_id,i_category_id]
+ CometFilter [i_brand_id,i_class_id,i_category_id,sales,number_sales]
+ ReusedSubquery [average_sales] #3
+ CometHashAggregate [sum,isEmpty,count] [i_brand_id,i_class_id,i_category_id,sales,number_sales,sum((cast(cs_quantity as decimal(10,0)) * cs_list_price)),count(1)]
+ CometExchange [i_brand_id,i_class_id,i_category_id] #16
+ CometHashAggregate [cs_quantity,cs_list_price] [i_brand_id,i_class_id,i_category_id,sum,isEmpty,count]
+ CometProject [cs_quantity,cs_list_price,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [cs_quantity,cs_list_price,cs_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [cs_quantity,cs_list_price,cs_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [cs_item_sk,cs_quantity,cs_list_price,cs_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [cs_item_sk,cs_quantity,cs_list_price,cs_sold_date_sk,ss_item_sk]
+ CometFilter [cs_item_sk,cs_quantity,cs_list_price,cs_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_item_sk,cs_quantity,cs_list_price,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ ReusedExchange [ss_item_sk] #4
+ ReusedExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #13
+ ReusedExchange [d_date_sk] #14
+ CometProject [sales,number_sales,channel,i_brand_id,i_class_id,i_category_id]
+ CometFilter [i_brand_id,i_class_id,i_category_id,sales,number_sales]
+ ReusedSubquery [average_sales] #3
+ CometHashAggregate [sum,isEmpty,count] [i_brand_id,i_class_id,i_category_id,sales,number_sales,sum((cast(ws_quantity as decimal(10,0)) * ws_list_price)),count(1)]
+ CometExchange [i_brand_id,i_class_id,i_category_id] #17
+ CometHashAggregate [ws_quantity,ws_list_price] [i_brand_id,i_class_id,i_category_id,sum,isEmpty,count]
+ CometProject [ws_quantity,ws_list_price,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ws_quantity,ws_list_price,ws_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [ws_quantity,ws_list_price,ws_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ws_item_sk,ws_quantity,ws_list_price,ws_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ws_item_sk,ws_quantity,ws_list_price,ws_sold_date_sk,ss_item_sk]
+ CometFilter [ws_item_sk,ws_quantity,ws_list_price,ws_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_item_sk,ws_quantity,ws_list_price,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ ReusedExchange [ss_item_sk] #4
+ ReusedExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #13
+ ReusedExchange [d_date_sk] #14
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a/explain.txt
new file mode 100644
index 0000000000..22f1896b63
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a/explain.txt
@@ -0,0 +1,754 @@
+== Physical Plan ==
+* CometColumnarToRow (102)
++- CometTakeOrderedAndProject (101)
+ +- CometHashAggregate (100)
+ +- CometExchange (99)
+ +- CometHashAggregate (98)
+ +- CometExpand (97)
+ +- CometUnion (96)
+ :- CometProject (65)
+ : +- CometFilter (64)
+ : +- CometHashAggregate (63)
+ : +- CometExchange (62)
+ : +- CometHashAggregate (61)
+ : +- CometProject (60)
+ : +- CometBroadcastHashJoin (59)
+ : :- CometProject (54)
+ : : +- CometBroadcastHashJoin (53)
+ : : :- CometBroadcastHashJoin (47)
+ : : : :- CometFilter (2)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (1)
+ : : : +- CometBroadcastExchange (46)
+ : : : +- CometProject (45)
+ : : : +- CometBroadcastHashJoin (44)
+ : : : :- CometFilter (4)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (3)
+ : : : +- CometBroadcastExchange (43)
+ : : : +- CometBroadcastHashJoin (42)
+ : : : :- CometHashAggregate (32)
+ : : : : +- CometExchange (31)
+ : : : : +- CometHashAggregate (30)
+ : : : : +- CometProject (29)
+ : : : : +- CometBroadcastHashJoin (28)
+ : : : : :- CometProject (26)
+ : : : : : +- CometBroadcastHashJoin (25)
+ : : : : : :- CometFilter (6)
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (5)
+ : : : : : +- CometBroadcastExchange (24)
+ : : : : : +- CometBroadcastHashJoin (23)
+ : : : : : :- CometFilter (8)
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (7)
+ : : : : : +- CometBroadcastExchange (22)
+ : : : : : +- CometProject (21)
+ : : : : : +- CometBroadcastHashJoin (20)
+ : : : : : :- CometProject (15)
+ : : : : : : +- CometBroadcastHashJoin (14)
+ : : : : : : :- CometFilter (10)
+ : : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (9)
+ : : : : : : +- CometBroadcastExchange (13)
+ : : : : : : +- CometFilter (12)
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (11)
+ : : : : : +- CometBroadcastExchange (19)
+ : : : : : +- CometProject (18)
+ : : : : : +- CometFilter (17)
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (16)
+ : : : : +- ReusedExchange (27)
+ : : : +- CometBroadcastExchange (41)
+ : : : +- CometProject (40)
+ : : : +- CometBroadcastHashJoin (39)
+ : : : :- CometProject (37)
+ : : : : +- CometBroadcastHashJoin (36)
+ : : : : :- CometFilter (34)
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (33)
+ : : : : +- ReusedExchange (35)
+ : : : +- ReusedExchange (38)
+ : : +- CometBroadcastExchange (52)
+ : : +- CometBroadcastHashJoin (51)
+ : : :- CometFilter (49)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (48)
+ : : +- ReusedExchange (50)
+ : +- CometBroadcastExchange (58)
+ : +- CometProject (57)
+ : +- CometFilter (56)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (55)
+ :- CometProject (80)
+ : +- CometFilter (79)
+ : +- CometHashAggregate (78)
+ : +- CometExchange (77)
+ : +- CometHashAggregate (76)
+ : +- CometProject (75)
+ : +- CometBroadcastHashJoin (74)
+ : :- CometProject (72)
+ : : +- CometBroadcastHashJoin (71)
+ : : :- CometBroadcastHashJoin (69)
+ : : : :- CometFilter (67)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (66)
+ : : : +- ReusedExchange (68)
+ : : +- ReusedExchange (70)
+ : +- ReusedExchange (73)
+ +- CometProject (95)
+ +- CometFilter (94)
+ +- CometHashAggregate (93)
+ +- CometExchange (92)
+ +- CometHashAggregate (91)
+ +- CometProject (90)
+ +- CometBroadcastHashJoin (89)
+ :- CometProject (87)
+ : +- CometBroadcastHashJoin (86)
+ : :- CometBroadcastHashJoin (84)
+ : : :- CometFilter (82)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (81)
+ : : +- ReusedExchange (83)
+ : +- ReusedExchange (85)
+ +- ReusedExchange (88)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#4), dynamicpruningexpression(ss_sold_date_sk#4 IN dynamicpruning#5)]
+PushedFilters: [IsNotNull(ss_item_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Condition : isnotnull(ss_item_sk#1)
+
+(3) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_brand_id), IsNotNull(i_class_id), IsNotNull(i_category_id)]
+ReadSchema: struct
+
+(4) CometFilter
+Input [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+Condition : ((isnotnull(i_brand_id#7) AND isnotnull(i_class_id#8)) AND isnotnull(i_category_id#9))
+
+(5) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#11), dynamicpruningexpression(ss_sold_date_sk#11 IN dynamicpruning#12)]
+PushedFilters: [IsNotNull(ss_item_sk)]
+ReadSchema: struct
+
+(6) CometFilter
+Input [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+Condition : isnotnull(ss_item_sk#10)
+
+(7) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk), IsNotNull(i_brand_id), IsNotNull(i_class_id), IsNotNull(i_category_id)]
+ReadSchema: struct
+
+(8) CometFilter
+Input [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Condition : (((isnotnull(i_item_sk#13) AND isnotnull(i_brand_id#14)) AND isnotnull(i_class_id#15)) AND isnotnull(i_category_id#16))
+
+(9) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#18), dynamicpruningexpression(cs_sold_date_sk#18 IN dynamicpruning#19)]
+PushedFilters: [IsNotNull(cs_item_sk)]
+ReadSchema: struct
+
+(10) CometFilter
+Input [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+Condition : isnotnull(cs_item_sk#17)
+
+(11) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [4]: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk)]
+ReadSchema: struct
+
+(12) CometFilter
+Input [4]: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Condition : isnotnull(i_item_sk#20)
+
+(13) CometBroadcastExchange
+Input [4]: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+
+(14) CometBroadcastHashJoin
+Left output [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+Right output [4]: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [cs_item_sk#17], [i_item_sk#20], Inner, BuildRight
+
+(15) CometProject
+Input [6]: [cs_item_sk#17, cs_sold_date_sk#18, i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [cs_sold_date_sk#18, i_brand_id#21, i_class_id#22, i_category_id#23], [cs_sold_date_sk#18, i_brand_id#21, i_class_id#22, i_category_id#23]
+
+(16) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#24, d_year#25]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), GreaterThanOrEqual(d_year,1999), LessThanOrEqual(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(17) CometFilter
+Input [2]: [d_date_sk#24, d_year#25]
+Condition : (((isnotnull(d_year#25) AND (d_year#25 >= 1999)) AND (d_year#25 <= 2001)) AND isnotnull(d_date_sk#24))
+
+(18) CometProject
+Input [2]: [d_date_sk#24, d_year#25]
+Arguments: [d_date_sk#24], [d_date_sk#24]
+
+(19) CometBroadcastExchange
+Input [1]: [d_date_sk#24]
+Arguments: [d_date_sk#24]
+
+(20) CometBroadcastHashJoin
+Left output [4]: [cs_sold_date_sk#18, i_brand_id#21, i_class_id#22, i_category_id#23]
+Right output [1]: [d_date_sk#24]
+Arguments: [cs_sold_date_sk#18], [d_date_sk#24], Inner, BuildRight
+
+(21) CometProject
+Input [5]: [cs_sold_date_sk#18, i_brand_id#21, i_class_id#22, i_category_id#23, d_date_sk#24]
+Arguments: [i_brand_id#21, i_class_id#22, i_category_id#23], [i_brand_id#21, i_class_id#22, i_category_id#23]
+
+(22) CometBroadcastExchange
+Input [3]: [i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [i_brand_id#21, i_class_id#22, i_category_id#23]
+
+(23) CometBroadcastHashJoin
+Left output [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Right output [3]: [i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [coalesce(i_brand_id#14, 0), isnull(i_brand_id#14), coalesce(i_class_id#15, 0), isnull(i_class_id#15), coalesce(i_category_id#16, 0), isnull(i_category_id#16)], [coalesce(i_brand_id#21, 0), isnull(i_brand_id#21), coalesce(i_class_id#22, 0), isnull(i_class_id#22), coalesce(i_category_id#23, 0), isnull(i_category_id#23)], LeftSemi, BuildRight
+
+(24) CometBroadcastExchange
+Input [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Arguments: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+
+(25) CometBroadcastHashJoin
+Left output [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+Right output [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Arguments: [ss_item_sk#10], [i_item_sk#13], Inner, BuildRight
+
+(26) CometProject
+Input [6]: [ss_item_sk#10, ss_sold_date_sk#11, i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Arguments: [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16], [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16]
+
+(27) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#26]
+
+(28) CometBroadcastHashJoin
+Left output [4]: [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16]
+Right output [1]: [d_date_sk#26]
+Arguments: [ss_sold_date_sk#11], [d_date_sk#26], Inner, BuildRight
+
+(29) CometProject
+Input [5]: [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16, d_date_sk#26]
+Arguments: [brand_id#27, class_id#28, category_id#29], [i_brand_id#14 AS brand_id#27, i_class_id#15 AS class_id#28, i_category_id#16 AS category_id#29]
+
+(30) CometHashAggregate
+Input [3]: [brand_id#27, class_id#28, category_id#29]
+Keys [3]: [brand_id#27, class_id#28, category_id#29]
+Functions: []
+
+(31) CometExchange
+Input [3]: [brand_id#27, class_id#28, category_id#29]
+Arguments: hashpartitioning(brand_id#27, class_id#28, category_id#29, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=1]
+
+(32) CometHashAggregate
+Input [3]: [brand_id#27, class_id#28, category_id#29]
+Keys [3]: [brand_id#27, class_id#28, category_id#29]
+Functions: []
+
+(33) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [2]: [ws_item_sk#30, ws_sold_date_sk#31]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#31), dynamicpruningexpression(ws_sold_date_sk#31 IN dynamicpruning#32)]
+PushedFilters: [IsNotNull(ws_item_sk)]
+ReadSchema: struct
+
+(34) CometFilter
+Input [2]: [ws_item_sk#30, ws_sold_date_sk#31]
+Condition : isnotnull(ws_item_sk#30)
+
+(35) ReusedExchange [Reuses operator id: 13]
+Output [4]: [i_item_sk#33, i_brand_id#34, i_class_id#35, i_category_id#36]
+
+(36) CometBroadcastHashJoin
+Left output [2]: [ws_item_sk#30, ws_sold_date_sk#31]
+Right output [4]: [i_item_sk#33, i_brand_id#34, i_class_id#35, i_category_id#36]
+Arguments: [ws_item_sk#30], [i_item_sk#33], Inner, BuildRight
+
+(37) CometProject
+Input [6]: [ws_item_sk#30, ws_sold_date_sk#31, i_item_sk#33, i_brand_id#34, i_class_id#35, i_category_id#36]
+Arguments: [ws_sold_date_sk#31, i_brand_id#34, i_class_id#35, i_category_id#36], [ws_sold_date_sk#31, i_brand_id#34, i_class_id#35, i_category_id#36]
+
+(38) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#37]
+
+(39) CometBroadcastHashJoin
+Left output [4]: [ws_sold_date_sk#31, i_brand_id#34, i_class_id#35, i_category_id#36]
+Right output [1]: [d_date_sk#37]
+Arguments: [ws_sold_date_sk#31], [d_date_sk#37], Inner, BuildRight
+
+(40) CometProject
+Input [5]: [ws_sold_date_sk#31, i_brand_id#34, i_class_id#35, i_category_id#36, d_date_sk#37]
+Arguments: [i_brand_id#34, i_class_id#35, i_category_id#36], [i_brand_id#34, i_class_id#35, i_category_id#36]
+
+(41) CometBroadcastExchange
+Input [3]: [i_brand_id#34, i_class_id#35, i_category_id#36]
+Arguments: [i_brand_id#34, i_class_id#35, i_category_id#36]
+
+(42) CometBroadcastHashJoin
+Left output [3]: [brand_id#27, class_id#28, category_id#29]
+Right output [3]: [i_brand_id#34, i_class_id#35, i_category_id#36]
+Arguments: [coalesce(brand_id#27, 0), isnull(brand_id#27), coalesce(class_id#28, 0), isnull(class_id#28), coalesce(category_id#29, 0), isnull(category_id#29)], [coalesce(i_brand_id#34, 0), isnull(i_brand_id#34), coalesce(i_class_id#35, 0), isnull(i_class_id#35), coalesce(i_category_id#36, 0), isnull(i_category_id#36)], LeftSemi, BuildRight
+
+(43) CometBroadcastExchange
+Input [3]: [brand_id#27, class_id#28, category_id#29]
+Arguments: [brand_id#27, class_id#28, category_id#29]
+
+(44) CometBroadcastHashJoin
+Left output [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+Right output [3]: [brand_id#27, class_id#28, category_id#29]
+Arguments: [i_brand_id#7, i_class_id#8, i_category_id#9], [brand_id#27, class_id#28, category_id#29], Inner, BuildRight
+
+(45) CometProject
+Input [7]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9, brand_id#27, class_id#28, category_id#29]
+Arguments: [ss_item_sk#38], [i_item_sk#6 AS ss_item_sk#38]
+
+(46) CometBroadcastExchange
+Input [1]: [ss_item_sk#38]
+Arguments: [ss_item_sk#38]
+
+(47) CometBroadcastHashJoin
+Left output [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Right output [1]: [ss_item_sk#38]
+Arguments: [ss_item_sk#1], [ss_item_sk#38], LeftSemi, BuildRight
+
+(48) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk)]
+ReadSchema: struct
+
+(49) CometFilter
+Input [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Condition : isnotnull(i_item_sk#39)
+
+(50) ReusedExchange [Reuses operator id: 46]
+Output [1]: [ss_item_sk#38]
+
+(51) CometBroadcastHashJoin
+Left output [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Right output [1]: [ss_item_sk#38]
+Arguments: [i_item_sk#39], [ss_item_sk#38], LeftSemi, BuildRight
+
+(52) CometBroadcastExchange
+Input [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Arguments: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+
+(53) CometBroadcastHashJoin
+Left output [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Right output [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Arguments: [ss_item_sk#1], [i_item_sk#39], Inner, BuildRight
+
+(54) CometProject
+Input [8]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Arguments: [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#40, i_class_id#41, i_category_id#42], [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#40, i_class_id#41, i_category_id#42]
+
+(55) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [3]: [d_date_sk#43, d_year#44, d_moy#45]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), IsNotNull(d_moy), EqualTo(d_year,2001), EqualTo(d_moy,11), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(56) CometFilter
+Input [3]: [d_date_sk#43, d_year#44, d_moy#45]
+Condition : ((((isnotnull(d_year#44) AND isnotnull(d_moy#45)) AND (d_year#44 = 2001)) AND (d_moy#45 = 11)) AND isnotnull(d_date_sk#43))
+
+(57) CometProject
+Input [3]: [d_date_sk#43, d_year#44, d_moy#45]
+Arguments: [d_date_sk#43], [d_date_sk#43]
+
+(58) CometBroadcastExchange
+Input [1]: [d_date_sk#43]
+Arguments: [d_date_sk#43]
+
+(59) CometBroadcastHashJoin
+Left output [6]: [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#40, i_class_id#41, i_category_id#42]
+Right output [1]: [d_date_sk#43]
+Arguments: [ss_sold_date_sk#4], [d_date_sk#43], Inner, BuildRight
+
+(60) CometProject
+Input [7]: [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#40, i_class_id#41, i_category_id#42, d_date_sk#43]
+Arguments: [ss_quantity#2, ss_list_price#3, i_brand_id#40, i_class_id#41, i_category_id#42], [ss_quantity#2, ss_list_price#3, i_brand_id#40, i_class_id#41, i_category_id#42]
+
+(61) CometHashAggregate
+Input [5]: [ss_quantity#2, ss_list_price#3, i_brand_id#40, i_class_id#41, i_category_id#42]
+Keys [3]: [i_brand_id#40, i_class_id#41, i_category_id#42]
+Functions [2]: [partial_sum((cast(ss_quantity#2 as decimal(10,0)) * ss_list_price#3)), partial_count(1)]
+
+(62) CometExchange
+Input [6]: [i_brand_id#40, i_class_id#41, i_category_id#42, sum#46, isEmpty#47, count#48]
+Arguments: hashpartitioning(i_brand_id#40, i_class_id#41, i_category_id#42, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=2]
+
+(63) CometHashAggregate
+Input [6]: [i_brand_id#40, i_class_id#41, i_category_id#42, sum#46, isEmpty#47, count#48]
+Keys [3]: [i_brand_id#40, i_class_id#41, i_category_id#42]
+Functions [2]: [sum((cast(ss_quantity#2 as decimal(10,0)) * ss_list_price#3)), count(1)]
+
+(64) CometFilter
+Input [5]: [i_brand_id#40, i_class_id#41, i_category_id#42, sales#49, number_sales#50]
+Condition : (isnotnull(sales#49) AND (cast(sales#49 as decimal(32,6)) > cast(Subquery scalar-subquery#51, [id=#52] as decimal(32,6))))
+
+(65) CometProject
+Input [5]: [i_brand_id#40, i_class_id#41, i_category_id#42, sales#49, number_sales#50]
+Arguments: [sales#49, number_sales#50, channel#53, i_brand_id#54, i_class_id#55, i_category_id#56], [sales#49, number_sales#50, store AS channel#53, i_brand_id#40 AS i_brand_id#54, i_class_id#41 AS i_class_id#55, i_category_id#42 AS i_category_id#56]
+
+(66) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [4]: [cs_item_sk#57, cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#60), dynamicpruningexpression(cs_sold_date_sk#60 IN dynamicpruning#61)]
+PushedFilters: [IsNotNull(cs_item_sk)]
+ReadSchema: struct
+
+(67) CometFilter
+Input [4]: [cs_item_sk#57, cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60]
+Condition : isnotnull(cs_item_sk#57)
+
+(68) ReusedExchange [Reuses operator id: 46]
+Output [1]: [ss_item_sk#62]
+
+(69) CometBroadcastHashJoin
+Left output [4]: [cs_item_sk#57, cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60]
+Right output [1]: [ss_item_sk#62]
+Arguments: [cs_item_sk#57], [ss_item_sk#62], LeftSemi, BuildRight
+
+(70) ReusedExchange [Reuses operator id: 52]
+Output [4]: [i_item_sk#63, i_brand_id#64, i_class_id#65, i_category_id#66]
+
+(71) CometBroadcastHashJoin
+Left output [4]: [cs_item_sk#57, cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60]
+Right output [4]: [i_item_sk#63, i_brand_id#64, i_class_id#65, i_category_id#66]
+Arguments: [cs_item_sk#57], [i_item_sk#63], Inner, BuildRight
+
+(72) CometProject
+Input [8]: [cs_item_sk#57, cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60, i_item_sk#63, i_brand_id#64, i_class_id#65, i_category_id#66]
+Arguments: [cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60, i_brand_id#64, i_class_id#65, i_category_id#66], [cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60, i_brand_id#64, i_class_id#65, i_category_id#66]
+
+(73) ReusedExchange [Reuses operator id: 58]
+Output [1]: [d_date_sk#67]
+
+(74) CometBroadcastHashJoin
+Left output [6]: [cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60, i_brand_id#64, i_class_id#65, i_category_id#66]
+Right output [1]: [d_date_sk#67]
+Arguments: [cs_sold_date_sk#60], [d_date_sk#67], Inner, BuildRight
+
+(75) CometProject
+Input [7]: [cs_quantity#58, cs_list_price#59, cs_sold_date_sk#60, i_brand_id#64, i_class_id#65, i_category_id#66, d_date_sk#67]
+Arguments: [cs_quantity#58, cs_list_price#59, i_brand_id#64, i_class_id#65, i_category_id#66], [cs_quantity#58, cs_list_price#59, i_brand_id#64, i_class_id#65, i_category_id#66]
+
+(76) CometHashAggregate
+Input [5]: [cs_quantity#58, cs_list_price#59, i_brand_id#64, i_class_id#65, i_category_id#66]
+Keys [3]: [i_brand_id#64, i_class_id#65, i_category_id#66]
+Functions [2]: [partial_sum((cast(cs_quantity#58 as decimal(10,0)) * cs_list_price#59)), partial_count(1)]
+
+(77) CometExchange
+Input [6]: [i_brand_id#64, i_class_id#65, i_category_id#66, sum#68, isEmpty#69, count#70]
+Arguments: hashpartitioning(i_brand_id#64, i_class_id#65, i_category_id#66, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=3]
+
+(78) CometHashAggregate
+Input [6]: [i_brand_id#64, i_class_id#65, i_category_id#66, sum#68, isEmpty#69, count#70]
+Keys [3]: [i_brand_id#64, i_class_id#65, i_category_id#66]
+Functions [2]: [sum((cast(cs_quantity#58 as decimal(10,0)) * cs_list_price#59)), count(1)]
+
+(79) CometFilter
+Input [5]: [i_brand_id#64, i_class_id#65, i_category_id#66, sales#71, number_sales#72]
+Condition : (isnotnull(sales#71) AND (cast(sales#71 as decimal(32,6)) > cast(ReusedSubquery Subquery scalar-subquery#51, [id=#52] as decimal(32,6))))
+
+(80) CometProject
+Input [5]: [i_brand_id#64, i_class_id#65, i_category_id#66, sales#71, number_sales#72]
+Arguments: [sales#71, number_sales#72, channel#73, i_brand_id#64, i_class_id#65, i_category_id#66], [sales#71, number_sales#72, catalog AS channel#73, i_brand_id#64, i_class_id#65, i_category_id#66]
+
+(81) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [4]: [ws_item_sk#74, ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#77), dynamicpruningexpression(ws_sold_date_sk#77 IN dynamicpruning#78)]
+PushedFilters: [IsNotNull(ws_item_sk)]
+ReadSchema: struct
+
+(82) CometFilter
+Input [4]: [ws_item_sk#74, ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77]
+Condition : isnotnull(ws_item_sk#74)
+
+(83) ReusedExchange [Reuses operator id: 46]
+Output [1]: [ss_item_sk#79]
+
+(84) CometBroadcastHashJoin
+Left output [4]: [ws_item_sk#74, ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77]
+Right output [1]: [ss_item_sk#79]
+Arguments: [ws_item_sk#74], [ss_item_sk#79], LeftSemi, BuildRight
+
+(85) ReusedExchange [Reuses operator id: 52]
+Output [4]: [i_item_sk#80, i_brand_id#81, i_class_id#82, i_category_id#83]
+
+(86) CometBroadcastHashJoin
+Left output [4]: [ws_item_sk#74, ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77]
+Right output [4]: [i_item_sk#80, i_brand_id#81, i_class_id#82, i_category_id#83]
+Arguments: [ws_item_sk#74], [i_item_sk#80], Inner, BuildRight
+
+(87) CometProject
+Input [8]: [ws_item_sk#74, ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77, i_item_sk#80, i_brand_id#81, i_class_id#82, i_category_id#83]
+Arguments: [ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77, i_brand_id#81, i_class_id#82, i_category_id#83], [ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77, i_brand_id#81, i_class_id#82, i_category_id#83]
+
+(88) ReusedExchange [Reuses operator id: 58]
+Output [1]: [d_date_sk#84]
+
+(89) CometBroadcastHashJoin
+Left output [6]: [ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77, i_brand_id#81, i_class_id#82, i_category_id#83]
+Right output [1]: [d_date_sk#84]
+Arguments: [ws_sold_date_sk#77], [d_date_sk#84], Inner, BuildRight
+
+(90) CometProject
+Input [7]: [ws_quantity#75, ws_list_price#76, ws_sold_date_sk#77, i_brand_id#81, i_class_id#82, i_category_id#83, d_date_sk#84]
+Arguments: [ws_quantity#75, ws_list_price#76, i_brand_id#81, i_class_id#82, i_category_id#83], [ws_quantity#75, ws_list_price#76, i_brand_id#81, i_class_id#82, i_category_id#83]
+
+(91) CometHashAggregate
+Input [5]: [ws_quantity#75, ws_list_price#76, i_brand_id#81, i_class_id#82, i_category_id#83]
+Keys [3]: [i_brand_id#81, i_class_id#82, i_category_id#83]
+Functions [2]: [partial_sum((cast(ws_quantity#75 as decimal(10,0)) * ws_list_price#76)), partial_count(1)]
+
+(92) CometExchange
+Input [6]: [i_brand_id#81, i_class_id#82, i_category_id#83, sum#85, isEmpty#86, count#87]
+Arguments: hashpartitioning(i_brand_id#81, i_class_id#82, i_category_id#83, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=4]
+
+(93) CometHashAggregate
+Input [6]: [i_brand_id#81, i_class_id#82, i_category_id#83, sum#85, isEmpty#86, count#87]
+Keys [3]: [i_brand_id#81, i_class_id#82, i_category_id#83]
+Functions [2]: [sum((cast(ws_quantity#75 as decimal(10,0)) * ws_list_price#76)), count(1)]
+
+(94) CometFilter
+Input [5]: [i_brand_id#81, i_class_id#82, i_category_id#83, sales#88, number_sales#89]
+Condition : (isnotnull(sales#88) AND (cast(sales#88 as decimal(32,6)) > cast(ReusedSubquery Subquery scalar-subquery#51, [id=#52] as decimal(32,6))))
+
+(95) CometProject
+Input [5]: [i_brand_id#81, i_class_id#82, i_category_id#83, sales#88, number_sales#89]
+Arguments: [sales#88, number_sales#89, channel#90, i_brand_id#81, i_class_id#82, i_category_id#83], [sales#88, number_sales#89, web AS channel#90, i_brand_id#81, i_class_id#82, i_category_id#83]
+
+(96) CometUnion
+Child 0 Input [6]: [sales#49, number_sales#50, channel#53, i_brand_id#54, i_class_id#55, i_category_id#56]
+Child 1 Input [6]: [sales#71, number_sales#72, channel#73, i_brand_id#64, i_class_id#65, i_category_id#66]
+Child 2 Input [6]: [sales#88, number_sales#89, channel#90, i_brand_id#81, i_class_id#82, i_category_id#83]
+
+(97) CometExpand
+Input [6]: [sales#49, number_sales#50, channel#53, i_brand_id#54, i_class_id#55, i_category_id#56]
+Arguments: [[sales#49, number_sales#50, channel#53, i_brand_id#54, i_class_id#55, i_category_id#56, 0], [sales#49, number_sales#50, channel#53, i_brand_id#54, i_class_id#55, null, 1], [sales#49, number_sales#50, channel#53, i_brand_id#54, null, null, 3], [sales#49, number_sales#50, channel#53, null, null, null, 7], [sales#49, number_sales#50, null, null, null, null, 15]], [sales#49, number_sales#50, channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, spark_grouping_id#95]
+
+(98) CometHashAggregate
+Input [7]: [sales#49, number_sales#50, channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, spark_grouping_id#95]
+Keys [5]: [channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, spark_grouping_id#95]
+Functions [2]: [partial_sum(sales#49), partial_sum(number_sales#50)]
+
+(99) CometExchange
+Input [8]: [channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, spark_grouping_id#95, sum#96, isEmpty#97, sum#98]
+Arguments: hashpartitioning(channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, spark_grouping_id#95, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=5]
+
+(100) CometHashAggregate
+Input [8]: [channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, spark_grouping_id#95, sum#96, isEmpty#97, sum#98]
+Keys [5]: [channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, spark_grouping_id#95]
+Functions [2]: [sum(sales#49), sum(number_sales#50)]
+
+(101) CometTakeOrderedAndProject
+Input [6]: [channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, sum(sales)#99, sum(number_sales)#100]
+Arguments: TakeOrderedAndProject(limit=100, orderBy=[channel#91 ASC NULLS FIRST,i_brand_id#92 ASC NULLS FIRST,i_class_id#93 ASC NULLS FIRST,i_category_id#94 ASC NULLS FIRST], output=[channel#91,i_brand_id#92,i_class_id#93,i_category_id#94,sum(sales)#99,sum(number_sales)#100]), [channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, sum(sales)#99, sum(number_sales)#100], 100, 0, [channel#91 ASC NULLS FIRST, i_brand_id#92 ASC NULLS FIRST, i_class_id#93 ASC NULLS FIRST, i_category_id#94 ASC NULLS FIRST], [channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, sum(sales)#99, sum(number_sales)#100]
+
+(102) CometColumnarToRow [codegen id : 1]
+Input [6]: [channel#91, i_brand_id#92, i_class_id#93, i_category_id#94, sum(sales)#99, sum(number_sales)#100]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 64 Hosting Expression = Subquery scalar-subquery#51, [id=#52]
+* CometColumnarToRow (119)
++- CometHashAggregate (118)
+ +- CometExchange (117)
+ +- CometHashAggregate (116)
+ +- CometUnion (115)
+ :- CometProject (106)
+ : +- CometBroadcastHashJoin (105)
+ : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (103)
+ : +- ReusedExchange (104)
+ :- CometProject (110)
+ : +- CometBroadcastHashJoin (109)
+ : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (107)
+ : +- ReusedExchange (108)
+ +- CometProject (114)
+ +- CometBroadcastHashJoin (113)
+ :- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (111)
+ +- ReusedExchange (112)
+
+
+(103) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [3]: [ss_quantity#101, ss_list_price#102, ss_sold_date_sk#103]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#103), dynamicpruningexpression(ss_sold_date_sk#103 IN dynamicpruning#104)]
+ReadSchema: struct
+
+(104) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#105]
+
+(105) CometBroadcastHashJoin
+Left output [3]: [ss_quantity#101, ss_list_price#102, ss_sold_date_sk#103]
+Right output [1]: [d_date_sk#105]
+Arguments: [ss_sold_date_sk#103], [d_date_sk#105], Inner, BuildRight
+
+(106) CometProject
+Input [4]: [ss_quantity#101, ss_list_price#102, ss_sold_date_sk#103, d_date_sk#105]
+Arguments: [quantity#106, list_price#107], [ss_quantity#101 AS quantity#106, ss_list_price#102 AS list_price#107]
+
+(107) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [3]: [cs_quantity#108, cs_list_price#109, cs_sold_date_sk#110]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#110), dynamicpruningexpression(cs_sold_date_sk#110 IN dynamicpruning#111)]
+ReadSchema: struct
+
+(108) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#112]
+
+(109) CometBroadcastHashJoin
+Left output [3]: [cs_quantity#108, cs_list_price#109, cs_sold_date_sk#110]
+Right output [1]: [d_date_sk#112]
+Arguments: [cs_sold_date_sk#110], [d_date_sk#112], Inner, BuildRight
+
+(110) CometProject
+Input [4]: [cs_quantity#108, cs_list_price#109, cs_sold_date_sk#110, d_date_sk#112]
+Arguments: [quantity#113, list_price#114], [cs_quantity#108 AS quantity#113, cs_list_price#109 AS list_price#114]
+
+(111) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [3]: [ws_quantity#115, ws_list_price#116, ws_sold_date_sk#117]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#117), dynamicpruningexpression(ws_sold_date_sk#117 IN dynamicpruning#118)]
+ReadSchema: struct
+
+(112) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#119]
+
+(113) CometBroadcastHashJoin
+Left output [3]: [ws_quantity#115, ws_list_price#116, ws_sold_date_sk#117]
+Right output [1]: [d_date_sk#119]
+Arguments: [ws_sold_date_sk#117], [d_date_sk#119], Inner, BuildRight
+
+(114) CometProject
+Input [4]: [ws_quantity#115, ws_list_price#116, ws_sold_date_sk#117, d_date_sk#119]
+Arguments: [quantity#120, list_price#121], [ws_quantity#115 AS quantity#120, ws_list_price#116 AS list_price#121]
+
+(115) CometUnion
+Child 0 Input [2]: [quantity#106, list_price#107]
+Child 1 Input [2]: [quantity#113, list_price#114]
+Child 2 Input [2]: [quantity#120, list_price#121]
+
+(116) CometHashAggregate
+Input [2]: [quantity#106, list_price#107]
+Keys: []
+Functions [1]: [partial_avg((cast(quantity#106 as decimal(10,0)) * list_price#107))]
+
+(117) CometExchange
+Input [2]: [sum#122, count#123]
+Arguments: SinglePartition, ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=6]
+
+(118) CometHashAggregate
+Input [2]: [sum#122, count#123]
+Keys: []
+Functions [1]: [avg((cast(quantity#106 as decimal(10,0)) * list_price#107))]
+
+(119) CometColumnarToRow [codegen id : 1]
+Input [1]: [average_sales#124]
+
+Subquery:2 Hosting operator id = 103 Hosting Expression = ss_sold_date_sk#103 IN dynamicpruning#12
+
+Subquery:3 Hosting operator id = 107 Hosting Expression = cs_sold_date_sk#110 IN dynamicpruning#12
+
+Subquery:4 Hosting operator id = 111 Hosting Expression = ws_sold_date_sk#117 IN dynamicpruning#12
+
+Subquery:5 Hosting operator id = 1 Hosting Expression = ss_sold_date_sk#4 IN dynamicpruning#5
+BroadcastExchange (124)
++- * CometColumnarToRow (123)
+ +- CometProject (122)
+ +- CometFilter (121)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (120)
+
+
+(120) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [3]: [d_date_sk#43, d_year#44, d_moy#45]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), IsNotNull(d_moy), EqualTo(d_year,2001), EqualTo(d_moy,11), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(121) CometFilter
+Input [3]: [d_date_sk#43, d_year#44, d_moy#45]
+Condition : ((((isnotnull(d_year#44) AND isnotnull(d_moy#45)) AND (d_year#44 = 2001)) AND (d_moy#45 = 11)) AND isnotnull(d_date_sk#43))
+
+(122) CometProject
+Input [3]: [d_date_sk#43, d_year#44, d_moy#45]
+Arguments: [d_date_sk#43], [d_date_sk#43]
+
+(123) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#43]
+
+(124) BroadcastExchange
+Input [1]: [d_date_sk#43]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=7]
+
+Subquery:6 Hosting operator id = 5 Hosting Expression = ss_sold_date_sk#11 IN dynamicpruning#12
+BroadcastExchange (129)
++- * CometColumnarToRow (128)
+ +- CometProject (127)
+ +- CometFilter (126)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (125)
+
+
+(125) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#26, d_year#125]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), GreaterThanOrEqual(d_year,1999), LessThanOrEqual(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(126) CometFilter
+Input [2]: [d_date_sk#26, d_year#125]
+Condition : (((isnotnull(d_year#125) AND (d_year#125 >= 1999)) AND (d_year#125 <= 2001)) AND isnotnull(d_date_sk#26))
+
+(127) CometProject
+Input [2]: [d_date_sk#26, d_year#125]
+Arguments: [d_date_sk#26], [d_date_sk#26]
+
+(128) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#26]
+
+(129) BroadcastExchange
+Input [1]: [d_date_sk#26]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=8]
+
+Subquery:7 Hosting operator id = 9 Hosting Expression = cs_sold_date_sk#18 IN dynamicpruning#12
+
+Subquery:8 Hosting operator id = 33 Hosting Expression = ws_sold_date_sk#31 IN dynamicpruning#12
+
+Subquery:9 Hosting operator id = 79 Hosting Expression = ReusedSubquery Subquery scalar-subquery#51, [id=#52]
+
+Subquery:10 Hosting operator id = 66 Hosting Expression = cs_sold_date_sk#60 IN dynamicpruning#5
+
+Subquery:11 Hosting operator id = 94 Hosting Expression = ReusedSubquery Subquery scalar-subquery#51, [id=#52]
+
+Subquery:12 Hosting operator id = 81 Hosting Expression = ws_sold_date_sk#77 IN dynamicpruning#5
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a/extended.txt
new file mode 100644
index 0000000000..4af04a7846
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a/extended.txt
@@ -0,0 +1,469 @@
+CometColumnarToRow
++- CometTakeOrderedAndProject
+ +- CometHashAggregate
+ +- CometExchange
+ +- CometHashAggregate
+ +- CometExpand
+ +- CometUnion
+ :- CometProject
+ : +- CometFilter
+ : : +- Subquery
+ : : +- CometColumnarToRow
+ : : +- CometHashAggregate
+ : : +- CometExchange
+ : : +- CometHashAggregate
+ : : +- CometUnion
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : +- ReusedSubquery
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometHashAggregate
+ : +- CometExchange
+ : +- CometHashAggregate
+ : +- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometHashAggregate
+ : : : : +- CometExchange
+ : : : : +- CometHashAggregate
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : : +- SubqueryBroadcast
+ : : : : : : +- BroadcastExchange
+ : : : : : : +- CometColumnarToRow
+ : : : : : : +- CometProject
+ : : : : : : +- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometProject
+ : : : : : : +- CometBroadcastHashJoin
+ : : : : : : :- CometFilter
+ : : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : : : +- ReusedSubquery
+ : : : : : : +- CometBroadcastExchange
+ : : : : : : +- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : : +- ReusedSubquery
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometBroadcastHashJoin
+ : : :- CometHashAggregate
+ : : : +- CometExchange
+ : : : +- CometHashAggregate
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : : +- ReusedSubquery
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ :- CometProject
+ : +- CometFilter
+ : : +- ReusedSubquery
+ : +- CometHashAggregate
+ : +- CometExchange
+ : +- CometHashAggregate
+ : +- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometHashAggregate
+ : : : : +- CometExchange
+ : : : : +- CometHashAggregate
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : : +- SubqueryBroadcast
+ : : : : : : +- BroadcastExchange
+ : : : : : : +- CometColumnarToRow
+ : : : : : : +- CometProject
+ : : : : : : +- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometProject
+ : : : : : : +- CometBroadcastHashJoin
+ : : : : : : :- CometFilter
+ : : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : : : +- ReusedSubquery
+ : : : : : : +- CometBroadcastExchange
+ : : : : : : +- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : : +- ReusedSubquery
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometBroadcastHashJoin
+ : : :- CometHashAggregate
+ : : : +- CometExchange
+ : : : +- CometHashAggregate
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : : +- ReusedSubquery
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ +- CometProject
+ +- CometFilter
+ : +- ReusedSubquery
+ +- CometHashAggregate
+ +- CometExchange
+ +- CometHashAggregate
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : +- ReusedSubquery
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometBroadcastHashJoin
+ : : :- CometHashAggregate
+ : : : +- CometExchange
+ : : : +- CometHashAggregate
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : : +- ReusedSubquery
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometBroadcastHashJoin
+ : :- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : +- CometBroadcastExchange
+ : +- CometBroadcastHashJoin
+ : :- CometHashAggregate
+ : : +- CometExchange
+ : : +- CometHashAggregate
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : +- ReusedSubquery
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : +- ReusedSubquery
+ : : +- CometBroadcastExchange
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ +- CometBroadcastExchange
+ +- CometProject
+ +- CometFilter
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+
+Comet accelerated 424 out of 458 eligible operators (92%). Final plan contains 9 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a/simplified.txt
new file mode 100644
index 0000000000..79c782f2ca
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14a/simplified.txt
@@ -0,0 +1,149 @@
+WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometTakeOrderedAndProject [channel,i_brand_id,i_class_id,i_category_id,sum(sales),sum(number_sales)]
+ CometHashAggregate [spark_grouping_id,sum,isEmpty,sum] [channel,i_brand_id,i_class_id,i_category_id,sum(sales),sum(number_sales),sum(sales),sum(number_salesL)]
+ CometExchange [channel,i_brand_id,i_class_id,i_category_id,spark_grouping_id] #1
+ CometHashAggregate [sales,number_sales] [channel,i_brand_id,i_class_id,i_category_id,spark_grouping_id,sum,isEmpty,sum]
+ CometExpand [channel,i_brand_id,i_class_id,i_category_id] [sales,number_sales,channel,i_brand_id,i_class_id,i_category_id,spark_grouping_id]
+ CometUnion [sales,number_sales,channel,i_brand_id,i_class_id,i_category_id]
+ CometProject [i_brand_id,i_class_id,i_category_id] [sales,number_sales,channel,i_brand_id,i_class_id,i_category_id]
+ CometFilter [i_brand_id,i_class_id,i_category_id,sales,number_sales]
+ Subquery #3
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometHashAggregate [sum,count] [average_sales,avg((cast(quantity as decimal(10,0)) * list_price))]
+ CometExchange #15
+ CometHashAggregate [quantity,list_price] [sum,count]
+ CometUnion [quantity,list_price]
+ CometProject [ss_quantity,ss_list_price] [quantity,list_price]
+ CometBroadcastHashJoin [ss_quantity,ss_list_price,ss_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_quantity,ss_list_price,ss_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ ReusedExchange [d_date_sk] #11
+ CometProject [cs_quantity,cs_list_price] [quantity,list_price]
+ CometBroadcastHashJoin [cs_quantity,cs_list_price,cs_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_quantity,cs_list_price,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ ReusedExchange [d_date_sk] #11
+ CometProject [ws_quantity,ws_list_price] [quantity,list_price]
+ CometBroadcastHashJoin [ws_quantity,ws_list_price,ws_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_quantity,ws_list_price,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ ReusedExchange [d_date_sk] #11
+ CometHashAggregate [sum,isEmpty,count] [i_brand_id,i_class_id,i_category_id,sales,number_sales,sum((cast(ss_quantity as decimal(10,0)) * ss_list_price)),count(1)]
+ CometExchange [i_brand_id,i_class_id,i_category_id] #2
+ CometHashAggregate [ss_quantity,ss_list_price] [i_brand_id,i_class_id,i_category_id,sum,isEmpty,count]
+ CometProject [ss_quantity,ss_list_price,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_quantity,ss_list_price,ss_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [ss_quantity,ss_list_price,ss_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk,ss_item_sk]
+ CometFilter [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #3
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year,d_moy]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year,d_moy]
+ CometBroadcastExchange [ss_item_sk] #4
+ CometProject [i_item_sk] [ss_item_sk]
+ CometBroadcastHashJoin [i_item_sk,i_brand_id,i_class_id,i_category_id,brand_id,class_id,category_id]
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastExchange [brand_id,class_id,category_id] #5
+ CometBroadcastHashJoin [brand_id,class_id,category_id,i_brand_id,i_class_id,i_category_id]
+ CometHashAggregate [brand_id,class_id,category_id]
+ CometExchange [brand_id,class_id,category_id] #6
+ CometHashAggregate [brand_id,class_id,category_id]
+ CometProject [i_brand_id,i_class_id,i_category_id] [brand_id,class_id,category_id]
+ CometBroadcastHashJoin [ss_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [ss_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_item_sk,ss_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometFilter [ss_item_sk,ss_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_item_sk,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #2
+ BroadcastExchange #7
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #8
+ CometBroadcastHashJoin [i_item_sk,i_brand_id,i_class_id,i_category_id,i_brand_id,i_class_id,i_category_id]
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastExchange [i_brand_id,i_class_id,i_category_id] #9
+ CometProject [i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [cs_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [cs_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [cs_item_sk,cs_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometFilter [cs_item_sk,cs_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_item_sk,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ CometBroadcastExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #10
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastExchange [d_date_sk] #11
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ ReusedExchange [d_date_sk] #11
+ CometBroadcastExchange [i_brand_id,i_class_id,i_category_id] #12
+ CometProject [i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ws_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [ws_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ws_item_sk,ws_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometFilter [ws_item_sk,ws_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_item_sk,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ ReusedExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #10
+ ReusedExchange [d_date_sk] #11
+ CometBroadcastExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #13
+ CometBroadcastHashJoin [i_item_sk,i_brand_id,i_class_id,i_category_id,ss_item_sk]
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ ReusedExchange [ss_item_sk] #4
+ CometBroadcastExchange [d_date_sk] #14
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year,d_moy]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year,d_moy]
+ CometProject [sales,number_sales,channel,i_brand_id,i_class_id,i_category_id]
+ CometFilter [i_brand_id,i_class_id,i_category_id,sales,number_sales]
+ ReusedSubquery [average_sales] #3
+ CometHashAggregate [sum,isEmpty,count] [i_brand_id,i_class_id,i_category_id,sales,number_sales,sum((cast(cs_quantity as decimal(10,0)) * cs_list_price)),count(1)]
+ CometExchange [i_brand_id,i_class_id,i_category_id] #16
+ CometHashAggregate [cs_quantity,cs_list_price] [i_brand_id,i_class_id,i_category_id,sum,isEmpty,count]
+ CometProject [cs_quantity,cs_list_price,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [cs_quantity,cs_list_price,cs_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [cs_quantity,cs_list_price,cs_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [cs_item_sk,cs_quantity,cs_list_price,cs_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [cs_item_sk,cs_quantity,cs_list_price,cs_sold_date_sk,ss_item_sk]
+ CometFilter [cs_item_sk,cs_quantity,cs_list_price,cs_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_item_sk,cs_quantity,cs_list_price,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ ReusedExchange [ss_item_sk] #4
+ ReusedExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #13
+ ReusedExchange [d_date_sk] #14
+ CometProject [sales,number_sales,channel,i_brand_id,i_class_id,i_category_id]
+ CometFilter [i_brand_id,i_class_id,i_category_id,sales,number_sales]
+ ReusedSubquery [average_sales] #3
+ CometHashAggregate [sum,isEmpty,count] [i_brand_id,i_class_id,i_category_id,sales,number_sales,sum((cast(ws_quantity as decimal(10,0)) * ws_list_price)),count(1)]
+ CometExchange [i_brand_id,i_class_id,i_category_id] #17
+ CometHashAggregate [ws_quantity,ws_list_price] [i_brand_id,i_class_id,i_category_id,sum,isEmpty,count]
+ CometProject [ws_quantity,ws_list_price,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ws_quantity,ws_list_price,ws_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [ws_quantity,ws_list_price,ws_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ws_item_sk,ws_quantity,ws_list_price,ws_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ws_item_sk,ws_quantity,ws_list_price,ws_sold_date_sk,ss_item_sk]
+ CometFilter [ws_item_sk,ws_quantity,ws_list_price,ws_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_item_sk,ws_quantity,ws_list_price,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #1
+ ReusedExchange [ss_item_sk] #4
+ ReusedExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #13
+ ReusedExchange [d_date_sk] #14
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_datafusion/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_datafusion/explain.txt
new file mode 100644
index 0000000000..7630396f0b
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_datafusion/explain.txt
@@ -0,0 +1,773 @@
+== Physical Plan ==
+TakeOrderedAndProject (87)
++- * BroadcastHashJoin Inner BuildRight (86)
+ :- * Filter (68)
+ : +- * HashAggregate (67)
+ : +- * CometColumnarToRow (66)
+ : +- CometColumnarExchange (65)
+ : +- * HashAggregate (64)
+ : +- * Project (63)
+ : +- * BroadcastHashJoin Inner BuildRight (62)
+ : :- * Project (60)
+ : : +- * BroadcastHashJoin Inner BuildRight (59)
+ : : :- * BroadcastHashJoin LeftSemi BuildRight (52)
+ : : : :- * Filter (3)
+ : : : : +- * ColumnarToRow (2)
+ : : : : +- Scan parquet spark_catalog.default.store_sales (1)
+ : : : +- BroadcastExchange (51)
+ : : : +- * Project (50)
+ : : : +- * BroadcastHashJoin Inner BuildRight (49)
+ : : : :- * CometColumnarToRow (6)
+ : : : : +- CometFilter (5)
+ : : : : +- CometNativeScan parquet spark_catalog.default.item (4)
+ : : : +- BroadcastExchange (48)
+ : : : +- * BroadcastHashJoin LeftSemi BuildRight (47)
+ : : : :- * CometColumnarToRow (36)
+ : : : : +- CometHashAggregate (35)
+ : : : : +- CometColumnarExchange (34)
+ : : : : +- * HashAggregate (33)
+ : : : : +- * Project (32)
+ : : : : +- * BroadcastHashJoin Inner BuildRight (31)
+ : : : : :- * Project (29)
+ : : : : : +- * BroadcastHashJoin Inner BuildRight (28)
+ : : : : : :- * Filter (9)
+ : : : : : : +- * ColumnarToRow (8)
+ : : : : : : +- Scan parquet spark_catalog.default.store_sales (7)
+ : : : : : +- BroadcastExchange (27)
+ : : : : : +- * BroadcastHashJoin LeftSemi BuildRight (26)
+ : : : : : :- * CometColumnarToRow (12)
+ : : : : : : +- CometFilter (11)
+ : : : : : : +- CometNativeScan parquet spark_catalog.default.item (10)
+ : : : : : +- BroadcastExchange (25)
+ : : : : : +- * Project (24)
+ : : : : : +- * BroadcastHashJoin Inner BuildRight (23)
+ : : : : : :- * Project (21)
+ : : : : : : +- * BroadcastHashJoin Inner BuildRight (20)
+ : : : : : : :- * Filter (15)
+ : : : : : : : +- * ColumnarToRow (14)
+ : : : : : : : +- Scan parquet spark_catalog.default.catalog_sales (13)
+ : : : : : : +- BroadcastExchange (19)
+ : : : : : : +- * CometColumnarToRow (18)
+ : : : : : : +- CometFilter (17)
+ : : : : : : +- CometNativeScan parquet spark_catalog.default.item (16)
+ : : : : : +- ReusedExchange (22)
+ : : : : +- ReusedExchange (30)
+ : : : +- BroadcastExchange (46)
+ : : : +- * Project (45)
+ : : : +- * BroadcastHashJoin Inner BuildRight (44)
+ : : : :- * Project (42)
+ : : : : +- * BroadcastHashJoin Inner BuildRight (41)
+ : : : : :- * Filter (39)
+ : : : : : +- * ColumnarToRow (38)
+ : : : : : +- Scan parquet spark_catalog.default.web_sales (37)
+ : : : : +- ReusedExchange (40)
+ : : : +- ReusedExchange (43)
+ : : +- BroadcastExchange (58)
+ : : +- * BroadcastHashJoin LeftSemi BuildRight (57)
+ : : :- * CometColumnarToRow (55)
+ : : : +- CometFilter (54)
+ : : : +- CometNativeScan parquet spark_catalog.default.item (53)
+ : : +- ReusedExchange (56)
+ : +- ReusedExchange (61)
+ +- BroadcastExchange (85)
+ +- * Filter (84)
+ +- * HashAggregate (83)
+ +- * CometColumnarToRow (82)
+ +- CometColumnarExchange (81)
+ +- * HashAggregate (80)
+ +- * Project (79)
+ +- * BroadcastHashJoin Inner BuildRight (78)
+ :- * Project (76)
+ : +- * BroadcastHashJoin Inner BuildRight (75)
+ : :- * BroadcastHashJoin LeftSemi BuildRight (73)
+ : : :- * Filter (71)
+ : : : +- * ColumnarToRow (70)
+ : : : +- Scan parquet spark_catalog.default.store_sales (69)
+ : : +- ReusedExchange (72)
+ : +- ReusedExchange (74)
+ +- ReusedExchange (77)
+
+
+(1) Scan parquet spark_catalog.default.store_sales
+Output [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#4), dynamicpruningexpression(ss_sold_date_sk#4 IN dynamicpruning#5)]
+PushedFilters: [IsNotNull(ss_item_sk)]
+ReadSchema: struct
+
+(2) ColumnarToRow [codegen id : 25]
+Input [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+
+(3) Filter [codegen id : 25]
+Input [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Condition : isnotnull(ss_item_sk#1)
+
+(4) CometNativeScan parquet spark_catalog.default.item
+Output [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_brand_id), IsNotNull(i_class_id), IsNotNull(i_category_id)]
+ReadSchema: struct
+
+(5) CometFilter
+Input [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+Condition : ((isnotnull(i_brand_id#7) AND isnotnull(i_class_id#8)) AND isnotnull(i_category_id#9))
+
+(6) CometColumnarToRow [codegen id : 11]
+Input [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+
+(7) Scan parquet spark_catalog.default.store_sales
+Output [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#11), dynamicpruningexpression(ss_sold_date_sk#11 IN dynamicpruning#12)]
+PushedFilters: [IsNotNull(ss_item_sk)]
+ReadSchema: struct
+
+(8) ColumnarToRow [codegen id : 6]
+Input [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+
+(9) Filter [codegen id : 6]
+Input [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+Condition : isnotnull(ss_item_sk#10)
+
+(10) CometNativeScan parquet spark_catalog.default.item
+Output [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk), IsNotNull(i_brand_id), IsNotNull(i_class_id), IsNotNull(i_category_id)]
+ReadSchema: struct
+
+(11) CometFilter
+Input [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Condition : (((isnotnull(i_item_sk#13) AND isnotnull(i_brand_id#14)) AND isnotnull(i_class_id#15)) AND isnotnull(i_category_id#16))
+
+(12) CometColumnarToRow [codegen id : 4]
+Input [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+
+(13) Scan parquet spark_catalog.default.catalog_sales
+Output [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#18), dynamicpruningexpression(cs_sold_date_sk#18 IN dynamicpruning#12)]
+PushedFilters: [IsNotNull(cs_item_sk)]
+ReadSchema: struct
+
+(14) ColumnarToRow [codegen id : 3]
+Input [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+
+(15) Filter [codegen id : 3]
+Input [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+Condition : isnotnull(cs_item_sk#17)
+
+(16) CometNativeScan parquet spark_catalog.default.item
+Output [4]: [i_item_sk#19, i_brand_id#20, i_class_id#21, i_category_id#22]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk)]
+ReadSchema: struct
+
+(17) CometFilter
+Input [4]: [i_item_sk#19, i_brand_id#20, i_class_id#21, i_category_id#22]
+Condition : isnotnull(i_item_sk#19)
+
+(18) CometColumnarToRow [codegen id : 1]
+Input [4]: [i_item_sk#19, i_brand_id#20, i_class_id#21, i_category_id#22]
+
+(19) BroadcastExchange
+Input [4]: [i_item_sk#19, i_brand_id#20, i_class_id#21, i_category_id#22]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=1]
+
+(20) BroadcastHashJoin [codegen id : 3]
+Left keys [1]: [cs_item_sk#17]
+Right keys [1]: [i_item_sk#19]
+Join type: Inner
+Join condition: None
+
+(21) Project [codegen id : 3]
+Output [4]: [cs_sold_date_sk#18, i_brand_id#20, i_class_id#21, i_category_id#22]
+Input [6]: [cs_item_sk#17, cs_sold_date_sk#18, i_item_sk#19, i_brand_id#20, i_class_id#21, i_category_id#22]
+
+(22) ReusedExchange [Reuses operator id: 121]
+Output [1]: [d_date_sk#23]
+
+(23) BroadcastHashJoin [codegen id : 3]
+Left keys [1]: [cs_sold_date_sk#18]
+Right keys [1]: [d_date_sk#23]
+Join type: Inner
+Join condition: None
+
+(24) Project [codegen id : 3]
+Output [3]: [i_brand_id#20, i_class_id#21, i_category_id#22]
+Input [5]: [cs_sold_date_sk#18, i_brand_id#20, i_class_id#21, i_category_id#22, d_date_sk#23]
+
+(25) BroadcastExchange
+Input [3]: [i_brand_id#20, i_class_id#21, i_category_id#22]
+Arguments: HashedRelationBroadcastMode(List(coalesce(input[0, int, true], 0), isnull(input[0, int, true]), coalesce(input[1, int, true], 0), isnull(input[1, int, true]), coalesce(input[2, int, true], 0), isnull(input[2, int, true])),false), [plan_id=2]
+
+(26) BroadcastHashJoin [codegen id : 4]
+Left keys [6]: [coalesce(i_brand_id#14, 0), isnull(i_brand_id#14), coalesce(i_class_id#15, 0), isnull(i_class_id#15), coalesce(i_category_id#16, 0), isnull(i_category_id#16)]
+Right keys [6]: [coalesce(i_brand_id#20, 0), isnull(i_brand_id#20), coalesce(i_class_id#21, 0), isnull(i_class_id#21), coalesce(i_category_id#22, 0), isnull(i_category_id#22)]
+Join type: LeftSemi
+Join condition: None
+
+(27) BroadcastExchange
+Input [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=3]
+
+(28) BroadcastHashJoin [codegen id : 6]
+Left keys [1]: [ss_item_sk#10]
+Right keys [1]: [i_item_sk#13]
+Join type: Inner
+Join condition: None
+
+(29) Project [codegen id : 6]
+Output [4]: [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16]
+Input [6]: [ss_item_sk#10, ss_sold_date_sk#11, i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+
+(30) ReusedExchange [Reuses operator id: 121]
+Output [1]: [d_date_sk#24]
+
+(31) BroadcastHashJoin [codegen id : 6]
+Left keys [1]: [ss_sold_date_sk#11]
+Right keys [1]: [d_date_sk#24]
+Join type: Inner
+Join condition: None
+
+(32) Project [codegen id : 6]
+Output [3]: [i_brand_id#14 AS brand_id#25, i_class_id#15 AS class_id#26, i_category_id#16 AS category_id#27]
+Input [5]: [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16, d_date_sk#24]
+
+(33) HashAggregate [codegen id : 6]
+Input [3]: [brand_id#25, class_id#26, category_id#27]
+Keys [3]: [brand_id#25, class_id#26, category_id#27]
+Functions: []
+Aggregate Attributes: []
+Results [3]: [brand_id#25, class_id#26, category_id#27]
+
+(34) CometColumnarExchange
+Input [3]: [brand_id#25, class_id#26, category_id#27]
+Arguments: hashpartitioning(brand_id#25, class_id#26, category_id#27, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=4]
+
+(35) CometHashAggregate
+Input [3]: [brand_id#25, class_id#26, category_id#27]
+Keys [3]: [brand_id#25, class_id#26, category_id#27]
+Functions: []
+
+(36) CometColumnarToRow [codegen id : 10]
+Input [3]: [brand_id#25, class_id#26, category_id#27]
+
+(37) Scan parquet spark_catalog.default.web_sales
+Output [2]: [ws_item_sk#28, ws_sold_date_sk#29]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#29), dynamicpruningexpression(ws_sold_date_sk#29 IN dynamicpruning#12)]
+PushedFilters: [IsNotNull(ws_item_sk)]
+ReadSchema: struct
+
+(38) ColumnarToRow [codegen id : 9]
+Input [2]: [ws_item_sk#28, ws_sold_date_sk#29]
+
+(39) Filter [codegen id : 9]
+Input [2]: [ws_item_sk#28, ws_sold_date_sk#29]
+Condition : isnotnull(ws_item_sk#28)
+
+(40) ReusedExchange [Reuses operator id: 19]
+Output [4]: [i_item_sk#30, i_brand_id#31, i_class_id#32, i_category_id#33]
+
+(41) BroadcastHashJoin [codegen id : 9]
+Left keys [1]: [ws_item_sk#28]
+Right keys [1]: [i_item_sk#30]
+Join type: Inner
+Join condition: None
+
+(42) Project [codegen id : 9]
+Output [4]: [ws_sold_date_sk#29, i_brand_id#31, i_class_id#32, i_category_id#33]
+Input [6]: [ws_item_sk#28, ws_sold_date_sk#29, i_item_sk#30, i_brand_id#31, i_class_id#32, i_category_id#33]
+
+(43) ReusedExchange [Reuses operator id: 121]
+Output [1]: [d_date_sk#34]
+
+(44) BroadcastHashJoin [codegen id : 9]
+Left keys [1]: [ws_sold_date_sk#29]
+Right keys [1]: [d_date_sk#34]
+Join type: Inner
+Join condition: None
+
+(45) Project [codegen id : 9]
+Output [3]: [i_brand_id#31, i_class_id#32, i_category_id#33]
+Input [5]: [ws_sold_date_sk#29, i_brand_id#31, i_class_id#32, i_category_id#33, d_date_sk#34]
+
+(46) BroadcastExchange
+Input [3]: [i_brand_id#31, i_class_id#32, i_category_id#33]
+Arguments: HashedRelationBroadcastMode(List(coalesce(input[0, int, true], 0), isnull(input[0, int, true]), coalesce(input[1, int, true], 0), isnull(input[1, int, true]), coalesce(input[2, int, true], 0), isnull(input[2, int, true])),false), [plan_id=5]
+
+(47) BroadcastHashJoin [codegen id : 10]
+Left keys [6]: [coalesce(brand_id#25, 0), isnull(brand_id#25), coalesce(class_id#26, 0), isnull(class_id#26), coalesce(category_id#27, 0), isnull(category_id#27)]
+Right keys [6]: [coalesce(i_brand_id#31, 0), isnull(i_brand_id#31), coalesce(i_class_id#32, 0), isnull(i_class_id#32), coalesce(i_category_id#33, 0), isnull(i_category_id#33)]
+Join type: LeftSemi
+Join condition: None
+
+(48) BroadcastExchange
+Input [3]: [brand_id#25, class_id#26, category_id#27]
+Arguments: HashedRelationBroadcastMode(List(input[0, int, true], input[1, int, true], input[2, int, true]),false), [plan_id=6]
+
+(49) BroadcastHashJoin [codegen id : 11]
+Left keys [3]: [i_brand_id#7, i_class_id#8, i_category_id#9]
+Right keys [3]: [brand_id#25, class_id#26, category_id#27]
+Join type: Inner
+Join condition: None
+
+(50) Project [codegen id : 11]
+Output [1]: [i_item_sk#6 AS ss_item_sk#35]
+Input [7]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9, brand_id#25, class_id#26, category_id#27]
+
+(51) BroadcastExchange
+Input [1]: [ss_item_sk#35]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=7]
+
+(52) BroadcastHashJoin [codegen id : 25]
+Left keys [1]: [ss_item_sk#1]
+Right keys [1]: [ss_item_sk#35]
+Join type: LeftSemi
+Join condition: None
+
+(53) CometNativeScan parquet spark_catalog.default.item
+Output [4]: [i_item_sk#36, i_brand_id#37, i_class_id#38, i_category_id#39]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk), IsNotNull(i_brand_id), IsNotNull(i_class_id), IsNotNull(i_category_id)]
+ReadSchema: struct
+
+(54) CometFilter
+Input [4]: [i_item_sk#36, i_brand_id#37, i_class_id#38, i_category_id#39]
+Condition : (((isnotnull(i_item_sk#36) AND isnotnull(i_brand_id#37)) AND isnotnull(i_class_id#38)) AND isnotnull(i_category_id#39))
+
+(55) CometColumnarToRow [codegen id : 23]
+Input [4]: [i_item_sk#36, i_brand_id#37, i_class_id#38, i_category_id#39]
+
+(56) ReusedExchange [Reuses operator id: 51]
+Output [1]: [ss_item_sk#35]
+
+(57) BroadcastHashJoin [codegen id : 23]
+Left keys [1]: [i_item_sk#36]
+Right keys [1]: [ss_item_sk#35]
+Join type: LeftSemi
+Join condition: None
+
+(58) BroadcastExchange
+Input [4]: [i_item_sk#36, i_brand_id#37, i_class_id#38, i_category_id#39]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=8]
+
+(59) BroadcastHashJoin [codegen id : 25]
+Left keys [1]: [ss_item_sk#1]
+Right keys [1]: [i_item_sk#36]
+Join type: Inner
+Join condition: None
+
+(60) Project [codegen id : 25]
+Output [6]: [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#37, i_class_id#38, i_category_id#39]
+Input [8]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_item_sk#36, i_brand_id#37, i_class_id#38, i_category_id#39]
+
+(61) ReusedExchange [Reuses operator id: 112]
+Output [1]: [d_date_sk#40]
+
+(62) BroadcastHashJoin [codegen id : 25]
+Left keys [1]: [ss_sold_date_sk#4]
+Right keys [1]: [d_date_sk#40]
+Join type: Inner
+Join condition: None
+
+(63) Project [codegen id : 25]
+Output [5]: [ss_quantity#2, ss_list_price#3, i_brand_id#37, i_class_id#38, i_category_id#39]
+Input [7]: [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#37, i_class_id#38, i_category_id#39, d_date_sk#40]
+
+(64) HashAggregate [codegen id : 25]
+Input [5]: [ss_quantity#2, ss_list_price#3, i_brand_id#37, i_class_id#38, i_category_id#39]
+Keys [3]: [i_brand_id#37, i_class_id#38, i_category_id#39]
+Functions [2]: [partial_sum((cast(ss_quantity#2 as decimal(10,0)) * ss_list_price#3)), partial_count(1)]
+Aggregate Attributes [3]: [sum#41, isEmpty#42, count#43]
+Results [6]: [i_brand_id#37, i_class_id#38, i_category_id#39, sum#44, isEmpty#45, count#46]
+
+(65) CometColumnarExchange
+Input [6]: [i_brand_id#37, i_class_id#38, i_category_id#39, sum#44, isEmpty#45, count#46]
+Arguments: hashpartitioning(i_brand_id#37, i_class_id#38, i_category_id#39, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=9]
+
+(66) CometColumnarToRow [codegen id : 52]
+Input [6]: [i_brand_id#37, i_class_id#38, i_category_id#39, sum#44, isEmpty#45, count#46]
+
+(67) HashAggregate [codegen id : 52]
+Input [6]: [i_brand_id#37, i_class_id#38, i_category_id#39, sum#44, isEmpty#45, count#46]
+Keys [3]: [i_brand_id#37, i_class_id#38, i_category_id#39]
+Functions [2]: [sum((cast(ss_quantity#2 as decimal(10,0)) * ss_list_price#3)), count(1)]
+Aggregate Attributes [2]: [sum((cast(ss_quantity#2 as decimal(10,0)) * ss_list_price#3))#47, count(1)#48]
+Results [6]: [store AS channel#49, i_brand_id#37, i_class_id#38, i_category_id#39, sum((cast(ss_quantity#2 as decimal(10,0)) * ss_list_price#3))#47 AS sales#50, count(1)#48 AS number_sales#51]
+
+(68) Filter [codegen id : 52]
+Input [6]: [channel#49, i_brand_id#37, i_class_id#38, i_category_id#39, sales#50, number_sales#51]
+Condition : (isnotnull(sales#50) AND (cast(sales#50 as decimal(32,6)) > cast(Subquery scalar-subquery#52, [id=#53] as decimal(32,6))))
+
+(69) Scan parquet spark_catalog.default.store_sales
+Output [4]: [ss_item_sk#54, ss_quantity#55, ss_list_price#56, ss_sold_date_sk#57]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#57), dynamicpruningexpression(ss_sold_date_sk#57 IN dynamicpruning#58)]
+PushedFilters: [IsNotNull(ss_item_sk)]
+ReadSchema: struct
+
+(70) ColumnarToRow [codegen id : 50]
+Input [4]: [ss_item_sk#54, ss_quantity#55, ss_list_price#56, ss_sold_date_sk#57]
+
+(71) Filter [codegen id : 50]
+Input [4]: [ss_item_sk#54, ss_quantity#55, ss_list_price#56, ss_sold_date_sk#57]
+Condition : isnotnull(ss_item_sk#54)
+
+(72) ReusedExchange [Reuses operator id: 51]
+Output [1]: [ss_item_sk#59]
+
+(73) BroadcastHashJoin [codegen id : 50]
+Left keys [1]: [ss_item_sk#54]
+Right keys [1]: [ss_item_sk#59]
+Join type: LeftSemi
+Join condition: None
+
+(74) ReusedExchange [Reuses operator id: 58]
+Output [4]: [i_item_sk#60, i_brand_id#61, i_class_id#62, i_category_id#63]
+
+(75) BroadcastHashJoin [codegen id : 50]
+Left keys [1]: [ss_item_sk#54]
+Right keys [1]: [i_item_sk#60]
+Join type: Inner
+Join condition: None
+
+(76) Project [codegen id : 50]
+Output [6]: [ss_quantity#55, ss_list_price#56, ss_sold_date_sk#57, i_brand_id#61, i_class_id#62, i_category_id#63]
+Input [8]: [ss_item_sk#54, ss_quantity#55, ss_list_price#56, ss_sold_date_sk#57, i_item_sk#60, i_brand_id#61, i_class_id#62, i_category_id#63]
+
+(77) ReusedExchange [Reuses operator id: 126]
+Output [1]: [d_date_sk#64]
+
+(78) BroadcastHashJoin [codegen id : 50]
+Left keys [1]: [ss_sold_date_sk#57]
+Right keys [1]: [d_date_sk#64]
+Join type: Inner
+Join condition: None
+
+(79) Project [codegen id : 50]
+Output [5]: [ss_quantity#55, ss_list_price#56, i_brand_id#61, i_class_id#62, i_category_id#63]
+Input [7]: [ss_quantity#55, ss_list_price#56, ss_sold_date_sk#57, i_brand_id#61, i_class_id#62, i_category_id#63, d_date_sk#64]
+
+(80) HashAggregate [codegen id : 50]
+Input [5]: [ss_quantity#55, ss_list_price#56, i_brand_id#61, i_class_id#62, i_category_id#63]
+Keys [3]: [i_brand_id#61, i_class_id#62, i_category_id#63]
+Functions [2]: [partial_sum((cast(ss_quantity#55 as decimal(10,0)) * ss_list_price#56)), partial_count(1)]
+Aggregate Attributes [3]: [sum#65, isEmpty#66, count#67]
+Results [6]: [i_brand_id#61, i_class_id#62, i_category_id#63, sum#68, isEmpty#69, count#70]
+
+(81) CometColumnarExchange
+Input [6]: [i_brand_id#61, i_class_id#62, i_category_id#63, sum#68, isEmpty#69, count#70]
+Arguments: hashpartitioning(i_brand_id#61, i_class_id#62, i_category_id#63, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=10]
+
+(82) CometColumnarToRow [codegen id : 51]
+Input [6]: [i_brand_id#61, i_class_id#62, i_category_id#63, sum#68, isEmpty#69, count#70]
+
+(83) HashAggregate [codegen id : 51]
+Input [6]: [i_brand_id#61, i_class_id#62, i_category_id#63, sum#68, isEmpty#69, count#70]
+Keys [3]: [i_brand_id#61, i_class_id#62, i_category_id#63]
+Functions [2]: [sum((cast(ss_quantity#55 as decimal(10,0)) * ss_list_price#56)), count(1)]
+Aggregate Attributes [2]: [sum((cast(ss_quantity#55 as decimal(10,0)) * ss_list_price#56))#71, count(1)#72]
+Results [6]: [store AS channel#73, i_brand_id#61, i_class_id#62, i_category_id#63, sum((cast(ss_quantity#55 as decimal(10,0)) * ss_list_price#56))#71 AS sales#74, count(1)#72 AS number_sales#75]
+
+(84) Filter [codegen id : 51]
+Input [6]: [channel#73, i_brand_id#61, i_class_id#62, i_category_id#63, sales#74, number_sales#75]
+Condition : (isnotnull(sales#74) AND (cast(sales#74 as decimal(32,6)) > cast(ReusedSubquery Subquery scalar-subquery#52, [id=#53] as decimal(32,6))))
+
+(85) BroadcastExchange
+Input [6]: [channel#73, i_brand_id#61, i_class_id#62, i_category_id#63, sales#74, number_sales#75]
+Arguments: HashedRelationBroadcastMode(List(input[1, int, true], input[2, int, true], input[3, int, true]),false), [plan_id=11]
+
+(86) BroadcastHashJoin [codegen id : 52]
+Left keys [3]: [i_brand_id#37, i_class_id#38, i_category_id#39]
+Right keys [3]: [i_brand_id#61, i_class_id#62, i_category_id#63]
+Join type: Inner
+Join condition: None
+
+(87) TakeOrderedAndProject
+Input [12]: [channel#49, i_brand_id#37, i_class_id#38, i_category_id#39, sales#50, number_sales#51, channel#73, i_brand_id#61, i_class_id#62, i_category_id#63, sales#74, number_sales#75]
+Arguments: 100, [i_brand_id#37 ASC NULLS FIRST, i_class_id#38 ASC NULLS FIRST, i_category_id#39 ASC NULLS FIRST], [channel#49, i_brand_id#37, i_class_id#38, i_category_id#39, sales#50, number_sales#51, channel#73, i_brand_id#61, i_class_id#62, i_category_id#63, sales#74, number_sales#75]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 68 Hosting Expression = Subquery scalar-subquery#52, [id=#53]
+* HashAggregate (107)
++- * CometColumnarToRow (106)
+ +- CometColumnarExchange (105)
+ +- * HashAggregate (104)
+ +- Union (103)
+ :- * Project (92)
+ : +- * BroadcastHashJoin Inner BuildRight (91)
+ : :- * ColumnarToRow (89)
+ : : +- Scan parquet spark_catalog.default.store_sales (88)
+ : +- ReusedExchange (90)
+ :- * Project (97)
+ : +- * BroadcastHashJoin Inner BuildRight (96)
+ : :- * ColumnarToRow (94)
+ : : +- Scan parquet spark_catalog.default.catalog_sales (93)
+ : +- ReusedExchange (95)
+ +- * Project (102)
+ +- * BroadcastHashJoin Inner BuildRight (101)
+ :- * ColumnarToRow (99)
+ : +- Scan parquet spark_catalog.default.web_sales (98)
+ +- ReusedExchange (100)
+
+
+(88) Scan parquet spark_catalog.default.store_sales
+Output [3]: [ss_quantity#76, ss_list_price#77, ss_sold_date_sk#78]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#78), dynamicpruningexpression(ss_sold_date_sk#78 IN dynamicpruning#12)]
+ReadSchema: struct
+
+(89) ColumnarToRow [codegen id : 2]
+Input [3]: [ss_quantity#76, ss_list_price#77, ss_sold_date_sk#78]
+
+(90) ReusedExchange [Reuses operator id: 121]
+Output [1]: [d_date_sk#79]
+
+(91) BroadcastHashJoin [codegen id : 2]
+Left keys [1]: [ss_sold_date_sk#78]
+Right keys [1]: [d_date_sk#79]
+Join type: Inner
+Join condition: None
+
+(92) Project [codegen id : 2]
+Output [2]: [ss_quantity#76 AS quantity#80, ss_list_price#77 AS list_price#81]
+Input [4]: [ss_quantity#76, ss_list_price#77, ss_sold_date_sk#78, d_date_sk#79]
+
+(93) Scan parquet spark_catalog.default.catalog_sales
+Output [3]: [cs_quantity#82, cs_list_price#83, cs_sold_date_sk#84]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#84), dynamicpruningexpression(cs_sold_date_sk#84 IN dynamicpruning#12)]
+ReadSchema: struct
+
+(94) ColumnarToRow [codegen id : 4]
+Input [3]: [cs_quantity#82, cs_list_price#83, cs_sold_date_sk#84]
+
+(95) ReusedExchange [Reuses operator id: 121]
+Output [1]: [d_date_sk#85]
+
+(96) BroadcastHashJoin [codegen id : 4]
+Left keys [1]: [cs_sold_date_sk#84]
+Right keys [1]: [d_date_sk#85]
+Join type: Inner
+Join condition: None
+
+(97) Project [codegen id : 4]
+Output [2]: [cs_quantity#82 AS quantity#86, cs_list_price#83 AS list_price#87]
+Input [4]: [cs_quantity#82, cs_list_price#83, cs_sold_date_sk#84, d_date_sk#85]
+
+(98) Scan parquet spark_catalog.default.web_sales
+Output [3]: [ws_quantity#88, ws_list_price#89, ws_sold_date_sk#90]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#90), dynamicpruningexpression(ws_sold_date_sk#90 IN dynamicpruning#12)]
+ReadSchema: struct
+
+(99) ColumnarToRow [codegen id : 6]
+Input [3]: [ws_quantity#88, ws_list_price#89, ws_sold_date_sk#90]
+
+(100) ReusedExchange [Reuses operator id: 121]
+Output [1]: [d_date_sk#91]
+
+(101) BroadcastHashJoin [codegen id : 6]
+Left keys [1]: [ws_sold_date_sk#90]
+Right keys [1]: [d_date_sk#91]
+Join type: Inner
+Join condition: None
+
+(102) Project [codegen id : 6]
+Output [2]: [ws_quantity#88 AS quantity#92, ws_list_price#89 AS list_price#93]
+Input [4]: [ws_quantity#88, ws_list_price#89, ws_sold_date_sk#90, d_date_sk#91]
+
+(103) Union
+
+(104) HashAggregate [codegen id : 7]
+Input [2]: [quantity#80, list_price#81]
+Keys: []
+Functions [1]: [partial_avg((cast(quantity#80 as decimal(10,0)) * list_price#81))]
+Aggregate Attributes [2]: [sum#94, count#95]
+Results [2]: [sum#96, count#97]
+
+(105) CometColumnarExchange
+Input [2]: [sum#96, count#97]
+Arguments: SinglePartition, ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=12]
+
+(106) CometColumnarToRow [codegen id : 8]
+Input [2]: [sum#96, count#97]
+
+(107) HashAggregate [codegen id : 8]
+Input [2]: [sum#96, count#97]
+Keys: []
+Functions [1]: [avg((cast(quantity#80 as decimal(10,0)) * list_price#81))]
+Aggregate Attributes [1]: [avg((cast(quantity#80 as decimal(10,0)) * list_price#81))#98]
+Results [1]: [avg((cast(quantity#80 as decimal(10,0)) * list_price#81))#98 AS average_sales#99]
+
+Subquery:2 Hosting operator id = 88 Hosting Expression = ss_sold_date_sk#78 IN dynamicpruning#12
+
+Subquery:3 Hosting operator id = 93 Hosting Expression = cs_sold_date_sk#84 IN dynamicpruning#12
+
+Subquery:4 Hosting operator id = 98 Hosting Expression = ws_sold_date_sk#90 IN dynamicpruning#12
+
+Subquery:5 Hosting operator id = 1 Hosting Expression = ss_sold_date_sk#4 IN dynamicpruning#5
+BroadcastExchange (112)
++- * CometColumnarToRow (111)
+ +- CometProject (110)
+ +- CometFilter (109)
+ +- CometNativeScan parquet spark_catalog.default.date_dim (108)
+
+
+(108) CometNativeScan parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#40, d_week_seq#100]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_week_seq), EqualTo(d_week_seq,ScalarSubquery#101), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(109) CometFilter
+Input [2]: [d_date_sk#40, d_week_seq#100]
+Condition : ((isnotnull(d_week_seq#100) AND (d_week_seq#100 = ReusedSubquery Subquery scalar-subquery#101, [id=#102])) AND isnotnull(d_date_sk#40))
+
+(110) CometProject
+Input [2]: [d_date_sk#40, d_week_seq#100]
+Arguments: [d_date_sk#40], [d_date_sk#40]
+
+(111) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#40]
+
+(112) BroadcastExchange
+Input [1]: [d_date_sk#40]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=13]
+
+Subquery:6 Hosting operator id = 109 Hosting Expression = ReusedSubquery Subquery scalar-subquery#101, [id=#102]
+
+Subquery:7 Hosting operator id = 108 Hosting Expression = Subquery scalar-subquery#101, [id=#102]
+* CometColumnarToRow (116)
++- CometProject (115)
+ +- CometFilter (114)
+ +- CometNativeScan parquet spark_catalog.default.date_dim (113)
+
+
+(113) CometNativeScan parquet spark_catalog.default.date_dim
+Output [4]: [d_week_seq#103, d_year#104, d_moy#105, d_dom#106]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), IsNotNull(d_moy), IsNotNull(d_dom), EqualTo(d_year,2000), EqualTo(d_moy,12), EqualTo(d_dom,11)]
+ReadSchema: struct
+
+(114) CometFilter
+Input [4]: [d_week_seq#103, d_year#104, d_moy#105, d_dom#106]
+Condition : (((((isnotnull(d_year#104) AND isnotnull(d_moy#105)) AND isnotnull(d_dom#106)) AND (d_year#104 = 2000)) AND (d_moy#105 = 12)) AND (d_dom#106 = 11))
+
+(115) CometProject
+Input [4]: [d_week_seq#103, d_year#104, d_moy#105, d_dom#106]
+Arguments: [d_week_seq#103], [d_week_seq#103]
+
+(116) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_week_seq#103]
+
+Subquery:8 Hosting operator id = 7 Hosting Expression = ss_sold_date_sk#11 IN dynamicpruning#12
+BroadcastExchange (121)
++- * CometColumnarToRow (120)
+ +- CometProject (119)
+ +- CometFilter (118)
+ +- CometNativeScan parquet spark_catalog.default.date_dim (117)
+
+
+(117) CometNativeScan parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#24, d_year#107]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), GreaterThanOrEqual(d_year,1999), LessThanOrEqual(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(118) CometFilter
+Input [2]: [d_date_sk#24, d_year#107]
+Condition : (((isnotnull(d_year#107) AND (d_year#107 >= 1999)) AND (d_year#107 <= 2001)) AND isnotnull(d_date_sk#24))
+
+(119) CometProject
+Input [2]: [d_date_sk#24, d_year#107]
+Arguments: [d_date_sk#24], [d_date_sk#24]
+
+(120) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#24]
+
+(121) BroadcastExchange
+Input [1]: [d_date_sk#24]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=14]
+
+Subquery:9 Hosting operator id = 13 Hosting Expression = cs_sold_date_sk#18 IN dynamicpruning#12
+
+Subquery:10 Hosting operator id = 37 Hosting Expression = ws_sold_date_sk#29 IN dynamicpruning#12
+
+Subquery:11 Hosting operator id = 84 Hosting Expression = ReusedSubquery Subquery scalar-subquery#52, [id=#53]
+
+Subquery:12 Hosting operator id = 69 Hosting Expression = ss_sold_date_sk#57 IN dynamicpruning#58
+BroadcastExchange (126)
++- * CometColumnarToRow (125)
+ +- CometProject (124)
+ +- CometFilter (123)
+ +- CometNativeScan parquet spark_catalog.default.date_dim (122)
+
+
+(122) CometNativeScan parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#64, d_week_seq#108]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_week_seq), EqualTo(d_week_seq,ScalarSubquery#109), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(123) CometFilter
+Input [2]: [d_date_sk#64, d_week_seq#108]
+Condition : ((isnotnull(d_week_seq#108) AND (d_week_seq#108 = ReusedSubquery Subquery scalar-subquery#109, [id=#110])) AND isnotnull(d_date_sk#64))
+
+(124) CometProject
+Input [2]: [d_date_sk#64, d_week_seq#108]
+Arguments: [d_date_sk#64], [d_date_sk#64]
+
+(125) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#64]
+
+(126) BroadcastExchange
+Input [1]: [d_date_sk#64]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=15]
+
+Subquery:13 Hosting operator id = 123 Hosting Expression = ReusedSubquery Subquery scalar-subquery#109, [id=#110]
+
+Subquery:14 Hosting operator id = 122 Hosting Expression = Subquery scalar-subquery#109, [id=#110]
+* CometColumnarToRow (130)
++- CometProject (129)
+ +- CometFilter (128)
+ +- CometNativeScan parquet spark_catalog.default.date_dim (127)
+
+
+(127) CometNativeScan parquet spark_catalog.default.date_dim
+Output [4]: [d_week_seq#111, d_year#112, d_moy#113, d_dom#114]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), IsNotNull(d_moy), IsNotNull(d_dom), EqualTo(d_year,1999), EqualTo(d_moy,12), EqualTo(d_dom,11)]
+ReadSchema: struct
+
+(128) CometFilter
+Input [4]: [d_week_seq#111, d_year#112, d_moy#113, d_dom#114]
+Condition : (((((isnotnull(d_year#112) AND isnotnull(d_moy#113)) AND isnotnull(d_dom#114)) AND (d_year#112 = 1999)) AND (d_moy#113 = 12)) AND (d_dom#114 = 11))
+
+(129) CometProject
+Input [4]: [d_week_seq#111, d_year#112, d_moy#113, d_dom#114]
+Arguments: [d_week_seq#111], [d_week_seq#111]
+
+(130) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_week_seq#111]
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_datafusion/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_datafusion/extended.txt
new file mode 100644
index 0000000000..e44d85bdc2
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_datafusion/extended.txt
@@ -0,0 +1,408 @@
+TakeOrderedAndProject
++- BroadcastHashJoin
+ :- Filter
+ : : +- Subquery
+ : : +- HashAggregate
+ : : +- CometColumnarToRow
+ : : +- CometColumnarExchange
+ : : +- HashAggregate
+ : : +- Union
+ : : :- Project
+ : : : +- BroadcastHashJoin
+ : : : :- ColumnarToRow
+ : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : +- ReusedSubquery
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : :- Project
+ : : : +- BroadcastHashJoin
+ : : : :- ColumnarToRow
+ : : : : +- Scan parquet spark_catalog.default.catalog_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : +- ReusedSubquery
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- Project
+ : : +- BroadcastHashJoin
+ : : :- ColumnarToRow
+ : : : +- Scan parquet spark_catalog.default.web_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : +- ReusedSubquery
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : +- HashAggregate
+ : +- CometColumnarToRow
+ : +- CometColumnarExchange
+ : +- HashAggregate
+ : +- Project
+ : +- BroadcastHashJoin
+ : :- Project
+ : : +- BroadcastHashJoin
+ : : :- BroadcastHashJoin
+ : : : :- Filter
+ : : : : +- ColumnarToRow
+ : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : : +- ReusedSubquery
+ : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : : +- Subquery
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- Project
+ : : : +- BroadcastHashJoin
+ : : : :- CometColumnarToRow
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : +- BroadcastExchange
+ : : : +- BroadcastHashJoin
+ : : : :- CometColumnarToRow
+ : : : : +- CometHashAggregate
+ : : : : +- CometColumnarExchange
+ : : : : +- HashAggregate
+ : : : : +- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Project
+ : : : : : +- BroadcastHashJoin
+ : : : : : :- Filter
+ : : : : : : +- ColumnarToRow
+ : : : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : : +- SubqueryBroadcast
+ : : : : : : +- BroadcastExchange
+ : : : : : : +- CometColumnarToRow
+ : : : : : : +- CometProject
+ : : : : : : +- CometFilter
+ : : : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : : : +- BroadcastExchange
+ : : : : : +- BroadcastHashJoin
+ : : : : : :- CometColumnarToRow
+ : : : : : : +- CometFilter
+ : : : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : : : +- BroadcastExchange
+ : : : : : +- Project
+ : : : : : +- BroadcastHashJoin
+ : : : : : :- Project
+ : : : : : : +- BroadcastHashJoin
+ : : : : : : :- Filter
+ : : : : : : : +- ColumnarToRow
+ : : : : : : : +- Scan parquet spark_catalog.default.catalog_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : : : +- ReusedSubquery
+ : : : : : : +- BroadcastExchange
+ : : : : : : +- CometColumnarToRow
+ : : : : : : +- CometFilter
+ : : : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Filter
+ : : : : : +- ColumnarToRow
+ : : : : : +- Scan parquet spark_catalog.default.web_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : +- ReusedSubquery
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- BroadcastHashJoin
+ : : :- CometColumnarToRow
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : +- BroadcastExchange
+ : : +- Project
+ : : +- BroadcastHashJoin
+ : : :- CometColumnarToRow
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : +- BroadcastExchange
+ : : +- BroadcastHashJoin
+ : : :- CometColumnarToRow
+ : : : +- CometHashAggregate
+ : : : +- CometColumnarExchange
+ : : : +- HashAggregate
+ : : : +- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Filter
+ : : : : : +- ColumnarToRow
+ : : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : : +- BroadcastExchange
+ : : : : +- BroadcastHashJoin
+ : : : : :- CometColumnarToRow
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : : +- BroadcastExchange
+ : : : : +- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Project
+ : : : : : +- BroadcastHashJoin
+ : : : : : :- Filter
+ : : : : : : +- ColumnarToRow
+ : : : : : : +- Scan parquet spark_catalog.default.catalog_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : : +- ReusedSubquery
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- Project
+ : : +- BroadcastHashJoin
+ : : :- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Filter
+ : : : : +- ColumnarToRow
+ : : : : +- Scan parquet spark_catalog.default.web_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : +- ReusedSubquery
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : +- BroadcastExchange
+ : +- CometColumnarToRow
+ : +- CometProject
+ : +- CometFilter
+ : : +- ReusedSubquery
+ : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : +- Subquery
+ : +- CometColumnarToRow
+ : +- CometProject
+ : +- CometFilter
+ : +- CometNativeScan parquet spark_catalog.default.date_dim
+ +- BroadcastExchange
+ +- Filter
+ : +- ReusedSubquery
+ +- HashAggregate
+ +- CometColumnarToRow
+ +- CometColumnarExchange
+ +- HashAggregate
+ +- Project
+ +- BroadcastHashJoin
+ :- Project
+ : +- BroadcastHashJoin
+ : :- BroadcastHashJoin
+ : : :- Filter
+ : : : +- ColumnarToRow
+ : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : +- SubqueryBroadcast
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : : +- ReusedSubquery
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : +- Subquery
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- Project
+ : : +- BroadcastHashJoin
+ : : :- CometColumnarToRow
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : +- BroadcastExchange
+ : : +- BroadcastHashJoin
+ : : :- CometColumnarToRow
+ : : : +- CometHashAggregate
+ : : : +- CometColumnarExchange
+ : : : +- HashAggregate
+ : : : +- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Filter
+ : : : : : +- ColumnarToRow
+ : : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : : +- BroadcastExchange
+ : : : : +- BroadcastHashJoin
+ : : : : :- CometColumnarToRow
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : : +- BroadcastExchange
+ : : : : +- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Project
+ : : : : : +- BroadcastHashJoin
+ : : : : : :- Filter
+ : : : : : : +- ColumnarToRow
+ : : : : : : +- Scan parquet spark_catalog.default.catalog_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : : +- ReusedSubquery
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- Project
+ : : +- BroadcastHashJoin
+ : : :- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Filter
+ : : : : +- ColumnarToRow
+ : : : : +- Scan parquet spark_catalog.default.web_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : +- ReusedSubquery
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : +- BroadcastExchange
+ : +- BroadcastHashJoin
+ : :- CometColumnarToRow
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.item
+ : +- BroadcastExchange
+ : +- Project
+ : +- BroadcastHashJoin
+ : :- CometColumnarToRow
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.item
+ : +- BroadcastExchange
+ : +- BroadcastHashJoin
+ : :- CometColumnarToRow
+ : : +- CometHashAggregate
+ : : +- CometColumnarExchange
+ : : +- HashAggregate
+ : : +- Project
+ : : +- BroadcastHashJoin
+ : : :- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Filter
+ : : : : +- ColumnarToRow
+ : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- BroadcastHashJoin
+ : : : :- CometColumnarToRow
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : +- BroadcastExchange
+ : : : +- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Filter
+ : : : : : +- ColumnarToRow
+ : : : : : +- Scan parquet spark_catalog.default.catalog_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : +- ReusedSubquery
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.item
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : +- BroadcastExchange
+ : +- Project
+ : +- BroadcastHashJoin
+ : :- Project
+ : : +- BroadcastHashJoin
+ : : :- Filter
+ : : : +- ColumnarToRow
+ : : : +- Scan parquet spark_catalog.default.web_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : +- ReusedSubquery
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.item
+ : +- BroadcastExchange
+ : +- CometColumnarToRow
+ : +- CometProject
+ : +- CometFilter
+ : +- CometNativeScan parquet spark_catalog.default.date_dim
+ +- BroadcastExchange
+ +- CometColumnarToRow
+ +- CometProject
+ +- CometFilter
+ : +- ReusedSubquery
+ +- CometNativeScan parquet spark_catalog.default.date_dim
+ +- Subquery
+ +- CometColumnarToRow
+ +- CometProject
+ +- CometFilter
+ +- CometNativeScan parquet spark_catalog.default.date_dim
+
+Comet accelerated 128 out of 337 eligible operators (37%). Final plan contains 69 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_datafusion/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_datafusion/simplified.txt
new file mode 100644
index 0000000000..cc02a716ea
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_datafusion/simplified.txt
@@ -0,0 +1,208 @@
+TakeOrderedAndProject [i_brand_id,i_class_id,i_category_id,channel,sales,number_sales,channel,i_brand_id,i_class_id,i_category_id,sales,number_sales]
+ WholeStageCodegen (52)
+ BroadcastHashJoin [i_brand_id,i_class_id,i_category_id,i_brand_id,i_class_id,i_category_id]
+ Filter [sales]
+ Subquery #4
+ WholeStageCodegen (8)
+ HashAggregate [sum,count] [avg((cast(quantity as decimal(10,0)) * list_price)),average_sales,sum,count]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange #12
+ WholeStageCodegen (7)
+ HashAggregate [quantity,list_price] [sum,count,sum,count]
+ InputAdapter
+ Union
+ WholeStageCodegen (2)
+ Project [ss_quantity,ss_list_price]
+ BroadcastHashJoin [ss_sold_date_sk,d_date_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.store_sales [ss_quantity,ss_list_price,ss_sold_date_sk]
+ ReusedSubquery [d_date_sk] #3
+ InputAdapter
+ ReusedExchange [d_date_sk] #6
+ WholeStageCodegen (4)
+ Project [cs_quantity,cs_list_price]
+ BroadcastHashJoin [cs_sold_date_sk,d_date_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.catalog_sales [cs_quantity,cs_list_price,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #3
+ InputAdapter
+ ReusedExchange [d_date_sk] #6
+ WholeStageCodegen (6)
+ Project [ws_quantity,ws_list_price]
+ BroadcastHashJoin [ws_sold_date_sk,d_date_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.web_sales [ws_quantity,ws_list_price,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #3
+ InputAdapter
+ ReusedExchange [d_date_sk] #6
+ HashAggregate [i_brand_id,i_class_id,i_category_id,sum,isEmpty,count] [sum((cast(ss_quantity as decimal(10,0)) * ss_list_price)),count(1),channel,sales,number_sales,sum,isEmpty,count]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [i_brand_id,i_class_id,i_category_id] #1
+ WholeStageCodegen (25)
+ HashAggregate [i_brand_id,i_class_id,i_category_id,ss_quantity,ss_list_price] [sum,isEmpty,count,sum,isEmpty,count]
+ Project [ss_quantity,ss_list_price,i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [ss_sold_date_sk,d_date_sk]
+ Project [ss_quantity,ss_list_price,ss_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [ss_item_sk,i_item_sk]
+ BroadcastHashJoin [ss_item_sk,ss_item_sk]
+ Filter [ss_item_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.store_sales [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #2
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_week_seq]
+ ReusedSubquery [d_week_seq] #2
+ CometNativeScan parquet spark_catalog.default.date_dim [d_date_sk,d_week_seq]
+ Subquery #2
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_week_seq]
+ CometFilter [d_week_seq,d_year,d_moy,d_dom]
+ CometNativeScan parquet spark_catalog.default.date_dim [d_week_seq,d_year,d_moy,d_dom]
+ InputAdapter
+ BroadcastExchange #3
+ WholeStageCodegen (11)
+ Project [i_item_sk]
+ BroadcastHashJoin [i_brand_id,i_class_id,i_category_id,brand_id,class_id,category_id]
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometNativeScan parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ InputAdapter
+ BroadcastExchange #4
+ WholeStageCodegen (10)
+ BroadcastHashJoin [brand_id,class_id,category_id,i_brand_id,i_class_id,i_category_id]
+ CometColumnarToRow
+ InputAdapter
+ CometHashAggregate [brand_id,class_id,category_id]
+ CometColumnarExchange [brand_id,class_id,category_id] #5
+ WholeStageCodegen (6)
+ HashAggregate [brand_id,class_id,category_id]
+ Project [i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [ss_sold_date_sk,d_date_sk]
+ Project [ss_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [ss_item_sk,i_item_sk]
+ Filter [ss_item_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.store_sales [ss_item_sk,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #3
+ BroadcastExchange #6
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometNativeScan parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ InputAdapter
+ BroadcastExchange #7
+ WholeStageCodegen (4)
+ BroadcastHashJoin [i_brand_id,i_class_id,i_category_id,i_brand_id,i_class_id,i_category_id]
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometNativeScan parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ InputAdapter
+ BroadcastExchange #8
+ WholeStageCodegen (3)
+ Project [i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [cs_sold_date_sk,d_date_sk]
+ Project [cs_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [cs_item_sk,i_item_sk]
+ Filter [cs_item_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.catalog_sales [cs_item_sk,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #3
+ InputAdapter
+ BroadcastExchange #9
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometNativeScan parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ InputAdapter
+ ReusedExchange [d_date_sk] #6
+ InputAdapter
+ ReusedExchange [d_date_sk] #6
+ InputAdapter
+ BroadcastExchange #10
+ WholeStageCodegen (9)
+ Project [i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [ws_sold_date_sk,d_date_sk]
+ Project [ws_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [ws_item_sk,i_item_sk]
+ Filter [ws_item_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.web_sales [ws_item_sk,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #3
+ InputAdapter
+ ReusedExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #9
+ InputAdapter
+ ReusedExchange [d_date_sk] #6
+ InputAdapter
+ BroadcastExchange #11
+ WholeStageCodegen (23)
+ BroadcastHashJoin [i_item_sk,ss_item_sk]
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometNativeScan parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ InputAdapter
+ ReusedExchange [ss_item_sk] #3
+ InputAdapter
+ ReusedExchange [d_date_sk] #2
+ InputAdapter
+ BroadcastExchange #13
+ WholeStageCodegen (51)
+ Filter [sales]
+ ReusedSubquery [average_sales] #4
+ HashAggregate [i_brand_id,i_class_id,i_category_id,sum,isEmpty,count] [sum((cast(ss_quantity as decimal(10,0)) * ss_list_price)),count(1),channel,sales,number_sales,sum,isEmpty,count]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [i_brand_id,i_class_id,i_category_id] #14
+ WholeStageCodegen (50)
+ HashAggregate [i_brand_id,i_class_id,i_category_id,ss_quantity,ss_list_price] [sum,isEmpty,count,sum,isEmpty,count]
+ Project [ss_quantity,ss_list_price,i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [ss_sold_date_sk,d_date_sk]
+ Project [ss_quantity,ss_list_price,ss_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ BroadcastHashJoin [ss_item_sk,i_item_sk]
+ BroadcastHashJoin [ss_item_sk,ss_item_sk]
+ Filter [ss_item_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.store_sales [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #5
+ BroadcastExchange #15
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_week_seq]
+ ReusedSubquery [d_week_seq] #6
+ CometNativeScan parquet spark_catalog.default.date_dim [d_date_sk,d_week_seq]
+ Subquery #6
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_week_seq]
+ CometFilter [d_week_seq,d_year,d_moy,d_dom]
+ CometNativeScan parquet spark_catalog.default.date_dim [d_week_seq,d_year,d_moy,d_dom]
+ InputAdapter
+ ReusedExchange [ss_item_sk] #3
+ InputAdapter
+ ReusedExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #11
+ InputAdapter
+ ReusedExchange [d_date_sk] #15
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_iceberg_compat/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_iceberg_compat/explain.txt
new file mode 100644
index 0000000000..ccc69246c8
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_iceberg_compat/explain.txt
@@ -0,0 +1,751 @@
+== Physical Plan ==
+* CometColumnarToRow (85)
++- CometTakeOrderedAndProject (84)
+ +- CometBroadcastHashJoin (83)
+ :- CometFilter (64)
+ : +- CometHashAggregate (63)
+ : +- CometExchange (62)
+ : +- CometHashAggregate (61)
+ : +- CometProject (60)
+ : +- CometBroadcastHashJoin (59)
+ : :- CometProject (54)
+ : : +- CometBroadcastHashJoin (53)
+ : : :- CometBroadcastHashJoin (47)
+ : : : :- CometFilter (2)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (1)
+ : : : +- CometBroadcastExchange (46)
+ : : : +- CometProject (45)
+ : : : +- CometBroadcastHashJoin (44)
+ : : : :- CometFilter (4)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (3)
+ : : : +- CometBroadcastExchange (43)
+ : : : +- CometBroadcastHashJoin (42)
+ : : : :- CometHashAggregate (32)
+ : : : : +- CometExchange (31)
+ : : : : +- CometHashAggregate (30)
+ : : : : +- CometProject (29)
+ : : : : +- CometBroadcastHashJoin (28)
+ : : : : :- CometProject (26)
+ : : : : : +- CometBroadcastHashJoin (25)
+ : : : : : :- CometFilter (6)
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (5)
+ : : : : : +- CometBroadcastExchange (24)
+ : : : : : +- CometBroadcastHashJoin (23)
+ : : : : : :- CometFilter (8)
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (7)
+ : : : : : +- CometBroadcastExchange (22)
+ : : : : : +- CometProject (21)
+ : : : : : +- CometBroadcastHashJoin (20)
+ : : : : : :- CometProject (15)
+ : : : : : : +- CometBroadcastHashJoin (14)
+ : : : : : : :- CometFilter (10)
+ : : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (9)
+ : : : : : : +- CometBroadcastExchange (13)
+ : : : : : : +- CometFilter (12)
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (11)
+ : : : : : +- CometBroadcastExchange (19)
+ : : : : : +- CometProject (18)
+ : : : : : +- CometFilter (17)
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (16)
+ : : : : +- ReusedExchange (27)
+ : : : +- CometBroadcastExchange (41)
+ : : : +- CometProject (40)
+ : : : +- CometBroadcastHashJoin (39)
+ : : : :- CometProject (37)
+ : : : : +- CometBroadcastHashJoin (36)
+ : : : : :- CometFilter (34)
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (33)
+ : : : : +- ReusedExchange (35)
+ : : : +- ReusedExchange (38)
+ : : +- CometBroadcastExchange (52)
+ : : +- CometBroadcastHashJoin (51)
+ : : :- CometFilter (49)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (48)
+ : : +- ReusedExchange (50)
+ : +- CometBroadcastExchange (58)
+ : +- CometProject (57)
+ : +- CometFilter (56)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (55)
+ +- CometBroadcastExchange (82)
+ +- CometFilter (81)
+ +- CometHashAggregate (80)
+ +- CometExchange (79)
+ +- CometHashAggregate (78)
+ +- CometProject (77)
+ +- CometBroadcastHashJoin (76)
+ :- CometProject (71)
+ : +- CometBroadcastHashJoin (70)
+ : :- CometBroadcastHashJoin (68)
+ : : :- CometFilter (66)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (65)
+ : : +- ReusedExchange (67)
+ : +- ReusedExchange (69)
+ +- CometBroadcastExchange (75)
+ +- CometProject (74)
+ +- CometFilter (73)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (72)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#4), dynamicpruningexpression(ss_sold_date_sk#4 IN dynamicpruning#5)]
+PushedFilters: [IsNotNull(ss_item_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Condition : isnotnull(ss_item_sk#1)
+
+(3) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_brand_id), IsNotNull(i_class_id), IsNotNull(i_category_id)]
+ReadSchema: struct
+
+(4) CometFilter
+Input [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+Condition : ((isnotnull(i_brand_id#7) AND isnotnull(i_class_id#8)) AND isnotnull(i_category_id#9))
+
+(5) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#11), dynamicpruningexpression(ss_sold_date_sk#11 IN dynamicpruning#12)]
+PushedFilters: [IsNotNull(ss_item_sk)]
+ReadSchema: struct
+
+(6) CometFilter
+Input [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+Condition : isnotnull(ss_item_sk#10)
+
+(7) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk), IsNotNull(i_brand_id), IsNotNull(i_class_id), IsNotNull(i_category_id)]
+ReadSchema: struct
+
+(8) CometFilter
+Input [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Condition : (((isnotnull(i_item_sk#13) AND isnotnull(i_brand_id#14)) AND isnotnull(i_class_id#15)) AND isnotnull(i_category_id#16))
+
+(9) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#18), dynamicpruningexpression(cs_sold_date_sk#18 IN dynamicpruning#19)]
+PushedFilters: [IsNotNull(cs_item_sk)]
+ReadSchema: struct
+
+(10) CometFilter
+Input [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+Condition : isnotnull(cs_item_sk#17)
+
+(11) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [4]: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk)]
+ReadSchema: struct
+
+(12) CometFilter
+Input [4]: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Condition : isnotnull(i_item_sk#20)
+
+(13) CometBroadcastExchange
+Input [4]: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+
+(14) CometBroadcastHashJoin
+Left output [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+Right output [4]: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [cs_item_sk#17], [i_item_sk#20], Inner, BuildRight
+
+(15) CometProject
+Input [6]: [cs_item_sk#17, cs_sold_date_sk#18, i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [cs_sold_date_sk#18, i_brand_id#21, i_class_id#22, i_category_id#23], [cs_sold_date_sk#18, i_brand_id#21, i_class_id#22, i_category_id#23]
+
+(16) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#24, d_year#25]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), GreaterThanOrEqual(d_year,1999), LessThanOrEqual(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(17) CometFilter
+Input [2]: [d_date_sk#24, d_year#25]
+Condition : (((isnotnull(d_year#25) AND (d_year#25 >= 1999)) AND (d_year#25 <= 2001)) AND isnotnull(d_date_sk#24))
+
+(18) CometProject
+Input [2]: [d_date_sk#24, d_year#25]
+Arguments: [d_date_sk#24], [d_date_sk#24]
+
+(19) CometBroadcastExchange
+Input [1]: [d_date_sk#24]
+Arguments: [d_date_sk#24]
+
+(20) CometBroadcastHashJoin
+Left output [4]: [cs_sold_date_sk#18, i_brand_id#21, i_class_id#22, i_category_id#23]
+Right output [1]: [d_date_sk#24]
+Arguments: [cs_sold_date_sk#18], [d_date_sk#24], Inner, BuildRight
+
+(21) CometProject
+Input [5]: [cs_sold_date_sk#18, i_brand_id#21, i_class_id#22, i_category_id#23, d_date_sk#24]
+Arguments: [i_brand_id#21, i_class_id#22, i_category_id#23], [i_brand_id#21, i_class_id#22, i_category_id#23]
+
+(22) CometBroadcastExchange
+Input [3]: [i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [i_brand_id#21, i_class_id#22, i_category_id#23]
+
+(23) CometBroadcastHashJoin
+Left output [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Right output [3]: [i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [coalesce(i_brand_id#14, 0), isnull(i_brand_id#14), coalesce(i_class_id#15, 0), isnull(i_class_id#15), coalesce(i_category_id#16, 0), isnull(i_category_id#16)], [coalesce(i_brand_id#21, 0), isnull(i_brand_id#21), coalesce(i_class_id#22, 0), isnull(i_class_id#22), coalesce(i_category_id#23, 0), isnull(i_category_id#23)], LeftSemi, BuildRight
+
+(24) CometBroadcastExchange
+Input [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Arguments: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+
+(25) CometBroadcastHashJoin
+Left output [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+Right output [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Arguments: [ss_item_sk#10], [i_item_sk#13], Inner, BuildRight
+
+(26) CometProject
+Input [6]: [ss_item_sk#10, ss_sold_date_sk#11, i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Arguments: [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16], [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16]
+
+(27) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#26]
+
+(28) CometBroadcastHashJoin
+Left output [4]: [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16]
+Right output [1]: [d_date_sk#26]
+Arguments: [ss_sold_date_sk#11], [d_date_sk#26], Inner, BuildRight
+
+(29) CometProject
+Input [5]: [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16, d_date_sk#26]
+Arguments: [brand_id#27, class_id#28, category_id#29], [i_brand_id#14 AS brand_id#27, i_class_id#15 AS class_id#28, i_category_id#16 AS category_id#29]
+
+(30) CometHashAggregate
+Input [3]: [brand_id#27, class_id#28, category_id#29]
+Keys [3]: [brand_id#27, class_id#28, category_id#29]
+Functions: []
+
+(31) CometExchange
+Input [3]: [brand_id#27, class_id#28, category_id#29]
+Arguments: hashpartitioning(brand_id#27, class_id#28, category_id#29, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=1]
+
+(32) CometHashAggregate
+Input [3]: [brand_id#27, class_id#28, category_id#29]
+Keys [3]: [brand_id#27, class_id#28, category_id#29]
+Functions: []
+
+(33) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [2]: [ws_item_sk#30, ws_sold_date_sk#31]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#31), dynamicpruningexpression(ws_sold_date_sk#31 IN dynamicpruning#32)]
+PushedFilters: [IsNotNull(ws_item_sk)]
+ReadSchema: struct
+
+(34) CometFilter
+Input [2]: [ws_item_sk#30, ws_sold_date_sk#31]
+Condition : isnotnull(ws_item_sk#30)
+
+(35) ReusedExchange [Reuses operator id: 13]
+Output [4]: [i_item_sk#33, i_brand_id#34, i_class_id#35, i_category_id#36]
+
+(36) CometBroadcastHashJoin
+Left output [2]: [ws_item_sk#30, ws_sold_date_sk#31]
+Right output [4]: [i_item_sk#33, i_brand_id#34, i_class_id#35, i_category_id#36]
+Arguments: [ws_item_sk#30], [i_item_sk#33], Inner, BuildRight
+
+(37) CometProject
+Input [6]: [ws_item_sk#30, ws_sold_date_sk#31, i_item_sk#33, i_brand_id#34, i_class_id#35, i_category_id#36]
+Arguments: [ws_sold_date_sk#31, i_brand_id#34, i_class_id#35, i_category_id#36], [ws_sold_date_sk#31, i_brand_id#34, i_class_id#35, i_category_id#36]
+
+(38) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#37]
+
+(39) CometBroadcastHashJoin
+Left output [4]: [ws_sold_date_sk#31, i_brand_id#34, i_class_id#35, i_category_id#36]
+Right output [1]: [d_date_sk#37]
+Arguments: [ws_sold_date_sk#31], [d_date_sk#37], Inner, BuildRight
+
+(40) CometProject
+Input [5]: [ws_sold_date_sk#31, i_brand_id#34, i_class_id#35, i_category_id#36, d_date_sk#37]
+Arguments: [i_brand_id#34, i_class_id#35, i_category_id#36], [i_brand_id#34, i_class_id#35, i_category_id#36]
+
+(41) CometBroadcastExchange
+Input [3]: [i_brand_id#34, i_class_id#35, i_category_id#36]
+Arguments: [i_brand_id#34, i_class_id#35, i_category_id#36]
+
+(42) CometBroadcastHashJoin
+Left output [3]: [brand_id#27, class_id#28, category_id#29]
+Right output [3]: [i_brand_id#34, i_class_id#35, i_category_id#36]
+Arguments: [coalesce(brand_id#27, 0), isnull(brand_id#27), coalesce(class_id#28, 0), isnull(class_id#28), coalesce(category_id#29, 0), isnull(category_id#29)], [coalesce(i_brand_id#34, 0), isnull(i_brand_id#34), coalesce(i_class_id#35, 0), isnull(i_class_id#35), coalesce(i_category_id#36, 0), isnull(i_category_id#36)], LeftSemi, BuildRight
+
+(43) CometBroadcastExchange
+Input [3]: [brand_id#27, class_id#28, category_id#29]
+Arguments: [brand_id#27, class_id#28, category_id#29]
+
+(44) CometBroadcastHashJoin
+Left output [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+Right output [3]: [brand_id#27, class_id#28, category_id#29]
+Arguments: [i_brand_id#7, i_class_id#8, i_category_id#9], [brand_id#27, class_id#28, category_id#29], Inner, BuildRight
+
+(45) CometProject
+Input [7]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9, brand_id#27, class_id#28, category_id#29]
+Arguments: [ss_item_sk#38], [i_item_sk#6 AS ss_item_sk#38]
+
+(46) CometBroadcastExchange
+Input [1]: [ss_item_sk#38]
+Arguments: [ss_item_sk#38]
+
+(47) CometBroadcastHashJoin
+Left output [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Right output [1]: [ss_item_sk#38]
+Arguments: [ss_item_sk#1], [ss_item_sk#38], LeftSemi, BuildRight
+
+(48) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk), IsNotNull(i_brand_id), IsNotNull(i_class_id), IsNotNull(i_category_id)]
+ReadSchema: struct
+
+(49) CometFilter
+Input [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Condition : (((isnotnull(i_item_sk#39) AND isnotnull(i_brand_id#40)) AND isnotnull(i_class_id#41)) AND isnotnull(i_category_id#42))
+
+(50) ReusedExchange [Reuses operator id: 46]
+Output [1]: [ss_item_sk#38]
+
+(51) CometBroadcastHashJoin
+Left output [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Right output [1]: [ss_item_sk#38]
+Arguments: [i_item_sk#39], [ss_item_sk#38], LeftSemi, BuildRight
+
+(52) CometBroadcastExchange
+Input [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Arguments: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+
+(53) CometBroadcastHashJoin
+Left output [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Right output [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Arguments: [ss_item_sk#1], [i_item_sk#39], Inner, BuildRight
+
+(54) CometProject
+Input [8]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Arguments: [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#40, i_class_id#41, i_category_id#42], [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#40, i_class_id#41, i_category_id#42]
+
+(55) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#43, d_week_seq#44]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_week_seq), EqualTo(d_week_seq,ScalarSubquery#45), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(56) CometFilter
+Input [2]: [d_date_sk#43, d_week_seq#44]
+Condition : ((isnotnull(d_week_seq#44) AND (d_week_seq#44 = ReusedSubquery Subquery scalar-subquery#45, [id=#46])) AND isnotnull(d_date_sk#43))
+
+(57) CometProject
+Input [2]: [d_date_sk#43, d_week_seq#44]
+Arguments: [d_date_sk#43], [d_date_sk#43]
+
+(58) CometBroadcastExchange
+Input [1]: [d_date_sk#43]
+Arguments: [d_date_sk#43]
+
+(59) CometBroadcastHashJoin
+Left output [6]: [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#40, i_class_id#41, i_category_id#42]
+Right output [1]: [d_date_sk#43]
+Arguments: [ss_sold_date_sk#4], [d_date_sk#43], Inner, BuildRight
+
+(60) CometProject
+Input [7]: [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#40, i_class_id#41, i_category_id#42, d_date_sk#43]
+Arguments: [ss_quantity#2, ss_list_price#3, i_brand_id#40, i_class_id#41, i_category_id#42], [ss_quantity#2, ss_list_price#3, i_brand_id#40, i_class_id#41, i_category_id#42]
+
+(61) CometHashAggregate
+Input [5]: [ss_quantity#2, ss_list_price#3, i_brand_id#40, i_class_id#41, i_category_id#42]
+Keys [3]: [i_brand_id#40, i_class_id#41, i_category_id#42]
+Functions [2]: [partial_sum((cast(ss_quantity#2 as decimal(10,0)) * ss_list_price#3)), partial_count(1)]
+
+(62) CometExchange
+Input [6]: [i_brand_id#40, i_class_id#41, i_category_id#42, sum#47, isEmpty#48, count#49]
+Arguments: hashpartitioning(i_brand_id#40, i_class_id#41, i_category_id#42, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=2]
+
+(63) CometHashAggregate
+Input [6]: [i_brand_id#40, i_class_id#41, i_category_id#42, sum#47, isEmpty#48, count#49]
+Keys [3]: [i_brand_id#40, i_class_id#41, i_category_id#42]
+Functions [2]: [sum((cast(ss_quantity#2 as decimal(10,0)) * ss_list_price#3)), count(1)]
+
+(64) CometFilter
+Input [6]: [channel#50, i_brand_id#40, i_class_id#41, i_category_id#42, sales#51, number_sales#52]
+Condition : (isnotnull(sales#51) AND (cast(sales#51 as decimal(32,6)) > cast(Subquery scalar-subquery#53, [id=#54] as decimal(32,6))))
+
+(65) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [4]: [ss_item_sk#55, ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#58), dynamicpruningexpression(ss_sold_date_sk#58 IN dynamicpruning#59)]
+PushedFilters: [IsNotNull(ss_item_sk)]
+ReadSchema: struct
+
+(66) CometFilter
+Input [4]: [ss_item_sk#55, ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58]
+Condition : isnotnull(ss_item_sk#55)
+
+(67) ReusedExchange [Reuses operator id: 46]
+Output [1]: [ss_item_sk#60]
+
+(68) CometBroadcastHashJoin
+Left output [4]: [ss_item_sk#55, ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58]
+Right output [1]: [ss_item_sk#60]
+Arguments: [ss_item_sk#55], [ss_item_sk#60], LeftSemi, BuildRight
+
+(69) ReusedExchange [Reuses operator id: 52]
+Output [4]: [i_item_sk#61, i_brand_id#62, i_class_id#63, i_category_id#64]
+
+(70) CometBroadcastHashJoin
+Left output [4]: [ss_item_sk#55, ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58]
+Right output [4]: [i_item_sk#61, i_brand_id#62, i_class_id#63, i_category_id#64]
+Arguments: [ss_item_sk#55], [i_item_sk#61], Inner, BuildRight
+
+(71) CometProject
+Input [8]: [ss_item_sk#55, ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58, i_item_sk#61, i_brand_id#62, i_class_id#63, i_category_id#64]
+Arguments: [ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58, i_brand_id#62, i_class_id#63, i_category_id#64], [ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58, i_brand_id#62, i_class_id#63, i_category_id#64]
+
+(72) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#65, d_week_seq#66]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_week_seq), EqualTo(d_week_seq,ScalarSubquery#67), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(73) CometFilter
+Input [2]: [d_date_sk#65, d_week_seq#66]
+Condition : ((isnotnull(d_week_seq#66) AND (d_week_seq#66 = ReusedSubquery Subquery scalar-subquery#67, [id=#68])) AND isnotnull(d_date_sk#65))
+
+(74) CometProject
+Input [2]: [d_date_sk#65, d_week_seq#66]
+Arguments: [d_date_sk#65], [d_date_sk#65]
+
+(75) CometBroadcastExchange
+Input [1]: [d_date_sk#65]
+Arguments: [d_date_sk#65]
+
+(76) CometBroadcastHashJoin
+Left output [6]: [ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58, i_brand_id#62, i_class_id#63, i_category_id#64]
+Right output [1]: [d_date_sk#65]
+Arguments: [ss_sold_date_sk#58], [d_date_sk#65], Inner, BuildRight
+
+(77) CometProject
+Input [7]: [ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58, i_brand_id#62, i_class_id#63, i_category_id#64, d_date_sk#65]
+Arguments: [ss_quantity#56, ss_list_price#57, i_brand_id#62, i_class_id#63, i_category_id#64], [ss_quantity#56, ss_list_price#57, i_brand_id#62, i_class_id#63, i_category_id#64]
+
+(78) CometHashAggregate
+Input [5]: [ss_quantity#56, ss_list_price#57, i_brand_id#62, i_class_id#63, i_category_id#64]
+Keys [3]: [i_brand_id#62, i_class_id#63, i_category_id#64]
+Functions [2]: [partial_sum((cast(ss_quantity#56 as decimal(10,0)) * ss_list_price#57)), partial_count(1)]
+
+(79) CometExchange
+Input [6]: [i_brand_id#62, i_class_id#63, i_category_id#64, sum#69, isEmpty#70, count#71]
+Arguments: hashpartitioning(i_brand_id#62, i_class_id#63, i_category_id#64, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=3]
+
+(80) CometHashAggregate
+Input [6]: [i_brand_id#62, i_class_id#63, i_category_id#64, sum#69, isEmpty#70, count#71]
+Keys [3]: [i_brand_id#62, i_class_id#63, i_category_id#64]
+Functions [2]: [sum((cast(ss_quantity#56 as decimal(10,0)) * ss_list_price#57)), count(1)]
+
+(81) CometFilter
+Input [6]: [channel#72, i_brand_id#62, i_class_id#63, i_category_id#64, sales#73, number_sales#74]
+Condition : (isnotnull(sales#73) AND (cast(sales#73 as decimal(32,6)) > cast(ReusedSubquery Subquery scalar-subquery#53, [id=#54] as decimal(32,6))))
+
+(82) CometBroadcastExchange
+Input [6]: [channel#72, i_brand_id#62, i_class_id#63, i_category_id#64, sales#73, number_sales#74]
+Arguments: [channel#72, i_brand_id#62, i_class_id#63, i_category_id#64, sales#73, number_sales#74]
+
+(83) CometBroadcastHashJoin
+Left output [6]: [channel#50, i_brand_id#40, i_class_id#41, i_category_id#42, sales#51, number_sales#52]
+Right output [6]: [channel#72, i_brand_id#62, i_class_id#63, i_category_id#64, sales#73, number_sales#74]
+Arguments: [i_brand_id#40, i_class_id#41, i_category_id#42], [i_brand_id#62, i_class_id#63, i_category_id#64], Inner, BuildRight
+
+(84) CometTakeOrderedAndProject
+Input [12]: [channel#50, i_brand_id#40, i_class_id#41, i_category_id#42, sales#51, number_sales#52, channel#72, i_brand_id#62, i_class_id#63, i_category_id#64, sales#73, number_sales#74]
+Arguments: TakeOrderedAndProject(limit=100, orderBy=[i_brand_id#40 ASC NULLS FIRST,i_class_id#41 ASC NULLS FIRST,i_category_id#42 ASC NULLS FIRST], output=[channel#50,i_brand_id#40,i_class_id#41,i_category_id#42,sales#51,number_sales#52,channel#72,i_brand_id#62,i_class_id#63,i_category_id#64,sales#73,number_sales#74]), [channel#50, i_brand_id#40, i_class_id#41, i_category_id#42, sales#51, number_sales#52, channel#72, i_brand_id#62, i_class_id#63, i_category_id#64, sales#73, number_sales#74], 100, 0, [i_brand_id#40 ASC NULLS FIRST, i_class_id#41 ASC NULLS FIRST, i_category_id#42 ASC NULLS FIRST], [channel#50, i_brand_id#40, i_class_id#41, i_category_id#42, sales#51, number_sales#52, channel#72, i_brand_id#62, i_class_id#63, i_category_id#64, sales#73, number_sales#74]
+
+(85) CometColumnarToRow [codegen id : 1]
+Input [12]: [channel#50, i_brand_id#40, i_class_id#41, i_category_id#42, sales#51, number_sales#52, channel#72, i_brand_id#62, i_class_id#63, i_category_id#64, sales#73, number_sales#74]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 64 Hosting Expression = Subquery scalar-subquery#53, [id=#54]
+* CometColumnarToRow (102)
++- CometHashAggregate (101)
+ +- CometExchange (100)
+ +- CometHashAggregate (99)
+ +- CometUnion (98)
+ :- CometProject (89)
+ : +- CometBroadcastHashJoin (88)
+ : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (86)
+ : +- ReusedExchange (87)
+ :- CometProject (93)
+ : +- CometBroadcastHashJoin (92)
+ : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (90)
+ : +- ReusedExchange (91)
+ +- CometProject (97)
+ +- CometBroadcastHashJoin (96)
+ :- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (94)
+ +- ReusedExchange (95)
+
+
+(86) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [3]: [ss_quantity#75, ss_list_price#76, ss_sold_date_sk#77]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#77), dynamicpruningexpression(ss_sold_date_sk#77 IN dynamicpruning#78)]
+ReadSchema: struct
+
+(87) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#79]
+
+(88) CometBroadcastHashJoin
+Left output [3]: [ss_quantity#75, ss_list_price#76, ss_sold_date_sk#77]
+Right output [1]: [d_date_sk#79]
+Arguments: [ss_sold_date_sk#77], [d_date_sk#79], Inner, BuildRight
+
+(89) CometProject
+Input [4]: [ss_quantity#75, ss_list_price#76, ss_sold_date_sk#77, d_date_sk#79]
+Arguments: [quantity#80, list_price#81], [ss_quantity#75 AS quantity#80, ss_list_price#76 AS list_price#81]
+
+(90) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [3]: [cs_quantity#82, cs_list_price#83, cs_sold_date_sk#84]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#84), dynamicpruningexpression(cs_sold_date_sk#84 IN dynamicpruning#85)]
+ReadSchema: struct
+
+(91) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#86]
+
+(92) CometBroadcastHashJoin
+Left output [3]: [cs_quantity#82, cs_list_price#83, cs_sold_date_sk#84]
+Right output [1]: [d_date_sk#86]
+Arguments: [cs_sold_date_sk#84], [d_date_sk#86], Inner, BuildRight
+
+(93) CometProject
+Input [4]: [cs_quantity#82, cs_list_price#83, cs_sold_date_sk#84, d_date_sk#86]
+Arguments: [quantity#87, list_price#88], [cs_quantity#82 AS quantity#87, cs_list_price#83 AS list_price#88]
+
+(94) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [3]: [ws_quantity#89, ws_list_price#90, ws_sold_date_sk#91]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#91), dynamicpruningexpression(ws_sold_date_sk#91 IN dynamicpruning#92)]
+ReadSchema: struct
+
+(95) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#93]
+
+(96) CometBroadcastHashJoin
+Left output [3]: [ws_quantity#89, ws_list_price#90, ws_sold_date_sk#91]
+Right output [1]: [d_date_sk#93]
+Arguments: [ws_sold_date_sk#91], [d_date_sk#93], Inner, BuildRight
+
+(97) CometProject
+Input [4]: [ws_quantity#89, ws_list_price#90, ws_sold_date_sk#91, d_date_sk#93]
+Arguments: [quantity#94, list_price#95], [ws_quantity#89 AS quantity#94, ws_list_price#90 AS list_price#95]
+
+(98) CometUnion
+Child 0 Input [2]: [quantity#80, list_price#81]
+Child 1 Input [2]: [quantity#87, list_price#88]
+Child 2 Input [2]: [quantity#94, list_price#95]
+
+(99) CometHashAggregate
+Input [2]: [quantity#80, list_price#81]
+Keys: []
+Functions [1]: [partial_avg((cast(quantity#80 as decimal(10,0)) * list_price#81))]
+
+(100) CometExchange
+Input [2]: [sum#96, count#97]
+Arguments: SinglePartition, ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=4]
+
+(101) CometHashAggregate
+Input [2]: [sum#96, count#97]
+Keys: []
+Functions [1]: [avg((cast(quantity#80 as decimal(10,0)) * list_price#81))]
+
+(102) CometColumnarToRow [codegen id : 1]
+Input [1]: [average_sales#98]
+
+Subquery:2 Hosting operator id = 86 Hosting Expression = ss_sold_date_sk#77 IN dynamicpruning#12
+
+Subquery:3 Hosting operator id = 90 Hosting Expression = cs_sold_date_sk#84 IN dynamicpruning#12
+
+Subquery:4 Hosting operator id = 94 Hosting Expression = ws_sold_date_sk#91 IN dynamicpruning#12
+
+Subquery:5 Hosting operator id = 1 Hosting Expression = ss_sold_date_sk#4 IN dynamicpruning#5
+BroadcastExchange (107)
++- * CometColumnarToRow (106)
+ +- CometProject (105)
+ +- CometFilter (104)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (103)
+
+
+(103) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#43, d_week_seq#44]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_week_seq), EqualTo(d_week_seq,ScalarSubquery#45), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(104) CometFilter
+Input [2]: [d_date_sk#43, d_week_seq#44]
+Condition : ((isnotnull(d_week_seq#44) AND (d_week_seq#44 = ReusedSubquery Subquery scalar-subquery#45, [id=#46])) AND isnotnull(d_date_sk#43))
+
+(105) CometProject
+Input [2]: [d_date_sk#43, d_week_seq#44]
+Arguments: [d_date_sk#43], [d_date_sk#43]
+
+(106) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#43]
+
+(107) BroadcastExchange
+Input [1]: [d_date_sk#43]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=5]
+
+Subquery:6 Hosting operator id = 104 Hosting Expression = ReusedSubquery Subquery scalar-subquery#45, [id=#46]
+
+Subquery:7 Hosting operator id = 103 Hosting Expression = Subquery scalar-subquery#45, [id=#46]
+* CometColumnarToRow (111)
++- CometProject (110)
+ +- CometFilter (109)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (108)
+
+
+(108) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [4]: [d_week_seq#99, d_year#100, d_moy#101, d_dom#102]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), IsNotNull(d_moy), IsNotNull(d_dom), EqualTo(d_year,2000), EqualTo(d_moy,12), EqualTo(d_dom,11)]
+ReadSchema: struct
+
+(109) CometFilter
+Input [4]: [d_week_seq#99, d_year#100, d_moy#101, d_dom#102]
+Condition : (((((isnotnull(d_year#100) AND isnotnull(d_moy#101)) AND isnotnull(d_dom#102)) AND (d_year#100 = 2000)) AND (d_moy#101 = 12)) AND (d_dom#102 = 11))
+
+(110) CometProject
+Input [4]: [d_week_seq#99, d_year#100, d_moy#101, d_dom#102]
+Arguments: [d_week_seq#99], [d_week_seq#99]
+
+(111) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_week_seq#99]
+
+Subquery:8 Hosting operator id = 5 Hosting Expression = ss_sold_date_sk#11 IN dynamicpruning#12
+BroadcastExchange (116)
++- * CometColumnarToRow (115)
+ +- CometProject (114)
+ +- CometFilter (113)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (112)
+
+
+(112) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#26, d_year#103]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), GreaterThanOrEqual(d_year,1999), LessThanOrEqual(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(113) CometFilter
+Input [2]: [d_date_sk#26, d_year#103]
+Condition : (((isnotnull(d_year#103) AND (d_year#103 >= 1999)) AND (d_year#103 <= 2001)) AND isnotnull(d_date_sk#26))
+
+(114) CometProject
+Input [2]: [d_date_sk#26, d_year#103]
+Arguments: [d_date_sk#26], [d_date_sk#26]
+
+(115) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#26]
+
+(116) BroadcastExchange
+Input [1]: [d_date_sk#26]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=6]
+
+Subquery:9 Hosting operator id = 9 Hosting Expression = cs_sold_date_sk#18 IN dynamicpruning#12
+
+Subquery:10 Hosting operator id = 33 Hosting Expression = ws_sold_date_sk#31 IN dynamicpruning#12
+
+Subquery:11 Hosting operator id = 56 Hosting Expression = ReusedSubquery Subquery scalar-subquery#45, [id=#46]
+
+Subquery:12 Hosting operator id = 55 Hosting Expression = ReusedSubquery Subquery scalar-subquery#45, [id=#46]
+
+Subquery:13 Hosting operator id = 81 Hosting Expression = ReusedSubquery Subquery scalar-subquery#53, [id=#54]
+
+Subquery:14 Hosting operator id = 65 Hosting Expression = ss_sold_date_sk#58 IN dynamicpruning#59
+BroadcastExchange (121)
++- * CometColumnarToRow (120)
+ +- CometProject (119)
+ +- CometFilter (118)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (117)
+
+
+(117) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#65, d_week_seq#66]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_week_seq), EqualTo(d_week_seq,ScalarSubquery#67), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(118) CometFilter
+Input [2]: [d_date_sk#65, d_week_seq#66]
+Condition : ((isnotnull(d_week_seq#66) AND (d_week_seq#66 = ReusedSubquery Subquery scalar-subquery#67, [id=#68])) AND isnotnull(d_date_sk#65))
+
+(119) CometProject
+Input [2]: [d_date_sk#65, d_week_seq#66]
+Arguments: [d_date_sk#65], [d_date_sk#65]
+
+(120) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#65]
+
+(121) BroadcastExchange
+Input [1]: [d_date_sk#65]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=7]
+
+Subquery:15 Hosting operator id = 118 Hosting Expression = ReusedSubquery Subquery scalar-subquery#67, [id=#68]
+
+Subquery:16 Hosting operator id = 117 Hosting Expression = Subquery scalar-subquery#67, [id=#68]
+* CometColumnarToRow (125)
++- CometProject (124)
+ +- CometFilter (123)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (122)
+
+
+(122) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [4]: [d_week_seq#104, d_year#105, d_moy#106, d_dom#107]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), IsNotNull(d_moy), IsNotNull(d_dom), EqualTo(d_year,1999), EqualTo(d_moy,12), EqualTo(d_dom,11)]
+ReadSchema: struct
+
+(123) CometFilter
+Input [4]: [d_week_seq#104, d_year#105, d_moy#106, d_dom#107]
+Condition : (((((isnotnull(d_year#105) AND isnotnull(d_moy#106)) AND isnotnull(d_dom#107)) AND (d_year#105 = 1999)) AND (d_moy#106 = 12)) AND (d_dom#107 = 11))
+
+(124) CometProject
+Input [4]: [d_week_seq#104, d_year#105, d_moy#106, d_dom#107]
+Arguments: [d_week_seq#104], [d_week_seq#104]
+
+(125) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_week_seq#104]
+
+Subquery:17 Hosting operator id = 73 Hosting Expression = ReusedSubquery Subquery scalar-subquery#67, [id=#68]
+
+Subquery:18 Hosting operator id = 72 Hosting Expression = ReusedSubquery Subquery scalar-subquery#67, [id=#68]
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_iceberg_compat/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_iceberg_compat/extended.txt
new file mode 100644
index 0000000000..b32dd95954
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_iceberg_compat/extended.txt
@@ -0,0 +1,343 @@
+CometColumnarToRow
++- CometTakeOrderedAndProject
+ +- CometBroadcastHashJoin
+ :- CometFilter
+ : : +- Subquery
+ : : +- CometColumnarToRow
+ : : +- CometHashAggregate
+ : : +- CometExchange
+ : : +- CometHashAggregate
+ : : +- CometUnion
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : +- ReusedSubquery
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometHashAggregate
+ : +- CometExchange
+ : +- CometHashAggregate
+ : +- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : : +- ReusedSubquery
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- Subquery
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometHashAggregate
+ : : : : +- CometExchange
+ : : : : +- CometHashAggregate
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : : +- SubqueryBroadcast
+ : : : : : : +- BroadcastExchange
+ : : : : : : +- CometColumnarToRow
+ : : : : : : +- CometProject
+ : : : : : : +- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometProject
+ : : : : : : +- CometBroadcastHashJoin
+ : : : : : : :- CometFilter
+ : : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : : : +- ReusedSubquery
+ : : : : : : +- CometBroadcastExchange
+ : : : : : : +- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : : +- ReusedSubquery
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometBroadcastHashJoin
+ : : :- CometHashAggregate
+ : : : +- CometExchange
+ : : : +- CometHashAggregate
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : : +- ReusedSubquery
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : : +- ReusedSubquery
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- ReusedSubquery
+ +- CometBroadcastExchange
+ +- CometFilter
+ : +- ReusedSubquery
+ +- CometHashAggregate
+ +- CometExchange
+ +- CometHashAggregate
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : +- SubqueryBroadcast
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : : +- ReusedSubquery
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- Subquery
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometBroadcastHashJoin
+ : : :- CometHashAggregate
+ : : : +- CometExchange
+ : : : +- CometHashAggregate
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : : +- ReusedSubquery
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometBroadcastHashJoin
+ : :- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : +- CometBroadcastExchange
+ : +- CometBroadcastHashJoin
+ : :- CometHashAggregate
+ : : +- CometExchange
+ : : +- CometHashAggregate
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : +- ReusedSubquery
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : +- ReusedSubquery
+ : : +- CometBroadcastExchange
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ +- CometBroadcastExchange
+ +- CometProject
+ +- CometFilter
+ : +- ReusedSubquery
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ +- ReusedSubquery
+
+Comet accelerated 298 out of 331 eligible operators (90%). Final plan contains 10 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_iceberg_compat/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_iceberg_compat/simplified.txt
new file mode 100644
index 0000000000..6b5264b76d
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b.native_iceberg_compat/simplified.txt
@@ -0,0 +1,157 @@
+WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometTakeOrderedAndProject [channel,i_brand_id,i_class_id,i_category_id,sales,number_sales,channel,i_brand_id,i_class_id,i_category_id,sales,number_sales]
+ CometBroadcastHashJoin [channel,i_brand_id,i_class_id,i_category_id,sales,number_sales,channel,i_brand_id,i_class_id,i_category_id,sales,number_sales]
+ CometFilter [channel,i_brand_id,i_class_id,i_category_id,sales,number_sales]
+ Subquery #4
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometHashAggregate [sum,count] [average_sales,avg((cast(quantity as decimal(10,0)) * list_price))]
+ CometExchange #14
+ CometHashAggregate [quantity,list_price] [sum,count]
+ CometUnion [quantity,list_price]
+ CometProject [ss_quantity,ss_list_price] [quantity,list_price]
+ CometBroadcastHashJoin [ss_quantity,ss_list_price,ss_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_quantity,ss_list_price,ss_sold_date_sk]
+ ReusedSubquery [d_date_sk] #3
+ ReusedExchange [d_date_sk] #10
+ CometProject [cs_quantity,cs_list_price] [quantity,list_price]
+ CometBroadcastHashJoin [cs_quantity,cs_list_price,cs_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_quantity,cs_list_price,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #3
+ ReusedExchange [d_date_sk] #10
+ CometProject [ws_quantity,ws_list_price] [quantity,list_price]
+ CometBroadcastHashJoin [ws_quantity,ws_list_price,ws_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_quantity,ws_list_price,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #3
+ ReusedExchange [d_date_sk] #10
+ CometHashAggregate [sum,isEmpty,count] [channel,i_brand_id,i_class_id,i_category_id,sales,number_sales,sum((cast(ss_quantity as decimal(10,0)) * ss_list_price)),count(1)]
+ CometExchange [i_brand_id,i_class_id,i_category_id] #1
+ CometHashAggregate [ss_quantity,ss_list_price] [i_brand_id,i_class_id,i_category_id,sum,isEmpty,count]
+ CometProject [ss_quantity,ss_list_price,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_quantity,ss_list_price,ss_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [ss_quantity,ss_list_price,ss_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk,ss_item_sk]
+ CometFilter [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #2
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_week_seq]
+ ReusedSubquery [d_week_seq] #2
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_week_seq]
+ Subquery #2
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_week_seq]
+ CometFilter [d_week_seq,d_year,d_moy,d_dom]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_week_seq,d_year,d_moy,d_dom]
+ CometBroadcastExchange [ss_item_sk] #3
+ CometProject [i_item_sk] [ss_item_sk]
+ CometBroadcastHashJoin [i_item_sk,i_brand_id,i_class_id,i_category_id,brand_id,class_id,category_id]
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastExchange [brand_id,class_id,category_id] #4
+ CometBroadcastHashJoin [brand_id,class_id,category_id,i_brand_id,i_class_id,i_category_id]
+ CometHashAggregate [brand_id,class_id,category_id]
+ CometExchange [brand_id,class_id,category_id] #5
+ CometHashAggregate [brand_id,class_id,category_id]
+ CometProject [i_brand_id,i_class_id,i_category_id] [brand_id,class_id,category_id]
+ CometBroadcastHashJoin [ss_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [ss_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_item_sk,ss_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometFilter [ss_item_sk,ss_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_item_sk,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #3
+ BroadcastExchange #6
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #7
+ CometBroadcastHashJoin [i_item_sk,i_brand_id,i_class_id,i_category_id,i_brand_id,i_class_id,i_category_id]
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastExchange [i_brand_id,i_class_id,i_category_id] #8
+ CometProject [i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [cs_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [cs_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [cs_item_sk,cs_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometFilter [cs_item_sk,cs_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_item_sk,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #3
+ CometBroadcastExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #9
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastExchange [d_date_sk] #10
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ ReusedExchange [d_date_sk] #10
+ CometBroadcastExchange [i_brand_id,i_class_id,i_category_id] #11
+ CometProject [i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ws_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [ws_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ws_item_sk,ws_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometFilter [ws_item_sk,ws_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_item_sk,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #3
+ ReusedExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #9
+ ReusedExchange [d_date_sk] #10
+ CometBroadcastExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #12
+ CometBroadcastHashJoin [i_item_sk,i_brand_id,i_class_id,i_category_id,ss_item_sk]
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ ReusedExchange [ss_item_sk] #3
+ CometBroadcastExchange [d_date_sk] #13
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_week_seq]
+ ReusedSubquery [d_week_seq] #2
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_week_seq]
+ ReusedSubquery [d_week_seq] #2
+ CometBroadcastExchange [channel,i_brand_id,i_class_id,i_category_id,sales,number_sales] #15
+ CometFilter [channel,i_brand_id,i_class_id,i_category_id,sales,number_sales]
+ ReusedSubquery [average_sales] #4
+ CometHashAggregate [sum,isEmpty,count] [channel,i_brand_id,i_class_id,i_category_id,sales,number_sales,sum((cast(ss_quantity as decimal(10,0)) * ss_list_price)),count(1)]
+ CometExchange [i_brand_id,i_class_id,i_category_id] #16
+ CometHashAggregate [ss_quantity,ss_list_price] [i_brand_id,i_class_id,i_category_id,sum,isEmpty,count]
+ CometProject [ss_quantity,ss_list_price,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_quantity,ss_list_price,ss_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [ss_quantity,ss_list_price,ss_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk,ss_item_sk]
+ CometFilter [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #5
+ BroadcastExchange #17
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_week_seq]
+ ReusedSubquery [d_week_seq] #6
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_week_seq]
+ Subquery #6
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_week_seq]
+ CometFilter [d_week_seq,d_year,d_moy,d_dom]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_week_seq,d_year,d_moy,d_dom]
+ ReusedExchange [ss_item_sk] #3
+ ReusedExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #12
+ CometBroadcastExchange [d_date_sk] #18
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_week_seq]
+ ReusedSubquery [d_week_seq] #6
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_week_seq]
+ ReusedSubquery [d_week_seq] #6
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b/explain.txt
new file mode 100644
index 0000000000..ccc69246c8
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b/explain.txt
@@ -0,0 +1,751 @@
+== Physical Plan ==
+* CometColumnarToRow (85)
++- CometTakeOrderedAndProject (84)
+ +- CometBroadcastHashJoin (83)
+ :- CometFilter (64)
+ : +- CometHashAggregate (63)
+ : +- CometExchange (62)
+ : +- CometHashAggregate (61)
+ : +- CometProject (60)
+ : +- CometBroadcastHashJoin (59)
+ : :- CometProject (54)
+ : : +- CometBroadcastHashJoin (53)
+ : : :- CometBroadcastHashJoin (47)
+ : : : :- CometFilter (2)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (1)
+ : : : +- CometBroadcastExchange (46)
+ : : : +- CometProject (45)
+ : : : +- CometBroadcastHashJoin (44)
+ : : : :- CometFilter (4)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (3)
+ : : : +- CometBroadcastExchange (43)
+ : : : +- CometBroadcastHashJoin (42)
+ : : : :- CometHashAggregate (32)
+ : : : : +- CometExchange (31)
+ : : : : +- CometHashAggregate (30)
+ : : : : +- CometProject (29)
+ : : : : +- CometBroadcastHashJoin (28)
+ : : : : :- CometProject (26)
+ : : : : : +- CometBroadcastHashJoin (25)
+ : : : : : :- CometFilter (6)
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (5)
+ : : : : : +- CometBroadcastExchange (24)
+ : : : : : +- CometBroadcastHashJoin (23)
+ : : : : : :- CometFilter (8)
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (7)
+ : : : : : +- CometBroadcastExchange (22)
+ : : : : : +- CometProject (21)
+ : : : : : +- CometBroadcastHashJoin (20)
+ : : : : : :- CometProject (15)
+ : : : : : : +- CometBroadcastHashJoin (14)
+ : : : : : : :- CometFilter (10)
+ : : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (9)
+ : : : : : : +- CometBroadcastExchange (13)
+ : : : : : : +- CometFilter (12)
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (11)
+ : : : : : +- CometBroadcastExchange (19)
+ : : : : : +- CometProject (18)
+ : : : : : +- CometFilter (17)
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (16)
+ : : : : +- ReusedExchange (27)
+ : : : +- CometBroadcastExchange (41)
+ : : : +- CometProject (40)
+ : : : +- CometBroadcastHashJoin (39)
+ : : : :- CometProject (37)
+ : : : : +- CometBroadcastHashJoin (36)
+ : : : : :- CometFilter (34)
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (33)
+ : : : : +- ReusedExchange (35)
+ : : : +- ReusedExchange (38)
+ : : +- CometBroadcastExchange (52)
+ : : +- CometBroadcastHashJoin (51)
+ : : :- CometFilter (49)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (48)
+ : : +- ReusedExchange (50)
+ : +- CometBroadcastExchange (58)
+ : +- CometProject (57)
+ : +- CometFilter (56)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (55)
+ +- CometBroadcastExchange (82)
+ +- CometFilter (81)
+ +- CometHashAggregate (80)
+ +- CometExchange (79)
+ +- CometHashAggregate (78)
+ +- CometProject (77)
+ +- CometBroadcastHashJoin (76)
+ :- CometProject (71)
+ : +- CometBroadcastHashJoin (70)
+ : :- CometBroadcastHashJoin (68)
+ : : :- CometFilter (66)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (65)
+ : : +- ReusedExchange (67)
+ : +- ReusedExchange (69)
+ +- CometBroadcastExchange (75)
+ +- CometProject (74)
+ +- CometFilter (73)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (72)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#4), dynamicpruningexpression(ss_sold_date_sk#4 IN dynamicpruning#5)]
+PushedFilters: [IsNotNull(ss_item_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Condition : isnotnull(ss_item_sk#1)
+
+(3) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_brand_id), IsNotNull(i_class_id), IsNotNull(i_category_id)]
+ReadSchema: struct
+
+(4) CometFilter
+Input [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+Condition : ((isnotnull(i_brand_id#7) AND isnotnull(i_class_id#8)) AND isnotnull(i_category_id#9))
+
+(5) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#11), dynamicpruningexpression(ss_sold_date_sk#11 IN dynamicpruning#12)]
+PushedFilters: [IsNotNull(ss_item_sk)]
+ReadSchema: struct
+
+(6) CometFilter
+Input [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+Condition : isnotnull(ss_item_sk#10)
+
+(7) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk), IsNotNull(i_brand_id), IsNotNull(i_class_id), IsNotNull(i_category_id)]
+ReadSchema: struct
+
+(8) CometFilter
+Input [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Condition : (((isnotnull(i_item_sk#13) AND isnotnull(i_brand_id#14)) AND isnotnull(i_class_id#15)) AND isnotnull(i_category_id#16))
+
+(9) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#18), dynamicpruningexpression(cs_sold_date_sk#18 IN dynamicpruning#19)]
+PushedFilters: [IsNotNull(cs_item_sk)]
+ReadSchema: struct
+
+(10) CometFilter
+Input [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+Condition : isnotnull(cs_item_sk#17)
+
+(11) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [4]: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk)]
+ReadSchema: struct
+
+(12) CometFilter
+Input [4]: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Condition : isnotnull(i_item_sk#20)
+
+(13) CometBroadcastExchange
+Input [4]: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+
+(14) CometBroadcastHashJoin
+Left output [2]: [cs_item_sk#17, cs_sold_date_sk#18]
+Right output [4]: [i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [cs_item_sk#17], [i_item_sk#20], Inner, BuildRight
+
+(15) CometProject
+Input [6]: [cs_item_sk#17, cs_sold_date_sk#18, i_item_sk#20, i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [cs_sold_date_sk#18, i_brand_id#21, i_class_id#22, i_category_id#23], [cs_sold_date_sk#18, i_brand_id#21, i_class_id#22, i_category_id#23]
+
+(16) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#24, d_year#25]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), GreaterThanOrEqual(d_year,1999), LessThanOrEqual(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(17) CometFilter
+Input [2]: [d_date_sk#24, d_year#25]
+Condition : (((isnotnull(d_year#25) AND (d_year#25 >= 1999)) AND (d_year#25 <= 2001)) AND isnotnull(d_date_sk#24))
+
+(18) CometProject
+Input [2]: [d_date_sk#24, d_year#25]
+Arguments: [d_date_sk#24], [d_date_sk#24]
+
+(19) CometBroadcastExchange
+Input [1]: [d_date_sk#24]
+Arguments: [d_date_sk#24]
+
+(20) CometBroadcastHashJoin
+Left output [4]: [cs_sold_date_sk#18, i_brand_id#21, i_class_id#22, i_category_id#23]
+Right output [1]: [d_date_sk#24]
+Arguments: [cs_sold_date_sk#18], [d_date_sk#24], Inner, BuildRight
+
+(21) CometProject
+Input [5]: [cs_sold_date_sk#18, i_brand_id#21, i_class_id#22, i_category_id#23, d_date_sk#24]
+Arguments: [i_brand_id#21, i_class_id#22, i_category_id#23], [i_brand_id#21, i_class_id#22, i_category_id#23]
+
+(22) CometBroadcastExchange
+Input [3]: [i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [i_brand_id#21, i_class_id#22, i_category_id#23]
+
+(23) CometBroadcastHashJoin
+Left output [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Right output [3]: [i_brand_id#21, i_class_id#22, i_category_id#23]
+Arguments: [coalesce(i_brand_id#14, 0), isnull(i_brand_id#14), coalesce(i_class_id#15, 0), isnull(i_class_id#15), coalesce(i_category_id#16, 0), isnull(i_category_id#16)], [coalesce(i_brand_id#21, 0), isnull(i_brand_id#21), coalesce(i_class_id#22, 0), isnull(i_class_id#22), coalesce(i_category_id#23, 0), isnull(i_category_id#23)], LeftSemi, BuildRight
+
+(24) CometBroadcastExchange
+Input [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Arguments: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+
+(25) CometBroadcastHashJoin
+Left output [2]: [ss_item_sk#10, ss_sold_date_sk#11]
+Right output [4]: [i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Arguments: [ss_item_sk#10], [i_item_sk#13], Inner, BuildRight
+
+(26) CometProject
+Input [6]: [ss_item_sk#10, ss_sold_date_sk#11, i_item_sk#13, i_brand_id#14, i_class_id#15, i_category_id#16]
+Arguments: [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16], [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16]
+
+(27) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#26]
+
+(28) CometBroadcastHashJoin
+Left output [4]: [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16]
+Right output [1]: [d_date_sk#26]
+Arguments: [ss_sold_date_sk#11], [d_date_sk#26], Inner, BuildRight
+
+(29) CometProject
+Input [5]: [ss_sold_date_sk#11, i_brand_id#14, i_class_id#15, i_category_id#16, d_date_sk#26]
+Arguments: [brand_id#27, class_id#28, category_id#29], [i_brand_id#14 AS brand_id#27, i_class_id#15 AS class_id#28, i_category_id#16 AS category_id#29]
+
+(30) CometHashAggregate
+Input [3]: [brand_id#27, class_id#28, category_id#29]
+Keys [3]: [brand_id#27, class_id#28, category_id#29]
+Functions: []
+
+(31) CometExchange
+Input [3]: [brand_id#27, class_id#28, category_id#29]
+Arguments: hashpartitioning(brand_id#27, class_id#28, category_id#29, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=1]
+
+(32) CometHashAggregate
+Input [3]: [brand_id#27, class_id#28, category_id#29]
+Keys [3]: [brand_id#27, class_id#28, category_id#29]
+Functions: []
+
+(33) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [2]: [ws_item_sk#30, ws_sold_date_sk#31]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#31), dynamicpruningexpression(ws_sold_date_sk#31 IN dynamicpruning#32)]
+PushedFilters: [IsNotNull(ws_item_sk)]
+ReadSchema: struct
+
+(34) CometFilter
+Input [2]: [ws_item_sk#30, ws_sold_date_sk#31]
+Condition : isnotnull(ws_item_sk#30)
+
+(35) ReusedExchange [Reuses operator id: 13]
+Output [4]: [i_item_sk#33, i_brand_id#34, i_class_id#35, i_category_id#36]
+
+(36) CometBroadcastHashJoin
+Left output [2]: [ws_item_sk#30, ws_sold_date_sk#31]
+Right output [4]: [i_item_sk#33, i_brand_id#34, i_class_id#35, i_category_id#36]
+Arguments: [ws_item_sk#30], [i_item_sk#33], Inner, BuildRight
+
+(37) CometProject
+Input [6]: [ws_item_sk#30, ws_sold_date_sk#31, i_item_sk#33, i_brand_id#34, i_class_id#35, i_category_id#36]
+Arguments: [ws_sold_date_sk#31, i_brand_id#34, i_class_id#35, i_category_id#36], [ws_sold_date_sk#31, i_brand_id#34, i_class_id#35, i_category_id#36]
+
+(38) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#37]
+
+(39) CometBroadcastHashJoin
+Left output [4]: [ws_sold_date_sk#31, i_brand_id#34, i_class_id#35, i_category_id#36]
+Right output [1]: [d_date_sk#37]
+Arguments: [ws_sold_date_sk#31], [d_date_sk#37], Inner, BuildRight
+
+(40) CometProject
+Input [5]: [ws_sold_date_sk#31, i_brand_id#34, i_class_id#35, i_category_id#36, d_date_sk#37]
+Arguments: [i_brand_id#34, i_class_id#35, i_category_id#36], [i_brand_id#34, i_class_id#35, i_category_id#36]
+
+(41) CometBroadcastExchange
+Input [3]: [i_brand_id#34, i_class_id#35, i_category_id#36]
+Arguments: [i_brand_id#34, i_class_id#35, i_category_id#36]
+
+(42) CometBroadcastHashJoin
+Left output [3]: [brand_id#27, class_id#28, category_id#29]
+Right output [3]: [i_brand_id#34, i_class_id#35, i_category_id#36]
+Arguments: [coalesce(brand_id#27, 0), isnull(brand_id#27), coalesce(class_id#28, 0), isnull(class_id#28), coalesce(category_id#29, 0), isnull(category_id#29)], [coalesce(i_brand_id#34, 0), isnull(i_brand_id#34), coalesce(i_class_id#35, 0), isnull(i_class_id#35), coalesce(i_category_id#36, 0), isnull(i_category_id#36)], LeftSemi, BuildRight
+
+(43) CometBroadcastExchange
+Input [3]: [brand_id#27, class_id#28, category_id#29]
+Arguments: [brand_id#27, class_id#28, category_id#29]
+
+(44) CometBroadcastHashJoin
+Left output [4]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9]
+Right output [3]: [brand_id#27, class_id#28, category_id#29]
+Arguments: [i_brand_id#7, i_class_id#8, i_category_id#9], [brand_id#27, class_id#28, category_id#29], Inner, BuildRight
+
+(45) CometProject
+Input [7]: [i_item_sk#6, i_brand_id#7, i_class_id#8, i_category_id#9, brand_id#27, class_id#28, category_id#29]
+Arguments: [ss_item_sk#38], [i_item_sk#6 AS ss_item_sk#38]
+
+(46) CometBroadcastExchange
+Input [1]: [ss_item_sk#38]
+Arguments: [ss_item_sk#38]
+
+(47) CometBroadcastHashJoin
+Left output [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Right output [1]: [ss_item_sk#38]
+Arguments: [ss_item_sk#1], [ss_item_sk#38], LeftSemi, BuildRight
+
+(48) CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+Output [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk), IsNotNull(i_brand_id), IsNotNull(i_class_id), IsNotNull(i_category_id)]
+ReadSchema: struct
+
+(49) CometFilter
+Input [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Condition : (((isnotnull(i_item_sk#39) AND isnotnull(i_brand_id#40)) AND isnotnull(i_class_id#41)) AND isnotnull(i_category_id#42))
+
+(50) ReusedExchange [Reuses operator id: 46]
+Output [1]: [ss_item_sk#38]
+
+(51) CometBroadcastHashJoin
+Left output [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Right output [1]: [ss_item_sk#38]
+Arguments: [i_item_sk#39], [ss_item_sk#38], LeftSemi, BuildRight
+
+(52) CometBroadcastExchange
+Input [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Arguments: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+
+(53) CometBroadcastHashJoin
+Left output [4]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4]
+Right output [4]: [i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Arguments: [ss_item_sk#1], [i_item_sk#39], Inner, BuildRight
+
+(54) CometProject
+Input [8]: [ss_item_sk#1, ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_item_sk#39, i_brand_id#40, i_class_id#41, i_category_id#42]
+Arguments: [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#40, i_class_id#41, i_category_id#42], [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#40, i_class_id#41, i_category_id#42]
+
+(55) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#43, d_week_seq#44]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_week_seq), EqualTo(d_week_seq,ScalarSubquery#45), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(56) CometFilter
+Input [2]: [d_date_sk#43, d_week_seq#44]
+Condition : ((isnotnull(d_week_seq#44) AND (d_week_seq#44 = ReusedSubquery Subquery scalar-subquery#45, [id=#46])) AND isnotnull(d_date_sk#43))
+
+(57) CometProject
+Input [2]: [d_date_sk#43, d_week_seq#44]
+Arguments: [d_date_sk#43], [d_date_sk#43]
+
+(58) CometBroadcastExchange
+Input [1]: [d_date_sk#43]
+Arguments: [d_date_sk#43]
+
+(59) CometBroadcastHashJoin
+Left output [6]: [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#40, i_class_id#41, i_category_id#42]
+Right output [1]: [d_date_sk#43]
+Arguments: [ss_sold_date_sk#4], [d_date_sk#43], Inner, BuildRight
+
+(60) CometProject
+Input [7]: [ss_quantity#2, ss_list_price#3, ss_sold_date_sk#4, i_brand_id#40, i_class_id#41, i_category_id#42, d_date_sk#43]
+Arguments: [ss_quantity#2, ss_list_price#3, i_brand_id#40, i_class_id#41, i_category_id#42], [ss_quantity#2, ss_list_price#3, i_brand_id#40, i_class_id#41, i_category_id#42]
+
+(61) CometHashAggregate
+Input [5]: [ss_quantity#2, ss_list_price#3, i_brand_id#40, i_class_id#41, i_category_id#42]
+Keys [3]: [i_brand_id#40, i_class_id#41, i_category_id#42]
+Functions [2]: [partial_sum((cast(ss_quantity#2 as decimal(10,0)) * ss_list_price#3)), partial_count(1)]
+
+(62) CometExchange
+Input [6]: [i_brand_id#40, i_class_id#41, i_category_id#42, sum#47, isEmpty#48, count#49]
+Arguments: hashpartitioning(i_brand_id#40, i_class_id#41, i_category_id#42, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=2]
+
+(63) CometHashAggregate
+Input [6]: [i_brand_id#40, i_class_id#41, i_category_id#42, sum#47, isEmpty#48, count#49]
+Keys [3]: [i_brand_id#40, i_class_id#41, i_category_id#42]
+Functions [2]: [sum((cast(ss_quantity#2 as decimal(10,0)) * ss_list_price#3)), count(1)]
+
+(64) CometFilter
+Input [6]: [channel#50, i_brand_id#40, i_class_id#41, i_category_id#42, sales#51, number_sales#52]
+Condition : (isnotnull(sales#51) AND (cast(sales#51 as decimal(32,6)) > cast(Subquery scalar-subquery#53, [id=#54] as decimal(32,6))))
+
+(65) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [4]: [ss_item_sk#55, ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#58), dynamicpruningexpression(ss_sold_date_sk#58 IN dynamicpruning#59)]
+PushedFilters: [IsNotNull(ss_item_sk)]
+ReadSchema: struct
+
+(66) CometFilter
+Input [4]: [ss_item_sk#55, ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58]
+Condition : isnotnull(ss_item_sk#55)
+
+(67) ReusedExchange [Reuses operator id: 46]
+Output [1]: [ss_item_sk#60]
+
+(68) CometBroadcastHashJoin
+Left output [4]: [ss_item_sk#55, ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58]
+Right output [1]: [ss_item_sk#60]
+Arguments: [ss_item_sk#55], [ss_item_sk#60], LeftSemi, BuildRight
+
+(69) ReusedExchange [Reuses operator id: 52]
+Output [4]: [i_item_sk#61, i_brand_id#62, i_class_id#63, i_category_id#64]
+
+(70) CometBroadcastHashJoin
+Left output [4]: [ss_item_sk#55, ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58]
+Right output [4]: [i_item_sk#61, i_brand_id#62, i_class_id#63, i_category_id#64]
+Arguments: [ss_item_sk#55], [i_item_sk#61], Inner, BuildRight
+
+(71) CometProject
+Input [8]: [ss_item_sk#55, ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58, i_item_sk#61, i_brand_id#62, i_class_id#63, i_category_id#64]
+Arguments: [ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58, i_brand_id#62, i_class_id#63, i_category_id#64], [ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58, i_brand_id#62, i_class_id#63, i_category_id#64]
+
+(72) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#65, d_week_seq#66]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_week_seq), EqualTo(d_week_seq,ScalarSubquery#67), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(73) CometFilter
+Input [2]: [d_date_sk#65, d_week_seq#66]
+Condition : ((isnotnull(d_week_seq#66) AND (d_week_seq#66 = ReusedSubquery Subquery scalar-subquery#67, [id=#68])) AND isnotnull(d_date_sk#65))
+
+(74) CometProject
+Input [2]: [d_date_sk#65, d_week_seq#66]
+Arguments: [d_date_sk#65], [d_date_sk#65]
+
+(75) CometBroadcastExchange
+Input [1]: [d_date_sk#65]
+Arguments: [d_date_sk#65]
+
+(76) CometBroadcastHashJoin
+Left output [6]: [ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58, i_brand_id#62, i_class_id#63, i_category_id#64]
+Right output [1]: [d_date_sk#65]
+Arguments: [ss_sold_date_sk#58], [d_date_sk#65], Inner, BuildRight
+
+(77) CometProject
+Input [7]: [ss_quantity#56, ss_list_price#57, ss_sold_date_sk#58, i_brand_id#62, i_class_id#63, i_category_id#64, d_date_sk#65]
+Arguments: [ss_quantity#56, ss_list_price#57, i_brand_id#62, i_class_id#63, i_category_id#64], [ss_quantity#56, ss_list_price#57, i_brand_id#62, i_class_id#63, i_category_id#64]
+
+(78) CometHashAggregate
+Input [5]: [ss_quantity#56, ss_list_price#57, i_brand_id#62, i_class_id#63, i_category_id#64]
+Keys [3]: [i_brand_id#62, i_class_id#63, i_category_id#64]
+Functions [2]: [partial_sum((cast(ss_quantity#56 as decimal(10,0)) * ss_list_price#57)), partial_count(1)]
+
+(79) CometExchange
+Input [6]: [i_brand_id#62, i_class_id#63, i_category_id#64, sum#69, isEmpty#70, count#71]
+Arguments: hashpartitioning(i_brand_id#62, i_class_id#63, i_category_id#64, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=3]
+
+(80) CometHashAggregate
+Input [6]: [i_brand_id#62, i_class_id#63, i_category_id#64, sum#69, isEmpty#70, count#71]
+Keys [3]: [i_brand_id#62, i_class_id#63, i_category_id#64]
+Functions [2]: [sum((cast(ss_quantity#56 as decimal(10,0)) * ss_list_price#57)), count(1)]
+
+(81) CometFilter
+Input [6]: [channel#72, i_brand_id#62, i_class_id#63, i_category_id#64, sales#73, number_sales#74]
+Condition : (isnotnull(sales#73) AND (cast(sales#73 as decimal(32,6)) > cast(ReusedSubquery Subquery scalar-subquery#53, [id=#54] as decimal(32,6))))
+
+(82) CometBroadcastExchange
+Input [6]: [channel#72, i_brand_id#62, i_class_id#63, i_category_id#64, sales#73, number_sales#74]
+Arguments: [channel#72, i_brand_id#62, i_class_id#63, i_category_id#64, sales#73, number_sales#74]
+
+(83) CometBroadcastHashJoin
+Left output [6]: [channel#50, i_brand_id#40, i_class_id#41, i_category_id#42, sales#51, number_sales#52]
+Right output [6]: [channel#72, i_brand_id#62, i_class_id#63, i_category_id#64, sales#73, number_sales#74]
+Arguments: [i_brand_id#40, i_class_id#41, i_category_id#42], [i_brand_id#62, i_class_id#63, i_category_id#64], Inner, BuildRight
+
+(84) CometTakeOrderedAndProject
+Input [12]: [channel#50, i_brand_id#40, i_class_id#41, i_category_id#42, sales#51, number_sales#52, channel#72, i_brand_id#62, i_class_id#63, i_category_id#64, sales#73, number_sales#74]
+Arguments: TakeOrderedAndProject(limit=100, orderBy=[i_brand_id#40 ASC NULLS FIRST,i_class_id#41 ASC NULLS FIRST,i_category_id#42 ASC NULLS FIRST], output=[channel#50,i_brand_id#40,i_class_id#41,i_category_id#42,sales#51,number_sales#52,channel#72,i_brand_id#62,i_class_id#63,i_category_id#64,sales#73,number_sales#74]), [channel#50, i_brand_id#40, i_class_id#41, i_category_id#42, sales#51, number_sales#52, channel#72, i_brand_id#62, i_class_id#63, i_category_id#64, sales#73, number_sales#74], 100, 0, [i_brand_id#40 ASC NULLS FIRST, i_class_id#41 ASC NULLS FIRST, i_category_id#42 ASC NULLS FIRST], [channel#50, i_brand_id#40, i_class_id#41, i_category_id#42, sales#51, number_sales#52, channel#72, i_brand_id#62, i_class_id#63, i_category_id#64, sales#73, number_sales#74]
+
+(85) CometColumnarToRow [codegen id : 1]
+Input [12]: [channel#50, i_brand_id#40, i_class_id#41, i_category_id#42, sales#51, number_sales#52, channel#72, i_brand_id#62, i_class_id#63, i_category_id#64, sales#73, number_sales#74]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 64 Hosting Expression = Subquery scalar-subquery#53, [id=#54]
+* CometColumnarToRow (102)
++- CometHashAggregate (101)
+ +- CometExchange (100)
+ +- CometHashAggregate (99)
+ +- CometUnion (98)
+ :- CometProject (89)
+ : +- CometBroadcastHashJoin (88)
+ : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (86)
+ : +- ReusedExchange (87)
+ :- CometProject (93)
+ : +- CometBroadcastHashJoin (92)
+ : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (90)
+ : +- ReusedExchange (91)
+ +- CometProject (97)
+ +- CometBroadcastHashJoin (96)
+ :- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales (94)
+ +- ReusedExchange (95)
+
+
+(86) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [3]: [ss_quantity#75, ss_list_price#76, ss_sold_date_sk#77]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#77), dynamicpruningexpression(ss_sold_date_sk#77 IN dynamicpruning#78)]
+ReadSchema: struct
+
+(87) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#79]
+
+(88) CometBroadcastHashJoin
+Left output [3]: [ss_quantity#75, ss_list_price#76, ss_sold_date_sk#77]
+Right output [1]: [d_date_sk#79]
+Arguments: [ss_sold_date_sk#77], [d_date_sk#79], Inner, BuildRight
+
+(89) CometProject
+Input [4]: [ss_quantity#75, ss_list_price#76, ss_sold_date_sk#77, d_date_sk#79]
+Arguments: [quantity#80, list_price#81], [ss_quantity#75 AS quantity#80, ss_list_price#76 AS list_price#81]
+
+(90) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [3]: [cs_quantity#82, cs_list_price#83, cs_sold_date_sk#84]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#84), dynamicpruningexpression(cs_sold_date_sk#84 IN dynamicpruning#85)]
+ReadSchema: struct
+
+(91) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#86]
+
+(92) CometBroadcastHashJoin
+Left output [3]: [cs_quantity#82, cs_list_price#83, cs_sold_date_sk#84]
+Right output [1]: [d_date_sk#86]
+Arguments: [cs_sold_date_sk#84], [d_date_sk#86], Inner, BuildRight
+
+(93) CometProject
+Input [4]: [cs_quantity#82, cs_list_price#83, cs_sold_date_sk#84, d_date_sk#86]
+Arguments: [quantity#87, list_price#88], [cs_quantity#82 AS quantity#87, cs_list_price#83 AS list_price#88]
+
+(94) CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+Output [3]: [ws_quantity#89, ws_list_price#90, ws_sold_date_sk#91]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ws_sold_date_sk#91), dynamicpruningexpression(ws_sold_date_sk#91 IN dynamicpruning#92)]
+ReadSchema: struct
+
+(95) ReusedExchange [Reuses operator id: 19]
+Output [1]: [d_date_sk#93]
+
+(96) CometBroadcastHashJoin
+Left output [3]: [ws_quantity#89, ws_list_price#90, ws_sold_date_sk#91]
+Right output [1]: [d_date_sk#93]
+Arguments: [ws_sold_date_sk#91], [d_date_sk#93], Inner, BuildRight
+
+(97) CometProject
+Input [4]: [ws_quantity#89, ws_list_price#90, ws_sold_date_sk#91, d_date_sk#93]
+Arguments: [quantity#94, list_price#95], [ws_quantity#89 AS quantity#94, ws_list_price#90 AS list_price#95]
+
+(98) CometUnion
+Child 0 Input [2]: [quantity#80, list_price#81]
+Child 1 Input [2]: [quantity#87, list_price#88]
+Child 2 Input [2]: [quantity#94, list_price#95]
+
+(99) CometHashAggregate
+Input [2]: [quantity#80, list_price#81]
+Keys: []
+Functions [1]: [partial_avg((cast(quantity#80 as decimal(10,0)) * list_price#81))]
+
+(100) CometExchange
+Input [2]: [sum#96, count#97]
+Arguments: SinglePartition, ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=4]
+
+(101) CometHashAggregate
+Input [2]: [sum#96, count#97]
+Keys: []
+Functions [1]: [avg((cast(quantity#80 as decimal(10,0)) * list_price#81))]
+
+(102) CometColumnarToRow [codegen id : 1]
+Input [1]: [average_sales#98]
+
+Subquery:2 Hosting operator id = 86 Hosting Expression = ss_sold_date_sk#77 IN dynamicpruning#12
+
+Subquery:3 Hosting operator id = 90 Hosting Expression = cs_sold_date_sk#84 IN dynamicpruning#12
+
+Subquery:4 Hosting operator id = 94 Hosting Expression = ws_sold_date_sk#91 IN dynamicpruning#12
+
+Subquery:5 Hosting operator id = 1 Hosting Expression = ss_sold_date_sk#4 IN dynamicpruning#5
+BroadcastExchange (107)
++- * CometColumnarToRow (106)
+ +- CometProject (105)
+ +- CometFilter (104)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (103)
+
+
+(103) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#43, d_week_seq#44]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_week_seq), EqualTo(d_week_seq,ScalarSubquery#45), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(104) CometFilter
+Input [2]: [d_date_sk#43, d_week_seq#44]
+Condition : ((isnotnull(d_week_seq#44) AND (d_week_seq#44 = ReusedSubquery Subquery scalar-subquery#45, [id=#46])) AND isnotnull(d_date_sk#43))
+
+(105) CometProject
+Input [2]: [d_date_sk#43, d_week_seq#44]
+Arguments: [d_date_sk#43], [d_date_sk#43]
+
+(106) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#43]
+
+(107) BroadcastExchange
+Input [1]: [d_date_sk#43]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=5]
+
+Subquery:6 Hosting operator id = 104 Hosting Expression = ReusedSubquery Subquery scalar-subquery#45, [id=#46]
+
+Subquery:7 Hosting operator id = 103 Hosting Expression = Subquery scalar-subquery#45, [id=#46]
+* CometColumnarToRow (111)
++- CometProject (110)
+ +- CometFilter (109)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (108)
+
+
+(108) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [4]: [d_week_seq#99, d_year#100, d_moy#101, d_dom#102]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), IsNotNull(d_moy), IsNotNull(d_dom), EqualTo(d_year,2000), EqualTo(d_moy,12), EqualTo(d_dom,11)]
+ReadSchema: struct
+
+(109) CometFilter
+Input [4]: [d_week_seq#99, d_year#100, d_moy#101, d_dom#102]
+Condition : (((((isnotnull(d_year#100) AND isnotnull(d_moy#101)) AND isnotnull(d_dom#102)) AND (d_year#100 = 2000)) AND (d_moy#101 = 12)) AND (d_dom#102 = 11))
+
+(110) CometProject
+Input [4]: [d_week_seq#99, d_year#100, d_moy#101, d_dom#102]
+Arguments: [d_week_seq#99], [d_week_seq#99]
+
+(111) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_week_seq#99]
+
+Subquery:8 Hosting operator id = 5 Hosting Expression = ss_sold_date_sk#11 IN dynamicpruning#12
+BroadcastExchange (116)
++- * CometColumnarToRow (115)
+ +- CometProject (114)
+ +- CometFilter (113)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (112)
+
+
+(112) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#26, d_year#103]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), GreaterThanOrEqual(d_year,1999), LessThanOrEqual(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(113) CometFilter
+Input [2]: [d_date_sk#26, d_year#103]
+Condition : (((isnotnull(d_year#103) AND (d_year#103 >= 1999)) AND (d_year#103 <= 2001)) AND isnotnull(d_date_sk#26))
+
+(114) CometProject
+Input [2]: [d_date_sk#26, d_year#103]
+Arguments: [d_date_sk#26], [d_date_sk#26]
+
+(115) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#26]
+
+(116) BroadcastExchange
+Input [1]: [d_date_sk#26]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=6]
+
+Subquery:9 Hosting operator id = 9 Hosting Expression = cs_sold_date_sk#18 IN dynamicpruning#12
+
+Subquery:10 Hosting operator id = 33 Hosting Expression = ws_sold_date_sk#31 IN dynamicpruning#12
+
+Subquery:11 Hosting operator id = 56 Hosting Expression = ReusedSubquery Subquery scalar-subquery#45, [id=#46]
+
+Subquery:12 Hosting operator id = 55 Hosting Expression = ReusedSubquery Subquery scalar-subquery#45, [id=#46]
+
+Subquery:13 Hosting operator id = 81 Hosting Expression = ReusedSubquery Subquery scalar-subquery#53, [id=#54]
+
+Subquery:14 Hosting operator id = 65 Hosting Expression = ss_sold_date_sk#58 IN dynamicpruning#59
+BroadcastExchange (121)
++- * CometColumnarToRow (120)
+ +- CometProject (119)
+ +- CometFilter (118)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (117)
+
+
+(117) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#65, d_week_seq#66]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_week_seq), EqualTo(d_week_seq,ScalarSubquery#67), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(118) CometFilter
+Input [2]: [d_date_sk#65, d_week_seq#66]
+Condition : ((isnotnull(d_week_seq#66) AND (d_week_seq#66 = ReusedSubquery Subquery scalar-subquery#67, [id=#68])) AND isnotnull(d_date_sk#65))
+
+(119) CometProject
+Input [2]: [d_date_sk#65, d_week_seq#66]
+Arguments: [d_date_sk#65], [d_date_sk#65]
+
+(120) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#65]
+
+(121) BroadcastExchange
+Input [1]: [d_date_sk#65]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=7]
+
+Subquery:15 Hosting operator id = 118 Hosting Expression = ReusedSubquery Subquery scalar-subquery#67, [id=#68]
+
+Subquery:16 Hosting operator id = 117 Hosting Expression = Subquery scalar-subquery#67, [id=#68]
+* CometColumnarToRow (125)
++- CometProject (124)
+ +- CometFilter (123)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (122)
+
+
+(122) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [4]: [d_week_seq#104, d_year#105, d_moy#106, d_dom#107]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_year), IsNotNull(d_moy), IsNotNull(d_dom), EqualTo(d_year,1999), EqualTo(d_moy,12), EqualTo(d_dom,11)]
+ReadSchema: struct
+
+(123) CometFilter
+Input [4]: [d_week_seq#104, d_year#105, d_moy#106, d_dom#107]
+Condition : (((((isnotnull(d_year#105) AND isnotnull(d_moy#106)) AND isnotnull(d_dom#107)) AND (d_year#105 = 1999)) AND (d_moy#106 = 12)) AND (d_dom#107 = 11))
+
+(124) CometProject
+Input [4]: [d_week_seq#104, d_year#105, d_moy#106, d_dom#107]
+Arguments: [d_week_seq#104], [d_week_seq#104]
+
+(125) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_week_seq#104]
+
+Subquery:17 Hosting operator id = 73 Hosting Expression = ReusedSubquery Subquery scalar-subquery#67, [id=#68]
+
+Subquery:18 Hosting operator id = 72 Hosting Expression = ReusedSubquery Subquery scalar-subquery#67, [id=#68]
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b/extended.txt
new file mode 100644
index 0000000000..b32dd95954
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b/extended.txt
@@ -0,0 +1,343 @@
+CometColumnarToRow
++- CometTakeOrderedAndProject
+ +- CometBroadcastHashJoin
+ :- CometFilter
+ : : +- Subquery
+ : : +- CometColumnarToRow
+ : : +- CometHashAggregate
+ : : +- CometExchange
+ : : +- CometHashAggregate
+ : : +- CometUnion
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : +- ReusedSubquery
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometHashAggregate
+ : +- CometExchange
+ : +- CometHashAggregate
+ : +- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : : +- ReusedSubquery
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- Subquery
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometHashAggregate
+ : : : : +- CometExchange
+ : : : : +- CometHashAggregate
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : : +- SubqueryBroadcast
+ : : : : : : +- BroadcastExchange
+ : : : : : : +- CometColumnarToRow
+ : : : : : : +- CometProject
+ : : : : : : +- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometProject
+ : : : : : : +- CometBroadcastHashJoin
+ : : : : : : :- CometFilter
+ : : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : : : +- ReusedSubquery
+ : : : : : : +- CometBroadcastExchange
+ : : : : : : +- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : : +- ReusedSubquery
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometBroadcastHashJoin
+ : : :- CometHashAggregate
+ : : : +- CometExchange
+ : : : +- CometHashAggregate
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : : +- ReusedSubquery
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : : +- ReusedSubquery
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- ReusedSubquery
+ +- CometBroadcastExchange
+ +- CometFilter
+ : +- ReusedSubquery
+ +- CometHashAggregate
+ +- CometExchange
+ +- CometHashAggregate
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : +- SubqueryBroadcast
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : : +- ReusedSubquery
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- Subquery
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometBroadcastHashJoin
+ : : :- CometHashAggregate
+ : : : +- CometExchange
+ : : : +- CometHashAggregate
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : : +- SubqueryBroadcast
+ : : : : : +- BroadcastExchange
+ : : : : : +- CometColumnarToRow
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometProject
+ : : : : : +- CometBroadcastHashJoin
+ : : : : : :- CometFilter
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : : +- ReusedSubquery
+ : : : : : +- CometBroadcastExchange
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : : +- ReusedSubquery
+ : : : +- CometBroadcastExchange
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometBroadcastHashJoin
+ : :- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : +- CometBroadcastExchange
+ : +- CometBroadcastHashJoin
+ : :- CometHashAggregate
+ : : +- CometExchange
+ : : +- CometHashAggregate
+ : : +- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+ : : : : +- SubqueryBroadcast
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : : +- CometBroadcastExchange
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometBroadcastHashJoin
+ : : : :- CometProject
+ : : : : +- CometBroadcastHashJoin
+ : : : : :- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : : +- ReusedSubquery
+ : : : : +- CometBroadcastExchange
+ : : : : +- CometFilter
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : : : +- CometBroadcastExchange
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales
+ : : : +- ReusedSubquery
+ : : +- CometBroadcastExchange
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ +- CometBroadcastExchange
+ +- CometProject
+ +- CometFilter
+ : +- ReusedSubquery
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ +- ReusedSubquery
+
+Comet accelerated 298 out of 331 eligible operators (90%). Final plan contains 10 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b/simplified.txt
new file mode 100644
index 0000000000..6b5264b76d
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q14b/simplified.txt
@@ -0,0 +1,157 @@
+WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometTakeOrderedAndProject [channel,i_brand_id,i_class_id,i_category_id,sales,number_sales,channel,i_brand_id,i_class_id,i_category_id,sales,number_sales]
+ CometBroadcastHashJoin [channel,i_brand_id,i_class_id,i_category_id,sales,number_sales,channel,i_brand_id,i_class_id,i_category_id,sales,number_sales]
+ CometFilter [channel,i_brand_id,i_class_id,i_category_id,sales,number_sales]
+ Subquery #4
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometHashAggregate [sum,count] [average_sales,avg((cast(quantity as decimal(10,0)) * list_price))]
+ CometExchange #14
+ CometHashAggregate [quantity,list_price] [sum,count]
+ CometUnion [quantity,list_price]
+ CometProject [ss_quantity,ss_list_price] [quantity,list_price]
+ CometBroadcastHashJoin [ss_quantity,ss_list_price,ss_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_quantity,ss_list_price,ss_sold_date_sk]
+ ReusedSubquery [d_date_sk] #3
+ ReusedExchange [d_date_sk] #10
+ CometProject [cs_quantity,cs_list_price] [quantity,list_price]
+ CometBroadcastHashJoin [cs_quantity,cs_list_price,cs_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_quantity,cs_list_price,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #3
+ ReusedExchange [d_date_sk] #10
+ CometProject [ws_quantity,ws_list_price] [quantity,list_price]
+ CometBroadcastHashJoin [ws_quantity,ws_list_price,ws_sold_date_sk,d_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_quantity,ws_list_price,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #3
+ ReusedExchange [d_date_sk] #10
+ CometHashAggregate [sum,isEmpty,count] [channel,i_brand_id,i_class_id,i_category_id,sales,number_sales,sum((cast(ss_quantity as decimal(10,0)) * ss_list_price)),count(1)]
+ CometExchange [i_brand_id,i_class_id,i_category_id] #1
+ CometHashAggregate [ss_quantity,ss_list_price] [i_brand_id,i_class_id,i_category_id,sum,isEmpty,count]
+ CometProject [ss_quantity,ss_list_price,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_quantity,ss_list_price,ss_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [ss_quantity,ss_list_price,ss_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk,ss_item_sk]
+ CometFilter [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #2
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_week_seq]
+ ReusedSubquery [d_week_seq] #2
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_week_seq]
+ Subquery #2
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_week_seq]
+ CometFilter [d_week_seq,d_year,d_moy,d_dom]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_week_seq,d_year,d_moy,d_dom]
+ CometBroadcastExchange [ss_item_sk] #3
+ CometProject [i_item_sk] [ss_item_sk]
+ CometBroadcastHashJoin [i_item_sk,i_brand_id,i_class_id,i_category_id,brand_id,class_id,category_id]
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastExchange [brand_id,class_id,category_id] #4
+ CometBroadcastHashJoin [brand_id,class_id,category_id,i_brand_id,i_class_id,i_category_id]
+ CometHashAggregate [brand_id,class_id,category_id]
+ CometExchange [brand_id,class_id,category_id] #5
+ CometHashAggregate [brand_id,class_id,category_id]
+ CometProject [i_brand_id,i_class_id,i_category_id] [brand_id,class_id,category_id]
+ CometBroadcastHashJoin [ss_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [ss_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_item_sk,ss_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometFilter [ss_item_sk,ss_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_item_sk,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #3
+ BroadcastExchange #6
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ CometBroadcastExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #7
+ CometBroadcastHashJoin [i_item_sk,i_brand_id,i_class_id,i_category_id,i_brand_id,i_class_id,i_category_id]
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastExchange [i_brand_id,i_class_id,i_category_id] #8
+ CometProject [i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [cs_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [cs_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [cs_item_sk,cs_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometFilter [cs_item_sk,cs_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_item_sk,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #3
+ CometBroadcastExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #9
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastExchange [d_date_sk] #10
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year]
+ ReusedExchange [d_date_sk] #10
+ CometBroadcastExchange [i_brand_id,i_class_id,i_category_id] #11
+ CometProject [i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ws_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [ws_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ws_item_sk,ws_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometFilter [ws_item_sk,ws_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.web_sales [ws_item_sk,ws_sold_date_sk]
+ ReusedSubquery [d_date_sk] #3
+ ReusedExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #9
+ ReusedExchange [d_date_sk] #10
+ CometBroadcastExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #12
+ CometBroadcastHashJoin [i_item_sk,i_brand_id,i_class_id,i_category_id,ss_item_sk]
+ CometFilter [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.item [i_item_sk,i_brand_id,i_class_id,i_category_id]
+ ReusedExchange [ss_item_sk] #3
+ CometBroadcastExchange [d_date_sk] #13
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_week_seq]
+ ReusedSubquery [d_week_seq] #2
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_week_seq]
+ ReusedSubquery [d_week_seq] #2
+ CometBroadcastExchange [channel,i_brand_id,i_class_id,i_category_id,sales,number_sales] #15
+ CometFilter [channel,i_brand_id,i_class_id,i_category_id,sales,number_sales]
+ ReusedSubquery [average_sales] #4
+ CometHashAggregate [sum,isEmpty,count] [channel,i_brand_id,i_class_id,i_category_id,sales,number_sales,sum((cast(ss_quantity as decimal(10,0)) * ss_list_price)),count(1)]
+ CometExchange [i_brand_id,i_class_id,i_category_id] #16
+ CometHashAggregate [ss_quantity,ss_list_price] [i_brand_id,i_class_id,i_category_id,sum,isEmpty,count]
+ CometProject [ss_quantity,ss_list_price,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_quantity,ss_list_price,ss_sold_date_sk,i_brand_id,i_class_id,i_category_id,d_date_sk]
+ CometProject [ss_quantity,ss_list_price,ss_sold_date_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk,i_item_sk,i_brand_id,i_class_id,i_category_id]
+ CometBroadcastHashJoin [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk,ss_item_sk]
+ CometFilter [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales [ss_item_sk,ss_quantity,ss_list_price,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #5
+ BroadcastExchange #17
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_week_seq]
+ ReusedSubquery [d_week_seq] #6
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_week_seq]
+ Subquery #6
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_week_seq]
+ CometFilter [d_week_seq,d_year,d_moy,d_dom]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_week_seq,d_year,d_moy,d_dom]
+ ReusedExchange [ss_item_sk] #3
+ ReusedExchange [i_item_sk,i_brand_id,i_class_id,i_category_id] #12
+ CometBroadcastExchange [d_date_sk] #18
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_week_seq]
+ ReusedSubquery [d_week_seq] #6
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_week_seq]
+ ReusedSubquery [d_week_seq] #6
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_datafusion/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_datafusion/explain.txt
new file mode 100644
index 0000000000..ddc9c5e253
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_datafusion/explain.txt
@@ -0,0 +1,173 @@
+== Physical Plan ==
+TakeOrderedAndProject (24)
++- * HashAggregate (23)
+ +- * CometColumnarToRow (22)
+ +- CometColumnarExchange (21)
+ +- * HashAggregate (20)
+ +- * Project (19)
+ +- * BroadcastHashJoin Inner BuildRight (18)
+ :- * Project (16)
+ : +- * BroadcastHashJoin Inner BuildRight (15)
+ : :- * Project (9)
+ : : +- * BroadcastHashJoin Inner BuildRight (8)
+ : : :- * Filter (3)
+ : : : +- * ColumnarToRow (2)
+ : : : +- Scan parquet spark_catalog.default.catalog_sales (1)
+ : : +- BroadcastExchange (7)
+ : : +- * CometColumnarToRow (6)
+ : : +- CometFilter (5)
+ : : +- CometNativeScan parquet spark_catalog.default.customer (4)
+ : +- BroadcastExchange (14)
+ : +- * CometColumnarToRow (13)
+ : +- CometProject (12)
+ : +- CometFilter (11)
+ : +- CometNativeScan parquet spark_catalog.default.customer_address (10)
+ +- ReusedExchange (17)
+
+
+(1) Scan parquet spark_catalog.default.catalog_sales
+Output [3]: [cs_bill_customer_sk#1, cs_sales_price#2, cs_sold_date_sk#3]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#3), dynamicpruningexpression(cs_sold_date_sk#3 IN dynamicpruning#4)]
+PushedFilters: [IsNotNull(cs_bill_customer_sk)]
+ReadSchema: struct
+
+(2) ColumnarToRow [codegen id : 4]
+Input [3]: [cs_bill_customer_sk#1, cs_sales_price#2, cs_sold_date_sk#3]
+
+(3) Filter [codegen id : 4]
+Input [3]: [cs_bill_customer_sk#1, cs_sales_price#2, cs_sold_date_sk#3]
+Condition : isnotnull(cs_bill_customer_sk#1)
+
+(4) CometNativeScan parquet spark_catalog.default.customer
+Output [2]: [c_customer_sk#5, c_current_addr_sk#6]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk), IsNotNull(c_current_addr_sk)]
+ReadSchema: struct
+
+(5) CometFilter
+Input [2]: [c_customer_sk#5, c_current_addr_sk#6]
+Condition : (isnotnull(c_customer_sk#5) AND isnotnull(c_current_addr_sk#6))
+
+(6) CometColumnarToRow [codegen id : 1]
+Input [2]: [c_customer_sk#5, c_current_addr_sk#6]
+
+(7) BroadcastExchange
+Input [2]: [c_customer_sk#5, c_current_addr_sk#6]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=1]
+
+(8) BroadcastHashJoin [codegen id : 4]
+Left keys [1]: [cs_bill_customer_sk#1]
+Right keys [1]: [c_customer_sk#5]
+Join type: Inner
+Join condition: None
+
+(9) Project [codegen id : 4]
+Output [3]: [cs_sales_price#2, cs_sold_date_sk#3, c_current_addr_sk#6]
+Input [5]: [cs_bill_customer_sk#1, cs_sales_price#2, cs_sold_date_sk#3, c_customer_sk#5, c_current_addr_sk#6]
+
+(10) CometNativeScan parquet spark_catalog.default.customer_address
+Output [3]: [ca_address_sk#7, ca_state#8, ca_zip#9]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_address]
+PushedFilters: [IsNotNull(ca_address_sk)]
+ReadSchema: struct
+
+(11) CometFilter
+Input [3]: [ca_address_sk#7, ca_state#8, ca_zip#9]
+Condition : isnotnull(ca_address_sk#7)
+
+(12) CometProject
+Input [3]: [ca_address_sk#7, ca_state#8, ca_zip#9]
+Arguments: [ca_address_sk#7, ca_state#10, ca_zip#11], [ca_address_sk#7, static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#8, 2)) AS ca_state#10, static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_zip#9, 10)) AS ca_zip#11]
+
+(13) CometColumnarToRow [codegen id : 2]
+Input [3]: [ca_address_sk#7, ca_state#10, ca_zip#11]
+
+(14) BroadcastExchange
+Input [3]: [ca_address_sk#7, ca_state#10, ca_zip#11]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=2]
+
+(15) BroadcastHashJoin [codegen id : 4]
+Left keys [1]: [c_current_addr_sk#6]
+Right keys [1]: [ca_address_sk#7]
+Join type: Inner
+Join condition: ((substr(ca_zip#11, 1, 5) IN (85669,86197,88274,83405,86475,85392,85460,80348,81792) OR ca_state#10 IN (CA,WA,GA)) OR (cs_sales_price#2 > 500.00))
+
+(16) Project [codegen id : 4]
+Output [3]: [cs_sales_price#2, cs_sold_date_sk#3, ca_zip#11]
+Input [6]: [cs_sales_price#2, cs_sold_date_sk#3, c_current_addr_sk#6, ca_address_sk#7, ca_state#10, ca_zip#11]
+
+(17) ReusedExchange [Reuses operator id: 29]
+Output [1]: [d_date_sk#12]
+
+(18) BroadcastHashJoin [codegen id : 4]
+Left keys [1]: [cs_sold_date_sk#3]
+Right keys [1]: [d_date_sk#12]
+Join type: Inner
+Join condition: None
+
+(19) Project [codegen id : 4]
+Output [2]: [cs_sales_price#2, ca_zip#11]
+Input [4]: [cs_sales_price#2, cs_sold_date_sk#3, ca_zip#11, d_date_sk#12]
+
+(20) HashAggregate [codegen id : 4]
+Input [2]: [cs_sales_price#2, ca_zip#11]
+Keys [1]: [ca_zip#11]
+Functions [1]: [partial_sum(UnscaledValue(cs_sales_price#2))]
+Aggregate Attributes [1]: [sum#13]
+Results [2]: [ca_zip#11, sum#14]
+
+(21) CometColumnarExchange
+Input [2]: [ca_zip#11, sum#14]
+Arguments: hashpartitioning(ca_zip#11, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=3]
+
+(22) CometColumnarToRow [codegen id : 5]
+Input [2]: [ca_zip#11, sum#14]
+
+(23) HashAggregate [codegen id : 5]
+Input [2]: [ca_zip#11, sum#14]
+Keys [1]: [ca_zip#11]
+Functions [1]: [sum(UnscaledValue(cs_sales_price#2))]
+Aggregate Attributes [1]: [sum(UnscaledValue(cs_sales_price#2))#15]
+Results [2]: [ca_zip#11, MakeDecimal(sum(UnscaledValue(cs_sales_price#2))#15,17,2) AS sum(cs_sales_price)#16]
+
+(24) TakeOrderedAndProject
+Input [2]: [ca_zip#11, sum(cs_sales_price)#16]
+Arguments: 100, [ca_zip#11 ASC NULLS FIRST], [ca_zip#11, sum(cs_sales_price)#16]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 1 Hosting Expression = cs_sold_date_sk#3 IN dynamicpruning#4
+BroadcastExchange (29)
++- * CometColumnarToRow (28)
+ +- CometProject (27)
+ +- CometFilter (26)
+ +- CometNativeScan parquet spark_catalog.default.date_dim (25)
+
+
+(25) CometNativeScan parquet spark_catalog.default.date_dim
+Output [3]: [d_date_sk#12, d_year#17, d_qoy#18]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_qoy), IsNotNull(d_year), EqualTo(d_qoy,2), EqualTo(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(26) CometFilter
+Input [3]: [d_date_sk#12, d_year#17, d_qoy#18]
+Condition : ((((isnotnull(d_qoy#18) AND isnotnull(d_year#17)) AND (d_qoy#18 = 2)) AND (d_year#17 = 2001)) AND isnotnull(d_date_sk#12))
+
+(27) CometProject
+Input [3]: [d_date_sk#12, d_year#17, d_qoy#18]
+Arguments: [d_date_sk#12], [d_date_sk#12]
+
+(28) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#12]
+
+(29) BroadcastExchange
+Input [1]: [d_date_sk#12]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=4]
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_datafusion/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_datafusion/extended.txt
new file mode 100644
index 0000000000..8ed98bc5cb
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_datafusion/extended.txt
@@ -0,0 +1,36 @@
+TakeOrderedAndProject
++- HashAggregate
+ +- CometColumnarToRow
+ +- CometColumnarExchange
+ +- HashAggregate
+ +- Project
+ +- BroadcastHashJoin
+ :- Project
+ : +- BroadcastHashJoin
+ : :- Project
+ : : +- BroadcastHashJoin
+ : : :- Filter
+ : : : +- ColumnarToRow
+ : : : +- Scan parquet spark_catalog.default.catalog_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : +- SubqueryBroadcast
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.customer
+ : +- BroadcastExchange
+ : +- CometColumnarToRow
+ : +- CometProject
+ : +- CometFilter
+ : +- CometNativeScan parquet spark_catalog.default.customer_address
+ +- BroadcastExchange
+ +- CometColumnarToRow
+ +- CometProject
+ +- CometFilter
+ +- CometNativeScan parquet spark_catalog.default.date_dim
+
+Comet accelerated 12 out of 28 eligible operators (42%). Final plan contains 6 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_datafusion/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_datafusion/simplified.txt
new file mode 100644
index 0000000000..f31442dcfe
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_datafusion/simplified.txt
@@ -0,0 +1,43 @@
+TakeOrderedAndProject [ca_zip,sum(cs_sales_price)]
+ WholeStageCodegen (5)
+ HashAggregate [ca_zip,sum] [sum(UnscaledValue(cs_sales_price)),sum(cs_sales_price),sum]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [ca_zip] #1
+ WholeStageCodegen (4)
+ HashAggregate [ca_zip,cs_sales_price] [sum,sum]
+ Project [cs_sales_price,ca_zip]
+ BroadcastHashJoin [cs_sold_date_sk,d_date_sk]
+ Project [cs_sales_price,cs_sold_date_sk,ca_zip]
+ BroadcastHashJoin [c_current_addr_sk,ca_address_sk,ca_zip,ca_state,cs_sales_price]
+ Project [cs_sales_price,cs_sold_date_sk,c_current_addr_sk]
+ BroadcastHashJoin [cs_bill_customer_sk,c_customer_sk]
+ Filter [cs_bill_customer_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.catalog_sales [cs_bill_customer_sk,cs_sales_price,cs_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #2
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year,d_qoy]
+ CometNativeScan parquet spark_catalog.default.date_dim [d_date_sk,d_year,d_qoy]
+ InputAdapter
+ BroadcastExchange #3
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometFilter [c_customer_sk,c_current_addr_sk]
+ CometNativeScan parquet spark_catalog.default.customer [c_customer_sk,c_current_addr_sk]
+ InputAdapter
+ BroadcastExchange #4
+ WholeStageCodegen (2)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [ca_state,ca_zip] [ca_address_sk,ca_state,ca_zip]
+ CometFilter [ca_address_sk,ca_state,ca_zip]
+ CometNativeScan parquet spark_catalog.default.customer_address [ca_address_sk,ca_state,ca_zip]
+ InputAdapter
+ ReusedExchange [d_date_sk] #2
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_iceberg_compat/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_iceberg_compat/explain.txt
new file mode 100644
index 0000000000..8a4fb53ece
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_iceberg_compat/explain.txt
@@ -0,0 +1,173 @@
+== Physical Plan ==
+* CometColumnarToRow (24)
++- CometTakeOrderedAndProject (23)
+ +- CometHashAggregate (22)
+ +- CometExchange (21)
+ +- CometHashAggregate (20)
+ +- CometProject (19)
+ +- CometBroadcastHashJoin (18)
+ :- CometProject (13)
+ : +- CometBroadcastHashJoin (12)
+ : :- CometProject (7)
+ : : +- CometBroadcastHashJoin (6)
+ : : :- CometFilter (2)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (1)
+ : : +- CometBroadcastExchange (5)
+ : : +- CometFilter (4)
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer (3)
+ : +- CometBroadcastExchange (11)
+ : +- CometProject (10)
+ : +- CometFilter (9)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address (8)
+ +- CometBroadcastExchange (17)
+ +- CometProject (16)
+ +- CometFilter (15)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (14)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [3]: [cs_bill_customer_sk#1, cs_sales_price#2, cs_sold_date_sk#3]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#3), dynamicpruningexpression(cs_sold_date_sk#3 IN dynamicpruning#4)]
+PushedFilters: [IsNotNull(cs_bill_customer_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [3]: [cs_bill_customer_sk#1, cs_sales_price#2, cs_sold_date_sk#3]
+Condition : isnotnull(cs_bill_customer_sk#1)
+
+(3) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+Output [2]: [c_customer_sk#5, c_current_addr_sk#6]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk), IsNotNull(c_current_addr_sk)]
+ReadSchema: struct
+
+(4) CometFilter
+Input [2]: [c_customer_sk#5, c_current_addr_sk#6]
+Condition : (isnotnull(c_customer_sk#5) AND isnotnull(c_current_addr_sk#6))
+
+(5) CometBroadcastExchange
+Input [2]: [c_customer_sk#5, c_current_addr_sk#6]
+Arguments: [c_customer_sk#5, c_current_addr_sk#6]
+
+(6) CometBroadcastHashJoin
+Left output [3]: [cs_bill_customer_sk#1, cs_sales_price#2, cs_sold_date_sk#3]
+Right output [2]: [c_customer_sk#5, c_current_addr_sk#6]
+Arguments: [cs_bill_customer_sk#1], [c_customer_sk#5], Inner, BuildRight
+
+(7) CometProject
+Input [5]: [cs_bill_customer_sk#1, cs_sales_price#2, cs_sold_date_sk#3, c_customer_sk#5, c_current_addr_sk#6]
+Arguments: [cs_sales_price#2, cs_sold_date_sk#3, c_current_addr_sk#6], [cs_sales_price#2, cs_sold_date_sk#3, c_current_addr_sk#6]
+
+(8) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address
+Output [3]: [ca_address_sk#7, ca_state#8, ca_zip#9]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_address]
+PushedFilters: [IsNotNull(ca_address_sk)]
+ReadSchema: struct
+
+(9) CometFilter
+Input [3]: [ca_address_sk#7, ca_state#8, ca_zip#9]
+Condition : isnotnull(ca_address_sk#7)
+
+(10) CometProject
+Input [3]: [ca_address_sk#7, ca_state#8, ca_zip#9]
+Arguments: [ca_address_sk#7, ca_state#10, ca_zip#11], [ca_address_sk#7, static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#8, 2)) AS ca_state#10, static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_zip#9, 10)) AS ca_zip#11]
+
+(11) CometBroadcastExchange
+Input [3]: [ca_address_sk#7, ca_state#10, ca_zip#11]
+Arguments: [ca_address_sk#7, ca_state#10, ca_zip#11]
+
+(12) CometBroadcastHashJoin
+Left output [3]: [cs_sales_price#2, cs_sold_date_sk#3, c_current_addr_sk#6]
+Right output [3]: [ca_address_sk#7, ca_state#10, ca_zip#11]
+Arguments: [c_current_addr_sk#6], [ca_address_sk#7], Inner, ((substr(ca_zip#11, 1, 5) IN (85669,86197,88274,83405,86475,85392,85460,80348,81792) OR ca_state#10 IN (CA,WA,GA)) OR (cs_sales_price#2 > 500.00)), BuildRight
+
+(13) CometProject
+Input [6]: [cs_sales_price#2, cs_sold_date_sk#3, c_current_addr_sk#6, ca_address_sk#7, ca_state#10, ca_zip#11]
+Arguments: [cs_sales_price#2, cs_sold_date_sk#3, ca_zip#11], [cs_sales_price#2, cs_sold_date_sk#3, ca_zip#11]
+
+(14) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [3]: [d_date_sk#12, d_year#13, d_qoy#14]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_qoy), IsNotNull(d_year), EqualTo(d_qoy,2), EqualTo(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(15) CometFilter
+Input [3]: [d_date_sk#12, d_year#13, d_qoy#14]
+Condition : ((((isnotnull(d_qoy#14) AND isnotnull(d_year#13)) AND (d_qoy#14 = 2)) AND (d_year#13 = 2001)) AND isnotnull(d_date_sk#12))
+
+(16) CometProject
+Input [3]: [d_date_sk#12, d_year#13, d_qoy#14]
+Arguments: [d_date_sk#12], [d_date_sk#12]
+
+(17) CometBroadcastExchange
+Input [1]: [d_date_sk#12]
+Arguments: [d_date_sk#12]
+
+(18) CometBroadcastHashJoin
+Left output [3]: [cs_sales_price#2, cs_sold_date_sk#3, ca_zip#11]
+Right output [1]: [d_date_sk#12]
+Arguments: [cs_sold_date_sk#3], [d_date_sk#12], Inner, BuildRight
+
+(19) CometProject
+Input [4]: [cs_sales_price#2, cs_sold_date_sk#3, ca_zip#11, d_date_sk#12]
+Arguments: [cs_sales_price#2, ca_zip#11], [cs_sales_price#2, ca_zip#11]
+
+(20) CometHashAggregate
+Input [2]: [cs_sales_price#2, ca_zip#11]
+Keys [1]: [ca_zip#11]
+Functions [1]: [partial_sum(UnscaledValue(cs_sales_price#2))]
+
+(21) CometExchange
+Input [2]: [ca_zip#11, sum#15]
+Arguments: hashpartitioning(ca_zip#11, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=1]
+
+(22) CometHashAggregate
+Input [2]: [ca_zip#11, sum#15]
+Keys [1]: [ca_zip#11]
+Functions [1]: [sum(UnscaledValue(cs_sales_price#2))]
+
+(23) CometTakeOrderedAndProject
+Input [2]: [ca_zip#11, sum(cs_sales_price)#16]
+Arguments: TakeOrderedAndProject(limit=100, orderBy=[ca_zip#11 ASC NULLS FIRST], output=[ca_zip#11,sum(cs_sales_price)#16]), [ca_zip#11, sum(cs_sales_price)#16], 100, 0, [ca_zip#11 ASC NULLS FIRST], [ca_zip#11, sum(cs_sales_price)#16]
+
+(24) CometColumnarToRow [codegen id : 1]
+Input [2]: [ca_zip#11, sum(cs_sales_price)#16]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 1 Hosting Expression = cs_sold_date_sk#3 IN dynamicpruning#4
+BroadcastExchange (29)
++- * CometColumnarToRow (28)
+ +- CometProject (27)
+ +- CometFilter (26)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (25)
+
+
+(25) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [3]: [d_date_sk#12, d_year#13, d_qoy#14]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_qoy), IsNotNull(d_year), EqualTo(d_qoy,2), EqualTo(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(26) CometFilter
+Input [3]: [d_date_sk#12, d_year#13, d_qoy#14]
+Condition : ((((isnotnull(d_qoy#14) AND isnotnull(d_year#13)) AND (d_qoy#14 = 2)) AND (d_year#13 = 2001)) AND isnotnull(d_date_sk#12))
+
+(27) CometProject
+Input [3]: [d_date_sk#12, d_year#13, d_qoy#14]
+Arguments: [d_date_sk#12], [d_date_sk#12]
+
+(28) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#12]
+
+(29) BroadcastExchange
+Input [1]: [d_date_sk#12]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=2]
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_iceberg_compat/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_iceberg_compat/extended.txt
new file mode 100644
index 0000000000..6de0c64850
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_iceberg_compat/extended.txt
@@ -0,0 +1,32 @@
+CometColumnarToRow
++- CometTakeOrderedAndProject
+ +- CometHashAggregate
+ +- CometExchange
+ +- CometHashAggregate
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : +- SubqueryBroadcast
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address
+ +- CometBroadcastExchange
+ +- CometProject
+ +- CometFilter
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+
+Comet accelerated 26 out of 28 eligible operators (92%). Final plan contains 2 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_iceberg_compat/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_iceberg_compat/simplified.txt
new file mode 100644
index 0000000000..c39b96efe3
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15.native_iceberg_compat/simplified.txt
@@ -0,0 +1,34 @@
+WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometTakeOrderedAndProject [ca_zip,sum(cs_sales_price)]
+ CometHashAggregate [sum] [ca_zip,sum(cs_sales_price),sum(UnscaledValue(cs_sales_price))]
+ CometExchange [ca_zip] #1
+ CometHashAggregate [cs_sales_price] [ca_zip,sum]
+ CometProject [cs_sales_price,ca_zip]
+ CometBroadcastHashJoin [cs_sales_price,cs_sold_date_sk,ca_zip,d_date_sk]
+ CometProject [cs_sales_price,cs_sold_date_sk,ca_zip]
+ CometBroadcastHashJoin [cs_sales_price,cs_sold_date_sk,c_current_addr_sk,ca_address_sk,ca_state,ca_zip]
+ CometProject [cs_sales_price,cs_sold_date_sk,c_current_addr_sk]
+ CometBroadcastHashJoin [cs_bill_customer_sk,cs_sales_price,cs_sold_date_sk,c_customer_sk,c_current_addr_sk]
+ CometFilter [cs_bill_customer_sk,cs_sales_price,cs_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_bill_customer_sk,cs_sales_price,cs_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #2
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year,d_qoy]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year,d_qoy]
+ CometBroadcastExchange [c_customer_sk,c_current_addr_sk] #3
+ CometFilter [c_customer_sk,c_current_addr_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer [c_customer_sk,c_current_addr_sk]
+ CometBroadcastExchange [ca_address_sk,ca_state,ca_zip] #4
+ CometProject [ca_state,ca_zip] [ca_address_sk,ca_state,ca_zip]
+ CometFilter [ca_address_sk,ca_state,ca_zip]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address [ca_address_sk,ca_state,ca_zip]
+ CometBroadcastExchange [d_date_sk] #5
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year,d_qoy]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year,d_qoy]
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15/explain.txt
new file mode 100644
index 0000000000..8a4fb53ece
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15/explain.txt
@@ -0,0 +1,173 @@
+== Physical Plan ==
+* CometColumnarToRow (24)
++- CometTakeOrderedAndProject (23)
+ +- CometHashAggregate (22)
+ +- CometExchange (21)
+ +- CometHashAggregate (20)
+ +- CometProject (19)
+ +- CometBroadcastHashJoin (18)
+ :- CometProject (13)
+ : +- CometBroadcastHashJoin (12)
+ : :- CometProject (7)
+ : : +- CometBroadcastHashJoin (6)
+ : : :- CometFilter (2)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (1)
+ : : +- CometBroadcastExchange (5)
+ : : +- CometFilter (4)
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer (3)
+ : +- CometBroadcastExchange (11)
+ : +- CometProject (10)
+ : +- CometFilter (9)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address (8)
+ +- CometBroadcastExchange (17)
+ +- CometProject (16)
+ +- CometFilter (15)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (14)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [3]: [cs_bill_customer_sk#1, cs_sales_price#2, cs_sold_date_sk#3]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#3), dynamicpruningexpression(cs_sold_date_sk#3 IN dynamicpruning#4)]
+PushedFilters: [IsNotNull(cs_bill_customer_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [3]: [cs_bill_customer_sk#1, cs_sales_price#2, cs_sold_date_sk#3]
+Condition : isnotnull(cs_bill_customer_sk#1)
+
+(3) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+Output [2]: [c_customer_sk#5, c_current_addr_sk#6]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer]
+PushedFilters: [IsNotNull(c_customer_sk), IsNotNull(c_current_addr_sk)]
+ReadSchema: struct
+
+(4) CometFilter
+Input [2]: [c_customer_sk#5, c_current_addr_sk#6]
+Condition : (isnotnull(c_customer_sk#5) AND isnotnull(c_current_addr_sk#6))
+
+(5) CometBroadcastExchange
+Input [2]: [c_customer_sk#5, c_current_addr_sk#6]
+Arguments: [c_customer_sk#5, c_current_addr_sk#6]
+
+(6) CometBroadcastHashJoin
+Left output [3]: [cs_bill_customer_sk#1, cs_sales_price#2, cs_sold_date_sk#3]
+Right output [2]: [c_customer_sk#5, c_current_addr_sk#6]
+Arguments: [cs_bill_customer_sk#1], [c_customer_sk#5], Inner, BuildRight
+
+(7) CometProject
+Input [5]: [cs_bill_customer_sk#1, cs_sales_price#2, cs_sold_date_sk#3, c_customer_sk#5, c_current_addr_sk#6]
+Arguments: [cs_sales_price#2, cs_sold_date_sk#3, c_current_addr_sk#6], [cs_sales_price#2, cs_sold_date_sk#3, c_current_addr_sk#6]
+
+(8) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address
+Output [3]: [ca_address_sk#7, ca_state#8, ca_zip#9]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_address]
+PushedFilters: [IsNotNull(ca_address_sk)]
+ReadSchema: struct
+
+(9) CometFilter
+Input [3]: [ca_address_sk#7, ca_state#8, ca_zip#9]
+Condition : isnotnull(ca_address_sk#7)
+
+(10) CometProject
+Input [3]: [ca_address_sk#7, ca_state#8, ca_zip#9]
+Arguments: [ca_address_sk#7, ca_state#10, ca_zip#11], [ca_address_sk#7, static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#8, 2)) AS ca_state#10, static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_zip#9, 10)) AS ca_zip#11]
+
+(11) CometBroadcastExchange
+Input [3]: [ca_address_sk#7, ca_state#10, ca_zip#11]
+Arguments: [ca_address_sk#7, ca_state#10, ca_zip#11]
+
+(12) CometBroadcastHashJoin
+Left output [3]: [cs_sales_price#2, cs_sold_date_sk#3, c_current_addr_sk#6]
+Right output [3]: [ca_address_sk#7, ca_state#10, ca_zip#11]
+Arguments: [c_current_addr_sk#6], [ca_address_sk#7], Inner, ((substr(ca_zip#11, 1, 5) IN (85669,86197,88274,83405,86475,85392,85460,80348,81792) OR ca_state#10 IN (CA,WA,GA)) OR (cs_sales_price#2 > 500.00)), BuildRight
+
+(13) CometProject
+Input [6]: [cs_sales_price#2, cs_sold_date_sk#3, c_current_addr_sk#6, ca_address_sk#7, ca_state#10, ca_zip#11]
+Arguments: [cs_sales_price#2, cs_sold_date_sk#3, ca_zip#11], [cs_sales_price#2, cs_sold_date_sk#3, ca_zip#11]
+
+(14) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [3]: [d_date_sk#12, d_year#13, d_qoy#14]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_qoy), IsNotNull(d_year), EqualTo(d_qoy,2), EqualTo(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(15) CometFilter
+Input [3]: [d_date_sk#12, d_year#13, d_qoy#14]
+Condition : ((((isnotnull(d_qoy#14) AND isnotnull(d_year#13)) AND (d_qoy#14 = 2)) AND (d_year#13 = 2001)) AND isnotnull(d_date_sk#12))
+
+(16) CometProject
+Input [3]: [d_date_sk#12, d_year#13, d_qoy#14]
+Arguments: [d_date_sk#12], [d_date_sk#12]
+
+(17) CometBroadcastExchange
+Input [1]: [d_date_sk#12]
+Arguments: [d_date_sk#12]
+
+(18) CometBroadcastHashJoin
+Left output [3]: [cs_sales_price#2, cs_sold_date_sk#3, ca_zip#11]
+Right output [1]: [d_date_sk#12]
+Arguments: [cs_sold_date_sk#3], [d_date_sk#12], Inner, BuildRight
+
+(19) CometProject
+Input [4]: [cs_sales_price#2, cs_sold_date_sk#3, ca_zip#11, d_date_sk#12]
+Arguments: [cs_sales_price#2, ca_zip#11], [cs_sales_price#2, ca_zip#11]
+
+(20) CometHashAggregate
+Input [2]: [cs_sales_price#2, ca_zip#11]
+Keys [1]: [ca_zip#11]
+Functions [1]: [partial_sum(UnscaledValue(cs_sales_price#2))]
+
+(21) CometExchange
+Input [2]: [ca_zip#11, sum#15]
+Arguments: hashpartitioning(ca_zip#11, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=1]
+
+(22) CometHashAggregate
+Input [2]: [ca_zip#11, sum#15]
+Keys [1]: [ca_zip#11]
+Functions [1]: [sum(UnscaledValue(cs_sales_price#2))]
+
+(23) CometTakeOrderedAndProject
+Input [2]: [ca_zip#11, sum(cs_sales_price)#16]
+Arguments: TakeOrderedAndProject(limit=100, orderBy=[ca_zip#11 ASC NULLS FIRST], output=[ca_zip#11,sum(cs_sales_price)#16]), [ca_zip#11, sum(cs_sales_price)#16], 100, 0, [ca_zip#11 ASC NULLS FIRST], [ca_zip#11, sum(cs_sales_price)#16]
+
+(24) CometColumnarToRow [codegen id : 1]
+Input [2]: [ca_zip#11, sum(cs_sales_price)#16]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 1 Hosting Expression = cs_sold_date_sk#3 IN dynamicpruning#4
+BroadcastExchange (29)
++- * CometColumnarToRow (28)
+ +- CometProject (27)
+ +- CometFilter (26)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (25)
+
+
+(25) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [3]: [d_date_sk#12, d_year#13, d_qoy#14]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_qoy), IsNotNull(d_year), EqualTo(d_qoy,2), EqualTo(d_year,2001), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(26) CometFilter
+Input [3]: [d_date_sk#12, d_year#13, d_qoy#14]
+Condition : ((((isnotnull(d_qoy#14) AND isnotnull(d_year#13)) AND (d_qoy#14 = 2)) AND (d_year#13 = 2001)) AND isnotnull(d_date_sk#12))
+
+(27) CometProject
+Input [3]: [d_date_sk#12, d_year#13, d_qoy#14]
+Arguments: [d_date_sk#12], [d_date_sk#12]
+
+(28) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#12]
+
+(29) BroadcastExchange
+Input [1]: [d_date_sk#12]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=2]
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15/extended.txt
new file mode 100644
index 0000000000..6de0c64850
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15/extended.txt
@@ -0,0 +1,32 @@
+CometColumnarToRow
++- CometTakeOrderedAndProject
+ +- CometHashAggregate
+ +- CometExchange
+ +- CometHashAggregate
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : +- SubqueryBroadcast
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : : +- CometBroadcastExchange
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address
+ +- CometBroadcastExchange
+ +- CometProject
+ +- CometFilter
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+
+Comet accelerated 26 out of 28 eligible operators (92%). Final plan contains 2 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15/simplified.txt
new file mode 100644
index 0000000000..c39b96efe3
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q15/simplified.txt
@@ -0,0 +1,34 @@
+WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometTakeOrderedAndProject [ca_zip,sum(cs_sales_price)]
+ CometHashAggregate [sum] [ca_zip,sum(cs_sales_price),sum(UnscaledValue(cs_sales_price))]
+ CometExchange [ca_zip] #1
+ CometHashAggregate [cs_sales_price] [ca_zip,sum]
+ CometProject [cs_sales_price,ca_zip]
+ CometBroadcastHashJoin [cs_sales_price,cs_sold_date_sk,ca_zip,d_date_sk]
+ CometProject [cs_sales_price,cs_sold_date_sk,ca_zip]
+ CometBroadcastHashJoin [cs_sales_price,cs_sold_date_sk,c_current_addr_sk,ca_address_sk,ca_state,ca_zip]
+ CometProject [cs_sales_price,cs_sold_date_sk,c_current_addr_sk]
+ CometBroadcastHashJoin [cs_bill_customer_sk,cs_sales_price,cs_sold_date_sk,c_customer_sk,c_current_addr_sk]
+ CometFilter [cs_bill_customer_sk,cs_sales_price,cs_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_bill_customer_sk,cs_sales_price,cs_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #2
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year,d_qoy]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year,d_qoy]
+ CometBroadcastExchange [c_customer_sk,c_current_addr_sk] #3
+ CometFilter [c_customer_sk,c_current_addr_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer [c_customer_sk,c_current_addr_sk]
+ CometBroadcastExchange [ca_address_sk,ca_state,ca_zip] #4
+ CometProject [ca_state,ca_zip] [ca_address_sk,ca_state,ca_zip]
+ CometFilter [ca_address_sk,ca_state,ca_zip]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address [ca_address_sk,ca_state,ca_zip]
+ CometBroadcastExchange [d_date_sk] #5
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_year,d_qoy]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_year,d_qoy]
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_datafusion/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_datafusion/explain.txt
new file mode 100644
index 0000000000..2c1be26c56
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_datafusion/explain.txt
@@ -0,0 +1,235 @@
+== Physical Plan ==
+* CometColumnarToRow (41)
++- CometHashAggregate (40)
+ +- CometColumnarExchange (39)
+ +- * HashAggregate (38)
+ +- * HashAggregate (37)
+ +- * CometColumnarToRow (36)
+ +- CometHashAggregate (35)
+ +- CometProject (34)
+ +- CometBroadcastHashJoin (33)
+ :- CometProject (28)
+ : +- CometBroadcastHashJoin (27)
+ : :- CometProject (22)
+ : : +- CometBroadcastHashJoin (21)
+ : : :- CometSortMergeJoin (16)
+ : : : :- CometProject (11)
+ : : : : +- CometSortMergeJoin (10)
+ : : : : :- CometSort (5)
+ : : : : : +- CometExchange (4)
+ : : : : : +- CometProject (3)
+ : : : : : +- CometFilter (2)
+ : : : : : +- CometNativeScan parquet spark_catalog.default.catalog_sales (1)
+ : : : : +- CometSort (9)
+ : : : : +- CometExchange (8)
+ : : : : +- CometProject (7)
+ : : : : +- CometNativeScan parquet spark_catalog.default.catalog_sales (6)
+ : : : +- CometSort (15)
+ : : : +- CometExchange (14)
+ : : : +- CometProject (13)
+ : : : +- CometNativeScan parquet spark_catalog.default.catalog_returns (12)
+ : : +- CometBroadcastExchange (20)
+ : : +- CometProject (19)
+ : : +- CometFilter (18)
+ : : +- CometNativeScan parquet spark_catalog.default.date_dim (17)
+ : +- CometBroadcastExchange (26)
+ : +- CometProject (25)
+ : +- CometFilter (24)
+ : +- CometNativeScan parquet spark_catalog.default.customer_address (23)
+ +- CometBroadcastExchange (32)
+ +- CometProject (31)
+ +- CometFilter (30)
+ +- CometNativeScan parquet spark_catalog.default.call_center (29)
+
+
+(1) CometNativeScan parquet spark_catalog.default.catalog_sales
+Output [8]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, cs_sold_date_sk#8]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/catalog_sales]
+PushedFilters: [IsNotNull(cs_ship_date_sk), IsNotNull(cs_ship_addr_sk), IsNotNull(cs_call_center_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [8]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, cs_sold_date_sk#8]
+Condition : ((isnotnull(cs_ship_date_sk#1) AND isnotnull(cs_ship_addr_sk#2)) AND isnotnull(cs_call_center_sk#3))
+
+(3) CometProject
+Input [8]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, cs_sold_date_sk#8]
+Arguments: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+
+(4) CometExchange
+Input [7]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Arguments: hashpartitioning(cs_order_number#5, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=1]
+
+(5) CometSort
+Input [7]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Arguments: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_order_number#5 ASC NULLS FIRST]
+
+(6) CometNativeScan parquet spark_catalog.default.catalog_sales
+Output [3]: [cs_warehouse_sk#9, cs_order_number#10, cs_sold_date_sk#11]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/catalog_sales]
+ReadSchema: struct
+
+(7) CometProject
+Input [3]: [cs_warehouse_sk#9, cs_order_number#10, cs_sold_date_sk#11]
+Arguments: [cs_warehouse_sk#9, cs_order_number#10], [cs_warehouse_sk#9, cs_order_number#10]
+
+(8) CometExchange
+Input [2]: [cs_warehouse_sk#9, cs_order_number#10]
+Arguments: hashpartitioning(cs_order_number#10, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=2]
+
+(9) CometSort
+Input [2]: [cs_warehouse_sk#9, cs_order_number#10]
+Arguments: [cs_warehouse_sk#9, cs_order_number#10], [cs_order_number#10 ASC NULLS FIRST]
+
+(10) CometSortMergeJoin
+Left output [7]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Right output [2]: [cs_warehouse_sk#9, cs_order_number#10]
+Arguments: [cs_order_number#5], [cs_order_number#10], LeftSemi, NOT (cs_warehouse_sk#4 = cs_warehouse_sk#9)
+
+(11) CometProject
+Input [7]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Arguments: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+
+(12) CometNativeScan parquet spark_catalog.default.catalog_returns
+Output [2]: [cr_order_number#12, cr_returned_date_sk#13]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/catalog_returns]
+ReadSchema: struct
+
+(13) CometProject
+Input [2]: [cr_order_number#12, cr_returned_date_sk#13]
+Arguments: [cr_order_number#12], [cr_order_number#12]
+
+(14) CometExchange
+Input [1]: [cr_order_number#12]
+Arguments: hashpartitioning(cr_order_number#12, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=3]
+
+(15) CometSort
+Input [1]: [cr_order_number#12]
+Arguments: [cr_order_number#12], [cr_order_number#12 ASC NULLS FIRST]
+
+(16) CometSortMergeJoin
+Left output [6]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Right output [1]: [cr_order_number#12]
+Arguments: [cs_order_number#5], [cr_order_number#12], LeftAnti
+
+(17) CometNativeScan parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#14, d_date#15]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_date), GreaterThanOrEqual(d_date,2002-02-01), LessThanOrEqual(d_date,2002-04-02), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(18) CometFilter
+Input [2]: [d_date_sk#14, d_date#15]
+Condition : (((isnotnull(d_date#15) AND (d_date#15 >= 2002-02-01)) AND (d_date#15 <= 2002-04-02)) AND isnotnull(d_date_sk#14))
+
+(19) CometProject
+Input [2]: [d_date_sk#14, d_date#15]
+Arguments: [d_date_sk#14], [d_date_sk#14]
+
+(20) CometBroadcastExchange
+Input [1]: [d_date_sk#14]
+Arguments: [d_date_sk#14]
+
+(21) CometBroadcastHashJoin
+Left output [6]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Right output [1]: [d_date_sk#14]
+Arguments: [cs_ship_date_sk#1], [d_date_sk#14], Inner, BuildRight
+
+(22) CometProject
+Input [7]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, d_date_sk#14]
+Arguments: [cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+
+(23) CometNativeScan parquet spark_catalog.default.customer_address
+Output [2]: [ca_address_sk#16, ca_state#17]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_address]
+PushedFilters: [IsNotNull(ca_state), IsNotNull(ca_address_sk)]
+ReadSchema: struct
+
+(24) CometFilter
+Input [2]: [ca_address_sk#16, ca_state#17]
+Condition : ((isnotnull(ca_state#17) AND (static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#17, 2)) = GA)) AND isnotnull(ca_address_sk#16))
+
+(25) CometProject
+Input [2]: [ca_address_sk#16, ca_state#17]
+Arguments: [ca_address_sk#16], [ca_address_sk#16]
+
+(26) CometBroadcastExchange
+Input [1]: [ca_address_sk#16]
+Arguments: [ca_address_sk#16]
+
+(27) CometBroadcastHashJoin
+Left output [5]: [cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Right output [1]: [ca_address_sk#16]
+Arguments: [cs_ship_addr_sk#2], [ca_address_sk#16], Inner, BuildRight
+
+(28) CometProject
+Input [6]: [cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, ca_address_sk#16]
+Arguments: [cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+
+(29) CometNativeScan parquet spark_catalog.default.call_center
+Output [2]: [cc_call_center_sk#18, cc_county#19]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/call_center]
+PushedFilters: [IsNotNull(cc_county), EqualTo(cc_county,Williamson County), IsNotNull(cc_call_center_sk)]
+ReadSchema: struct
+
+(30) CometFilter
+Input [2]: [cc_call_center_sk#18, cc_county#19]
+Condition : ((isnotnull(cc_county#19) AND (cc_county#19 = Williamson County)) AND isnotnull(cc_call_center_sk#18))
+
+(31) CometProject
+Input [2]: [cc_call_center_sk#18, cc_county#19]
+Arguments: [cc_call_center_sk#18], [cc_call_center_sk#18]
+
+(32) CometBroadcastExchange
+Input [1]: [cc_call_center_sk#18]
+Arguments: [cc_call_center_sk#18]
+
+(33) CometBroadcastHashJoin
+Left output [4]: [cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Right output [1]: [cc_call_center_sk#18]
+Arguments: [cs_call_center_sk#3], [cc_call_center_sk#18], Inner, BuildRight
+
+(34) CometProject
+Input [5]: [cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, cc_call_center_sk#18]
+Arguments: [cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+
+(35) CometHashAggregate
+Input [3]: [cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Keys [1]: [cs_order_number#5]
+Functions [2]: [partial_sum(UnscaledValue(cs_ext_ship_cost#6)), partial_sum(UnscaledValue(cs_net_profit#7))]
+
+(36) CometColumnarToRow [codegen id : 1]
+Input [3]: [cs_order_number#5, sum#20, sum#21]
+
+(37) HashAggregate [codegen id : 1]
+Input [3]: [cs_order_number#5, sum#20, sum#21]
+Keys [1]: [cs_order_number#5]
+Functions [2]: [merge_sum(UnscaledValue(cs_ext_ship_cost#6)), merge_sum(UnscaledValue(cs_net_profit#7))]
+Aggregate Attributes [2]: [sum(UnscaledValue(cs_ext_ship_cost#6))#22, sum(UnscaledValue(cs_net_profit#7))#23]
+Results [3]: [cs_order_number#5, sum#20, sum#21]
+
+(38) HashAggregate [codegen id : 1]
+Input [3]: [cs_order_number#5, sum#20, sum#21]
+Keys: []
+Functions [3]: [merge_sum(UnscaledValue(cs_ext_ship_cost#6)), merge_sum(UnscaledValue(cs_net_profit#7)), partial_count(distinct cs_order_number#5)]
+Aggregate Attributes [3]: [sum(UnscaledValue(cs_ext_ship_cost#6))#22, sum(UnscaledValue(cs_net_profit#7))#23, count(cs_order_number#5)#24]
+Results [3]: [sum#20, sum#21, count#25]
+
+(39) CometColumnarExchange
+Input [3]: [sum#20, sum#21, count#25]
+Arguments: SinglePartition, ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=4]
+
+(40) CometHashAggregate
+Input [3]: [sum#20, sum#21, count#25]
+Keys: []
+Functions [3]: [sum(UnscaledValue(cs_ext_ship_cost#6)), sum(UnscaledValue(cs_net_profit#7)), count(distinct cs_order_number#5)]
+
+(41) CometColumnarToRow [codegen id : 2]
+Input [3]: [order count #26, total shipping cost #27, total net profit #28]
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_datafusion/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_datafusion/extended.txt
new file mode 100644
index 0000000000..9889eeaca3
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_datafusion/extended.txt
@@ -0,0 +1,43 @@
+CometColumnarToRow
++- CometHashAggregate
+ +- CometColumnarExchange
+ +- HashAggregate
+ +- HashAggregate [COMET: Unsupported aggregation mode PartialMerge]
+ +- CometColumnarToRow
+ +- CometHashAggregate
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometSortMergeJoin
+ : : : :- CometProject
+ : : : : +- CometSortMergeJoin
+ : : : : :- CometSort
+ : : : : : +- CometExchange
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometNativeScan parquet spark_catalog.default.catalog_sales
+ : : : : +- CometSort
+ : : : : +- CometExchange
+ : : : : +- CometProject
+ : : : : +- CometNativeScan parquet spark_catalog.default.catalog_sales
+ : : : +- CometSort
+ : : : +- CometExchange
+ : : : +- CometProject
+ : : : +- CometNativeScan parquet spark_catalog.default.catalog_returns
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometNativeScan parquet spark_catalog.default.customer_address
+ +- CometBroadcastExchange
+ +- CometProject
+ +- CometFilter
+ +- CometNativeScan parquet spark_catalog.default.call_center
+
+Comet accelerated 37 out of 39 eligible operators (94%). Final plan contains 2 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_datafusion/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_datafusion/simplified.txt
new file mode 100644
index 0000000000..429d83d08c
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_datafusion/simplified.txt
@@ -0,0 +1,45 @@
+WholeStageCodegen (2)
+ CometColumnarToRow
+ InputAdapter
+ CometHashAggregate [sum,sum,count] [order count ,total shipping cost ,total net profit ,count(cs_order_number),sum(UnscaledValue(cs_ext_ship_cost)),sum(UnscaledValue(cs_net_profit))]
+ CometColumnarExchange #1
+ WholeStageCodegen (1)
+ HashAggregate [cs_order_number] [sum(UnscaledValue(cs_ext_ship_cost)),sum(UnscaledValue(cs_net_profit)),count(cs_order_number),sum,sum,count,sum,sum,count]
+ HashAggregate [cs_order_number] [sum(UnscaledValue(cs_ext_ship_cost)),sum(UnscaledValue(cs_net_profit)),sum,sum,sum,sum]
+ CometColumnarToRow
+ InputAdapter
+ CometHashAggregate [cs_ext_ship_cost,cs_net_profit] [cs_order_number,sum,sum]
+ CometProject [cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometBroadcastHashJoin [cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,cc_call_center_sk]
+ CometProject [cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometBroadcastHashJoin [cs_ship_addr_sk,cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,ca_address_sk]
+ CometProject [cs_ship_addr_sk,cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometBroadcastHashJoin [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,d_date_sk]
+ CometSortMergeJoin [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,cr_order_number]
+ CometProject [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometSortMergeJoin [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_warehouse_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,cs_order_number,cs_warehouse_sk]
+ CometSort [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_warehouse_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometExchange [cs_order_number] #2
+ CometProject [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_warehouse_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometFilter [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_warehouse_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,cs_sold_date_sk]
+ CometNativeScan parquet spark_catalog.default.catalog_sales [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_warehouse_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,cs_sold_date_sk]
+ CometSort [cs_warehouse_sk,cs_order_number]
+ CometExchange [cs_order_number] #3
+ CometProject [cs_warehouse_sk,cs_order_number]
+ CometNativeScan parquet spark_catalog.default.catalog_sales [cs_warehouse_sk,cs_order_number,cs_sold_date_sk]
+ CometSort [cr_order_number]
+ CometExchange [cr_order_number] #4
+ CometProject [cr_order_number]
+ CometNativeScan parquet spark_catalog.default.catalog_returns [cr_order_number,cr_returned_date_sk]
+ CometBroadcastExchange [d_date_sk] #5
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_date]
+ CometNativeScan parquet spark_catalog.default.date_dim [d_date_sk,d_date]
+ CometBroadcastExchange [ca_address_sk] #6
+ CometProject [ca_address_sk]
+ CometFilter [ca_address_sk,ca_state]
+ CometNativeScan parquet spark_catalog.default.customer_address [ca_address_sk,ca_state]
+ CometBroadcastExchange [cc_call_center_sk] #7
+ CometProject [cc_call_center_sk]
+ CometFilter [cc_call_center_sk,cc_county]
+ CometNativeScan parquet spark_catalog.default.call_center [cc_call_center_sk,cc_county]
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_iceberg_compat/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_iceberg_compat/explain.txt
new file mode 100644
index 0000000000..7a4c0fa400
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_iceberg_compat/explain.txt
@@ -0,0 +1,235 @@
+== Physical Plan ==
+* CometColumnarToRow (41)
++- CometHashAggregate (40)
+ +- CometColumnarExchange (39)
+ +- * HashAggregate (38)
+ +- * HashAggregate (37)
+ +- * CometColumnarToRow (36)
+ +- CometHashAggregate (35)
+ +- CometProject (34)
+ +- CometBroadcastHashJoin (33)
+ :- CometProject (28)
+ : +- CometBroadcastHashJoin (27)
+ : :- CometProject (22)
+ : : +- CometBroadcastHashJoin (21)
+ : : :- CometSortMergeJoin (16)
+ : : : :- CometProject (11)
+ : : : : +- CometSortMergeJoin (10)
+ : : : : :- CometSort (5)
+ : : : : : +- CometExchange (4)
+ : : : : : +- CometProject (3)
+ : : : : : +- CometFilter (2)
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (1)
+ : : : : +- CometSort (9)
+ : : : : +- CometExchange (8)
+ : : : : +- CometProject (7)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (6)
+ : : : +- CometSort (15)
+ : : : +- CometExchange (14)
+ : : : +- CometProject (13)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_returns (12)
+ : : +- CometBroadcastExchange (20)
+ : : +- CometProject (19)
+ : : +- CometFilter (18)
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (17)
+ : +- CometBroadcastExchange (26)
+ : +- CometProject (25)
+ : +- CometFilter (24)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address (23)
+ +- CometBroadcastExchange (32)
+ +- CometProject (31)
+ +- CometFilter (30)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.call_center (29)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [8]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, cs_sold_date_sk#8]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/catalog_sales]
+PushedFilters: [IsNotNull(cs_ship_date_sk), IsNotNull(cs_ship_addr_sk), IsNotNull(cs_call_center_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [8]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, cs_sold_date_sk#8]
+Condition : ((isnotnull(cs_ship_date_sk#1) AND isnotnull(cs_ship_addr_sk#2)) AND isnotnull(cs_call_center_sk#3))
+
+(3) CometProject
+Input [8]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, cs_sold_date_sk#8]
+Arguments: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+
+(4) CometExchange
+Input [7]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Arguments: hashpartitioning(cs_order_number#5, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=1]
+
+(5) CometSort
+Input [7]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Arguments: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_order_number#5 ASC NULLS FIRST]
+
+(6) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [3]: [cs_warehouse_sk#9, cs_order_number#10, cs_sold_date_sk#11]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/catalog_sales]
+ReadSchema: struct
+
+(7) CometProject
+Input [3]: [cs_warehouse_sk#9, cs_order_number#10, cs_sold_date_sk#11]
+Arguments: [cs_warehouse_sk#9, cs_order_number#10], [cs_warehouse_sk#9, cs_order_number#10]
+
+(8) CometExchange
+Input [2]: [cs_warehouse_sk#9, cs_order_number#10]
+Arguments: hashpartitioning(cs_order_number#10, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=2]
+
+(9) CometSort
+Input [2]: [cs_warehouse_sk#9, cs_order_number#10]
+Arguments: [cs_warehouse_sk#9, cs_order_number#10], [cs_order_number#10 ASC NULLS FIRST]
+
+(10) CometSortMergeJoin
+Left output [7]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Right output [2]: [cs_warehouse_sk#9, cs_order_number#10]
+Arguments: [cs_order_number#5], [cs_order_number#10], LeftSemi, NOT (cs_warehouse_sk#4 = cs_warehouse_sk#9)
+
+(11) CometProject
+Input [7]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Arguments: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+
+(12) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_returns
+Output [2]: [cr_order_number#12, cr_returned_date_sk#13]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/catalog_returns]
+ReadSchema: struct
+
+(13) CometProject
+Input [2]: [cr_order_number#12, cr_returned_date_sk#13]
+Arguments: [cr_order_number#12], [cr_order_number#12]
+
+(14) CometExchange
+Input [1]: [cr_order_number#12]
+Arguments: hashpartitioning(cr_order_number#12, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=3]
+
+(15) CometSort
+Input [1]: [cr_order_number#12]
+Arguments: [cr_order_number#12], [cr_order_number#12 ASC NULLS FIRST]
+
+(16) CometSortMergeJoin
+Left output [6]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Right output [1]: [cr_order_number#12]
+Arguments: [cs_order_number#5], [cr_order_number#12], LeftAnti
+
+(17) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#14, d_date#15]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_date), GreaterThanOrEqual(d_date,2002-02-01), LessThanOrEqual(d_date,2002-04-02), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(18) CometFilter
+Input [2]: [d_date_sk#14, d_date#15]
+Condition : (((isnotnull(d_date#15) AND (d_date#15 >= 2002-02-01)) AND (d_date#15 <= 2002-04-02)) AND isnotnull(d_date_sk#14))
+
+(19) CometProject
+Input [2]: [d_date_sk#14, d_date#15]
+Arguments: [d_date_sk#14], [d_date_sk#14]
+
+(20) CometBroadcastExchange
+Input [1]: [d_date_sk#14]
+Arguments: [d_date_sk#14]
+
+(21) CometBroadcastHashJoin
+Left output [6]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Right output [1]: [d_date_sk#14]
+Arguments: [cs_ship_date_sk#1], [d_date_sk#14], Inner, BuildRight
+
+(22) CometProject
+Input [7]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, d_date_sk#14]
+Arguments: [cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+
+(23) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address
+Output [2]: [ca_address_sk#16, ca_state#17]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_address]
+PushedFilters: [IsNotNull(ca_state), IsNotNull(ca_address_sk)]
+ReadSchema: struct
+
+(24) CometFilter
+Input [2]: [ca_address_sk#16, ca_state#17]
+Condition : ((isnotnull(ca_state#17) AND (static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#17, 2)) = GA)) AND isnotnull(ca_address_sk#16))
+
+(25) CometProject
+Input [2]: [ca_address_sk#16, ca_state#17]
+Arguments: [ca_address_sk#16], [ca_address_sk#16]
+
+(26) CometBroadcastExchange
+Input [1]: [ca_address_sk#16]
+Arguments: [ca_address_sk#16]
+
+(27) CometBroadcastHashJoin
+Left output [5]: [cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Right output [1]: [ca_address_sk#16]
+Arguments: [cs_ship_addr_sk#2], [ca_address_sk#16], Inner, BuildRight
+
+(28) CometProject
+Input [6]: [cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, ca_address_sk#16]
+Arguments: [cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+
+(29) CometScan [native_iceberg_compat] parquet spark_catalog.default.call_center
+Output [2]: [cc_call_center_sk#18, cc_county#19]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/call_center]
+PushedFilters: [IsNotNull(cc_county), EqualTo(cc_county,Williamson County), IsNotNull(cc_call_center_sk)]
+ReadSchema: struct
+
+(30) CometFilter
+Input [2]: [cc_call_center_sk#18, cc_county#19]
+Condition : ((isnotnull(cc_county#19) AND (cc_county#19 = Williamson County)) AND isnotnull(cc_call_center_sk#18))
+
+(31) CometProject
+Input [2]: [cc_call_center_sk#18, cc_county#19]
+Arguments: [cc_call_center_sk#18], [cc_call_center_sk#18]
+
+(32) CometBroadcastExchange
+Input [1]: [cc_call_center_sk#18]
+Arguments: [cc_call_center_sk#18]
+
+(33) CometBroadcastHashJoin
+Left output [4]: [cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Right output [1]: [cc_call_center_sk#18]
+Arguments: [cs_call_center_sk#3], [cc_call_center_sk#18], Inner, BuildRight
+
+(34) CometProject
+Input [5]: [cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, cc_call_center_sk#18]
+Arguments: [cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+
+(35) CometHashAggregate
+Input [3]: [cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Keys [1]: [cs_order_number#5]
+Functions [2]: [partial_sum(UnscaledValue(cs_ext_ship_cost#6)), partial_sum(UnscaledValue(cs_net_profit#7))]
+
+(36) CometColumnarToRow [codegen id : 1]
+Input [3]: [cs_order_number#5, sum#20, sum#21]
+
+(37) HashAggregate [codegen id : 1]
+Input [3]: [cs_order_number#5, sum#20, sum#21]
+Keys [1]: [cs_order_number#5]
+Functions [2]: [merge_sum(UnscaledValue(cs_ext_ship_cost#6)), merge_sum(UnscaledValue(cs_net_profit#7))]
+Aggregate Attributes [2]: [sum(UnscaledValue(cs_ext_ship_cost#6))#22, sum(UnscaledValue(cs_net_profit#7))#23]
+Results [3]: [cs_order_number#5, sum#20, sum#21]
+
+(38) HashAggregate [codegen id : 1]
+Input [3]: [cs_order_number#5, sum#20, sum#21]
+Keys: []
+Functions [3]: [merge_sum(UnscaledValue(cs_ext_ship_cost#6)), merge_sum(UnscaledValue(cs_net_profit#7)), partial_count(distinct cs_order_number#5)]
+Aggregate Attributes [3]: [sum(UnscaledValue(cs_ext_ship_cost#6))#22, sum(UnscaledValue(cs_net_profit#7))#23, count(cs_order_number#5)#24]
+Results [3]: [sum#20, sum#21, count#25]
+
+(39) CometColumnarExchange
+Input [3]: [sum#20, sum#21, count#25]
+Arguments: SinglePartition, ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=4]
+
+(40) CometHashAggregate
+Input [3]: [sum#20, sum#21, count#25]
+Keys: []
+Functions [3]: [sum(UnscaledValue(cs_ext_ship_cost#6)), sum(UnscaledValue(cs_net_profit#7)), count(distinct cs_order_number#5)]
+
+(41) CometColumnarToRow [codegen id : 2]
+Input [3]: [order count #26, total shipping cost #27, total net profit #28]
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_iceberg_compat/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_iceberg_compat/extended.txt
new file mode 100644
index 0000000000..2ad029e444
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_iceberg_compat/extended.txt
@@ -0,0 +1,43 @@
+CometColumnarToRow
++- CometHashAggregate
+ +- CometColumnarExchange
+ +- HashAggregate
+ +- HashAggregate [COMET: Unsupported aggregation mode PartialMerge]
+ +- CometColumnarToRow
+ +- CometHashAggregate
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometSortMergeJoin
+ : : : :- CometProject
+ : : : : +- CometSortMergeJoin
+ : : : : :- CometSort
+ : : : : : +- CometExchange
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : +- CometSort
+ : : : : +- CometExchange
+ : : : : +- CometProject
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : +- CometSort
+ : : : +- CometExchange
+ : : : +- CometProject
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_returns
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address
+ +- CometBroadcastExchange
+ +- CometProject
+ +- CometFilter
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.call_center
+
+Comet accelerated 37 out of 39 eligible operators (94%). Final plan contains 2 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_iceberg_compat/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_iceberg_compat/simplified.txt
new file mode 100644
index 0000000000..8427aa49a9
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16.native_iceberg_compat/simplified.txt
@@ -0,0 +1,45 @@
+WholeStageCodegen (2)
+ CometColumnarToRow
+ InputAdapter
+ CometHashAggregate [sum,sum,count] [order count ,total shipping cost ,total net profit ,count(cs_order_number),sum(UnscaledValue(cs_ext_ship_cost)),sum(UnscaledValue(cs_net_profit))]
+ CometColumnarExchange #1
+ WholeStageCodegen (1)
+ HashAggregate [cs_order_number] [sum(UnscaledValue(cs_ext_ship_cost)),sum(UnscaledValue(cs_net_profit)),count(cs_order_number),sum,sum,count,sum,sum,count]
+ HashAggregate [cs_order_number] [sum(UnscaledValue(cs_ext_ship_cost)),sum(UnscaledValue(cs_net_profit)),sum,sum,sum,sum]
+ CometColumnarToRow
+ InputAdapter
+ CometHashAggregate [cs_ext_ship_cost,cs_net_profit] [cs_order_number,sum,sum]
+ CometProject [cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometBroadcastHashJoin [cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,cc_call_center_sk]
+ CometProject [cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometBroadcastHashJoin [cs_ship_addr_sk,cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,ca_address_sk]
+ CometProject [cs_ship_addr_sk,cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometBroadcastHashJoin [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,d_date_sk]
+ CometSortMergeJoin [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,cr_order_number]
+ CometProject [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometSortMergeJoin [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_warehouse_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,cs_order_number,cs_warehouse_sk]
+ CometSort [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_warehouse_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometExchange [cs_order_number] #2
+ CometProject [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_warehouse_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometFilter [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_warehouse_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,cs_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_warehouse_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,cs_sold_date_sk]
+ CometSort [cs_warehouse_sk,cs_order_number]
+ CometExchange [cs_order_number] #3
+ CometProject [cs_warehouse_sk,cs_order_number]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_warehouse_sk,cs_order_number,cs_sold_date_sk]
+ CometSort [cr_order_number]
+ CometExchange [cr_order_number] #4
+ CometProject [cr_order_number]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_returns [cr_order_number,cr_returned_date_sk]
+ CometBroadcastExchange [d_date_sk] #5
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_date]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_date]
+ CometBroadcastExchange [ca_address_sk] #6
+ CometProject [ca_address_sk]
+ CometFilter [ca_address_sk,ca_state]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address [ca_address_sk,ca_state]
+ CometBroadcastExchange [cc_call_center_sk] #7
+ CometProject [cc_call_center_sk]
+ CometFilter [cc_call_center_sk,cc_county]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.call_center [cc_call_center_sk,cc_county]
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16/explain.txt
new file mode 100644
index 0000000000..7a4c0fa400
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16/explain.txt
@@ -0,0 +1,235 @@
+== Physical Plan ==
+* CometColumnarToRow (41)
++- CometHashAggregate (40)
+ +- CometColumnarExchange (39)
+ +- * HashAggregate (38)
+ +- * HashAggregate (37)
+ +- * CometColumnarToRow (36)
+ +- CometHashAggregate (35)
+ +- CometProject (34)
+ +- CometBroadcastHashJoin (33)
+ :- CometProject (28)
+ : +- CometBroadcastHashJoin (27)
+ : :- CometProject (22)
+ : : +- CometBroadcastHashJoin (21)
+ : : :- CometSortMergeJoin (16)
+ : : : :- CometProject (11)
+ : : : : +- CometSortMergeJoin (10)
+ : : : : :- CometSort (5)
+ : : : : : +- CometExchange (4)
+ : : : : : +- CometProject (3)
+ : : : : : +- CometFilter (2)
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (1)
+ : : : : +- CometSort (9)
+ : : : : +- CometExchange (8)
+ : : : : +- CometProject (7)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (6)
+ : : : +- CometSort (15)
+ : : : +- CometExchange (14)
+ : : : +- CometProject (13)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_returns (12)
+ : : +- CometBroadcastExchange (20)
+ : : +- CometProject (19)
+ : : +- CometFilter (18)
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (17)
+ : +- CometBroadcastExchange (26)
+ : +- CometProject (25)
+ : +- CometFilter (24)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address (23)
+ +- CometBroadcastExchange (32)
+ +- CometProject (31)
+ +- CometFilter (30)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.call_center (29)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [8]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, cs_sold_date_sk#8]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/catalog_sales]
+PushedFilters: [IsNotNull(cs_ship_date_sk), IsNotNull(cs_ship_addr_sk), IsNotNull(cs_call_center_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [8]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, cs_sold_date_sk#8]
+Condition : ((isnotnull(cs_ship_date_sk#1) AND isnotnull(cs_ship_addr_sk#2)) AND isnotnull(cs_call_center_sk#3))
+
+(3) CometProject
+Input [8]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, cs_sold_date_sk#8]
+Arguments: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+
+(4) CometExchange
+Input [7]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Arguments: hashpartitioning(cs_order_number#5, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=1]
+
+(5) CometSort
+Input [7]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Arguments: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_order_number#5 ASC NULLS FIRST]
+
+(6) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [3]: [cs_warehouse_sk#9, cs_order_number#10, cs_sold_date_sk#11]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/catalog_sales]
+ReadSchema: struct
+
+(7) CometProject
+Input [3]: [cs_warehouse_sk#9, cs_order_number#10, cs_sold_date_sk#11]
+Arguments: [cs_warehouse_sk#9, cs_order_number#10], [cs_warehouse_sk#9, cs_order_number#10]
+
+(8) CometExchange
+Input [2]: [cs_warehouse_sk#9, cs_order_number#10]
+Arguments: hashpartitioning(cs_order_number#10, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=2]
+
+(9) CometSort
+Input [2]: [cs_warehouse_sk#9, cs_order_number#10]
+Arguments: [cs_warehouse_sk#9, cs_order_number#10], [cs_order_number#10 ASC NULLS FIRST]
+
+(10) CometSortMergeJoin
+Left output [7]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Right output [2]: [cs_warehouse_sk#9, cs_order_number#10]
+Arguments: [cs_order_number#5], [cs_order_number#10], LeftSemi, NOT (cs_warehouse_sk#4 = cs_warehouse_sk#9)
+
+(11) CometProject
+Input [7]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_warehouse_sk#4, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Arguments: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+
+(12) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_returns
+Output [2]: [cr_order_number#12, cr_returned_date_sk#13]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/catalog_returns]
+ReadSchema: struct
+
+(13) CometProject
+Input [2]: [cr_order_number#12, cr_returned_date_sk#13]
+Arguments: [cr_order_number#12], [cr_order_number#12]
+
+(14) CometExchange
+Input [1]: [cr_order_number#12]
+Arguments: hashpartitioning(cr_order_number#12, 5), ENSURE_REQUIREMENTS, CometNativeShuffle, [plan_id=3]
+
+(15) CometSort
+Input [1]: [cr_order_number#12]
+Arguments: [cr_order_number#12], [cr_order_number#12 ASC NULLS FIRST]
+
+(16) CometSortMergeJoin
+Left output [6]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Right output [1]: [cr_order_number#12]
+Arguments: [cs_order_number#5], [cr_order_number#12], LeftAnti
+
+(17) CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#14, d_date#15]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_date), GreaterThanOrEqual(d_date,2002-02-01), LessThanOrEqual(d_date,2002-04-02), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(18) CometFilter
+Input [2]: [d_date_sk#14, d_date#15]
+Condition : (((isnotnull(d_date#15) AND (d_date#15 >= 2002-02-01)) AND (d_date#15 <= 2002-04-02)) AND isnotnull(d_date_sk#14))
+
+(19) CometProject
+Input [2]: [d_date_sk#14, d_date#15]
+Arguments: [d_date_sk#14], [d_date_sk#14]
+
+(20) CometBroadcastExchange
+Input [1]: [d_date_sk#14]
+Arguments: [d_date_sk#14]
+
+(21) CometBroadcastHashJoin
+Left output [6]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Right output [1]: [d_date_sk#14]
+Arguments: [cs_ship_date_sk#1], [d_date_sk#14], Inner, BuildRight
+
+(22) CometProject
+Input [7]: [cs_ship_date_sk#1, cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, d_date_sk#14]
+Arguments: [cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+
+(23) CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address
+Output [2]: [ca_address_sk#16, ca_state#17]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/customer_address]
+PushedFilters: [IsNotNull(ca_state), IsNotNull(ca_address_sk)]
+ReadSchema: struct
+
+(24) CometFilter
+Input [2]: [ca_address_sk#16, ca_state#17]
+Condition : ((isnotnull(ca_state#17) AND (static_invoke(CharVarcharCodegenUtils.readSidePadding(ca_state#17, 2)) = GA)) AND isnotnull(ca_address_sk#16))
+
+(25) CometProject
+Input [2]: [ca_address_sk#16, ca_state#17]
+Arguments: [ca_address_sk#16], [ca_address_sk#16]
+
+(26) CometBroadcastExchange
+Input [1]: [ca_address_sk#16]
+Arguments: [ca_address_sk#16]
+
+(27) CometBroadcastHashJoin
+Left output [5]: [cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Right output [1]: [ca_address_sk#16]
+Arguments: [cs_ship_addr_sk#2], [ca_address_sk#16], Inner, BuildRight
+
+(28) CometProject
+Input [6]: [cs_ship_addr_sk#2, cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, ca_address_sk#16]
+Arguments: [cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+
+(29) CometScan [native_iceberg_compat] parquet spark_catalog.default.call_center
+Output [2]: [cc_call_center_sk#18, cc_county#19]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/call_center]
+PushedFilters: [IsNotNull(cc_county), EqualTo(cc_county,Williamson County), IsNotNull(cc_call_center_sk)]
+ReadSchema: struct
+
+(30) CometFilter
+Input [2]: [cc_call_center_sk#18, cc_county#19]
+Condition : ((isnotnull(cc_county#19) AND (cc_county#19 = Williamson County)) AND isnotnull(cc_call_center_sk#18))
+
+(31) CometProject
+Input [2]: [cc_call_center_sk#18, cc_county#19]
+Arguments: [cc_call_center_sk#18], [cc_call_center_sk#18]
+
+(32) CometBroadcastExchange
+Input [1]: [cc_call_center_sk#18]
+Arguments: [cc_call_center_sk#18]
+
+(33) CometBroadcastHashJoin
+Left output [4]: [cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Right output [1]: [cc_call_center_sk#18]
+Arguments: [cs_call_center_sk#3], [cc_call_center_sk#18], Inner, BuildRight
+
+(34) CometProject
+Input [5]: [cs_call_center_sk#3, cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7, cc_call_center_sk#18]
+Arguments: [cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7], [cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+
+(35) CometHashAggregate
+Input [3]: [cs_order_number#5, cs_ext_ship_cost#6, cs_net_profit#7]
+Keys [1]: [cs_order_number#5]
+Functions [2]: [partial_sum(UnscaledValue(cs_ext_ship_cost#6)), partial_sum(UnscaledValue(cs_net_profit#7))]
+
+(36) CometColumnarToRow [codegen id : 1]
+Input [3]: [cs_order_number#5, sum#20, sum#21]
+
+(37) HashAggregate [codegen id : 1]
+Input [3]: [cs_order_number#5, sum#20, sum#21]
+Keys [1]: [cs_order_number#5]
+Functions [2]: [merge_sum(UnscaledValue(cs_ext_ship_cost#6)), merge_sum(UnscaledValue(cs_net_profit#7))]
+Aggregate Attributes [2]: [sum(UnscaledValue(cs_ext_ship_cost#6))#22, sum(UnscaledValue(cs_net_profit#7))#23]
+Results [3]: [cs_order_number#5, sum#20, sum#21]
+
+(38) HashAggregate [codegen id : 1]
+Input [3]: [cs_order_number#5, sum#20, sum#21]
+Keys: []
+Functions [3]: [merge_sum(UnscaledValue(cs_ext_ship_cost#6)), merge_sum(UnscaledValue(cs_net_profit#7)), partial_count(distinct cs_order_number#5)]
+Aggregate Attributes [3]: [sum(UnscaledValue(cs_ext_ship_cost#6))#22, sum(UnscaledValue(cs_net_profit#7))#23, count(cs_order_number#5)#24]
+Results [3]: [sum#20, sum#21, count#25]
+
+(39) CometColumnarExchange
+Input [3]: [sum#20, sum#21, count#25]
+Arguments: SinglePartition, ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=4]
+
+(40) CometHashAggregate
+Input [3]: [sum#20, sum#21, count#25]
+Keys: []
+Functions [3]: [sum(UnscaledValue(cs_ext_ship_cost#6)), sum(UnscaledValue(cs_net_profit#7)), count(distinct cs_order_number#5)]
+
+(41) CometColumnarToRow [codegen id : 2]
+Input [3]: [order count #26, total shipping cost #27, total net profit #28]
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16/extended.txt
new file mode 100644
index 0000000000..2ad029e444
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16/extended.txt
@@ -0,0 +1,43 @@
+CometColumnarToRow
++- CometHashAggregate
+ +- CometColumnarExchange
+ +- HashAggregate
+ +- HashAggregate [COMET: Unsupported aggregation mode PartialMerge]
+ +- CometColumnarToRow
+ +- CometHashAggregate
+ +- CometProject
+ +- CometBroadcastHashJoin
+ :- CometProject
+ : +- CometBroadcastHashJoin
+ : :- CometProject
+ : : +- CometBroadcastHashJoin
+ : : :- CometSortMergeJoin
+ : : : :- CometProject
+ : : : : +- CometSortMergeJoin
+ : : : : :- CometSort
+ : : : : : +- CometExchange
+ : : : : : +- CometProject
+ : : : : : +- CometFilter
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : : +- CometSort
+ : : : : +- CometExchange
+ : : : : +- CometProject
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+ : : : +- CometSort
+ : : : +- CometExchange
+ : : : +- CometProject
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_returns
+ : : +- CometBroadcastExchange
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim
+ : +- CometBroadcastExchange
+ : +- CometProject
+ : +- CometFilter
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address
+ +- CometBroadcastExchange
+ +- CometProject
+ +- CometFilter
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.call_center
+
+Comet accelerated 37 out of 39 eligible operators (94%). Final plan contains 2 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16/simplified.txt
new file mode 100644
index 0000000000..8427aa49a9
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q16/simplified.txt
@@ -0,0 +1,45 @@
+WholeStageCodegen (2)
+ CometColumnarToRow
+ InputAdapter
+ CometHashAggregate [sum,sum,count] [order count ,total shipping cost ,total net profit ,count(cs_order_number),sum(UnscaledValue(cs_ext_ship_cost)),sum(UnscaledValue(cs_net_profit))]
+ CometColumnarExchange #1
+ WholeStageCodegen (1)
+ HashAggregate [cs_order_number] [sum(UnscaledValue(cs_ext_ship_cost)),sum(UnscaledValue(cs_net_profit)),count(cs_order_number),sum,sum,count,sum,sum,count]
+ HashAggregate [cs_order_number] [sum(UnscaledValue(cs_ext_ship_cost)),sum(UnscaledValue(cs_net_profit)),sum,sum,sum,sum]
+ CometColumnarToRow
+ InputAdapter
+ CometHashAggregate [cs_ext_ship_cost,cs_net_profit] [cs_order_number,sum,sum]
+ CometProject [cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometBroadcastHashJoin [cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,cc_call_center_sk]
+ CometProject [cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometBroadcastHashJoin [cs_ship_addr_sk,cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,ca_address_sk]
+ CometProject [cs_ship_addr_sk,cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometBroadcastHashJoin [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,d_date_sk]
+ CometSortMergeJoin [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,cr_order_number]
+ CometProject [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometSortMergeJoin [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_warehouse_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,cs_order_number,cs_warehouse_sk]
+ CometSort [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_warehouse_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometExchange [cs_order_number] #2
+ CometProject [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_warehouse_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit]
+ CometFilter [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_warehouse_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,cs_sold_date_sk]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_ship_date_sk,cs_ship_addr_sk,cs_call_center_sk,cs_warehouse_sk,cs_order_number,cs_ext_ship_cost,cs_net_profit,cs_sold_date_sk]
+ CometSort [cs_warehouse_sk,cs_order_number]
+ CometExchange [cs_order_number] #3
+ CometProject [cs_warehouse_sk,cs_order_number]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales [cs_warehouse_sk,cs_order_number,cs_sold_date_sk]
+ CometSort [cr_order_number]
+ CometExchange [cr_order_number] #4
+ CometProject [cr_order_number]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_returns [cr_order_number,cr_returned_date_sk]
+ CometBroadcastExchange [d_date_sk] #5
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_date]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim [d_date_sk,d_date]
+ CometBroadcastExchange [ca_address_sk] #6
+ CometProject [ca_address_sk]
+ CometFilter [ca_address_sk,ca_state]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.customer_address [ca_address_sk,ca_state]
+ CometBroadcastExchange [cc_call_center_sk] #7
+ CometProject [cc_call_center_sk]
+ CometFilter [cc_call_center_sk,cc_county]
+ CometScan [native_iceberg_compat] parquet spark_catalog.default.call_center [cc_call_center_sk,cc_county]
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q17.native_datafusion/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q17.native_datafusion/explain.txt
new file mode 100644
index 0000000000..f6ba10374e
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q17.native_datafusion/explain.txt
@@ -0,0 +1,312 @@
+== Physical Plan ==
+TakeOrderedAndProject (43)
++- * HashAggregate (42)
+ +- * CometColumnarToRow (41)
+ +- CometColumnarExchange (40)
+ +- * HashAggregate (39)
+ +- * Project (38)
+ +- * BroadcastHashJoin Inner BuildRight (37)
+ :- * Project (31)
+ : +- * BroadcastHashJoin Inner BuildRight (30)
+ : :- * Project (24)
+ : : +- * BroadcastHashJoin Inner BuildRight (23)
+ : : :- * Project (21)
+ : : : +- * BroadcastHashJoin Inner BuildRight (20)
+ : : : :- * Project (18)
+ : : : : +- * BroadcastHashJoin Inner BuildRight (17)
+ : : : : :- * Project (15)
+ : : : : : +- * BroadcastHashJoin Inner BuildRight (14)
+ : : : : : :- * Project (9)
+ : : : : : : +- * BroadcastHashJoin Inner BuildRight (8)
+ : : : : : : :- * Filter (3)
+ : : : : : : : +- * ColumnarToRow (2)
+ : : : : : : : +- Scan parquet spark_catalog.default.store_sales (1)
+ : : : : : : +- BroadcastExchange (7)
+ : : : : : : +- * Filter (6)
+ : : : : : : +- * ColumnarToRow (5)
+ : : : : : : +- Scan parquet spark_catalog.default.store_returns (4)
+ : : : : : +- BroadcastExchange (13)
+ : : : : : +- * Filter (12)
+ : : : : : +- * ColumnarToRow (11)
+ : : : : : +- Scan parquet spark_catalog.default.catalog_sales (10)
+ : : : : +- ReusedExchange (16)
+ : : : +- ReusedExchange (19)
+ : : +- ReusedExchange (22)
+ : +- BroadcastExchange (29)
+ : +- * CometColumnarToRow (28)
+ : +- CometProject (27)
+ : +- CometFilter (26)
+ : +- CometNativeScan parquet spark_catalog.default.store (25)
+ +- BroadcastExchange (36)
+ +- * CometColumnarToRow (35)
+ +- CometProject (34)
+ +- CometFilter (33)
+ +- CometNativeScan parquet spark_catalog.default.item (32)
+
+
+(1) Scan parquet spark_catalog.default.store_sales
+Output [6]: [ss_item_sk#1, ss_customer_sk#2, ss_store_sk#3, ss_ticket_number#4, ss_quantity#5, ss_sold_date_sk#6]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#6), dynamicpruningexpression(ss_sold_date_sk#6 IN dynamicpruning#7)]
+PushedFilters: [IsNotNull(ss_customer_sk), IsNotNull(ss_item_sk), IsNotNull(ss_ticket_number), IsNotNull(ss_store_sk)]
+ReadSchema: struct
+
+(2) ColumnarToRow [codegen id : 8]
+Input [6]: [ss_item_sk#1, ss_customer_sk#2, ss_store_sk#3, ss_ticket_number#4, ss_quantity#5, ss_sold_date_sk#6]
+
+(3) Filter [codegen id : 8]
+Input [6]: [ss_item_sk#1, ss_customer_sk#2, ss_store_sk#3, ss_ticket_number#4, ss_quantity#5, ss_sold_date_sk#6]
+Condition : (((isnotnull(ss_customer_sk#2) AND isnotnull(ss_item_sk#1)) AND isnotnull(ss_ticket_number#4)) AND isnotnull(ss_store_sk#3))
+
+(4) Scan parquet spark_catalog.default.store_returns
+Output [5]: [sr_item_sk#8, sr_customer_sk#9, sr_ticket_number#10, sr_return_quantity#11, sr_returned_date_sk#12]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(sr_returned_date_sk#12), dynamicpruningexpression(sr_returned_date_sk#12 IN dynamicpruning#13)]
+PushedFilters: [IsNotNull(sr_customer_sk), IsNotNull(sr_item_sk), IsNotNull(sr_ticket_number)]
+ReadSchema: struct
+
+(5) ColumnarToRow [codegen id : 1]
+Input [5]: [sr_item_sk#8, sr_customer_sk#9, sr_ticket_number#10, sr_return_quantity#11, sr_returned_date_sk#12]
+
+(6) Filter [codegen id : 1]
+Input [5]: [sr_item_sk#8, sr_customer_sk#9, sr_ticket_number#10, sr_return_quantity#11, sr_returned_date_sk#12]
+Condition : ((isnotnull(sr_customer_sk#9) AND isnotnull(sr_item_sk#8)) AND isnotnull(sr_ticket_number#10))
+
+(7) BroadcastExchange
+Input [5]: [sr_item_sk#8, sr_customer_sk#9, sr_ticket_number#10, sr_return_quantity#11, sr_returned_date_sk#12]
+Arguments: HashedRelationBroadcastMode(List(input[1, int, false], input[0, int, false], input[2, int, false]),false), [plan_id=1]
+
+(8) BroadcastHashJoin [codegen id : 8]
+Left keys [3]: [ss_customer_sk#2, ss_item_sk#1, ss_ticket_number#4]
+Right keys [3]: [sr_customer_sk#9, sr_item_sk#8, sr_ticket_number#10]
+Join type: Inner
+Join condition: None
+
+(9) Project [codegen id : 8]
+Output [8]: [ss_item_sk#1, ss_store_sk#3, ss_quantity#5, ss_sold_date_sk#6, sr_item_sk#8, sr_customer_sk#9, sr_return_quantity#11, sr_returned_date_sk#12]
+Input [11]: [ss_item_sk#1, ss_customer_sk#2, ss_store_sk#3, ss_ticket_number#4, ss_quantity#5, ss_sold_date_sk#6, sr_item_sk#8, sr_customer_sk#9, sr_ticket_number#10, sr_return_quantity#11, sr_returned_date_sk#12]
+
+(10) Scan parquet spark_catalog.default.catalog_sales
+Output [4]: [cs_bill_customer_sk#14, cs_item_sk#15, cs_quantity#16, cs_sold_date_sk#17]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#17), dynamicpruningexpression(cs_sold_date_sk#17 IN dynamicpruning#13)]
+PushedFilters: [IsNotNull(cs_bill_customer_sk), IsNotNull(cs_item_sk)]
+ReadSchema: struct
+
+(11) ColumnarToRow [codegen id : 2]
+Input [4]: [cs_bill_customer_sk#14, cs_item_sk#15, cs_quantity#16, cs_sold_date_sk#17]
+
+(12) Filter [codegen id : 2]
+Input [4]: [cs_bill_customer_sk#14, cs_item_sk#15, cs_quantity#16, cs_sold_date_sk#17]
+Condition : (isnotnull(cs_bill_customer_sk#14) AND isnotnull(cs_item_sk#15))
+
+(13) BroadcastExchange
+Input [4]: [cs_bill_customer_sk#14, cs_item_sk#15, cs_quantity#16, cs_sold_date_sk#17]
+Arguments: HashedRelationBroadcastMode(List((shiftleft(cast(input[0, int, false] as bigint), 32) | (cast(input[1, int, false] as bigint) & 4294967295))),false), [plan_id=2]
+
+(14) BroadcastHashJoin [codegen id : 8]
+Left keys [2]: [sr_customer_sk#9, sr_item_sk#8]
+Right keys [2]: [cs_bill_customer_sk#14, cs_item_sk#15]
+Join type: Inner
+Join condition: None
+
+(15) Project [codegen id : 8]
+Output [8]: [ss_item_sk#1, ss_store_sk#3, ss_quantity#5, ss_sold_date_sk#6, sr_return_quantity#11, sr_returned_date_sk#12, cs_quantity#16, cs_sold_date_sk#17]
+Input [12]: [ss_item_sk#1, ss_store_sk#3, ss_quantity#5, ss_sold_date_sk#6, sr_item_sk#8, sr_customer_sk#9, sr_return_quantity#11, sr_returned_date_sk#12, cs_bill_customer_sk#14, cs_item_sk#15, cs_quantity#16, cs_sold_date_sk#17]
+
+(16) ReusedExchange [Reuses operator id: 48]
+Output [1]: [d_date_sk#18]
+
+(17) BroadcastHashJoin [codegen id : 8]
+Left keys [1]: [ss_sold_date_sk#6]
+Right keys [1]: [d_date_sk#18]
+Join type: Inner
+Join condition: None
+
+(18) Project [codegen id : 8]
+Output [7]: [ss_item_sk#1, ss_store_sk#3, ss_quantity#5, sr_return_quantity#11, sr_returned_date_sk#12, cs_quantity#16, cs_sold_date_sk#17]
+Input [9]: [ss_item_sk#1, ss_store_sk#3, ss_quantity#5, ss_sold_date_sk#6, sr_return_quantity#11, sr_returned_date_sk#12, cs_quantity#16, cs_sold_date_sk#17, d_date_sk#18]
+
+(19) ReusedExchange [Reuses operator id: 53]
+Output [1]: [d_date_sk#19]
+
+(20) BroadcastHashJoin [codegen id : 8]
+Left keys [1]: [sr_returned_date_sk#12]
+Right keys [1]: [d_date_sk#19]
+Join type: Inner
+Join condition: None
+
+(21) Project [codegen id : 8]
+Output [6]: [ss_item_sk#1, ss_store_sk#3, ss_quantity#5, sr_return_quantity#11, cs_quantity#16, cs_sold_date_sk#17]
+Input [8]: [ss_item_sk#1, ss_store_sk#3, ss_quantity#5, sr_return_quantity#11, sr_returned_date_sk#12, cs_quantity#16, cs_sold_date_sk#17, d_date_sk#19]
+
+(22) ReusedExchange [Reuses operator id: 53]
+Output [1]: [d_date_sk#20]
+
+(23) BroadcastHashJoin [codegen id : 8]
+Left keys [1]: [cs_sold_date_sk#17]
+Right keys [1]: [d_date_sk#20]
+Join type: Inner
+Join condition: None
+
+(24) Project [codegen id : 8]
+Output [5]: [ss_item_sk#1, ss_store_sk#3, ss_quantity#5, sr_return_quantity#11, cs_quantity#16]
+Input [7]: [ss_item_sk#1, ss_store_sk#3, ss_quantity#5, sr_return_quantity#11, cs_quantity#16, cs_sold_date_sk#17, d_date_sk#20]
+
+(25) CometNativeScan parquet spark_catalog.default.store
+Output [2]: [s_store_sk#21, s_state#22]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/store]
+PushedFilters: [IsNotNull(s_store_sk)]
+ReadSchema: struct
+
+(26) CometFilter
+Input [2]: [s_store_sk#21, s_state#22]
+Condition : isnotnull(s_store_sk#21)
+
+(27) CometProject
+Input [2]: [s_store_sk#21, s_state#22]
+Arguments: [s_store_sk#21, s_state#23], [s_store_sk#21, static_invoke(CharVarcharCodegenUtils.readSidePadding(s_state#22, 2)) AS s_state#23]
+
+(28) CometColumnarToRow [codegen id : 6]
+Input [2]: [s_store_sk#21, s_state#23]
+
+(29) BroadcastExchange
+Input [2]: [s_store_sk#21, s_state#23]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=3]
+
+(30) BroadcastHashJoin [codegen id : 8]
+Left keys [1]: [ss_store_sk#3]
+Right keys [1]: [s_store_sk#21]
+Join type: Inner
+Join condition: None
+
+(31) Project [codegen id : 8]
+Output [5]: [ss_item_sk#1, ss_quantity#5, sr_return_quantity#11, cs_quantity#16, s_state#23]
+Input [7]: [ss_item_sk#1, ss_store_sk#3, ss_quantity#5, sr_return_quantity#11, cs_quantity#16, s_store_sk#21, s_state#23]
+
+(32) CometNativeScan parquet spark_catalog.default.item
+Output [3]: [i_item_sk#24, i_item_id#25, i_item_desc#26]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/item]
+PushedFilters: [IsNotNull(i_item_sk)]
+ReadSchema: struct
+
+(33) CometFilter
+Input [3]: [i_item_sk#24, i_item_id#25, i_item_desc#26]
+Condition : isnotnull(i_item_sk#24)
+
+(34) CometProject
+Input [3]: [i_item_sk#24, i_item_id#25, i_item_desc#26]
+Arguments: [i_item_sk#24, i_item_id#27, i_item_desc#26], [i_item_sk#24, static_invoke(CharVarcharCodegenUtils.readSidePadding(i_item_id#25, 16)) AS i_item_id#27, i_item_desc#26]
+
+(35) CometColumnarToRow [codegen id : 7]
+Input [3]: [i_item_sk#24, i_item_id#27, i_item_desc#26]
+
+(36) BroadcastExchange
+Input [3]: [i_item_sk#24, i_item_id#27, i_item_desc#26]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=4]
+
+(37) BroadcastHashJoin [codegen id : 8]
+Left keys [1]: [ss_item_sk#1]
+Right keys [1]: [i_item_sk#24]
+Join type: Inner
+Join condition: None
+
+(38) Project [codegen id : 8]
+Output [6]: [ss_quantity#5, sr_return_quantity#11, cs_quantity#16, s_state#23, i_item_id#27, i_item_desc#26]
+Input [8]: [ss_item_sk#1, ss_quantity#5, sr_return_quantity#11, cs_quantity#16, s_state#23, i_item_sk#24, i_item_id#27, i_item_desc#26]
+
+(39) HashAggregate [codegen id : 8]
+Input [6]: [ss_quantity#5, sr_return_quantity#11, cs_quantity#16, s_state#23, i_item_id#27, i_item_desc#26]
+Keys [3]: [i_item_id#27, i_item_desc#26, s_state#23]
+Functions [9]: [partial_count(ss_quantity#5), partial_avg(ss_quantity#5), partial_stddev_samp(cast(ss_quantity#5 as double)), partial_count(sr_return_quantity#11), partial_avg(sr_return_quantity#11), partial_stddev_samp(cast(sr_return_quantity#11 as double)), partial_count(cs_quantity#16), partial_avg(cs_quantity#16), partial_stddev_samp(cast(cs_quantity#16 as double))]
+Aggregate Attributes [18]: [count#28, sum#29, count#30, n#31, avg#32, m2#33, count#34, sum#35, count#36, n#37, avg#38, m2#39, count#40, sum#41, count#42, n#43, avg#44, m2#45]
+Results [21]: [i_item_id#27, i_item_desc#26, s_state#23, count#46, sum#47, count#48, n#49, avg#50, m2#51, count#52, sum#53, count#54, n#55, avg#56, m2#57, count#58, sum#59, count#60, n#61, avg#62, m2#63]
+
+(40) CometColumnarExchange
+Input [21]: [i_item_id#27, i_item_desc#26, s_state#23, count#46, sum#47, count#48, n#49, avg#50, m2#51, count#52, sum#53, count#54, n#55, avg#56, m2#57, count#58, sum#59, count#60, n#61, avg#62, m2#63]
+Arguments: hashpartitioning(i_item_id#27, i_item_desc#26, s_state#23, 5), ENSURE_REQUIREMENTS, CometColumnarShuffle, [plan_id=5]
+
+(41) CometColumnarToRow [codegen id : 9]
+Input [21]: [i_item_id#27, i_item_desc#26, s_state#23, count#46, sum#47, count#48, n#49, avg#50, m2#51, count#52, sum#53, count#54, n#55, avg#56, m2#57, count#58, sum#59, count#60, n#61, avg#62, m2#63]
+
+(42) HashAggregate [codegen id : 9]
+Input [21]: [i_item_id#27, i_item_desc#26, s_state#23, count#46, sum#47, count#48, n#49, avg#50, m2#51, count#52, sum#53, count#54, n#55, avg#56, m2#57, count#58, sum#59, count#60, n#61, avg#62, m2#63]
+Keys [3]: [i_item_id#27, i_item_desc#26, s_state#23]
+Functions [9]: [count(ss_quantity#5), avg(ss_quantity#5), stddev_samp(cast(ss_quantity#5 as double)), count(sr_return_quantity#11), avg(sr_return_quantity#11), stddev_samp(cast(sr_return_quantity#11 as double)), count(cs_quantity#16), avg(cs_quantity#16), stddev_samp(cast(cs_quantity#16 as double))]
+Aggregate Attributes [9]: [count(ss_quantity#5)#64, avg(ss_quantity#5)#65, stddev_samp(cast(ss_quantity#5 as double))#66, count(sr_return_quantity#11)#67, avg(sr_return_quantity#11)#68, stddev_samp(cast(sr_return_quantity#11 as double))#69, count(cs_quantity#16)#70, avg(cs_quantity#16)#71, stddev_samp(cast(cs_quantity#16 as double))#72]
+Results [15]: [i_item_id#27, i_item_desc#26, s_state#23, count(ss_quantity#5)#64 AS store_sales_quantitycount#73, avg(ss_quantity#5)#65 AS store_sales_quantityave#74, stddev_samp(cast(ss_quantity#5 as double))#66 AS store_sales_quantitystdev#75, (stddev_samp(cast(ss_quantity#5 as double))#66 / avg(ss_quantity#5)#65) AS store_sales_quantitycov#76, count(sr_return_quantity#11)#67 AS as_store_returns_quantitycount#77, avg(sr_return_quantity#11)#68 AS as_store_returns_quantityave#78, stddev_samp(cast(sr_return_quantity#11 as double))#69 AS as_store_returns_quantitystdev#79, (stddev_samp(cast(sr_return_quantity#11 as double))#69 / avg(sr_return_quantity#11)#68) AS store_returns_quantitycov#80, count(cs_quantity#16)#70 AS catalog_sales_quantitycount#81, avg(cs_quantity#16)#71 AS catalog_sales_quantityave#82, (stddev_samp(cast(cs_quantity#16 as double))#72 / avg(cs_quantity#16)#71) AS catalog_sales_quantitystdev#83, (stddev_samp(cast(cs_quantity#16 as double))#72 / avg(cs_quantity#16)#71) AS catalog_sales_quantitycov#84]
+
+(43) TakeOrderedAndProject
+Input [15]: [i_item_id#27, i_item_desc#26, s_state#23, store_sales_quantitycount#73, store_sales_quantityave#74, store_sales_quantitystdev#75, store_sales_quantitycov#76, as_store_returns_quantitycount#77, as_store_returns_quantityave#78, as_store_returns_quantitystdev#79, store_returns_quantitycov#80, catalog_sales_quantitycount#81, catalog_sales_quantityave#82, catalog_sales_quantitystdev#83, catalog_sales_quantitycov#84]
+Arguments: 100, [i_item_id#27 ASC NULLS FIRST, i_item_desc#26 ASC NULLS FIRST, s_state#23 ASC NULLS FIRST], [i_item_id#27, i_item_desc#26, s_state#23, store_sales_quantitycount#73, store_sales_quantityave#74, store_sales_quantitystdev#75, store_sales_quantitycov#76, as_store_returns_quantitycount#77, as_store_returns_quantityave#78, as_store_returns_quantitystdev#79, store_returns_quantitycov#80, catalog_sales_quantitycount#81, catalog_sales_quantityave#82, catalog_sales_quantitystdev#83, catalog_sales_quantitycov#84]
+
+===== Subqueries =====
+
+Subquery:1 Hosting operator id = 1 Hosting Expression = ss_sold_date_sk#6 IN dynamicpruning#7
+BroadcastExchange (48)
++- * CometColumnarToRow (47)
+ +- CometProject (46)
+ +- CometFilter (45)
+ +- CometNativeScan parquet spark_catalog.default.date_dim (44)
+
+
+(44) CometNativeScan parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#18, d_quarter_name#85]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_quarter_name), IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(45) CometFilter
+Input [2]: [d_date_sk#18, d_quarter_name#85]
+Condition : ((isnotnull(d_quarter_name#85) AND (static_invoke(CharVarcharCodegenUtils.readSidePadding(d_quarter_name#85, 6)) = 2001Q1)) AND isnotnull(d_date_sk#18))
+
+(46) CometProject
+Input [2]: [d_date_sk#18, d_quarter_name#85]
+Arguments: [d_date_sk#18], [d_date_sk#18]
+
+(47) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#18]
+
+(48) BroadcastExchange
+Input [1]: [d_date_sk#18]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=6]
+
+Subquery:2 Hosting operator id = 4 Hosting Expression = sr_returned_date_sk#12 IN dynamicpruning#13
+BroadcastExchange (53)
++- * CometColumnarToRow (52)
+ +- CometProject (51)
+ +- CometFilter (50)
+ +- CometNativeScan parquet spark_catalog.default.date_dim (49)
+
+
+(49) CometNativeScan parquet spark_catalog.default.date_dim
+Output [2]: [d_date_sk#19, d_quarter_name#86]
+Batched: true
+Location [not included in comparison]/{warehouse_dir}/date_dim]
+PushedFilters: [IsNotNull(d_date_sk)]
+ReadSchema: struct
+
+(50) CometFilter
+Input [2]: [d_date_sk#19, d_quarter_name#86]
+Condition : (static_invoke(CharVarcharCodegenUtils.readSidePadding(d_quarter_name#86, 6)) IN (2001Q1,2001Q2,2001Q3) AND isnotnull(d_date_sk#19))
+
+(51) CometProject
+Input [2]: [d_date_sk#19, d_quarter_name#86]
+Arguments: [d_date_sk#19], [d_date_sk#19]
+
+(52) CometColumnarToRow [codegen id : 1]
+Input [1]: [d_date_sk#19]
+
+(53) BroadcastExchange
+Input [1]: [d_date_sk#19]
+Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=7]
+
+Subquery:3 Hosting operator id = 10 Hosting Expression = cs_sold_date_sk#17 IN dynamicpruning#13
+
+
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q17.native_datafusion/extended.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q17.native_datafusion/extended.txt
new file mode 100644
index 0000000000..26e924fd7e
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q17.native_datafusion/extended.txt
@@ -0,0 +1,70 @@
+TakeOrderedAndProject
++- HashAggregate
+ +- CometColumnarToRow
+ +- CometColumnarExchange
+ +- HashAggregate
+ +- Project
+ +- BroadcastHashJoin
+ :- Project
+ : +- BroadcastHashJoin
+ : :- Project
+ : : +- BroadcastHashJoin
+ : : :- Project
+ : : : +- BroadcastHashJoin
+ : : : :- Project
+ : : : : +- BroadcastHashJoin
+ : : : : :- Project
+ : : : : : +- BroadcastHashJoin
+ : : : : : :- Project
+ : : : : : : +- BroadcastHashJoin
+ : : : : : : :- Filter
+ : : : : : : : +- ColumnarToRow
+ : : : : : : : +- Scan parquet spark_catalog.default.store_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : : : +- SubqueryBroadcast
+ : : : : : : : +- BroadcastExchange
+ : : : : : : : +- CometColumnarToRow
+ : : : : : : : +- CometProject
+ : : : : : : : +- CometFilter
+ : : : : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : : : : +- BroadcastExchange
+ : : : : : : +- Filter
+ : : : : : : +- ColumnarToRow
+ : : : : : : +- Scan parquet spark_catalog.default.store_returns [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : : +- SubqueryBroadcast
+ : : : : : : +- BroadcastExchange
+ : : : : : : +- CometColumnarToRow
+ : : : : : : +- CometProject
+ : : : : : : +- CometFilter
+ : : : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : : : +- BroadcastExchange
+ : : : : : +- Filter
+ : : : : : +- ColumnarToRow
+ : : : : : +- Scan parquet spark_catalog.default.catalog_sales [COMET: Native DataFusion scan does not support subqueries/dynamic pruning]
+ : : : : : +- ReusedSubquery
+ : : : : +- BroadcastExchange
+ : : : : +- CometColumnarToRow
+ : : : : +- CometProject
+ : : : : +- CometFilter
+ : : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : : +- BroadcastExchange
+ : : : +- CometColumnarToRow
+ : : : +- CometProject
+ : : : +- CometFilter
+ : : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : : +- BroadcastExchange
+ : : +- CometColumnarToRow
+ : : +- CometProject
+ : : +- CometFilter
+ : : +- CometNativeScan parquet spark_catalog.default.date_dim
+ : +- BroadcastExchange
+ : +- CometColumnarToRow
+ : +- CometProject
+ : +- CometFilter
+ : +- CometNativeScan parquet spark_catalog.default.store
+ +- BroadcastExchange
+ +- CometColumnarToRow
+ +- CometProject
+ +- CometFilter
+ +- CometNativeScan parquet spark_catalog.default.item
+
+Comet accelerated 22 out of 57 eligible operators (38%). Final plan contains 11 transitions between Spark and Comet.
\ No newline at end of file
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q17.native_datafusion/simplified.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q17.native_datafusion/simplified.txt
new file mode 100644
index 0000000000..c63dd716a1
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q17.native_datafusion/simplified.txt
@@ -0,0 +1,79 @@
+TakeOrderedAndProject [i_item_id,i_item_desc,s_state,store_sales_quantitycount,store_sales_quantityave,store_sales_quantitystdev,store_sales_quantitycov,as_store_returns_quantitycount,as_store_returns_quantityave,as_store_returns_quantitystdev,store_returns_quantitycov,catalog_sales_quantitycount,catalog_sales_quantityave,catalog_sales_quantitystdev,catalog_sales_quantitycov]
+ WholeStageCodegen (9)
+ HashAggregate [i_item_id,i_item_desc,s_state,count,sum,count,n,avg,m2,count,sum,count,n,avg,m2,count,sum,count,n,avg,m2] [count(ss_quantity),avg(ss_quantity),stddev_samp(cast(ss_quantity as double)),count(sr_return_quantity),avg(sr_return_quantity),stddev_samp(cast(sr_return_quantity as double)),count(cs_quantity),avg(cs_quantity),stddev_samp(cast(cs_quantity as double)),store_sales_quantitycount,store_sales_quantityave,store_sales_quantitystdev,store_sales_quantitycov,as_store_returns_quantitycount,as_store_returns_quantityave,as_store_returns_quantitystdev,store_returns_quantitycov,catalog_sales_quantitycount,catalog_sales_quantityave,catalog_sales_quantitystdev,catalog_sales_quantitycov,count,sum,count,n,avg,m2,count,sum,count,n,avg,m2,count,sum,count,n,avg,m2]
+ CometColumnarToRow
+ InputAdapter
+ CometColumnarExchange [i_item_id,i_item_desc,s_state] #1
+ WholeStageCodegen (8)
+ HashAggregate [i_item_id,i_item_desc,s_state,ss_quantity,sr_return_quantity,cs_quantity] [count,sum,count,n,avg,m2,count,sum,count,n,avg,m2,count,sum,count,n,avg,m2,count,sum,count,n,avg,m2,count,sum,count,n,avg,m2,count,sum,count,n,avg,m2]
+ Project [ss_quantity,sr_return_quantity,cs_quantity,s_state,i_item_id,i_item_desc]
+ BroadcastHashJoin [ss_item_sk,i_item_sk]
+ Project [ss_item_sk,ss_quantity,sr_return_quantity,cs_quantity,s_state]
+ BroadcastHashJoin [ss_store_sk,s_store_sk]
+ Project [ss_item_sk,ss_store_sk,ss_quantity,sr_return_quantity,cs_quantity]
+ BroadcastHashJoin [cs_sold_date_sk,d_date_sk]
+ Project [ss_item_sk,ss_store_sk,ss_quantity,sr_return_quantity,cs_quantity,cs_sold_date_sk]
+ BroadcastHashJoin [sr_returned_date_sk,d_date_sk]
+ Project [ss_item_sk,ss_store_sk,ss_quantity,sr_return_quantity,sr_returned_date_sk,cs_quantity,cs_sold_date_sk]
+ BroadcastHashJoin [ss_sold_date_sk,d_date_sk]
+ Project [ss_item_sk,ss_store_sk,ss_quantity,ss_sold_date_sk,sr_return_quantity,sr_returned_date_sk,cs_quantity,cs_sold_date_sk]
+ BroadcastHashJoin [sr_customer_sk,sr_item_sk,cs_bill_customer_sk,cs_item_sk]
+ Project [ss_item_sk,ss_store_sk,ss_quantity,ss_sold_date_sk,sr_item_sk,sr_customer_sk,sr_return_quantity,sr_returned_date_sk]
+ BroadcastHashJoin [ss_customer_sk,ss_item_sk,ss_ticket_number,sr_customer_sk,sr_item_sk,sr_ticket_number]
+ Filter [ss_customer_sk,ss_item_sk,ss_ticket_number,ss_store_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.store_sales [ss_item_sk,ss_customer_sk,ss_store_sk,ss_ticket_number,ss_quantity,ss_sold_date_sk]
+ SubqueryBroadcast [d_date_sk] #1
+ BroadcastExchange #2
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_quarter_name]
+ CometNativeScan parquet spark_catalog.default.date_dim [d_date_sk,d_quarter_name]
+ InputAdapter
+ BroadcastExchange #3
+ WholeStageCodegen (1)
+ Filter [sr_customer_sk,sr_item_sk,sr_ticket_number]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.store_returns [sr_item_sk,sr_customer_sk,sr_ticket_number,sr_return_quantity,sr_returned_date_sk]
+ SubqueryBroadcast [d_date_sk] #2
+ BroadcastExchange #4
+ WholeStageCodegen (1)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [d_date_sk]
+ CometFilter [d_date_sk,d_quarter_name]
+ CometNativeScan parquet spark_catalog.default.date_dim [d_date_sk,d_quarter_name]
+ InputAdapter
+ BroadcastExchange #5
+ WholeStageCodegen (2)
+ Filter [cs_bill_customer_sk,cs_item_sk]
+ ColumnarToRow
+ InputAdapter
+ Scan parquet spark_catalog.default.catalog_sales [cs_bill_customer_sk,cs_item_sk,cs_quantity,cs_sold_date_sk]
+ ReusedSubquery [d_date_sk] #2
+ InputAdapter
+ ReusedExchange [d_date_sk] #2
+ InputAdapter
+ ReusedExchange [d_date_sk] #4
+ InputAdapter
+ ReusedExchange [d_date_sk] #4
+ InputAdapter
+ BroadcastExchange #6
+ WholeStageCodegen (6)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [s_state] [s_store_sk,s_state]
+ CometFilter [s_store_sk,s_state]
+ CometNativeScan parquet spark_catalog.default.store [s_store_sk,s_state]
+ InputAdapter
+ BroadcastExchange #7
+ WholeStageCodegen (7)
+ CometColumnarToRow
+ InputAdapter
+ CometProject [i_item_id] [i_item_sk,i_item_id,i_item_desc]
+ CometFilter [i_item_sk,i_item_id,i_item_desc]
+ CometNativeScan parquet spark_catalog.default.item [i_item_sk,i_item_id,i_item_desc]
diff --git a/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q17.native_iceberg_compat/explain.txt b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q17.native_iceberg_compat/explain.txt
new file mode 100644
index 0000000000..e6d049b949
--- /dev/null
+++ b/spark/spark/src/test/resources/tpcds-plan-stability/approved-plans-v1_4-spark4_1/q17.native_iceberg_compat/explain.txt
@@ -0,0 +1,319 @@
+== Physical Plan ==
+* CometColumnarToRow (44)
++- CometTakeOrderedAndProject (43)
+ +- CometHashAggregate (42)
+ +- CometExchange (41)
+ +- CometHashAggregate (40)
+ +- CometProject (39)
+ +- CometBroadcastHashJoin (38)
+ :- CometProject (33)
+ : +- CometBroadcastHashJoin (32)
+ : :- CometProject (27)
+ : : +- CometBroadcastHashJoin (26)
+ : : :- CometProject (24)
+ : : : +- CometBroadcastHashJoin (23)
+ : : : :- CometProject (18)
+ : : : : +- CometBroadcastHashJoin (17)
+ : : : : :- CometProject (12)
+ : : : : : +- CometBroadcastHashJoin (11)
+ : : : : : :- CometProject (7)
+ : : : : : : +- CometBroadcastHashJoin (6)
+ : : : : : : :- CometFilter (2)
+ : : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales (1)
+ : : : : : : +- CometBroadcastExchange (5)
+ : : : : : : +- CometFilter (4)
+ : : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns (3)
+ : : : : : +- CometBroadcastExchange (10)
+ : : : : : +- CometFilter (9)
+ : : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales (8)
+ : : : : +- CometBroadcastExchange (16)
+ : : : : +- CometProject (15)
+ : : : : +- CometFilter (14)
+ : : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (13)
+ : : : +- CometBroadcastExchange (22)
+ : : : +- CometProject (21)
+ : : : +- CometFilter (20)
+ : : : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.date_dim (19)
+ : : +- ReusedExchange (25)
+ : +- CometBroadcastExchange (31)
+ : +- CometProject (30)
+ : +- CometFilter (29)
+ : +- CometScan [native_iceberg_compat] parquet spark_catalog.default.store (28)
+ +- CometBroadcastExchange (37)
+ +- CometProject (36)
+ +- CometFilter (35)
+ +- CometScan [native_iceberg_compat] parquet spark_catalog.default.item (34)
+
+
+(1) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_sales
+Output [6]: [ss_item_sk#1, ss_customer_sk#2, ss_store_sk#3, ss_ticket_number#4, ss_quantity#5, ss_sold_date_sk#6]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(ss_sold_date_sk#6), dynamicpruningexpression(ss_sold_date_sk#6 IN dynamicpruning#7)]
+PushedFilters: [IsNotNull(ss_customer_sk), IsNotNull(ss_item_sk), IsNotNull(ss_ticket_number), IsNotNull(ss_store_sk)]
+ReadSchema: struct
+
+(2) CometFilter
+Input [6]: [ss_item_sk#1, ss_customer_sk#2, ss_store_sk#3, ss_ticket_number#4, ss_quantity#5, ss_sold_date_sk#6]
+Condition : (((isnotnull(ss_customer_sk#2) AND isnotnull(ss_item_sk#1)) AND isnotnull(ss_ticket_number#4)) AND isnotnull(ss_store_sk#3))
+
+(3) CometScan [native_iceberg_compat] parquet spark_catalog.default.store_returns
+Output [5]: [sr_item_sk#8, sr_customer_sk#9, sr_ticket_number#10, sr_return_quantity#11, sr_returned_date_sk#12]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(sr_returned_date_sk#12), dynamicpruningexpression(sr_returned_date_sk#12 IN dynamicpruning#13)]
+PushedFilters: [IsNotNull(sr_customer_sk), IsNotNull(sr_item_sk), IsNotNull(sr_ticket_number)]
+ReadSchema: struct
+
+(4) CometFilter
+Input [5]: [sr_item_sk#8, sr_customer_sk#9, sr_ticket_number#10, sr_return_quantity#11, sr_returned_date_sk#12]
+Condition : ((isnotnull(sr_customer_sk#9) AND isnotnull(sr_item_sk#8)) AND isnotnull(sr_ticket_number#10))
+
+(5) CometBroadcastExchange
+Input [5]: [sr_item_sk#8, sr_customer_sk#9, sr_ticket_number#10, sr_return_quantity#11, sr_returned_date_sk#12]
+Arguments: [sr_item_sk#8, sr_customer_sk#9, sr_ticket_number#10, sr_return_quantity#11, sr_returned_date_sk#12]
+
+(6) CometBroadcastHashJoin
+Left output [6]: [ss_item_sk#1, ss_customer_sk#2, ss_store_sk#3, ss_ticket_number#4, ss_quantity#5, ss_sold_date_sk#6]
+Right output [5]: [sr_item_sk#8, sr_customer_sk#9, sr_ticket_number#10, sr_return_quantity#11, sr_returned_date_sk#12]
+Arguments: [ss_customer_sk#2, ss_item_sk#1, ss_ticket_number#4], [sr_customer_sk#9, sr_item_sk#8, sr_ticket_number#10], Inner, BuildRight
+
+(7) CometProject
+Input [11]: [ss_item_sk#1, ss_customer_sk#2, ss_store_sk#3, ss_ticket_number#4, ss_quantity#5, ss_sold_date_sk#6, sr_item_sk#8, sr_customer_sk#9, sr_ticket_number#10, sr_return_quantity#11, sr_returned_date_sk#12]
+Arguments: [ss_item_sk#1, ss_store_sk#3, ss_quantity#5, ss_sold_date_sk#6, sr_item_sk#8, sr_customer_sk#9, sr_return_quantity#11, sr_returned_date_sk#12], [ss_item_sk#1, ss_store_sk#3, ss_quantity#5, ss_sold_date_sk#6, sr_item_sk#8, sr_customer_sk#9, sr_return_quantity#11, sr_returned_date_sk#12]
+
+(8) CometScan [native_iceberg_compat] parquet spark_catalog.default.catalog_sales
+Output [4]: [cs_bill_customer_sk#14, cs_item_sk#15, cs_quantity#16, cs_sold_date_sk#17]
+Batched: true
+Location: InMemoryFileIndex []
+PartitionFilters: [isnotnull(cs_sold_date_sk#17), dynamicpruningexpression(cs_sold_date_sk#17 IN dynamicpruning#18)]
+PushedFilters: [IsNotNull(cs_bill_customer_sk), IsNotNull(cs_item_sk)]
+ReadSchema: struct