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

lzljs3620320 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 1b64b5d36c [core] Allow change ignore-delete/ignore-update-before from 
false to true (#6811)
1b64b5d36c is described below

commit 1b64b5d36c53e548697215a8256084336f901c70
Author: yuzelin <[email protected]>
AuthorDate: Fri Dec 12 17:41:46 2025 +0800

    [core] Allow change ignore-delete/ignore-update-before from false to true 
(#6811)
---
 .../main/java/org/apache/paimon/CoreOptions.java   |  2 --
 .../mergetree/compact/FirstRowMergeFunction.java   |  2 +-
 .../org/apache/paimon/schema/SchemaManager.java    | 28 +++++++++++++++++
 .../apache/paimon/flink/BatchFileStoreITCase.java  | 36 +++++++++++++++++++---
 4 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/paimon-api/src/main/java/org/apache/paimon/CoreOptions.java 
b/paimon-api/src/main/java/org/apache/paimon/CoreOptions.java
index 0151ad96e9..7526ae6099 100644
--- a/paimon-api/src/main/java/org/apache/paimon/CoreOptions.java
+++ b/paimon-api/src/main/java/org/apache/paimon/CoreOptions.java
@@ -482,7 +482,6 @@ public class CoreOptions implements Serializable {
                     .defaultValue(MergeEngine.DEDUPLICATE)
                     .withDescription("Specify the merge engine for table with 
primary key.");
 
-    @Immutable
     public static final ConfigOption<Boolean> IGNORE_DELETE =
             key("ignore-delete")
                     .booleanType()
@@ -493,7 +492,6 @@ public class CoreOptions implements Serializable {
                             "partial-update.ignore-delete")
                     .withDescription("Whether to ignore delete records.");
 
-    @Immutable
     public static final ConfigOption<Boolean> IGNORE_UPDATE_BEFORE =
             key("ignore-update-before")
                     .booleanType()
diff --git 
a/paimon-core/src/main/java/org/apache/paimon/mergetree/compact/FirstRowMergeFunction.java
 
b/paimon-core/src/main/java/org/apache/paimon/mergetree/compact/FirstRowMergeFunction.java
index d795f16bbd..4b9e4a6ff1 100644
--- 
a/paimon-core/src/main/java/org/apache/paimon/mergetree/compact/FirstRowMergeFunction.java
+++ 
b/paimon-core/src/main/java/org/apache/paimon/mergetree/compact/FirstRowMergeFunction.java
@@ -54,7 +54,7 @@ public class FirstRowMergeFunction implements 
MergeFunction<KeyValue> {
             } else {
                 throw new IllegalArgumentException(
                         "By default, First row merge engine can not accept 
DELETE/UPDATE_BEFORE records.\n"
-                                + "You can config 'first-row.ignore-delete' to 
ignore the DELETE/UPDATE_BEFORE records.");
+                                + "You can config 'ignore-delete' to ignore 
the DELETE/UPDATE_BEFORE records.");
             }
         }
 
diff --git 
a/paimon-core/src/main/java/org/apache/paimon/schema/SchemaManager.java 
b/paimon-core/src/main/java/org/apache/paimon/schema/SchemaManager.java
index 82b605204b..e726b80326 100644
--- a/paimon-core/src/main/java/org/apache/paimon/schema/SchemaManager.java
+++ b/paimon-core/src/main/java/org/apache/paimon/schema/SchemaManager.java
@@ -82,7 +82,9 @@ import static 
org.apache.paimon.CoreOptions.DELETION_VECTORS_ENABLED;
 import static org.apache.paimon.CoreOptions.DELETION_VECTORS_MODIFIABLE;
 import static org.apache.paimon.CoreOptions.DISTINCT;
 import static org.apache.paimon.CoreOptions.FIELDS_PREFIX;
+import static org.apache.paimon.CoreOptions.IGNORE_DELETE;
 import static org.apache.paimon.CoreOptions.IGNORE_RETRACT;
+import static org.apache.paimon.CoreOptions.IGNORE_UPDATE_BEFORE;
 import static org.apache.paimon.CoreOptions.LIST_AGG_DELIMITER;
 import static org.apache.paimon.CoreOptions.NESTED_KEY;
 import static org.apache.paimon.CoreOptions.SEQUENCE_FIELD;
@@ -1120,6 +1122,32 @@ public class SchemaManager implements Serializable {
                 }
             }
         }
+
+        if (IGNORE_DELETE.key().equals(key)) {
+            boolean oldIgnoreDelete =
+                    oldValue == null
+                            ? IGNORE_DELETE.defaultValue()
+                            : Boolean.parseBoolean(oldValue);
+            boolean newIgnoreDelete = Boolean.parseBoolean(newValue);
+            if (oldIgnoreDelete && !newIgnoreDelete) {
+                throw new UnsupportedOperationException(
+                        String.format("Cannot change %s from true to false.", 
IGNORE_DELETE.key()));
+            }
+        }
+
+        if (IGNORE_UPDATE_BEFORE.key().equals(key)) {
+            boolean oldIgnoreUpdateBefore =
+                    oldValue == null
+                            ? IGNORE_UPDATE_BEFORE.defaultValue()
+                            : Boolean.parseBoolean(oldValue);
+            boolean newIgnoreUpdateBefore = Boolean.parseBoolean(newValue);
+            if (oldIgnoreUpdateBefore && !newIgnoreUpdateBefore) {
+                throw new UnsupportedOperationException(
+                        String.format(
+                                "Cannot change %s from true to false.",
+                                IGNORE_UPDATE_BEFORE.key()));
+            }
+        }
     }
 
     public static void checkResetTableOption(String key) {
diff --git 
a/paimon-flink/paimon-flink-common/src/test/java/org/apache/paimon/flink/BatchFileStoreITCase.java
 
b/paimon-flink/paimon-flink-common/src/test/java/org/apache/paimon/flink/BatchFileStoreITCase.java
index 589eeb14af..af0d7d508d 100644
--- 
a/paimon-flink/paimon-flink-common/src/test/java/org/apache/paimon/flink/BatchFileStoreITCase.java
+++ 
b/paimon-flink/paimon-flink-common/src/test/java/org/apache/paimon/flink/BatchFileStoreITCase.java
@@ -42,6 +42,8 @@ import org.junit.jupiter.api.Timeout;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.ValueSource;
 
+import javax.annotation.Nullable;
+
 import java.math.BigDecimal;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -63,6 +65,12 @@ public class BatchFileStoreITCase extends CatalogITCaseBase {
         return singletonList("CREATE TABLE IF NOT EXISTS T (a INT, b INT, c 
INT)");
     }
 
+    @Nullable
+    @Override
+    protected Boolean sqlSyncMode() {
+        return true;
+    }
+
     @Test
     public void testCsvFileFormat() {
         innerTestTextFileFormat("csv");
@@ -605,16 +613,23 @@ public class BatchFileStoreITCase extends 
CatalogITCaseBase {
     public void testIgnoreDelete() {
         sql(
                 "CREATE TABLE ignore_delete (pk INT PRIMARY KEY NOT ENFORCED, 
v STRING) "
-                        + "WITH ('merge-engine' = 'deduplicate', 
'ignore-delete' = 'true', 'bucket' = '1')");
-
-        sql("INSERT INTO ignore_delete VALUES (1, 'A')");
+                        + "WITH ('merge-engine' = 'deduplicate', 'bucket' = 
'1')");
+        sql("INSERT INTO ignore_delete VALUES (1, 'A'), (2, 'B')");
+        sql("DELETE FROM ignore_delete WHERE pk = 2");
         assertThat(sql("SELECT * FROM 
ignore_delete")).containsExactly(Row.of(1, "A"));
 
+        // compact to merge the -D record
+        sql("CALL sys.compact(`table` => 'default.ignore_delete')");
+        sql("ALTER TABLE ignore_delete SET ('ignore-delete' = 'true')");
+
         sql("DELETE FROM ignore_delete WHERE pk = 1");
         assertThat(sql("SELECT * FROM 
ignore_delete")).containsExactly(Row.of(1, "A"));
 
         sql("INSERT INTO ignore_delete VALUES (1, 'B')");
         assertThat(sql("SELECT * FROM 
ignore_delete")).containsExactly(Row.of(1, "B"));
+
+        assertThatThrownBy(() -> sql("ALTER TABLE ignore_delete SET 
('ignore-delete' = 'false')"))
+                .hasRootCauseMessage("Cannot change ignore-delete from true to 
false.");
     }
 
     @Test
@@ -637,16 +652,27 @@ public class BatchFileStoreITCase extends 
CatalogITCaseBase {
     public void testIgnoreUpdateBeforeWithRowKindField() {
         sql(
                 "CREATE TABLE ignore_delete (pk INT PRIMARY KEY NOT ENFORCED, 
v STRING, kind STRING) "
-                        + "WITH ('ignore-update-before' = 'true', 'bucket' = 
'1', 'rowkind.field' = 'kind')");
+                        + "WITH ('bucket' = '1', 'rowkind.field' = 'kind')");
 
-        sql("INSERT INTO ignore_delete VALUES (1, 'A', '+I')");
+        sql("INSERT INTO ignore_delete VALUES (1, 'A', '+I'), (2, 'B', '+I')");
+        sql("INSERT INTO ignore_delete VALUES (2, 'B', '-U')");
         assertThat(sql("SELECT * FROM 
ignore_delete")).containsExactly(Row.of(1, "A", "+I"));
 
+        // compact to merge the -U record
+        sql("CALL sys.compact(`table` => 'default.ignore_delete')");
+        sql("ALTER TABLE ignore_delete SET ('ignore-update-before' = 'true')");
+
         sql("INSERT INTO ignore_delete VALUES (1, 'A', '-U')");
         assertThat(sql("SELECT * FROM 
ignore_delete")).containsExactly(Row.of(1, "A", "+I"));
 
         sql("INSERT INTO ignore_delete VALUES (1, 'A', '-D')");
         assertThat(sql("SELECT * FROM ignore_delete")).isEmpty();
+
+        assertThatThrownBy(
+                        () ->
+                                sql(
+                                        "ALTER TABLE ignore_delete SET 
('ignore-update-before' = 'false')"))
+                .hasRootCauseMessage("Cannot change ignore-update-before from 
true to false.");
     }
 
     @Test

Reply via email to