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

terrymanu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 0970dd603d9 Fix H2 index metadata loading (#39833)
0970dd603d9 is described below

commit 0970dd603d978e192c8c46034a22575be3f74fa8
Author: Liang Zhang <[email protected]>
AuthorDate: Sun Sep 13 20:09:10 2026 +0800

    Fix H2 index metadata loading (#39833)
---
 .../h2/metadata/data/loader/H2MetaDataLoader.java  | 23 +++++++++---------
 .../metadata/data/loader/H2MetaDataLoaderTest.java | 28 ++++++++++++++--------
 2 files changed, 30 insertions(+), 21 deletions(-)

diff --git 
a/database/connector/dialect/h2/src/main/java/org/apache/shardingsphere/database/connector/h2/metadata/data/loader/H2MetaDataLoader.java
 
b/database/connector/dialect/h2/src/main/java/org/apache/shardingsphere/database/connector/h2/metadata/data/loader/H2MetaDataLoader.java
index ff04cd11c33..3b1e9217c5f 100644
--- 
a/database/connector/dialect/h2/src/main/java/org/apache/shardingsphere/database/connector/h2/metadata/data/loader/H2MetaDataLoader.java
+++ 
b/database/connector/dialect/h2/src/main/java/org/apache/shardingsphere/database/connector/h2/metadata/data/loader/H2MetaDataLoader.java
@@ -53,8 +53,8 @@ public final class H2MetaDataLoader implements 
DialectMetaDataLoader {
     
     private static final String TABLE_META_DATA_SQL_IN_TABLES = 
TABLE_META_DATA_NO_ORDER + " AND UPPER(TABLE_NAME) IN (%s)" + 
ORDER_BY_ORDINAL_POSITION;
     
-    private static final String INDEX_META_DATA_SQL = "SELECT TABLE_CATALOG, 
TABLE_NAME, INDEX_NAME, INDEX_TYPE_NAME FROM INFORMATION_SCHEMA.INDEXES"
-            + " WHERE TABLE_CATALOG=? AND TABLE_SCHEMA=? AND UPPER(TABLE_NAME) 
IN (%s)";
+    private static final String INDEX_META_DATA_SQL = "SELECT TABLE_NAME, 
INDEX_NAME, COLUMN_NAME, IS_UNIQUE FROM INFORMATION_SCHEMA.INDEX_COLUMNS"
+            + " WHERE TABLE_CATALOG=? AND TABLE_SCHEMA=? AND UPPER(TABLE_NAME) 
IN (%s) ORDER BY TABLE_NAME, INDEX_NAME, ORDINAL_POSITION";
     
     private static final String PRIMARY_KEY_COLUMN_META_DATA_SQL = "SELECT 
KCU.TABLE_NAME, KCU.COLUMN_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC 
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU"
             + " USING (CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME) 
WHERE KCU.TABLE_CATALOG=? AND KCU.TABLE_SCHEMA=? AND 
TC.CONSTRAINT_TYPE='PRIMARY KEY'";
@@ -142,7 +142,7 @@ public final class H2MetaDataLoader implements 
DialectMetaDataLoader {
     }
     
     private Map<String, Collection<IndexMetaData>> loadIndexMetaData(final 
Connection connection, final Collection<String> tableNames) throws SQLException 
{
-        Map<String, Collection<IndexMetaData>> result = new HashMap<>();
+        Map<String, Map<String, IndexMetaData>> tableToIndex = new 
HashMap<>(tableNames.size(), 1F);
         try (PreparedStatement preparedStatement = 
connection.prepareStatement(getIndexMetaDataSQL(tableNames))) {
             preparedStatement.setString(1, connection.getCatalog());
             preparedStatement.setString(2, "PUBLIC");
@@ -150,18 +150,19 @@ public final class H2MetaDataLoader implements 
DialectMetaDataLoader {
                 while (resultSet.next()) {
                     String indexName = resultSet.getString("INDEX_NAME");
                     String tableName = resultSet.getString("TABLE_NAME");
-                    boolean uniqueIndex = "UNIQUE 
INDEX".equals(resultSet.getString("INDEX_TYPE_NAME"));
-                    if (!result.containsKey(tableName)) {
-                        result.put(tableName, new LinkedList<>());
+                    Map<String, IndexMetaData> indexMap = 
tableToIndex.computeIfAbsent(tableName, key -> new HashMap<>());
+                    String columnName = resultSet.getString("COLUMN_NAME");
+                    if (indexMap.containsKey(indexName)) {
+                        indexMap.get(indexName).getColumns().add(columnName);
+                    } else {
+                        IndexMetaData indexMetaData = new 
IndexMetaData(indexName, new LinkedList<>(Collections.singleton(columnName)));
+                        
indexMetaData.setUnique(resultSet.getBoolean("IS_UNIQUE"));
+                        indexMap.put(indexName, indexMetaData);
                     }
-                    IndexMetaData indexMetaData = new IndexMetaData(indexName);
-                    indexMetaData.setUnique(uniqueIndex);
-                    result.get(tableName).add(indexMetaData);
-                    
                 }
             }
         }
-        return result;
+        return 
tableToIndex.entrySet().stream().collect(Collectors.toMap(Entry::getKey, entry 
-> entry.getValue().values()));
     }
     
     private String getIndexMetaDataSQL(final Collection<String> tableNames) {
diff --git 
a/database/connector/dialect/h2/src/test/java/org/apache/shardingsphere/database/connector/h2/metadata/data/loader/H2MetaDataLoaderTest.java
 
b/database/connector/dialect/h2/src/test/java/org/apache/shardingsphere/database/connector/h2/metadata/data/loader/H2MetaDataLoaderTest.java
index fa932b99564..7b062c5f997 100644
--- 
a/database/connector/dialect/h2/src/test/java/org/apache/shardingsphere/database/connector/h2/metadata/data/loader/H2MetaDataLoaderTest.java
+++ 
b/database/connector/dialect/h2/src/test/java/org/apache/shardingsphere/database/connector/h2/metadata/data/loader/H2MetaDataLoaderTest.java
@@ -64,7 +64,8 @@ class H2MetaDataLoaderTest {
                 .executeQuery()).thenReturn(resultSet);
         ResultSet indexResultSet = mockIndexMetaDataResultSet();
         when(dataSource.getConnection().prepareStatement(
-                "SELECT TABLE_CATALOG, TABLE_NAME, INDEX_NAME, INDEX_TYPE_NAME 
FROM INFORMATION_SCHEMA.INDEXES WHERE TABLE_CATALOG=? AND TABLE_SCHEMA=? AND 
UPPER(TABLE_NAME) IN ('TBL')")
+                "SELECT TABLE_NAME, INDEX_NAME, COLUMN_NAME, IS_UNIQUE FROM 
INFORMATION_SCHEMA.INDEX_COLUMNS"
+                        + " WHERE TABLE_CATALOG=? AND TABLE_SCHEMA=? AND 
UPPER(TABLE_NAME) IN ('TBL') ORDER BY TABLE_NAME, INDEX_NAME, ORDINAL_POSITION")
                 .executeQuery()).thenReturn(indexResultSet);
         ResultSet primaryKeys = mockPrimaryKeysMetaDataResultSet();
         when(dataSource.getConnection().prepareStatement(
@@ -91,7 +92,8 @@ class H2MetaDataLoaderTest {
                 .executeQuery()).thenReturn(resultSet);
         ResultSet indexResultSet = mockIndexMetaDataResultSet();
         when(dataSource.getConnection().prepareStatement(
-                "SELECT TABLE_CATALOG, TABLE_NAME, INDEX_NAME, INDEX_TYPE_NAME 
FROM INFORMATION_SCHEMA.INDEXES WHERE TABLE_CATALOG=? AND TABLE_SCHEMA=? AND 
UPPER(TABLE_NAME) IN ('TBL')")
+                "SELECT TABLE_NAME, INDEX_NAME, COLUMN_NAME, IS_UNIQUE FROM 
INFORMATION_SCHEMA.INDEX_COLUMNS"
+                        + " WHERE TABLE_CATALOG=? AND TABLE_SCHEMA=? AND 
UPPER(TABLE_NAME) IN ('TBL') ORDER BY TABLE_NAME, INDEX_NAME, ORDINAL_POSITION")
                 .executeQuery()).thenReturn(indexResultSet);
         ResultSet primaryKeys = mockPrimaryKeysMetaDataResultSet();
         when(dataSource.getConnection().prepareStatement(
@@ -198,10 +200,11 @@ class H2MetaDataLoaderTest {
     
     private ResultSet mockIndexMetaDataResultSet() throws SQLException {
         ResultSet result = mock(ResultSet.class);
-        when(result.next()).thenReturn(true, false);
-        when(result.getString("INDEX_NAME")).thenReturn("id");
+        when(result.next()).thenReturn(true, true, true, false);
+        when(result.getString("INDEX_NAME")).thenReturn("foo_composite_idx", 
"foo_composite_idx", "foo_primary_idx");
         when(result.getString("TABLE_NAME")).thenReturn("tbl");
-        when(result.getString("INDEX_TYPE_NAME")).thenReturn("UNIQUE INDEX");
+        when(result.getString("COLUMN_NAME")).thenReturn("id", "name", "id");
+        when(result.getBoolean("IS_UNIQUE")).thenReturn(false, true);
         return result;
     }
     
@@ -218,11 +221,16 @@ class H2MetaDataLoaderTest {
         Iterator<ColumnMetaData> columnsIterator = 
actualTableMetaData.getColumns().iterator();
         assertColumnMetaData(columnsIterator.next(), new ColumnMetaData("id", 
Types.INTEGER, true, true, false, true, false, false));
         assertColumnMetaData(columnsIterator.next(), new 
ColumnMetaData("name", Types.VARCHAR, false, false, false, false, false, true));
-        assertThat(actualTableMetaData.getIndexes().size(), is(1));
-        Iterator<IndexMetaData> indexesIterator = 
actualTableMetaData.getIndexes().iterator();
-        IndexMetaData indexMetaData = new IndexMetaData("id");
-        indexMetaData.setUnique(true);
-        assertIndexMetaData(indexesIterator.next(), indexMetaData);
+        Map<String, IndexMetaData> actualIndexes = new 
HashMap<>(actualTableMetaData.getIndexes().size(), 1F);
+        for (IndexMetaData each : actualTableMetaData.getIndexes()) {
+            actualIndexes.put(each.getName(), each);
+        }
+        assertThat(actualIndexes.size(), is(2));
+        IndexMetaData expectedCompositeIndex = new 
IndexMetaData("foo_composite_idx", Arrays.asList("id", "name"));
+        
assertIndexMetaData(actualIndexes.get(expectedCompositeIndex.getName()), 
expectedCompositeIndex);
+        IndexMetaData expectedPrimaryIndex = new 
IndexMetaData("foo_primary_idx", Collections.singletonList("id"));
+        expectedPrimaryIndex.setUnique(true);
+        assertIndexMetaData(actualIndexes.get(expectedPrimaryIndex.getName()), 
expectedPrimaryIndex);
     }
     
     private void assertColumnMetaData(final ColumnMetaData actual, final 
ColumnMetaData expected) {

Reply via email to