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

github-merge-queue[bot] pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/seatunnel.git


The following commit(s) were added to refs/heads/dev by this push:
     new cec3276740 [Fix][Connector-V2][Jdbc] Handle empty sink primary keys 
(#11893)
cec3276740 is described below

commit cec3276740d989c8cb67c7b8c37e0a817e728059
Author: JacobZheng0927 <[email protected]>
AuthorDate: Wed Oct 28 05:39:36 2026 +0000

    [Fix][Connector-V2][Jdbc] Handle empty sink primary keys (#11893)
    
    Co-authored-by: zhiweiniu <[email protected]>
---
 .../connectors/seatunnel/jdbc/sink/JdbcSink.java   | 21 +++---
 .../seatunnel/jdbc/sink/JdbcSinkTest.java          | 81 ++++++++++++++++++++++
 2 files changed, 94 insertions(+), 8 deletions(-)

diff --git 
a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/sink/JdbcSink.java
 
b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/sink/JdbcSink.java
index f44509bd6f..3eb0d1471d 100644
--- 
a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/sink/JdbcSink.java
+++ 
b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/sink/JdbcSink.java
@@ -34,6 +34,7 @@ import org.apache.seatunnel.api.sink.SupportSaveMode;
 import org.apache.seatunnel.api.sink.SupportSchemaEvolutionSink;
 import org.apache.seatunnel.api.table.catalog.Catalog;
 import org.apache.seatunnel.api.table.catalog.CatalogTable;
+import org.apache.seatunnel.api.table.catalog.PrimaryKey;
 import org.apache.seatunnel.api.table.catalog.TablePath;
 import org.apache.seatunnel.api.table.catalog.TableSchema;
 import org.apache.seatunnel.api.table.catalog.exception.TableNotExistException;
@@ -141,14 +142,7 @@ public class JdbcSink
                             new ArrayList<>());
 
         } else {
-            Integer primaryKeyIndex = null;
-            if (catalogTable.getTableSchema().getPrimaryKey() != null) {
-                String keyName = 
tableSchema.getPrimaryKey().getColumnNames().get(0);
-                int index = 
tableSchema.toPhysicalRowDataType().indexOf(keyName);
-                if (index > -1) {
-                    primaryKeyIndex = index;
-                }
-            }
+            Integer primaryKeyIndex = 
getPrimaryKeyIndex(tableSchema).orElse(null);
             sinkWriter =
                     new JdbcSinkWriter(
                             sinkTablePath,
@@ -163,6 +157,17 @@ public class JdbcSink
         return sinkWriter;
     }
 
+    static Optional<Integer> getPrimaryKeyIndex(TableSchema tableSchema) {
+        PrimaryKey primaryKey = tableSchema.getPrimaryKey();
+        if (primaryKey == null
+                || primaryKey.getColumnNames() == null
+                || primaryKey.getColumnNames().isEmpty()) {
+            return Optional.empty();
+        }
+        int index = 
tableSchema.toPhysicalRowDataType().indexOf(primaryKey.getColumnNames().get(0));
+        return index > -1 ? Optional.of(index) : Optional.empty();
+    }
+
     @Override
     public SinkWriter<SeaTunnelRow, XidInfo, JdbcSinkState> restoreWriter(
             SinkWriter.Context context, List<JdbcSinkState> states) throws 
IOException {
diff --git 
a/seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/sink/JdbcSinkTest.java
 
b/seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/sink/JdbcSinkTest.java
new file mode 100644
index 0000000000..f715ea0a1d
--- /dev/null
+++ 
b/seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/sink/JdbcSinkTest.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.connectors.seatunnel.jdbc.sink;
+
+import org.apache.seatunnel.api.table.catalog.PhysicalColumn;
+import org.apache.seatunnel.api.table.catalog.PrimaryKey;
+import org.apache.seatunnel.api.table.catalog.TableSchema;
+import org.apache.seatunnel.api.table.type.BasicType;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+
+class JdbcSinkTest {
+
+    @Test
+    void getPrimaryKeyIndexReturnsEmptyForPrimaryKeyWithoutColumns() {
+        TableSchema tableSchema =
+                TableSchema.builder()
+                        .column(
+                                PhysicalColumn.builder()
+                                        .name("id")
+                                        .dataType(BasicType.INT_TYPE)
+                                        .build())
+                        .primaryKey(PrimaryKey.of("empty_pk", 
Collections.emptyList()))
+                        .build();
+
+        
Assertions.assertFalse(JdbcSink.getPrimaryKeyIndex(tableSchema).isPresent());
+    }
+
+    @Test
+    void getPrimaryKeyIndexReturnsEmptyForPrimaryKeyWithNullColumns() {
+        TableSchema tableSchema =
+                TableSchema.builder()
+                        .column(
+                                PhysicalColumn.builder()
+                                        .name("id")
+                                        .dataType(BasicType.INT_TYPE)
+                                        .build())
+                        .primaryKey(PrimaryKey.of("null_pk", null))
+                        .build();
+
+        
Assertions.assertFalse(JdbcSink.getPrimaryKeyIndex(tableSchema).isPresent());
+    }
+
+    @Test
+    void getPrimaryKeyIndexReturnsFirstPrimaryKeyColumnIndex() {
+        TableSchema tableSchema =
+                TableSchema.builder()
+                        .column(
+                                PhysicalColumn.builder()
+                                        .name("name")
+                                        .dataType(BasicType.STRING_TYPE)
+                                        .build())
+                        .column(
+                                PhysicalColumn.builder()
+                                        .name("id")
+                                        .dataType(BasicType.INT_TYPE)
+                                        .build())
+                        .primaryKey(PrimaryKey.of("id_pk", 
Collections.singletonList("id")))
+                        .build();
+
+        Assertions.assertEquals(1, 
JdbcSink.getPrimaryKeyIndex(tableSchema).get());
+    }
+}

Reply via email to