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 e546528c951 Fix openGauss official case-insensitive collation metadata 
(#39224)
e546528c951 is described below

commit e546528c951473bdf1274224fbd0a2e33ac4d983
Author: Liang Zhang <[email protected]>
AuthorDate: Thu Jul 23 21:14:15 2026 +0800

    Fix openGauss official case-insensitive collation metadata (#39224)
---
 .../data/loader/OpenGaussMetaDataLoader.java       | 13 ++++---
 .../data/loader/OpenGaussMetaDataLoaderTest.java   | 42 +++++++++++++++-------
 2 files changed, 38 insertions(+), 17 deletions(-)

diff --git 
a/database/connector/dialect/opengauss/src/main/java/org/apache/shardingsphere/database/connector/opengauss/metadata/data/loader/OpenGaussMetaDataLoader.java
 
b/database/connector/dialect/opengauss/src/main/java/org/apache/shardingsphere/database/connector/opengauss/metadata/data/loader/OpenGaussMetaDataLoader.java
index d14984e31b4..09b11d03a08 100644
--- 
a/database/connector/dialect/opengauss/src/main/java/org/apache/shardingsphere/database/connector/opengauss/metadata/data/loader/OpenGaussMetaDataLoader.java
+++ 
b/database/connector/dialect/opengauss/src/main/java/org/apache/shardingsphere/database/connector/opengauss/metadata/data/loader/OpenGaussMetaDataLoader.java
@@ -33,6 +33,7 @@ import java.sql.PreparedStatement;
 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.HashSet;
@@ -47,8 +48,12 @@ import java.util.stream.Collectors;
  */
 public final class OpenGaussMetaDataLoader implements DialectMetaDataLoader {
     
-    private static final String BASIC_TABLE_META_DATA_SQL = "SELECT 
table_name, column_name, ordinal_position, data_type, udt_name, column_default, 
table_schema, is_nullable"
-            + " FROM information_schema.columns WHERE table_schema IN (%s)";
+    private static final Collection<String> 
OFFICIAL_CASE_INSENSITIVE_COLLATIONS = Arrays.asList(
+            "utf8mb4_general_ci", "utf8mb4_unicode_ci", "utf8_general_ci", 
"utf8_unicode_ci", "gbk_chinese_ci", "gb18030_chinese_ci");
+    
+    private static final String BASIC_TABLE_META_DATA_SQL =
+            "SELECT table_name, column_name, ordinal_position, data_type, 
udt_name, column_default, table_schema, is_nullable, collation_schema, 
collation_name"
+                    + " FROM information_schema.columns WHERE table_schema IN 
(%s)";
     
     private static final String TABLE_META_DATA_SQL_WITHOUT_TABLES = 
BASIC_TABLE_META_DATA_SQL + " ORDER BY ordinal_position";
     
@@ -175,8 +180,8 @@ public final class OpenGaussMetaDataLoader implements 
DialectMetaDataLoader {
         boolean isPrimaryKey = primaryKeys.contains(schemaName + "," + 
tableName + "," + columnName);
         String columnDefault = resultSet.getString("column_default");
         boolean generated = null != columnDefault && 
columnDefault.startsWith("nextval(");
-        // TODO user defined collation which deterministic is false
-        boolean caseSensitive = true;
+        boolean caseSensitive = 
!"pg_catalog".equals(resultSet.getString("collation_schema"))
+                || 
!OFFICIAL_CASE_INSENSITIVE_COLLATIONS.contains(resultSet.getString("collation_name"));
         boolean isNullable = "YES".equals(resultSet.getString("is_nullable"));
         return new ColumnMetaData(columnName, 
DataTypeRegistry.getDataType(getDatabaseType(), dataType).orElse(Types.OTHER), 
isPrimaryKey, generated, caseSensitive, true, false, isNullable);
     }
diff --git 
a/database/connector/dialect/opengauss/src/test/java/org/apache/shardingsphere/database/connector/opengauss/metadata/data/loader/OpenGaussMetaDataLoaderTest.java
 
b/database/connector/dialect/opengauss/src/test/java/org/apache/shardingsphere/database/connector/opengauss/metadata/data/loader/OpenGaussMetaDataLoaderTest.java
index 7c56633a69f..3720be10d9b 100644
--- 
a/database/connector/dialect/opengauss/src/test/java/org/apache/shardingsphere/database/connector/opengauss/metadata/data/loader/OpenGaussMetaDataLoaderTest.java
+++ 
b/database/connector/dialect/opengauss/src/test/java/org/apache/shardingsphere/database/connector/opengauss/metadata/data/loader/OpenGaussMetaDataLoaderTest.java
@@ -49,8 +49,9 @@ import static org.mockito.Mockito.when;
 
 class OpenGaussMetaDataLoaderTest {
     
-    private static final String BASIC_TABLE_META_DATA_SQL = "SELECT 
table_name, column_name, ordinal_position, data_type, udt_name, column_default, 
table_schema, is_nullable"
-            + " FROM information_schema.columns WHERE table_schema IN 
('public')";
+    private static final String BASIC_TABLE_META_DATA_SQL =
+            "SELECT table_name, column_name, ordinal_position, data_type, 
udt_name, column_default, table_schema, is_nullable, collation_schema, 
collation_name"
+                    + " FROM information_schema.columns WHERE table_schema IN 
('public')";
     
     private static final String TABLE_META_DATA_SQL_WITHOUT_TABLES = 
BASIC_TABLE_META_DATA_SQL + " ORDER BY ordinal_position";
     
@@ -75,7 +76,8 @@ class OpenGaussMetaDataLoaderTest {
     @ParameterizedTest(name = "{0}")
     @MethodSource("loadArguments")
     void assertLoad(final String name, final Collection<String> 
actualTableNames, final String tableMetaDataSQL,
-                    final Callable<ResultSet> tableMetaDataResultSetFactory, 
final Callable<ResultSet> advanceIndexMetaDataResultSetFactory) throws 
Exception {
+                    final Callable<ResultSet> tableMetaDataResultSetFactory, 
final Callable<ResultSet> advanceIndexMetaDataResultSetFactory,
+                    final boolean expectedNameColumnCaseSensitive) throws 
Exception {
         DataSource dataSource = mockDataSource();
         ResultSet schemaResultSet = mockSchemaMetaDataResultSet();
         
when(dataSource.getConnection().getMetaData().getSchemas()).thenReturn(schemaResultSet);
@@ -88,7 +90,8 @@ class OpenGaussMetaDataLoaderTest {
         ResultSet advanceIndexResultSet = 
advanceIndexMetaDataResultSetFactory.call();
         
when(dataSource.getConnection().prepareStatement(ADVANCE_INDEX_META_DATA_SQL).executeQuery()).thenReturn(advanceIndexResultSet);
         DataTypeRegistry.load(dataSource, "openGauss");
-        assertTableMetaDataMap(dialectMetaDataLoader.load(new 
MetaDataLoaderMaterial(actualTableNames, "foo_ds", dataSource, databaseType, 
"sharding_db")));
+        assertTableMetaDataMap(dialectMetaDataLoader.load(new 
MetaDataLoaderMaterial(actualTableNames, "foo_ds", dataSource, databaseType, 
"sharding_db")),
+                expectedNameColumnCaseSensitive);
     }
     
     private ResultSet mockSchemaMetaDataResultSet() throws SQLException {
@@ -154,13 +157,13 @@ class OpenGaussMetaDataLoaderTest {
         return result;
     }
     
-    private void assertTableMetaDataMap(final Collection<SchemaMetaData> 
schemaMetaDataList) {
+    private void assertTableMetaDataMap(final Collection<SchemaMetaData> 
schemaMetaDataList, final boolean expectedNameColumnCaseSensitive) {
         assertThat(schemaMetaDataList.size(), is(1));
         TableMetaData actualTableMetaData = 
schemaMetaDataList.iterator().next().getTables().iterator().next();
         assertThat(actualTableMetaData.getColumns().size(), is(2));
         Iterator<ColumnMetaData> columnsIterator = 
actualTableMetaData.getColumns().iterator();
         assertColumnMetaData(columnsIterator.next(), new ColumnMetaData("id", 
Types.INTEGER, true, true, true, true, false, false));
-        assertColumnMetaData(columnsIterator.next(), new 
ColumnMetaData("name", Types.VARCHAR, false, false, true, true, false, true));
+        assertColumnMetaData(columnsIterator.next(), new 
ColumnMetaData("name", Types.VARCHAR, false, false, 
expectedNameColumnCaseSensitive, true, false, true));
         assertThat(actualTableMetaData.getIndexes().size(), is(1));
         Iterator<IndexMetaData> indexesIterator = 
actualTableMetaData.getIndexes().iterator();
         IndexMetaData indexMetaData = new IndexMetaData("id", 
Collections.singletonList("id"));
@@ -186,16 +189,27 @@ class OpenGaussMetaDataLoaderTest {
     }
     
     private static Stream<Arguments> loadArguments() {
-        return Stream.of(
-                Arguments.of("without tables", Collections.emptyList(), 
TABLE_META_DATA_SQL_WITHOUT_TABLES,
-                        (Callable<ResultSet>) () -> 
mockTableMetaDataResultSet(""), (Callable<ResultSet>) 
OpenGaussMetaDataLoaderTest::mockAdvanceIndexMetaDataResultSet),
-                Arguments.of("with tables", Collections.singletonList("tbl"), 
TABLE_META_DATA_SQL_WITH_TABLES,
-                        (Callable<ResultSet>) () -> 
mockTableMetaDataResultSet(""), (Callable<ResultSet>) 
OpenGaussMetaDataLoaderTest::mockAdvanceIndexMetaDataResultSet),
+        Stream<Arguments> officialCaseInsensitiveCollationArguments = 
Stream.of(
+                "utf8mb4_general_ci", "utf8mb4_unicode_ci", "utf8_general_ci", 
"utf8_unicode_ci", "gbk_chinese_ci", "gb18030_chinese_ci")
+                .map(each -> Arguments.of("with official case-insensitive 
collation " + each, Collections.singletonList("tbl"), 
TABLE_META_DATA_SQL_WITH_TABLES,
+                        (Callable<ResultSet>) () -> 
mockTableMetaDataResultSet("", "pg_catalog", each),
+                        (Callable<ResultSet>) 
OpenGaussMetaDataLoaderTest::mockAdvanceIndexMetaDataResultSet, false));
+        return Stream.concat(officialCaseInsensitiveCollationArguments, 
Stream.of(
+                Arguments.of("without tables and binary collation", 
Collections.emptyList(), TABLE_META_DATA_SQL_WITHOUT_TABLES,
+                        (Callable<ResultSet>) () -> 
mockTableMetaDataResultSet("", "pg_catalog", "utf8mb4_bin"),
+                        (Callable<ResultSet>) 
OpenGaussMetaDataLoaderTest::mockAdvanceIndexMetaDataResultSet, true),
+                Arguments.of("with unknown case-insensitive collation", 
Collections.singletonList("tbl"), TABLE_META_DATA_SQL_WITH_TABLES,
+                        (Callable<ResultSet>) () -> 
mockTableMetaDataResultSet("", "pg_catalog", "custom_ci"),
+                        (Callable<ResultSet>) 
OpenGaussMetaDataLoaderTest::mockAdvanceIndexMetaDataResultSet, true),
+                Arguments.of("with user-defined collation", 
Collections.singletonList("tbl"), TABLE_META_DATA_SQL_WITH_TABLES,
+                        (Callable<ResultSet>) () -> 
mockTableMetaDataResultSet("", "foo_schema", "utf8mb4_general_ci"),
+                        (Callable<ResultSet>) 
OpenGaussMetaDataLoaderTest::mockAdvanceIndexMetaDataResultSet, true),
                 Arguments.of("with unmatched advance index rows and null 
default", Collections.singletonList("tbl"), TABLE_META_DATA_SQL_WITH_TABLES,
-                        (Callable<ResultSet>) () -> 
mockTableMetaDataResultSet(null), (Callable<ResultSet>) 
OpenGaussMetaDataLoaderTest::mockAdvanceIndexMetaDataResultSetWithUnmatchedRows));
+                        (Callable<ResultSet>) () -> 
mockTableMetaDataResultSet(null, null, null),
+                        (Callable<ResultSet>) 
OpenGaussMetaDataLoaderTest::mockAdvanceIndexMetaDataResultSetWithUnmatchedRows,
 true)));
     }
     
-    private static ResultSet mockTableMetaDataResultSet(final String 
nameColumnDefault) throws SQLException {
+    private static ResultSet mockTableMetaDataResultSet(final String 
nameColumnDefault, final String nameColumnCollationSchema, final String 
nameColumnCollationName) throws SQLException {
         ResultSet result = mock(ResultSet.class);
         when(result.next()).thenReturn(true, true, false);
         when(result.getString("table_name")).thenReturn("tbl");
@@ -206,6 +220,8 @@ class OpenGaussMetaDataLoaderTest {
         
when(result.getString("column_default")).thenReturn("nextval('id_seq'::regclass)",
 nameColumnDefault);
         when(result.getString("table_schema")).thenReturn("public", "public");
         when(result.getString("is_nullable")).thenReturn("NO", "YES");
+        when(result.getString("collation_schema")).thenReturn(null, 
nameColumnCollationSchema);
+        
when(result.getString("collation_name")).thenReturn(nameColumnCollationName);
         return result;
     }
 }

Reply via email to