This is an automated email from the ASF dual-hosted git repository.
JNSimba pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 87d6090a758 [fix](jdbc) order composite primary key columns by KEY_SEQ
(#64740)
87d6090a758 is described below
commit 87d6090a7584088440ed82f4bd2849ad10fb1e66
Author: wudi <[email protected]>
AuthorDate: Thu Jun 25 15:49:43 2026 +0800
[fix](jdbc) order composite primary key columns by KEY_SEQ (#64740)
## Proposed changes
`JdbcClient` / `JdbcMySQLClient.getPrimaryKeys` returned primary-key
columns in whatever order the JDBC driver yielded them.
`DatabaseMetaData.getPrimaryKeys` orders its rows by `COLUMN_NAME`, not
`KEY_SEQ`, so for a composite primary key whose definition order differs
from alphabetical order (e.g. `PRIMARY KEY (tenant_id, order_id)`), the
columns came back reordered. This affected the resulting Doris key
columns and the bucket hash distribution.
This reorders the columns by their 1-based `KEY_SEQ`. Single-column keys
are unaffected; PostgreSQL is unaffected (its driver already returns
KEY_SEQ order); only MySQL (whose driver sorts by column name) is
corrected.
---
.../apache/doris/datasource/jdbc/client/JdbcMySQLClient.java | 10 ++++++----
.../cdc/test_streaming_mysql_job_composite_pk.out | 2 +-
.../cdc/test_streaming_mysql_job_composite_pk.groovy | 4 ++--
3 files changed, 9 insertions(+), 7 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClient.java
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClient.java
index aa85fd23f80..bcdc9ccc03b 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClient.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClient.java
@@ -40,6 +40,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import java.util.TreeMap;
import java.util.function.Consumer;
public class JdbcMySQLClient extends JdbcClient {
@@ -202,13 +203,14 @@ public class JdbcMySQLClient extends JdbcClient {
public List<String> getPrimaryKeys(String remoteDbName, String
remoteTableName) {
Connection conn = getConnection();
ResultSet rs = null;
- List<String> primaryKeys = Lists.newArrayList();
+ // getPrimaryKeys orders rows by COLUMN_NAME, not KEY_SEQ; reorder by
the 1-based KEY_SEQ
+ // to keep the real composite-PK column order.
+ TreeMap<Short, String> primaryKeys = new TreeMap<>();
try {
DatabaseMetaData databaseMetaData = conn.getMetaData();
rs = databaseMetaData.getPrimaryKeys(remoteDbName, null,
remoteTableName);
while (rs.next()) {
- String fieldName = rs.getString("COLUMN_NAME");
- primaryKeys.add(fieldName);
+ primaryKeys.put(rs.getShort("KEY_SEQ"),
rs.getString("COLUMN_NAME"));
}
} catch (SQLException e) {
throw new JdbcClientException("failed to get jdbc primary key info
for remote table `%s.%s`: %s",
@@ -216,7 +218,7 @@ public class JdbcMySQLClient extends JdbcClient {
} finally {
close(rs, conn);
}
- return primaryKeys;
+ return Lists.newArrayList(primaryKeys.values());
}
protected String getCatalogName(Connection conn) throws SQLException {
diff --git
a/regression-test/data/job_p0/streaming_job/cdc/test_streaming_mysql_job_composite_pk.out
b/regression-test/data/job_p0/streaming_job/cdc/test_streaming_mysql_job_composite_pk.out
index 5558c43e9ea..27c1b7a6357 100644
---
a/regression-test/data/job_p0/streaming_job/cdc/test_streaming_mysql_job_composite_pk.out
+++
b/regression-test/data/job_p0/streaming_job/cdc/test_streaming_mysql_job_composite_pk.out
@@ -1,7 +1,7 @@
-- This file is automatically generated. You should know what you did if you
want to edit this
-- !desc_composite_pk --
-order_id bigint No true \N
tenant_id int No true \N
+order_id bigint No true \N
order_no varchar(192) Yes false \N NONE
amount decimal(10,2) Yes false \N NONE
diff --git
a/regression-test/suites/job_p0/streaming_job/cdc/test_streaming_mysql_job_composite_pk.groovy
b/regression-test/suites/job_p0/streaming_job/cdc/test_streaming_mysql_job_composite_pk.groovy
index 188d459be5f..9cdd43adfa2 100644
---
a/regression-test/suites/job_p0/streaming_job/cdc/test_streaming_mysql_job_composite_pk.groovy
+++
b/regression-test/suites/job_p0/streaming_job/cdc/test_streaming_mysql_job_composite_pk.groovy
@@ -121,12 +121,12 @@ suite("test_streaming_mysql_job_composite_pk",
"p0,external,mysql,external_docke
def showTbl = sql """show create table ${currentDb}.${table1}"""
def createInfo = showTbl[0][1]
log.info("create table: " + createInfo)
- assert createInfo.contains("UNIQUE KEY(`order_id`, `tenant_id`)")
+ assert createInfo.contains("UNIQUE KEY(`tenant_id`, `order_id`)")
def showTbl2 = sql """show create table ${currentDb}.${table2}"""
def createInfo2 = showTbl2[0][1]
log.info("create table2: " + createInfo2)
- assert createInfo2.contains("UNIQUE KEY(`role_id`, `user_id`)")
+ assert createInfo2.contains("UNIQUE KEY(`user_id`, `role_id`)")
qt_desc_composite_pk """desc ${currentDb}.${table1};"""
qt_select_snapshot """select tenant_id, order_id, order_no, amount
from ${currentDb}.${table1} order by tenant_id, order_id;"""
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]