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 e103dd2c40 [Bug] Reject partially overlapping sequence-group ordering 
fields (#10513)
e103dd2c40 is described below

commit e103dd2c40187d927a7215eea5d37494b92171fe
Author: Ran Tao <[email protected]>
AuthorDate: Tue Oct 13 13:30:40 2026 +0800

    [Bug] Reject partially overlapping sequence-group ordering fields (#10513)
---
 .../merge-engine/partial-update.md                 |  2 ++
 .../compact/PartialUpdateMergeFunction.java        | 14 +++++++++++++
 .../apache/paimon/schema/SchemaValidationTest.java | 24 ++++++++++++++++++++++
 3 files changed, 40 insertions(+)

diff --git a/docs/docs/primary-key-table/merge-engine/partial-update.md 
b/docs/docs/primary-key-table/merge-engine/partial-update.md
index 2299de1c1d..491b85c221 100644
--- a/docs/docs/primary-key-table/merge-engine/partial-update.md
+++ b/docs/docs/primary-key-table/merge-engine/partial-update.md
@@ -73,6 +73,8 @@ independent streams update different columns, give each 
stream its own sequence
 stream's version does not determine whether the other stream's update is 
accepted.
 
 Configure `fields.<ordering-field>.sequence-group` with the columns that the 
version protects.
+Ordering fields cannot be shared by different sequence groups. If multiple 
fields use the same
+ordering tuple, list those protected value fields in one group.
 This example separates profile updates from score updates:
 
 ```sql
diff --git 
a/paimon-core/src/main/java/org/apache/paimon/mergetree/compact/PartialUpdateMergeFunction.java
 
b/paimon-core/src/main/java/org/apache/paimon/mergetree/compact/PartialUpdateMergeFunction.java
index 467524ee11..f40bcde8a3 100644
--- 
a/paimon-core/src/main/java/org/apache/paimon/mergetree/compact/PartialUpdateMergeFunction.java
+++ 
b/paimon-core/src/main/java/org/apache/paimon/mergetree/compact/PartialUpdateMergeFunction.java
@@ -436,6 +436,7 @@ public class PartialUpdateMergeFunction implements 
MergeFunction<KeyValue> {
             List<String> fieldNames = rowType.getFieldNames();
             this.fieldSeqComparators = new HashMap<>();
             Map<String, Integer> sequenceGroupMap = new HashMap<>();
+            Map<String, String> sequenceGroupByOrderingField = new HashMap<>();
             List<String> allSequenceFields = new ArrayList<>();
             List<String> fieldsProtectedBySequenceGroup = new ArrayList<>();
             for (Map.Entry<String, String> entry : options.toMap().entrySet()) 
{
@@ -447,6 +448,19 @@ public class PartialUpdateMergeFunction implements 
MergeFunction<KeyValue> {
                                     .mapToInt(fieldName -> 
requireField(fieldName, fieldNames))
                                     .toArray();
 
+                    for (int field : sequenceFields) {
+                        String fieldName = fieldNames.get(field);
+                        String previousGroup =
+                                
sequenceGroupByOrderingField.putIfAbsent(fieldName, k);
+                        checkArgument(
+                                previousGroup == null || 
previousGroup.equals(k),
+                                "Sequence field '%s' is shared by sequence 
groups '%s' and '%s'. "
+                                        + "Ordering fields must not overlap 
between sequence groups.",
+                                fieldName,
+                                previousGroup,
+                                k);
+                    }
+
                     Supplier<FieldsComparator> userDefinedSeqComparator =
                             () -> UserDefinedSeqComparator.create(rowType, 
sequenceFields, true);
                     sequenceGroupProtectedFields(v).stream()
diff --git 
a/paimon-core/src/test/java/org/apache/paimon/schema/SchemaValidationTest.java 
b/paimon-core/src/test/java/org/apache/paimon/schema/SchemaValidationTest.java
index 681edbf1da..8c4ac570af 100644
--- 
a/paimon-core/src/test/java/org/apache/paimon/schema/SchemaValidationTest.java
+++ 
b/paimon-core/src/test/java/org/apache/paimon/schema/SchemaValidationTest.java
@@ -700,6 +700,30 @@ class SchemaValidationTest {
                 .hasMessageContaining("Invalid sequence-group option: 
fields.ts.xsequence-group");
     }
 
+    @Test
+    public void 
testPartialUpdateRejectsOverlappingSequenceGroupOrderingFields() {
+        List<DataField> fields =
+                Arrays.asList(
+                        new DataField(0, "id", DataTypes.INT()),
+                        new DataField(1, "a", DataTypes.INT()),
+                        new DataField(2, "b", DataTypes.INT()),
+                        new DataField(3, "s", DataTypes.INT()),
+                        new DataField(4, "t", DataTypes.INT()));
+        Map<String, String> options = new HashMap<>();
+        options.put(BUCKET.key(), "1");
+        options.put(CoreOptions.MERGE_ENGINE.key(), "partial-update");
+        options.put("fields.s.sequence-group", "a");
+        options.put("fields.t,s.sequence-group", "b");
+        TableSchema schema =
+                new TableSchema(1, fields, 10, emptyList(), 
singletonList("id"), options, "");
+
+        assertThatThrownBy(() -> validateTableSchema(schema))
+                .isInstanceOf(IllegalArgumentException.class)
+                .hasMessageContaining("Sequence field 's' is shared by 
sequence groups")
+                .hasMessageContaining("fields.s.sequence-group")
+                .hasMessageContaining("fields.t,s.sequence-group");
+    }
+
     @Test
     public void testPrimaryKeyBlobViewCoexistsWithManagedBlob() {
         List<DataField> fields =

Reply via email to