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;
}
}