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

zhangliang 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 2078bb41399 Add more test cases on MySQLMetaDataLoaderTest (#38127)
2078bb41399 is described below

commit 2078bb413993ab9951472dab72f35a2093ffd393
Author: Liang Zhang <[email protected]>
AuthorDate: Sun Feb 22 00:04:27 2026 +0800

    Add more test cases on MySQLMetaDataLoaderTest (#38127)
---
 .../data/loader/MySQLMetaDataLoaderTest.java       | 158 ++++++++++++++++-----
 1 file changed, 121 insertions(+), 37 deletions(-)

diff --git 
a/database/connector/dialect/mysql/src/test/java/org/apache/shardingsphere/database/connector/mysql/metadata/data/loader/MySQLMetaDataLoaderTest.java
 
b/database/connector/dialect/mysql/src/test/java/org/apache/shardingsphere/database/connector/mysql/metadata/data/loader/MySQLMetaDataLoaderTest.java
index b9ea8080e9c..f31f74dbe60 100644
--- 
a/database/connector/dialect/mysql/src/test/java/org/apache/shardingsphere/database/connector/mysql/metadata/data/loader/MySQLMetaDataLoaderTest.java
+++ 
b/database/connector/dialect/mysql/src/test/java/org/apache/shardingsphere/database/connector/mysql/metadata/data/loader/MySQLMetaDataLoaderTest.java
@@ -17,9 +17,11 @@
 
 package 
org.apache.shardingsphere.database.connector.mysql.metadata.data.loader;
 
+import 
org.apache.shardingsphere.database.connector.core.GlobalDataSourceRegistry;
 import 
org.apache.shardingsphere.database.connector.core.metadata.data.loader.DialectMetaDataLoader;
 import 
org.apache.shardingsphere.database.connector.core.metadata.data.loader.MetaDataLoaderMaterial;
 import 
org.apache.shardingsphere.database.connector.core.metadata.data.model.ColumnMetaData;
+import 
org.apache.shardingsphere.database.connector.core.metadata.data.model.ConstraintMetaData;
 import 
org.apache.shardingsphere.database.connector.core.metadata.data.model.IndexMetaData;
 import 
org.apache.shardingsphere.database.connector.core.metadata.data.model.SchemaMetaData;
 import 
org.apache.shardingsphere.database.connector.core.metadata.data.model.TableMetaData;
@@ -28,56 +30,92 @@ import 
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoa
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 import javax.sql.DataSource;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Types;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.Map;
+import java.util.stream.Stream;
 
-import static org.hamcrest.Matchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 class MySQLMetaDataLoaderTest {
     
+    private static final String TABLE_METADATA_SQL = "SELECT TABLE_NAME, 
COLUMN_NAME, DATA_TYPE, COLUMN_KEY, EXTRA, COLLATION_NAME, ORDINAL_POSITION, 
COLUMN_TYPE, "
+            + "IS_NULLABLE FROM information_schema.columns WHERE 
TABLE_SCHEMA=? ORDER BY ORDINAL_POSITION";
+    
+    private static final String TABLE_METADATA_SQL_WITH_TABLE = "SELECT 
TABLE_NAME, COLUMN_NAME, DATA_TYPE, COLUMN_KEY, EXTRA, COLLATION_NAME, 
ORDINAL_POSITION, "
+            + "COLUMN_TYPE, IS_NULLABLE FROM information_schema.columns WHERE 
TABLE_SCHEMA=? AND TABLE_NAME IN ('tbl') ORDER BY ORDINAL_POSITION";
+    
+    private static final String INDEX_METADATA_SQL = "SELECT TABLE_NAME, 
INDEX_NAME, NON_UNIQUE, COLUMN_NAME FROM information_schema.statistics "
+            + "WHERE TABLE_SCHEMA=? and TABLE_NAME IN ('tbl') ORDER BY 
NON_UNIQUE, INDEX_NAME, SEQ_IN_INDEX";
+    
+    private static final String CONSTRAINT_METADATA_SQL = "SELECT 
CONSTRAINT_NAME, TABLE_NAME, REFERENCED_TABLE_NAME FROM 
information_schema.KEY_COLUMN_USAGE "
+            + "WHERE TABLE_NAME IN ('tbl') AND REFERENCED_TABLE_SCHEMA IS NOT 
NULL";
+    
+    private static final String VIEW_METADATA_SQL = "SELECT TABLE_NAME FROM 
information_schema.VIEWS WHERE TABLE_SCHEMA=? AND TABLE_NAME IN ('tbl')";
+    
     private final DatabaseType databaseType = 
TypedSPILoader.getService(DatabaseType.class, "MySQL");
     
     private final DialectMetaDataLoader dialectMetaDataLoader = 
DatabaseTypedSPILoader.getService(DialectMetaDataLoader.class, databaseType);
     
     @SuppressWarnings("JDBCResourceOpenedButNotSafelyClosed")
     @Test
-    void assertLoadWithoutTables() throws SQLException {
+    void assertLoadWithEmptyColumnMetaData() throws SQLException {
         DataSource dataSource = mockDataSource();
-        ResultSet resultSet = mockTableMetaDataResultSet();
-        when(dataSource.getConnection().prepareStatement("SELECT TABLE_NAME, 
COLUMN_NAME, DATA_TYPE, COLUMN_KEY, EXTRA, COLLATION_NAME, ORDINAL_POSITION, 
COLUMN_TYPE, IS_NULLABLE "
-                + "FROM information_schema.columns WHERE TABLE_SCHEMA=? ORDER 
BY ORDINAL_POSITION")
-                .executeQuery()).thenReturn(resultSet);
-        ResultSet indexResultSet = mockIndexMetaDataResultSet();
-        when(dataSource.getConnection().prepareStatement("SELECT TABLE_NAME, 
INDEX_NAME, NON_UNIQUE, COLUMN_NAME FROM information_schema.statistics "
-                + "WHERE TABLE_SCHEMA=? and TABLE_NAME IN ('tbl') ORDER BY 
NON_UNIQUE, INDEX_NAME, 
SEQ_IN_INDEX").executeQuery()).thenReturn(indexResultSet);
+        
when(dataSource.getConnection().getCatalog()).thenReturn("sharding_db");
         DataTypeRegistry.load(dataSource, "MySQL");
-        assertTableMetaDataMap(dialectMetaDataLoader.load(new 
MetaDataLoaderMaterial(Collections.emptyList(), "foo_ds", dataSource, 
databaseType, "sharding_db")));
+        Collection<SchemaMetaData> actual = dialectMetaDataLoader.load(new 
MetaDataLoaderMaterial(Collections.singletonList("tbl"), "foo_ds", dataSource, 
databaseType, "sharding_db"));
+        assertThat(actual.size(), is(1));
+        assertTrue(actual.iterator().next().getTables().isEmpty());
     }
     
-    @SuppressWarnings("JDBCResourceOpenedButNotSafelyClosed")
-    @Test
-    void assertLoadWithTables() throws SQLException {
+    @SuppressWarnings({"JDBCResourceOpenedButNotSafelyClosed", "resource"})
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("loadArguments")
+    void assertLoad(final String name, final Collection<String> 
actualTableNames, final String tableMetaDataSQL,
+                    final boolean emptyCatalog, final boolean includeView, 
final boolean includeConstraints, final boolean includeCompositeIndex) throws 
SQLException {
         DataSource dataSource = mockDataSource();
-        ResultSet resultSet = mockTableMetaDataResultSet();
-        when(dataSource.getConnection().prepareStatement("SELECT TABLE_NAME, 
COLUMN_NAME, DATA_TYPE, COLUMN_KEY, EXTRA, COLLATION_NAME, ORDINAL_POSITION, 
COLUMN_TYPE, IS_NULLABLE "
-                + "FROM information_schema.columns WHERE TABLE_SCHEMA=? AND 
TABLE_NAME IN ('tbl') ORDER BY ORDINAL_POSITION")
-                .executeQuery()).thenReturn(resultSet);
-        ResultSet indexResultSet = mockIndexMetaDataResultSet();
-        when(dataSource.getConnection().prepareStatement("SELECT TABLE_NAME, 
INDEX_NAME, NON_UNIQUE, COLUMN_NAME FROM information_schema.statistics WHERE 
TABLE_SCHEMA=? and TABLE_NAME IN ('tbl') "
-                + "ORDER BY NON_UNIQUE, INDEX_NAME, SEQ_IN_INDEX")
-                .executeQuery()).thenReturn(indexResultSet);
-        DataTypeRegistry.load(dataSource, "MySQL");
-        assertTableMetaDataMap(dialectMetaDataLoader.load(new 
MetaDataLoaderMaterial(Collections.singletonList("tbl"), "foo_ds", dataSource, 
databaseType, "sharding_db")));
+        ResultSet tableMetaDataResultSet = mockTableMetaDataResultSet();
+        
when(dataSource.getConnection().prepareStatement(tableMetaDataSQL).executeQuery()).thenReturn(tableMetaDataResultSet);
+        if (includeCompositeIndex) {
+            ResultSet compositeIndexMetaDataResultSet = 
mockCompositeIndexMetaDataResultSet();
+            
when(dataSource.getConnection().prepareStatement(INDEX_METADATA_SQL).executeQuery()).thenReturn(compositeIndexMetaDataResultSet);
+        } else {
+            ResultSet simpleIndexMetaDataResultSet = 
mockSimpleIndexMetaDataResultSet();
+            
when(dataSource.getConnection().prepareStatement(INDEX_METADATA_SQL).executeQuery()).thenReturn(simpleIndexMetaDataResultSet);
+        }
+        ResultSet viewResultSet = includeView ? mockSingleViewResultSet() : 
mock(ResultSet.class);
+        
when(dataSource.getConnection().prepareStatement(VIEW_METADATA_SQL).executeQuery()).thenReturn(viewResultSet);
+        ResultSet constraintMetaDataResultSet = includeConstraints ? 
mockConstraintMetaDataResultSet() : mock(ResultSet.class);
+        
when(dataSource.getConnection().prepareStatement(CONSTRAINT_METADATA_SQL).executeQuery()).thenReturn(constraintMetaDataResultSet);
+        Map<String, String> cachedDatabaseTables = 
GlobalDataSourceRegistry.getInstance().getCachedDatabaseTables();
+        String previous = cachedDatabaseTables.put("tbl", "fallback_db");
+        try {
+            
when(dataSource.getConnection().getCatalog()).thenReturn(emptyCatalog ? "" : 
"sharding_db");
+            DataTypeRegistry.load(dataSource, "MySQL");
+            Collection<SchemaMetaData> actual = dialectMetaDataLoader.load(new 
MetaDataLoaderMaterial(actualTableNames, "foo_ds", dataSource, databaseType, 
"sharding_db"));
+            assertTableMetaData(actual, includeConstraints, 
includeCompositeIndex);
+        } finally {
+            if (null == previous) {
+                cachedDatabaseTables.remove("tbl");
+            } else {
+                cachedDatabaseTables.put("tbl", previous);
+            }
+        }
     }
     
     @SuppressWarnings("JDBCResourceOpenedButNotSafelyClosed")
@@ -104,13 +142,13 @@ class MySQLMetaDataLoaderTest {
         when(result.getString("DATA_TYPE")).thenReturn("int", "varchar", 
"json", "geometry", "year", "polygon", "multipolygon", "point", "multipoint");
         when(result.getString("COLUMN_KEY")).thenReturn("PRI", "", "", "", "", 
"", "", "", "");
         when(result.getString("EXTRA")).thenReturn("auto_increment", 
"INVISIBLE", "", "", "", "", "", "", "");
-        when(result.getString("COLLATION_NAME")).thenReturn("utf8", 
"utf8_general_ci");
-        when(result.getString("COLUMN_TYPE")).thenReturn("int", "varchar");
+        when(result.getString("COLLATION_NAME")).thenReturn("utf8", 
"utf8_general_ci", null, null, null, null, null, null, null);
+        when(result.getString("COLUMN_TYPE")).thenReturn("int", "varchar", 
"json", "geometry", "year", "polygon", "multipolygon", "point", "multipoint");
         when(result.getString("IS_NULLABLE")).thenReturn("NO", "YES", "YES", 
"YES", "YES", "YES", "YES", "YES", "YES");
         return result;
     }
     
-    private ResultSet mockIndexMetaDataResultSet() throws SQLException {
+    private ResultSet mockSimpleIndexMetaDataResultSet() throws SQLException {
         ResultSet result = mock(ResultSet.class);
         when(result.next()).thenReturn(true, false);
         when(result.getString("INDEX_NAME")).thenReturn("id");
@@ -120,9 +158,38 @@ class MySQLMetaDataLoaderTest {
         return result;
     }
     
-    private void assertTableMetaDataMap(final Collection<SchemaMetaData> 
schemaMetaDataList) {
+    private ResultSet mockCompositeIndexMetaDataResultSet() throws 
SQLException {
+        ResultSet result = mock(ResultSet.class);
+        when(result.next()).thenReturn(true, true, true, false);
+        when(result.getString("INDEX_NAME")).thenReturn("idx_composite", 
"idx_composite", "idx_ignored");
+        when(result.getString("TABLE_NAME")).thenReturn("tbl", "tbl", "tbl");
+        when(result.getString("COLUMN_NAME")).thenReturn("id", "name", "");
+        when(result.getString("NON_UNIQUE")).thenReturn("0", "0", "1");
+        return result;
+    }
+    
+    private ResultSet mockConstraintMetaDataResultSet() throws SQLException {
+        ResultSet result = mock(ResultSet.class);
+        when(result.next()).thenReturn(true, true, false);
+        when(result.getString("CONSTRAINT_NAME")).thenReturn("fk_order", 
"fk_item");
+        when(result.getString("TABLE_NAME")).thenReturn("tbl", "tbl");
+        when(result.getString("REFERENCED_TABLE_NAME")).thenReturn("t_order", 
"t_item");
+        return result;
+    }
+    
+    private ResultSet mockSingleViewResultSet() throws SQLException {
+        ResultSet result = mock(ResultSet.class);
+        when(result.next()).thenReturn(true, false);
+        when(result.getString(1)).thenReturn("tbl");
+        return result;
+    }
+    
+    private void assertTableMetaData(final Collection<SchemaMetaData> 
schemaMetaDataList, final boolean expectedConstraintExists, final boolean 
expectedCompositeIndexExists) {
         assertThat(schemaMetaDataList.size(), is(1));
-        TableMetaData actualTableMetaData = 
schemaMetaDataList.iterator().next().getTables().iterator().next();
+        Collection<TableMetaData> tables = 
schemaMetaDataList.iterator().next().getTables();
+        assertThat(tables.size(), is(1));
+        TableMetaData actualTableMetaData = tables.iterator().next();
+        assertThat(actualTableMetaData.getName(), is("tbl"));
         assertThat(actualTableMetaData.getColumns().size(), is(9));
         Iterator<ColumnMetaData> columnsIterator = 
actualTableMetaData.getColumns().iterator();
         assertColumnMetaData(columnsIterator.next(), new ColumnMetaData("id", 
Types.INTEGER, true, true, true, true, false, false));
@@ -134,11 +201,8 @@ class MySQLMetaDataLoaderTest {
         assertColumnMetaData(columnsIterator.next(), new ColumnMetaData("mpg", 
Types.BINARY, false, false, false, true, false, true));
         assertColumnMetaData(columnsIterator.next(), new ColumnMetaData("pt", 
Types.BINARY, false, false, false, true, false, true));
         assertColumnMetaData(columnsIterator.next(), new ColumnMetaData("mpt", 
Types.BINARY, false, false, false, true, false, true));
-        assertThat(actualTableMetaData.getIndexes().size(), is(1));
-        Iterator<IndexMetaData> indexesIterator = 
actualTableMetaData.getIndexes().iterator();
-        IndexMetaData expected = new IndexMetaData("id", 
Collections.singletonList("id"));
-        expected.setUnique(true);
-        assertIndexMetaData(indexesIterator.next(), expected);
+        assertIndexMetaData(actualTableMetaData.getIndexes(), 
expectedCompositeIndexExists);
+        assertConstraintMetaData(actualTableMetaData.getConstraints(), 
expectedConstraintExists);
     }
     
     private void assertColumnMetaData(final ColumnMetaData actual, final 
ColumnMetaData expected) {
@@ -152,9 +216,29 @@ class MySQLMetaDataLoaderTest {
         assertThat(actual.isNullable(), is(expected.isNullable()));
     }
     
-    private void assertIndexMetaData(final IndexMetaData actual, final 
IndexMetaData expected) {
-        assertThat(actual.getName(), is(expected.getName()));
-        assertThat(actual.getColumns(), is(expected.getColumns()));
-        assertThat(actual.isUnique(), is(expected.isUnique()));
+    private void assertIndexMetaData(final Collection<IndexMetaData> 
actualIndexMetaData, final boolean expectedCompositeIndexExists) {
+        assertThat(actualIndexMetaData.size(), is(1));
+        IndexMetaData actualIndexMetaDataItem = 
actualIndexMetaData.iterator().next();
+        assertThat(actualIndexMetaDataItem.getName(), 
is(expectedCompositeIndexExists ? "idx_composite" : "id"));
+        assertThat(actualIndexMetaDataItem.getColumns(), 
is(expectedCompositeIndexExists ? Arrays.asList("id", "name") : 
Collections.singletonList("id")));
+        assertTrue(actualIndexMetaDataItem.isUnique());
+    }
+    
+    private void assertConstraintMetaData(final Collection<ConstraintMetaData> 
actualConstraintMetaData, final boolean expectedConstraintExists) {
+        if (expectedConstraintExists) {
+            assertThat(actualConstraintMetaData.size(), is(2));
+            Iterator<ConstraintMetaData> constraints = 
actualConstraintMetaData.iterator();
+            assertThat(constraints.next().getName(), is("fk_order"));
+            assertThat(constraints.next().getName(), is("fk_item"));
+        } else {
+            assertTrue(actualConstraintMetaData.isEmpty());
+        }
+    }
+    
+    private static Stream<Arguments> loadArguments() {
+        return Stream.of(
+                Arguments.of("load without requested table names", 
Collections.emptyList(), TABLE_METADATA_SQL, false, false, false, false),
+                Arguments.of("load with requested table names", 
Collections.singletonList("tbl"), TABLE_METADATA_SQL_WITH_TABLE, false, false, 
false, false),
+                Arguments.of("load with empty catalog fallback and view 
constraints", Collections.singletonList("tbl"), TABLE_METADATA_SQL_WITH_TABLE, 
true, true, true, true));
     }
 }

Reply via email to