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

JingsongLi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git


The following commit(s) were added to refs/heads/master by this push:
     new e462cf84d3 [spark] compact_chain_table should always use dynamic 
partition overwrite (#8529)
e462cf84d3 is described below

commit e462cf84d3e9fed4653f3e3e3bb6ee9ef3328076
Author: Juntao Zhang <[email protected]>
AuthorDate: Fri Jul 10 08:36:58 2026 +0800

    [spark] compact_chain_table should always use dynamic partition overwrite 
(#8529)
---
 .../procedure/CompactChainTableProcedure.java      |  14 +-
 .../procedure/CompactChainTableProcedureTest.scala | 165 ++++++++++++---------
 2 files changed, 109 insertions(+), 70 deletions(-)

diff --git 
a/paimon-spark/paimon-spark-common/src/main/java/org/apache/paimon/spark/procedure/CompactChainTableProcedure.java
 
b/paimon-spark/paimon-spark-common/src/main/java/org/apache/paimon/spark/procedure/CompactChainTableProcedure.java
index 6594dabd38..66f7f31615 100644
--- 
a/paimon-spark/paimon-spark-common/src/main/java/org/apache/paimon/spark/procedure/CompactChainTableProcedure.java
+++ 
b/paimon-spark/paimon-spark-common/src/main/java/org/apache/paimon/spark/procedure/CompactChainTableProcedure.java
@@ -44,6 +44,7 @@ import org.apache.spark.sql.types.StructType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
@@ -169,7 +170,14 @@ public class CompactChainTableProcedure extends 
BaseProcedure {
                         ScanPlanHelper$.MODULE$.createNewScanPlan(
                                 splits.toArray(new Split[0]), relation));
 
-        PaimonSparkWriter writer = PaimonSparkWriter.apply(snapshotTable);
+        // Always enable dynamic partition overwrite for compact_chain_table 
so that overwrite
+        // only affects the full partitions actually present in the compacted 
DataFrame,
+        // preserving other groups that have no delta data under the same 
partial partition.
+        PaimonSparkWriter writer =
+                PaimonSparkWriter.apply(
+                        snapshotTable.copy(
+                                Collections.singletonMap(
+                                        
CoreOptions.DYNAMIC_PARTITION_OVERWRITE.key(), "true")));
         Map<String, String> targetPartition =
                 ParameterUtils.parseCommaSeparatedKeyValues(partitionStr);
         for (Map.Entry<String, String> entry : targetPartition.entrySet()) {
@@ -190,12 +198,10 @@ public class CompactChainTableProcedure extends 
BaseProcedure {
         PartitionPredicate snapshotPartitionPredicate =
                 SparkProcedureUtils.convertPartitionsToPartitionPredicate(
                         partition, snapshotTable, spark());
-
         return !snapshotTable
                 .newScan()
                 .withPartitionFilter(snapshotPartitionPredicate)
-                .plan()
-                .splits()
+                .listPartitions()
                 .isEmpty();
     }
 
diff --git 
a/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/procedure/CompactChainTableProcedureTest.scala
 
b/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/procedure/CompactChainTableProcedureTest.scala
index b7ffc9be5f..aef65f9f30 100644
--- 
a/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/procedure/CompactChainTableProcedureTest.scala
+++ 
b/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/procedure/CompactChainTableProcedureTest.scala
@@ -305,72 +305,105 @@ class CompactChainTableProcedureTest extends 
PaimonSparkTestBase {
   }
 
   test("Paimon Procedure: compact_chain_table - test multiple partitions with 
group") {
-    withTable("chain_compact_t4") {
-      spark.sql(
-        """
-          |CREATE TABLE IF NOT EXISTS chain_compact_t4 (
-          |    `t1` BIGINT COMMENT 't1',
-          |    `t2` BIGINT COMMENT 't2',
-          |    `t3` STRING COMMENT 't3'
-          |  ) PARTITIONED BY (`region` STRING COMMENT 'region', `dt` STRING 
COMMENT 'dt', `hour` STRING COMMENT 'hour')
-          |TBLPROPERTIES (
-          |     'chain-table.enabled' = 'true',
-          |     'primary-key' = 'region,dt,hour,t1',
-          |     'sequence.field' = 't2',
-          |     'bucket-key' = 't1',
-          |     'bucket' = '1',
-          |     'partition.timestamp-pattern' = '$dt $hour:00:00',
-          |     'partition.timestamp-formatter' = 'yyyyMMdd HH:mm:ss',
-          |     'merge-engine' = 'deduplicate',
-          |     'chain-table.chain-partition-keys' = 'dt,hour'
-          |  )
-          |""".stripMargin)
-
-      // Create branches
-      setupChainTableBranches("chain_compact_t4")
-
-      // Write snapshot branch data
-      spark.sql(
-        "insert into `chain_compact_t4$branch_snapshot` partition 
(region='CN', dt = '20250810', hour = '20') values (1, 1, '1')")
-      spark.sql(
-        "insert into `chain_compact_t4$branch_snapshot` partition 
(region='CN', dt = '20250810', hour = '21') values (2, 1, '1')")
-      spark.sql(
-        "insert into `chain_compact_t4$branch_snapshot` partition 
(region='CN', dt = '20250810', hour = '22') values (3, 1, '1')")
-      spark.sql(
-        "insert into `chain_compact_t4$branch_snapshot` partition 
(region='UK', dt = '20250810', hour = '21') values (21, 1, '1')")
-
-      // Write delta branch data
-      spark.sql(
-        "insert into `chain_compact_t4$branch_delta` partition (region='CN', 
dt = '20250810', hour = '22') values (4, 1, '1')")
-      spark.sql(
-        "insert into `chain_compact_t4$branch_delta` partition (region='US', 
dt = '20250810', hour = '22') values (11, 1, '1')")
-      spark.sql(
-        "insert into `chain_compact_t4$branch_delta` partition (region='UK', 
dt = '20250810', hour = '22') values (22, 1, '1' )")
-
-      checkAnswer(
-        sql(
-          "SELECT * FROM `chain_compact_t4$branch_snapshot` where dt = 
'20250810' and hour = '22'"),
-        Seq(
-          Row(3, 1, "1", "CN", "20250810", "22")
-        )
-      )
-      checkAnswer(
-        spark.sql(
-          "CALL sys.compact_chain_table(table => '`chain_compact_t4`', 
partition => 'dt=\"20250810\", hour=\"22\"', overwrite => true)"),
-        Row(true) :: Nil
-      )
-      checkAnswer(
-        sql(
-          "SELECT * FROM `chain_compact_t4$branch_snapshot` where dt = 
'20250810' and hour = '22' order by region"),
-        Seq(
-          Row(2, 1, "1", "CN", "20250810", "22"),
-          Row(4, 1, "1", "CN", "20250810", "22"),
-          Row(21, 1, "1", "UK", "20250810", "22"),
-          Row(22, 1, "1", "UK", "20250810", "22"),
-          Row(11, 1, "1", "US", "20250810", "22")
-        )
-      )
-    }
+    Seq(true, false).foreach(
+      overwrite => {
+        withTable("chain_compact_t4") {
+          spark.sql(
+            s"""
+               |CREATE TABLE IF NOT EXISTS chain_compact_t4 (
+               |    `t1` BIGINT COMMENT 't1',
+               |    `t2` BIGINT COMMENT 't2',
+               |    `t3` STRING COMMENT 't3'
+               |  ) PARTITIONED BY (`region` STRING COMMENT 'region', `dt` 
STRING COMMENT 'dt', `hour` STRING COMMENT 'hour')
+               |TBLPROPERTIES (
+               |     'dynamic-partition-overwrite' = '$overwrite',
+               |     'chain-table.enabled' = 'true',
+               |     'primary-key' = 'region,dt,hour,t1',
+               |     'sequence.field' = 't2',
+               |     'bucket-key' = 't1',
+               |     'bucket' = '1',
+               |     'partition.timestamp-pattern' = '$$dt $$hour:00:00',
+               |     'partition.timestamp-formatter' = 'yyyyMMdd HH:mm:ss',
+               |     'merge-engine' = 'deduplicate',
+               |     'chain-table.chain-partition-keys' = 'dt,hour'
+               |  )
+               |""".stripMargin)
+
+          // Create branches
+          setupChainTableBranches("chain_compact_t4")
+
+          // Write snapshot branch data
+          spark.sql(
+            "insert into `chain_compact_t4$branch_snapshot` partition 
(region='CN', dt = '20250810', hour = '20') values (1, 1, '1')")
+          spark.sql(
+            "insert into `chain_compact_t4$branch_snapshot` partition 
(region='CN', dt = '20250810', hour = '21') values (2, 1, '1')")
+          spark.sql(
+            "insert into `chain_compact_t4$branch_snapshot` partition 
(region='CN', dt = '20250810', hour = '22') values (3, 1, '1')")
+          spark.sql(
+            "insert into `chain_compact_t4$branch_snapshot` partition 
(region='UK', dt = '20250810', hour = '21') values (21, 1, '1')")
+          spark.sql(
+            "insert into `chain_compact_t4$branch_snapshot` partition 
(region='FR', dt = '20250810', hour = '22') values (31, 1, '1')")
+          spark.sql(
+            "insert into `chain_compact_t4$branch_snapshot` partition 
(region='CA', dt = '20250810', hour = '21') values (41, 1, '1')")
+
+          // Write delta branch data
+          spark.sql(
+            "insert into `chain_compact_t4$branch_delta` partition 
(region='CN', dt = '20250810', hour = '22') values (4, 1, '1')")
+          spark.sql(
+            "insert into `chain_compact_t4$branch_delta` partition 
(region='US', dt = '20250810', hour = '22') values (11, 1, '1')")
+          spark.sql(
+            "insert into `chain_compact_t4$branch_delta` partition 
(region='UK', dt = '20250810', hour = '22') values (22, 1, '1' )")
+
+          checkAnswer(
+            sql(
+              "SELECT * FROM `chain_compact_t4$branch_snapshot` where dt = 
'20250810' and hour = '22'"),
+            Seq(
+              Row(3, 1, "1", "CN", "20250810", "22"),
+              Row(31, 1, "1", "FR", "20250810", "22")
+            )
+          )
+          checkAnswer(
+            spark.sql(
+              "CALL sys.compact_chain_table(table => '`chain_compact_t4`', 
partition => 'dt=\"20250810\", hour=\"22\"', overwrite => true)"),
+            Row(true) :: Nil
+          )
+          checkAnswer(
+            sql("select snapshot_id,commit_kind from 
`chain_compact_t4$branch_snapshot$snapshots`"),
+            Seq(
+              Row(1, "APPEND"),
+              Row(2, "APPEND"),
+              Row(3, "APPEND"),
+              Row(4, "APPEND"),
+              Row(5, "APPEND"),
+              Row(6, "APPEND"),
+              Row(7, "OVERWRITE")
+            )
+          )
+
+          checkAnswer(
+            sql(
+              "SELECT * FROM `chain_compact_t4$branch_snapshot` where dt = 
'20250810' and hour = '21'"),
+            Seq(
+              Row(2, 1, "1", "CN", "20250810", "21"),
+              Row(21, 1, "1", "UK", "20250810", "21"),
+              Row(41, 1, "1", "CA", "20250810", "21")
+            )
+          )
+
+          checkAnswer(
+            sql(
+              "SELECT * FROM `chain_compact_t4$branch_snapshot` where dt = 
'20250810' and hour = '22'"),
+            Seq(
+              Row(2, 1, "1", "CN", "20250810", "22"),
+              Row(4, 1, "1", "CN", "20250810", "22"),
+              Row(11, 1, "1", "US", "20250810", "22"),
+              Row(21, 1, "1", "UK", "20250810", "22"),
+              Row(22, 1, "1", "UK", "20250810", "22"),
+              Row(31, 1, "1", "FR", "20250810", "22")
+            )
+          )
+        }
+      })
   }
 
   def setupChainTableBranches(tableName: String): Unit = {

Reply via email to