This is an automated email from the ASF dual-hosted git repository.
menghaoranss 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 9cc2031c19f Use insensitive rule for COLUMN INDEX and CONSTRAINT
(#38840)
9cc2031c19f is described below
commit 9cc2031c19f1a795f23e8cd8679ff59ec35c2770
Author: Haoran Meng <[email protected]>
AuthorDate: Thu Jun 11 09:47:44 2026 +0800
Use insensitive rule for COLUMN INDEX and CONSTRAINT (#38840)
---
.../identifier/IdentifierCaseRuleSets.java | 11 +++++-
.../identifier/IdentifierCaseRuleSetsTest.java | 8 +++++
.../DatabaseIdentifierContextFactory.java | 9 +++++
.../ShardingSphereDatabaseIdentifierTest.java | 2 +-
.../DatabaseIdentifierContextFactoryTest.java | 42 ++++++++++++++++++----
5 files changed, 64 insertions(+), 8 deletions(-)
diff --git
a/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierCaseRuleSets.java
b/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierCaseRuleSets.java
index 9e7444ab005..ab52a8d1739 100644
---
a/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierCaseRuleSets.java
+++
b/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierCaseRuleSets.java
@@ -66,13 +66,22 @@ public final class IdentifierCaseRuleSets {
return new IdentifierCaseRuleSet(new
StandardIdentifierCaseRule(LookupMode.EXACT, LookupMode.NORMALIZED,
IdentifierCaseRuleSets::toLowerCase, each -> true));
}
+ /**
+ * Create quoted and unquoted case-insensitive rule set.
+ *
+ * @return quoted and unquoted case-insensitive rule set
+ */
+ public static IdentifierCaseRuleSet newQuotedInsensitiveRuleSet() {
+ return new IdentifierCaseRuleSet(new
StandardIdentifierCaseRule(LookupMode.NORMALIZED, LookupMode.NORMALIZED,
IdentifierCaseRuleSets::toLowerCase, each -> true));
+ }
+
/**
* Create MySQL case-insensitive rule set.
*
* @return MySQL case-insensitive rule set
*/
public static IdentifierCaseRuleSet newMySQLInsensitiveRuleSet() {
- return new IdentifierCaseRuleSet(new
StandardIdentifierCaseRule(LookupMode.NORMALIZED, LookupMode.NORMALIZED,
IdentifierCaseRuleSets::toLowerCase, each -> true));
+ return newQuotedInsensitiveRuleSet();
}
/**
diff --git
a/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierCaseRuleSetsTest.java
b/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierCaseRuleSetsTest.java
index dd576b6ae9c..30bc490fa8d 100644
---
a/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierCaseRuleSetsTest.java
+++
b/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierCaseRuleSetsTest.java
@@ -62,6 +62,14 @@ class IdentifierCaseRuleSetsTest {
assertFalse(actual.matches("t_mask", "T_MASK",
QuoteCharacter.BACK_QUOTE));
}
+ @Test
+ void assertNewQuotedInsensitiveRuleSet() {
+ IdentifierCaseRule actual =
IdentifierCaseRuleSets.newQuotedInsensitiveRuleSet().getRule(IdentifierScope.TABLE);
+ assertThat(actual.getLookupMode(QuoteCharacter.QUOTE),
is(LookupMode.NORMALIZED));
+ assertThat(actual.getLookupMode(QuoteCharacter.NONE),
is(LookupMode.NORMALIZED));
+ assertTrue(actual.matches("t_mask", "T_MASK",
QuoteCharacter.BACK_QUOTE));
+ }
+
@Test
void assertNewMySQLInsensitiveRuleSet() {
IdentifierCaseRule actual =
IdentifierCaseRuleSets.newMySQLInsensitiveRuleSet().getRule(IdentifierScope.TABLE);
diff --git
a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/identifier/DatabaseIdentifierContextFactory.java
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/identifier/DatabaseIdentifierContextFactory.java
index 22da25f7a47..a1f4b675e16 100644
---
a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/identifier/DatabaseIdentifierContextFactory.java
+++
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/identifier/DatabaseIdentifierContextFactory.java
@@ -129,18 +129,27 @@ public final class DatabaseIdentifierContextFactory {
private static IdentifierCaseRuleSet createScopeAwareRuleSet(final
IdentifierCaseRuleSet protocolRuleSet, final IdentifierCaseRuleSet
storageRuleSet) {
IdentifierCaseRuleSet databaseRuleSet =
IdentifierCaseRuleSets.newInsensitiveRuleSet();
+ IdentifierCaseRuleSet storageObjectRuleSet =
IdentifierCaseRuleSets.newQuotedInsensitiveRuleSet();
Map<IdentifierScope, IdentifierCaseRule> scopedRules = new
EnumMap<>(IdentifierScope.class);
for (IdentifierScope each : IdentifierScope.values()) {
if (IdentifierScope.DATABASE == each) {
scopedRules.put(each, databaseRuleSet.getRule(each));
continue;
}
+ if (isStorageObjectScope(each)) {
+ scopedRules.put(each, storageObjectRuleSet.getRule(each));
+ continue;
+ }
scopedRules.put(each, IdentifierScope.SCHEMA == each ?
protocolRuleSet.getRule(each) : storageRuleSet.getRule(each));
}
scopedRules.put(IdentifierScope.LOGICAL_TABLE,
protocolRuleSet.getRule(IdentifierScope.LOGICAL_TABLE));
return new
IdentifierCaseRuleSet(storageRuleSet.getRule(IdentifierScope.TABLE),
scopedRules);
}
+ private static boolean isStorageObjectScope(final IdentifierScope
identifierScope) {
+ return IdentifierScope.COLUMN == identifierScope ||
IdentifierScope.INDEX == identifierScope || IdentifierScope.CONSTRAINT ==
identifierScope;
+ }
+
private static Optional<DatabaseType> getIdentifierRuleDatabaseType(final
ResourceMetaData resourceMetaData) {
Collection<DatabaseType> storageDatabaseTypes =
getStorageDatabaseTypes(resourceMetaData);
return storageDatabaseTypes.stream().findFirst();
diff --git
a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabaseIdentifierTest.java
b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabaseIdentifierTest.java
index 255d4ca24c9..bc0cbaed47c 100644
---
a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabaseIdentifierTest.java
+++
b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabaseIdentifierTest.java
@@ -132,7 +132,7 @@ class ShardingSphereDatabaseIdentifierTest {
database.refreshIdentifierContext(new ConfigurationProperties(props));
assertFalse(database.containsSchema("FOO_SCHEMA"));
assertFalse(database.getSchema("foo_schema").containsTable("FOO_TBL"));
-
assertFalse(database.getSchema("foo_schema").getTable("foo_tbl").containsColumn("FOO_COL"));
+
assertTrue(database.getSchema("foo_schema").getTable("foo_tbl").containsColumn("FOO_COL"));
}
private ShardingSphereDatabase createDatabase(final DatabaseType
databaseType, final String schemaName) {
diff --git
a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/identifier/DatabaseIdentifierContextFactoryTest.java
b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/identifier/DatabaseIdentifierContextFactoryTest.java
index 5bb59d8eeba..9213c33e98e 100644
---
a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/identifier/DatabaseIdentifierContextFactoryTest.java
+++
b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/identifier/DatabaseIdentifierContextFactoryTest.java
@@ -266,6 +266,29 @@ class DatabaseIdentifierContextFactoryTest {
assertTrue(actualRule.matches("foo_db", "FOO_DB",
QuoteCharacter.NONE));
}
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("storageObjectScopes")
+ void assertCreateUsesInsensitiveRuleForStorageObjectScope(final String
name, final IdentifierScope identifierScope) {
+ DatabaseIdentifierContext actual =
DatabaseIdentifierContextFactory.create(MYSQL_DATABASE_TYPE,
MYSQL_SENSITIVE_STORAGE_RESOURCE_META_DATA, new ConfigurationProperties(new
Properties()));
+ IdentifierCaseRule actualRule = actual.getRule(identifierScope);
+ assertThat(actualRule.getLookupMode(QuoteCharacter.NONE),
is(LookupMode.NORMALIZED));
+ assertThat(actualRule.getLookupMode(QuoteCharacter.BACK_QUOTE),
is(LookupMode.NORMALIZED));
+ assertTrue(actualRule.matches("foo_name", "FOO_NAME",
QuoteCharacter.NONE));
+ assertTrue(actualRule.matches("foo_name", "FOO_NAME",
QuoteCharacter.BACK_QUOTE));
+ }
+
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("storageObjectScopes")
+ void assertRefreshUsesInsensitiveRuleForStorageObjectScope(final String
name, final IdentifierScope identifierScope) {
+ DatabaseIdentifierContext actual =
DatabaseIdentifierContextFactory.createDefault();
+ DatabaseIdentifierContextFactory.refresh(actual, MYSQL_DATABASE_TYPE,
MYSQL_SENSITIVE_STORAGE_RESOURCE_META_DATA, new ConfigurationProperties(new
Properties()));
+ IdentifierCaseRule actualRule = actual.getRule(identifierScope);
+ assertThat(actualRule.getLookupMode(QuoteCharacter.NONE),
is(LookupMode.NORMALIZED));
+ assertThat(actualRule.getLookupMode(QuoteCharacter.BACK_QUOTE),
is(LookupMode.NORMALIZED));
+ assertTrue(actualRule.matches("foo_name", "FOO_NAME",
QuoteCharacter.NONE));
+ assertTrue(actualRule.matches("foo_name", "FOO_NAME",
QuoteCharacter.BACK_QUOTE));
+ }
+
@ParameterizedTest(name = "{0}")
@MethodSource("createWithSupportedDatabaseSchemaLookupArguments")
void assertCreateFindSupportedDatabaseSchemaIdentifiers(final String name,
final DatabaseType protocolType, final ResourceMetaData resourceMetaData,
@@ -437,9 +460,9 @@ class DatabaseIdentifierContextFactoryTest {
return Stream.of(
createNormalizedLookupArguments("mysql column
lower_case_table_names=1", MYSQL_DATABASE_TYPE,
MYSQL_INSENSITIVE_RESOURCE_META_DATA, "foo_col", "`"),
createNormalizedLookupArguments("mysql column
lower_case_table_names=2", MYSQL_DATABASE_TYPE,
MYSQL_QUOTED_INSENSITIVE_RESOURCE_META_DATA, "foo_col", "`"),
- createLowerCaseLookupArguments("postgresql column",
POSTGRESQL_DATABASE_TYPE, POSTGRESQL_RESOURCE_META_DATA, "foo_col", "\""),
- createLowerCaseLookupArguments("openGauss column",
OPEN_GAUSS_DATABASE_TYPE, OPEN_GAUSS_RESOURCE_META_DATA, "foo_col", "\""),
- createUpperCaseLookupArguments("oracle column",
ORACLE_DATABASE_TYPE, ORACLE_RESOURCE_META_DATA, "foo_col", "\""))
+ createNormalizedLookupArguments("postgresql column",
POSTGRESQL_DATABASE_TYPE, POSTGRESQL_RESOURCE_META_DATA, "foo_col", "\""),
+ createNormalizedLookupArguments("openGauss column",
OPEN_GAUSS_DATABASE_TYPE, OPEN_GAUSS_RESOURCE_META_DATA, "foo_col", "\""),
+ createNormalizedLookupArguments("oracle column",
ORACLE_DATABASE_TYPE, ORACLE_RESOURCE_META_DATA, "foo_col", "\""))
.flatMap(each -> each);
}
@@ -494,9 +517,9 @@ class DatabaseIdentifierContextFactoryTest {
return Stream.of(
createNormalizedMixedLookupArguments("mysql column
lower_case_table_names=1", MYSQL_DATABASE_TYPE,
MYSQL_INSENSITIVE_RESOURCE_META_DATA, "foo_col", "`"),
createNormalizedMixedLookupArguments("mysql column
lower_case_table_names=2", MYSQL_DATABASE_TYPE,
MYSQL_QUOTED_INSENSITIVE_RESOURCE_META_DATA, "foo_col", "`"),
- createLowerCaseMixedLookupArguments("postgresql column",
POSTGRESQL_DATABASE_TYPE, POSTGRESQL_RESOURCE_META_DATA, "foo_col", "\""),
- createLowerCaseMixedLookupArguments("openGauss column",
OPEN_GAUSS_DATABASE_TYPE, OPEN_GAUSS_RESOURCE_META_DATA, "foo_col", "\""),
- createUpperCaseMixedLookupArguments("oracle column",
ORACLE_DATABASE_TYPE, ORACLE_RESOURCE_META_DATA, "foo_col", "\""))
+ createNormalizedMixedLookupArguments("postgresql column",
POSTGRESQL_DATABASE_TYPE, POSTGRESQL_RESOURCE_META_DATA, "foo_col", "\""),
+ createNormalizedMixedLookupArguments("openGauss column",
OPEN_GAUSS_DATABASE_TYPE, OPEN_GAUSS_RESOURCE_META_DATA, "foo_col", "\""),
+ createNormalizedMixedLookupArguments("oracle column",
ORACLE_DATABASE_TYPE, ORACLE_RESOURCE_META_DATA, "foo_col", "\""))
.flatMap(each -> each);
}
@@ -516,6 +539,13 @@ class DatabaseIdentifierContextFactoryTest {
return new ConfigurationProperties(PropertiesBuilder.build(new
Property(ConfigurationPropertyKey.METADATA_IDENTIFIER_CASE_SENSITIVITY.getKey(),
caseSensitivity.name())));
}
+ private static Stream<Arguments> storageObjectScopes() {
+ return Stream.of(
+ Arguments.of("column", IdentifierScope.COLUMN),
+ Arguments.of("index", IdentifierScope.INDEX),
+ Arguments.of("constraint", IdentifierScope.CONSTRAINT));
+ }
+
private static IdentifierIndex<String> createIdentifierIndex(final
DatabaseIdentifierContext identifierContext, final IdentifierScope
identifierScope, final String... actualNames) {
IdentifierIndex<String> result = new
IdentifierIndex<>(identifierContext, identifierScope);
Map<String, String> values = new LinkedHashMap<>(actualNames.length,
1F);