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

jianbin pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/incubator-seata.git


The following commit(s) were added to refs/heads/2.x by this push:
     new 7daf5b0c9e bugfix: different element order in two lists causes failure 
to set the index as primary key index (#7965)
7daf5b0c9e is described below

commit 7daf5b0c9e3b81550e3c1481364fbb2321baabe5
Author: funkye <[email protected]>
AuthorDate: Tue Jan 27 21:52:31 2026 +0800

    bugfix: different element order in two lists causes failure to set the 
index as primary key index (#7965)
---
 changes/en-us/2.6.0.md                             |  1 +
 changes/en-us/2.x.md                               |  1 +
 changes/zh-cn/2.6.0.md                             |  1 +
 changes/zh-cn/2.x.md                               |  2 +
 .../seata/namingserver/config/WebConfig.java       |  2 +-
 .../namingserver/contants/NamingConstant.java      |  2 +-
 .../sql/struct/cache/DmTableMetaCache.java         | 70 ++++++++++++----
 .../sql/struct/cache/KingbaseTableMetaCache.java   | 61 ++++++++++----
 .../sql/struct/cache/DmTableMetaCacheTest.java     | 98 ++++++++++++++++++++++
 .../struct/cache/KingbaseTableMetaCacheTest.java   | 98 ++++++++++++++++++++++
 10 files changed, 300 insertions(+), 36 deletions(-)

diff --git a/changes/en-us/2.6.0.md b/changes/en-us/2.6.0.md
index 4a919af909..c0e4aa0c75 100644
--- a/changes/en-us/2.6.0.md
+++ b/changes/en-us/2.6.0.md
@@ -75,6 +75,7 @@ Add changes here for all PR submitted to the 2.x branch.
 - [[#7908](https://github.com/apache/incubator-seata/pull/7908)] handle 
timestamp with time zone in postgresql primary key
 - [[#7938](https://github.com/apache/incubator-seata/pull/7938)] ensure the 
Jakarta-related package paths are correct.
 - [[#7959](https://github.com/apache/incubator-seata/pull/7959)] fix 
consoleApiService bean that could not be found
+- [[#7966](https://github.com/apache/incubator-seata/pull/7966)] Fix the issue 
where different element orders in two lists cause failure to set the index as 
the primary key
 
 
 ### optimize:
diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md
index 80d8165e99..29af662ab9 100644
--- a/changes/en-us/2.x.md
+++ b/changes/en-us/2.x.md
@@ -30,6 +30,7 @@ Add changes here for all PR submitted to the 2.x branch.
 - [[#7940](https://github.com/apache/incubator-seata/pull/7940)] ensure the 
Jakarta-related package paths are correct
 - [[#7960](https://github.com/apache/incubator-seata/pull/7960)] fix 
consoleApiService bean that could not be found
 - [[#7956](https://github.com/apache/incubator-seata/pull/7956)] fix empty 
jacoco report on local when jdk above 17
+- [[#7965](https://github.com/apache/incubator-seata/pull/7965)] fix the issue 
where different element order in two lists causes failure to set the index as 
the primary key
 
 
 ### optimize:
diff --git a/changes/zh-cn/2.6.0.md b/changes/zh-cn/2.6.0.md
index 1935426983..90503ce7d2 100644
--- a/changes/zh-cn/2.6.0.md
+++ b/changes/zh-cn/2.6.0.md
@@ -75,6 +75,7 @@
 - [[#7908](https://github.com/apache/incubator-seata/pull/7908)] 在 PostgreSQL 
主键中处理带时区的时间戳
 - [[#7938](https://github.com/apache/incubator-seata/pull/7938)] 
保证Jakarta相关包路径正确
 - [[#7959](https://github.com/apache/incubator-seata/pull/7959)] 
修复consoleApiService bean未加载的问题
+- [[#7966](https://github.com/apache/incubator-seata/pull/7966)] 修复在 dm 和 
kingbase 中当没有将索引设置为主键索引的问题
 
 
 ### optimize:
diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md
index 90da8bc393..1855319521 100644
--- a/changes/zh-cn/2.x.md
+++ b/changes/zh-cn/2.x.md
@@ -30,6 +30,8 @@
 - [[#7940](https://github.com/apache/incubator-seata/pull/7940)] 
保证Jakarta相关包路径正确
 - [[#7960](https://github.com/apache/incubator-seata/pull/7960)] 
修复consoleApiService bean未加载的问题
 - [[#7956](https://github.com/apache/incubator-seata/pull/7956)] 
修复本地JDK17以上jacoco报告为空的问题
+- [[#7965](https://github.com/apache/incubator-seata/pull/7965)] 修复在 dm 和 
kingbase 中当没有将索引设置为主键索引时出现的问题
+
 
 ### optimize:
 
diff --git 
a/namingserver/src/main/java/org/apache/seata/namingserver/config/WebConfig.java
 
b/namingserver/src/main/java/org/apache/seata/namingserver/config/WebConfig.java
index 563a9b7c21..f7d0a79f08 100644
--- 
a/namingserver/src/main/java/org/apache/seata/namingserver/config/WebConfig.java
+++ 
b/namingserver/src/main/java/org/apache/seata/namingserver/config/WebConfig.java
@@ -50,7 +50,7 @@ public class WebConfig {
                 .readTimeout(DEFAULT_REQUEST_TIMEOUT, TimeUnit.MILLISECONDS)
                 .writeTimeout(DEFAULT_WRITE_TIMEOUT, TimeUnit.MILLISECONDS)
                 .build();
-        
+
         // Create and return a RestTemplate with the custom request factory
         return new RestTemplate(new OkHttp3ClientHttpRequestFactory(client));
     }
diff --git 
a/namingserver/src/main/java/org/apache/seata/namingserver/contants/NamingConstant.java
 
b/namingserver/src/main/java/org/apache/seata/namingserver/contants/NamingConstant.java
index 6d0852a7df..c679b37200 100644
--- 
a/namingserver/src/main/java/org/apache/seata/namingserver/contants/NamingConstant.java
+++ 
b/namingserver/src/main/java/org/apache/seata/namingserver/contants/NamingConstant.java
@@ -21,7 +21,7 @@ public interface NamingConstant {
     String CONSOLE_PATTERN = "^/api/.*/console/.*";
 
     int DEFAULT_REQUEST_TIMEOUT = 5000;
-    
+
     int DEFAULT_WRITE_TIMEOUT = 5000;
 
     int DEFAULT_CONNECTION_MAX_TOTAL = 100;
diff --git 
a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/sql/struct/cache/DmTableMetaCache.java
 
b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/sql/struct/cache/DmTableMetaCache.java
index a9728e0b0f..4b99b558d9 100644
--- 
a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/sql/struct/cache/DmTableMetaCache.java
+++ 
b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/sql/struct/cache/DmTableMetaCache.java
@@ -28,8 +28,8 @@ import org.apache.seata.sqlparser.util.JdbcConstants;
 import java.sql.DatabaseMetaData;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.LinkedHashSet;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
@@ -124,25 +124,53 @@ public class DmTableMetaCache extends 
OracleTableMetaCache {
     }
 
     protected void processPrimaries(TableMeta tableMeta, ResultSet rs) throws 
SQLException {
-        List<String> primaryKeyColumns = new ArrayList<>();
+        // Collect primary key column names that couldn't be matched directly 
by PK_NAME
+        // In Oracle/DM: when primary key constraint name differs from unique 
index name,
+        // we need to match by column names instead
+        Set<String> unmatchedPkColumns = new LinkedHashSet<>();
+
+        // Iterate through each row of getPrimaryKeys() result set
+        // For composite primary key, there will be multiple rows with same 
PK_NAME
         while (rs.next()) {
-            String pkColName;
-            try {
-                pkColName = rs.getString("COLUMN_NAME");
-            } catch (Exception e) {
-                pkColName = rs.getString("PK_NAME");
+            String pkConstraintName = getStringSafely(rs, "PK_NAME");
+            String pkColName = getStringSafely(rs, "COLUMN_NAME");
+            if (StringUtils.isBlank(pkColName)) {
+                pkColName = pkConstraintName;
             }
-            primaryKeyColumns.add(pkColName);
-        }
-
-        for (IndexMeta index : tableMeta.getAllIndexes().values()) {
-            List<String> indexColumns = index.getValues().stream()
-                    .filter(col -> col != null && 
StringUtils.isNotBlank(col.getColumnName()))
-                    .map(ColumnMeta::getColumnName)
-                    .collect(Collectors.toList());
 
-            if (indexColumns.equals(primaryKeyColumns)) {
+            // Strategy 1: Try direct match by PK constraint name
+            // If the index name matches the primary key constraint name, mark 
it as PRIMARY
+            if (StringUtils.isNotBlank(pkConstraintName)
+                    && 
tableMeta.getAllIndexes().containsKey(pkConstraintName)) {
+                IndexMeta index = 
tableMeta.getAllIndexes().get(pkConstraintName);
                 index.setIndextype(IndexType.PRIMARY);
+            } else {
+                // Save columns for Strategy 2: fallback column-based matching
+                if (StringUtils.isNotBlank(pkColName)) {
+                    unmatchedPkColumns.add(pkColName.toUpperCase());
+                }
+            }
+        }
+
+        // Strategy 2: Fallback - find index whose columns match the primary 
key columns
+        // This handles the case where PK constraint name differs from unique 
index name
+        if (!unmatchedPkColumns.isEmpty()) {
+            for (IndexMeta index : tableMeta.getAllIndexes().values()) {
+                // Only check UNIQUE indexes as candidates (primary key is 
always unique)
+                if (index.getIndextype().value() == IndexType.UNIQUE.value()) {
+                    // Build index column set, normalized to uppercase and 
deduplicated
+                    Set<String> indexColsSet = index.getValues().stream()
+                            .filter(col -> col != null && 
StringUtils.isNotBlank(col.getColumnName()))
+                            .map(col -> col.getColumnName().toUpperCase())
+                            .collect(Collectors.toSet());
+
+                    // If sets are equal, this index exactly matches primary 
key columns
+                    if (indexColsSet.equals(unmatchedPkColumns)) {
+                        index.setIndextype(IndexType.PRIMARY);
+                        // Each table has only one primary key
+                        break;
+                    }
+                }
             }
         }
     }
@@ -186,4 +214,12 @@ public class DmTableMetaCache extends OracleTableMetaCache 
{
         }
         return result;
     }
+
+    private static String getStringSafely(ResultSet rs, String columnLabel) {
+        try {
+            return rs.getString(columnLabel);
+        } catch (Exception e) {
+            return null;
+        }
+    }
 }
diff --git 
a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/sql/struct/cache/KingbaseTableMetaCache.java
 
b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/sql/struct/cache/KingbaseTableMetaCache.java
index 31a41743d6..64b513462b 100644
--- 
a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/sql/struct/cache/KingbaseTableMetaCache.java
+++ 
b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/sql/struct/cache/KingbaseTableMetaCache.java
@@ -28,8 +28,8 @@ import org.apache.seata.sqlparser.util.JdbcConstants;
 import java.sql.DatabaseMetaData;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.LinkedHashSet;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
@@ -123,25 +123,44 @@ public class KingbaseTableMetaCache extends 
OracleTableMetaCache {
     }
 
     protected void processPrimaries(TableMeta tableMeta, ResultSet rs) throws 
SQLException {
-        List<String> primaryKeyColumns = new ArrayList<>();
+        // Collect primary key column names that couldn't be matched directly 
by PK_NAME
+        Set<String> unmatchedPkColumns = new LinkedHashSet<>();
+
+        // Iterate through each row of getPrimaryKeys() result set
         while (rs.next()) {
-            String pkColName;
-            try {
-                pkColName = rs.getString("COLUMN_NAME");
-            } catch (Exception e) {
-                pkColName = rs.getString("PK_NAME");
+            String pkConstraintName = getStringSafely(rs, "PK_NAME");
+            String pkColName = getStringSafely(rs, "COLUMN_NAME");
+            if (StringUtils.isBlank(pkColName)) {
+                pkColName = pkConstraintName;
             }
-            primaryKeyColumns.add(pkColName);
-        }
-
-        for (IndexMeta index : tableMeta.getAllIndexes().values()) {
-            List<String> indexColumns = index.getValues().stream()
-                    .filter(col -> col != null && 
StringUtils.isNotBlank(col.getColumnName()))
-                    .map(ColumnMeta::getColumnName)
-                    .collect(Collectors.toList());
 
-            if (indexColumns.equals(primaryKeyColumns)) {
+            // Strategy 1: Try direct match by PK constraint name
+            if (StringUtils.isNotBlank(pkConstraintName)
+                    && 
tableMeta.getAllIndexes().containsKey(pkConstraintName)) {
+                IndexMeta index = 
tableMeta.getAllIndexes().get(pkConstraintName);
                 index.setIndextype(IndexType.PRIMARY);
+            } else {
+                // Save columns for fallback column-based matching
+                if (StringUtils.isNotBlank(pkColName)) {
+                    unmatchedPkColumns.add(pkColName.toUpperCase());
+                }
+            }
+        }
+
+        // Strategy 2: fallback - match by column set equality 
(order-insensitive, deduped)
+        if (!unmatchedPkColumns.isEmpty()) {
+            for (IndexMeta index : tableMeta.getAllIndexes().values()) {
+                if (index.getIndextype().value() == IndexType.UNIQUE.value()) {
+                    Set<String> indexColsSet = index.getValues().stream()
+                            .filter(col -> col != null && 
StringUtils.isNotBlank(col.getColumnName()))
+                            .map(col -> col.getColumnName().toUpperCase())
+                            .collect(Collectors.toSet());
+
+                    if (indexColsSet.equals(unmatchedPkColumns)) {
+                        index.setIndextype(IndexType.PRIMARY);
+                        break;
+                    }
+                }
             }
         }
     }
@@ -185,4 +204,12 @@ public class KingbaseTableMetaCache extends 
OracleTableMetaCache {
         }
         return result;
     }
+
+    private static String getStringSafely(ResultSet rs, String columnLabel) {
+        try {
+            return rs.getString(columnLabel);
+        } catch (Exception e) {
+            return null;
+        }
+    }
 }
diff --git 
a/rm-datasource/src/test/java/org/apache/seata/rm/datasource/sql/struct/cache/DmTableMetaCacheTest.java
 
b/rm-datasource/src/test/java/org/apache/seata/rm/datasource/sql/struct/cache/DmTableMetaCacheTest.java
index 70d4987c64..04f7bc14e8 100644
--- 
a/rm-datasource/src/test/java/org/apache/seata/rm/datasource/sql/struct/cache/DmTableMetaCacheTest.java
+++ 
b/rm-datasource/src/test/java/org/apache/seata/rm/datasource/sql/struct/cache/DmTableMetaCacheTest.java
@@ -332,4 +332,102 @@ public class DmTableMetaCacheTest {
         Assertions.assertNotNull(tableMeta);
         Assertions.assertEquals(originalName, 
tableMeta.getOriginalTableName());
     }
+
+    @Test
+    public void testCompositeIndexWithDifferentColumnOrder() throws 
SQLException {
+        // Regression test for a bug fix: different column order caused 
List.equals to fail, which could lead to
+        // failing to recognize a primary key index.
+        // Scenario: composite primary key (ID, USER_ID) while a unique index 
lists the same columns in reverse order
+        // (USER_ID, ID).
+        // Before the fix: List.equals returned FALSE because of the different 
order, causing the primary key index to
+        // be unrecognized.
+        // After the fix: using Set.equals should return TRUE and correctly 
identify the index as PRIMARY.
+
+        Object[][] compositeIndexDiffOrder = new Object[][] {
+            new Object[] {"idx_id_userid", "id", false, "", 3, 1, "A", 34}, // 
column order 1
+            new Object[] {"idx_id_userid", "user_id", false, "", 3, 2, "A", 
34} // column order 2
+        };
+        Object[][] compositePKMetas = new Object[][] {
+            new Object[] {"id"}, // PK column order 1
+            new Object[] {"user_id"} // PK column order 2
+        };
+        Object[][] compositeColumnMetas = new Object[][] {
+            new Object[] {"", "", "dt2", "id", Types.INTEGER, "INTEGER", 64, 
0, 10, 1, "", "", 0, 0, 64, 1, "NO", "YES"
+            },
+            new Object[] {
+                "", "", "dt2", "user_id", Types.INTEGER, "INTEGER", 64, 0, 10, 
0, "", "", 0, 0, 64, 2, "YES", "NO"
+            }
+        };
+        Object[][] compositeTableMetas = new Object[][] {new Object[] {"", 
"t", "dt2"}};
+
+        MockDriver mockDriver =
+                new MockDriver(compositeColumnMetas, compositeIndexDiffOrder, 
compositePKMetas, compositeTableMetas);
+        DruidDataSource dataSource = new DruidDataSource();
+        dataSource.setUrl("jdbc:mock:dm");
+        dataSource.setDriver(mockDriver);
+
+        DataSourceProxy proxy = 
DataSourceProxyTest.getDataSourceProxy(dataSource);
+        TableMetaCache tableMetaCache = 
TableMetaCacheFactory.getTableMetaCache(JdbcConstants.DM);
+
+        TableMeta tableMeta = 
tableMetaCache.getTableMeta(proxy.getPlainConnection(), "t.dt2", 
proxy.getResourceId());
+
+        Assertions.assertNotNull(tableMeta);
+        IndexMeta compositeIndex = 
tableMeta.getAllIndexes().get("idx_id_userid");
+        Assertions.assertNotNull(compositeIndex);
+        // Key assertion: should be recognized as PRIMARY (after the fix), not 
mistakenly treated as UNIQUE
+        Assertions.assertEquals(
+                IndexType.PRIMARY,
+                compositeIndex.getIndextype(),
+                "Composite index with different column order should be 
recognized as PRIMARY");
+    }
+
+    @Test
+    public void testCompositeIndexWithExtraColumnsNotMarkedAsPrimary() throws 
SQLException {
+        // Regression test for a bug fix: a composite unique index that 
contains primary key columns plus extra columns
+        // should NOT be marked as PRIMARY.
+        // Scenario: primary key (ID), unique index (ID, NAME) — unique index 
contains PK column but has extra NAME.
+        // Before the fix: Oracle implementation matched by count (matchCols 
== pkcol.size()) and could misidentify
+        // PRIMARY.
+        // After the fix: using Set equality ({ID, NAME} != {ID}) prevents the 
index from being marked as PRIMARY
+
+        Object[][] mixedIndexMetas = new Object[][] {
+            new Object[] {"idx_id", "id", false, "", 3, 1, "A", 34},
+            new Object[] {"uk_id_name", "id", false, "", 3, 1, "A", 34}, // 
unique index contains the primary key column
+            new Object[] {"uk_id_name", "name1", false, "", 3, 2, "A", 34} // 
but it also has extra columns
+        };
+
+        // Use a dedicated table name to avoid cache hits from earlier tests
+        Object[][] extraColumnMetas = new Object[][] {
+            new Object[] {"", "", "dt3", "id", Types.INTEGER, "INTEGER", 64, 
0, 10, 1, "", "", 0, 0, 64, 1, "NO", "YES"
+            },
+            new Object[] {
+                "", "", "dt3", "name1", Types.VARCHAR, "VARCHAR", 64, 0, 10, 
0, "", "", 0, 0, 64, 2, "YES", "NO"
+            }
+        };
+        Object[][] extraPkMetas = new Object[][] {new Object[] {"id"}};
+        Object[][] extraTableMetas = new Object[][] {new Object[] {"", "t", 
"dt3"}};
+
+        MockDriver mockDriver = new MockDriver(extraColumnMetas, 
mixedIndexMetas, extraPkMetas, extraTableMetas);
+        DruidDataSource dataSource = new DruidDataSource();
+        dataSource.setUrl("jdbc:mock:dm");
+        dataSource.setDriver(mockDriver);
+
+        DataSourceProxy proxy = 
DataSourceProxyTest.getDataSourceProxy(dataSource);
+        TableMetaCache tableMetaCache = 
TableMetaCacheFactory.getTableMetaCache(JdbcConstants.DM);
+
+        TableMeta tableMeta = 
tableMetaCache.getTableMeta(proxy.getPlainConnection(), "t.dt3", 
proxy.getResourceId());
+
+        Assertions.assertNotNull(tableMeta);
+        IndexMeta pkIndex = tableMeta.getAllIndexes().get("idx_id");
+        Assertions.assertNotNull(pkIndex);
+        Assertions.assertEquals(IndexType.PRIMARY, pkIndex.getIndextype(), 
"Single column PK index should be PRIMARY");
+
+        IndexMeta mixedIndex = tableMeta.getAllIndexes().get("uk_id_name");
+        Assertions.assertNotNull(mixedIndex);
+        // Key assertion: should remain UNIQUE (should not be misidentified as 
PRIMARY)
+        Assertions.assertEquals(
+                IndexType.UNIQUE,
+                mixedIndex.getIndextype(),
+                "Composite index with extra columns should NOT be marked as 
PRIMARY");
+    }
 }
diff --git 
a/rm-datasource/src/test/java/org/apache/seata/rm/datasource/sql/struct/cache/KingbaseTableMetaCacheTest.java
 
b/rm-datasource/src/test/java/org/apache/seata/rm/datasource/sql/struct/cache/KingbaseTableMetaCacheTest.java
index 98850cd961..f3b4cee0cb 100644
--- 
a/rm-datasource/src/test/java/org/apache/seata/rm/datasource/sql/struct/cache/KingbaseTableMetaCacheTest.java
+++ 
b/rm-datasource/src/test/java/org/apache/seata/rm/datasource/sql/struct/cache/KingbaseTableMetaCacheTest.java
@@ -332,4 +332,102 @@ public class KingbaseTableMetaCacheTest {
         Assertions.assertNotNull(tableMeta);
         Assertions.assertEquals(originalName, 
tableMeta.getOriginalTableName());
     }
+
+    @Test
+    public void testCompositeIndexWithDifferentColumnOrder() throws 
SQLException {
+        // Regression test for a bug fix: different column order caused 
List.equals to fail, which could lead to
+        // failing to recognize a primary key index.
+        // Scenario: composite primary key (ID, USER_ID) while a unique index 
lists the same columns in reverse order
+        // (USER_ID, ID).
+        // Before the fix: List.equals returned FALSE because of the different 
order, causing the primary key index to
+        // be unrecognized.
+        // After the fix: using Set.equals should return TRUE and correctly 
identify the index as PRIMARY.
+
+        Object[][] compositeIndexDiffOrder = new Object[][] {
+            new Object[] {"idx_id_userid", "id", false, "", 3, 1, "A", 34}, // 
column order 1
+            new Object[] {"idx_id_userid", "user_id", false, "", 3, 2, "A", 
34} // column order 2
+        };
+        Object[][] compositePKMetas = new Object[][] {
+            new Object[] {"id"}, // PK column order 1
+            new Object[] {"user_id"} // PK column order 2
+        };
+        Object[][] compositeColumnMetas = new Object[][] {
+            new Object[] {"", "", "kt2", "id", Types.INTEGER, "INTEGER", 64, 
0, 10, 1, "", "", 0, 0, 64, 1, "NO", "YES"
+            },
+            new Object[] {
+                "", "", "kt2", "user_id", Types.INTEGER, "INTEGER", 64, 0, 10, 
0, "", "", 0, 0, 64, 2, "YES", "NO"
+            }
+        };
+        Object[][] compositeTableMetas = new Object[][] {new Object[] {"", 
"kb", "kt2"}};
+
+        MockDriver mockDriver =
+                new MockDriver(compositeColumnMetas, compositeIndexDiffOrder, 
compositePKMetas, compositeTableMetas);
+        DruidDataSource dataSource = new DruidDataSource();
+        dataSource.setUrl("jdbc:mock:kingbase");
+        dataSource.setDriver(mockDriver);
+
+        DataSourceProxy proxy = 
DataSourceProxyTest.getDataSourceProxy(dataSource);
+        TableMetaCache tableMetaCache = 
TableMetaCacheFactory.getTableMetaCache(JdbcConstants.KINGBASE);
+
+        TableMeta tableMeta = 
tableMetaCache.getTableMeta(proxy.getPlainConnection(), "kb.kt2", 
proxy.getResourceId());
+
+        Assertions.assertNotNull(tableMeta);
+        IndexMeta compositeIndex = 
tableMeta.getAllIndexes().get("idx_id_userid");
+        Assertions.assertNotNull(compositeIndex);
+        // Key assertion: should be recognized as PRIMARY (after the fix), not 
mistakenly treated as UNIQUE
+        Assertions.assertEquals(
+                IndexType.PRIMARY,
+                compositeIndex.getIndextype(),
+                "Composite index with different column order should be 
recognized as PRIMARY");
+    }
+
+    @Test
+    public void testCompositeIndexWithExtraColumnsNotMarkedAsPrimary() throws 
SQLException {
+        // Regression test for a bug fix: a composite unique index that 
contains primary key columns plus extra columns
+        // should NOT be marked as PRIMARY.
+        // Scenario: primary key (ID), unique index (ID, NAME) — unique index 
contains PK column but has extra NAME.
+        // Before the fix: previous implementation matched by count (matchCols 
== pkcol.size()) and could misidentify
+        // PRIMARY.
+        // After the fix: match by Set equality ({ID, NAME} != {ID}) so it 
won't be marked as PRIMARY
+
+        Object[][] mixedIndexMetas = new Object[][] {
+            new Object[] {"idx_id", "id", false, "", 3, 1, "A", 34},
+            new Object[] {"uk_id_name", "id", false, "", 3, 1, "A", 34}, // 
unique index contains the primary key column
+            new Object[] {"uk_id_name", "name1", false, "", 3, 2, "A", 34} // 
but it also has extra columns
+        };
+
+        // Use a dedicated table name to avoid cache hits from earlier tests
+        Object[][] extraColumnMetas = new Object[][] {
+            new Object[] {"", "", "kt3", "id", Types.INTEGER, "INTEGER", 64, 
0, 10, 1, "", "", 0, 0, 64, 1, "NO", "YES"
+            },
+            new Object[] {
+                "", "", "kt3", "name1", Types.VARCHAR, "VARCHAR", 64, 0, 10, 
0, "", "", 0, 0, 64, 2, "YES", "NO"
+            }
+        };
+        Object[][] extraPkMetas = new Object[][] {new Object[] {"id"}};
+        Object[][] extraTableMetas = new Object[][] {new Object[] {"", "kb", 
"kt3"}};
+
+        MockDriver mockDriver = new MockDriver(extraColumnMetas, 
mixedIndexMetas, extraPkMetas, extraTableMetas);
+        DruidDataSource dataSource = new DruidDataSource();
+        dataSource.setUrl("jdbc:mock:kingbase");
+        dataSource.setDriver(mockDriver);
+
+        DataSourceProxy proxy = 
DataSourceProxyTest.getDataSourceProxy(dataSource);
+        TableMetaCache tableMetaCache = 
TableMetaCacheFactory.getTableMetaCache(JdbcConstants.KINGBASE);
+
+        TableMeta tableMeta = 
tableMetaCache.getTableMeta(proxy.getPlainConnection(), "kb.kt3", 
proxy.getResourceId());
+
+        Assertions.assertNotNull(tableMeta);
+        IndexMeta pkIndex = tableMeta.getAllIndexes().get("idx_id");
+        Assertions.assertNotNull(pkIndex);
+        Assertions.assertEquals(IndexType.PRIMARY, pkIndex.getIndextype(), 
"Single column PK index should be PRIMARY");
+
+        IndexMeta mixedIndex = tableMeta.getAllIndexes().get("uk_id_name");
+        Assertions.assertNotNull(mixedIndex);
+        // Key assertion: should remain UNIQUE (should not be misidentified as 
PRIMARY)
+        Assertions.assertEquals(
+                IndexType.UNIQUE,
+                mixedIndex.getIndextype(),
+                "Composite index with extra columns should NOT be marked as 
PRIMARY");
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to