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 d13f5ccf6b1 Replace MySQL insensitive policy with quoted insensitive 
policy (#39228)
d13f5ccf6b1 is described below

commit d13f5ccf6b16739d75837373c95dec0ad8bc3080
Author: Haoran Meng <[email protected]>
AuthorDate: Fri Jul 24 12:16:56 2026 +0800

    Replace MySQL insensitive policy with quoted insensitive policy (#39228)
    
    * Replace MySQL insensitive policy with quoted insensitive policy
    
    * Update identifier case policy handling and related tests
    
    * Correct identifier case policy handling for mysql VIEW scope
---
 .../identifier/IdentifierCasePolicyFactory.java    | 29 +++++++++-----
 .../IdentifierCasePolicyFactoryTest.java           | 24 ++++++++----
 .../MySQLIdentifierCasePolicyProvider.java         | 33 ++++++++--------
 .../MySQLIdentifierCasePolicyProviderTest.java     | 44 ++++++++++++++++++++--
 4 files changed, 94 insertions(+), 36 deletions(-)

diff --git 
a/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierCasePolicyFactory.java
 
b/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierCasePolicyFactory.java
index 31f151218a3..c63e40a344c 100644
--- 
a/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierCasePolicyFactory.java
+++ 
b/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierCasePolicyFactory.java
@@ -70,22 +70,33 @@ public final class IdentifierCasePolicyFactory {
     }
     
     /**
-     * Create quoted and unquoted case-insensitive policy set.
+     * Create case-preserving and case-insensitive policy set.
      *
-     * @return quoted and unquoted case-insensitive policy set
+     * @return case-preserving and case-insensitive policy set
      */
-    public static IdentifierCasePolicySet newQuotedInsensitivePolicySet() {
-        return new IdentifierCasePolicySet(new 
IdentifierCasePolicy(LookupMode.NORMALIZED, LookupMode.NORMALIZED, 
UnaryOperator.identity(),
-                IdentifierCasePolicyFactory::toLowerCase, 
IdentifierCasePolicyFactory::toLowerCase, each -> true));
+    public static IdentifierCasePolicySet 
newCasePreservingInsensitivePolicySet() {
+        return new IdentifierCasePolicySet(new 
IdentifierCasePolicy(LookupMode.NORMALIZED, LookupMode.NORMALIZED,
+                UnaryOperator.identity(), UnaryOperator.identity(), 
IdentifierCasePolicyFactory::toLowerCase, each -> true));
     }
     
     /**
-     * Create MySQL case-insensitive policy set.
+     * Create lower-case and case-insensitive policy set.
      *
-     * @return MySQL case-insensitive policy set
+     * @return lower-case and case-insensitive policy set
      */
-    public static IdentifierCasePolicySet newMySQLInsensitivePolicySet() {
-        return newQuotedInsensitivePolicySet();
+    public static IdentifierCasePolicySet newLowerCaseInsensitivePolicySet() {
+        return new IdentifierCasePolicySet(new 
IdentifierCasePolicy(LookupMode.NORMALIZED, LookupMode.NORMALIZED,
+                IdentifierCasePolicyFactory::toLowerCase, 
IdentifierCasePolicyFactory::toLowerCase, 
IdentifierCasePolicyFactory::toLowerCase, each -> true));
+    }
+    
+    /**
+     * Create quoted and unquoted case-insensitive policy set.
+     *
+     * @return quoted and unquoted case-insensitive policy set
+     */
+    public static IdentifierCasePolicySet newQuotedInsensitivePolicySet() {
+        return new IdentifierCasePolicySet(new 
IdentifierCasePolicy(LookupMode.NORMALIZED, LookupMode.NORMALIZED, 
UnaryOperator.identity(),
+                IdentifierCasePolicyFactory::toLowerCase, 
IdentifierCasePolicyFactory::toLowerCase, each -> true));
     }
     
     private static String toLowerCase(final String value) {
diff --git 
a/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierCasePolicyFactoryTest.java
 
b/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierCasePolicyFactoryTest.java
index 1be04e0d9aa..541912e2c17 100644
--- 
a/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierCasePolicyFactoryTest.java
+++ 
b/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierCasePolicyFactoryTest.java
@@ -57,16 +57,26 @@ class IdentifierCasePolicyFactoryTest {
     }
     
     @Test
-    void assertNewQuotedInsensitivePolicySet() {
-        IdentifierCasePolicy actual = 
IdentifierCasePolicyFactory.newQuotedInsensitivePolicySet().getPolicy(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));
+    void assertNewCasePreservingInsensitivePolicySet() {
+        IdentifierCasePolicy actual = 
IdentifierCasePolicyFactory.newCasePreservingInsensitivePolicySet().getPolicy(IdentifierScope.TABLE);
+        assertThat(actual.normalizeForDefinition("Foo", QuoteCharacter.QUOTE), 
is("Foo"));
+        assertThat(actual.normalizeForDefinition("Foo", QuoteCharacter.NONE), 
is("Foo"));
+        assertTrue(actual.matches("Foo", "FOO", QuoteCharacter.BACK_QUOTE));
+        assertTrue(actual.matches("Foo", "FOO", QuoteCharacter.NONE));
     }
     
     @Test
-    void assertNewMySQLInsensitivePolicySet() {
-        IdentifierCasePolicy actual = 
IdentifierCasePolicyFactory.newMySQLInsensitivePolicySet().getPolicy(IdentifierScope.TABLE);
+    void assertNewLowerCaseInsensitivePolicySet() {
+        IdentifierCasePolicy actual = 
IdentifierCasePolicyFactory.newLowerCaseInsensitivePolicySet().getPolicy(IdentifierScope.TABLE);
+        assertThat(actual.normalizeForDefinition("Foo", QuoteCharacter.QUOTE), 
is("foo"));
+        assertThat(actual.normalizeForDefinition("Foo", QuoteCharacter.NONE), 
is("foo"));
+        assertTrue(actual.matches("Foo", "FOO", QuoteCharacter.BACK_QUOTE));
+        assertTrue(actual.matches("Foo", "FOO", QuoteCharacter.NONE));
+    }
+    
+    @Test
+    void assertNewQuotedInsensitivePolicySet() {
+        IdentifierCasePolicy actual = 
IdentifierCasePolicyFactory.newQuotedInsensitivePolicySet().getPolicy(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));
diff --git 
a/database/connector/dialect/mysql/src/main/java/org/apache/shardingsphere/database/connector/mysql/metadata/identifier/MySQLIdentifierCasePolicyProvider.java
 
b/database/connector/dialect/mysql/src/main/java/org/apache/shardingsphere/database/connector/mysql/metadata/identifier/MySQLIdentifierCasePolicyProvider.java
index 678d0bb3460..f868f82164f 100644
--- 
a/database/connector/dialect/mysql/src/main/java/org/apache/shardingsphere/database/connector/mysql/metadata/identifier/MySQLIdentifierCasePolicyProvider.java
+++ 
b/database/connector/dialect/mysql/src/main/java/org/apache/shardingsphere/database/connector/mysql/metadata/identifier/MySQLIdentifierCasePolicyProvider.java
@@ -41,44 +41,45 @@ public final class MySQLIdentifierCasePolicyProvider 
implements IdentifierCasePo
     @Override
     public IdentifierCasePolicySet provide(final 
IdentifierCasePolicyProviderContext context) {
         if (null == context.getDataSource()) {
-            return 
createStorageObjectSensitivePolicySet(IdentifierCasePolicyFactory.newMySQLInsensitivePolicySet());
+            return 
createStorageObjectPolicySet(IdentifierCasePolicyFactory.newQuotedInsensitivePolicySet());
         }
         try (Connection connection = context.getDataSource().getConnection()) {
             if (null == connection) {
-                return 
createStorageObjectSensitivePolicySet(IdentifierCasePolicyFactory.newInsensitivePolicySet());
+                return 
createStorageObjectPolicySet(IdentifierCasePolicyFactory.newInsensitivePolicySet());
             }
             try (
                     PreparedStatement preparedStatement = 
connection.prepareStatement(QUERY_LOWER_CASE_TABLE_NAMES);
                     ResultSet resultSet = preparedStatement.executeQuery()) {
-                return createStorageObjectSensitivePolicySet(resultSet.next() 
? createPolicySet(resultSet.getInt(1)) : 
IdentifierCasePolicyFactory.newInsensitivePolicySet());
+                return createStorageObjectPolicySet(resultSet.next() ? 
createPolicySet(resultSet.getInt(1)) : 
IdentifierCasePolicyFactory.newInsensitivePolicySet());
             }
         } catch (final SQLException ignored) {
-            return 
createStorageObjectSensitivePolicySet(IdentifierCasePolicyFactory.newInsensitivePolicySet());
+            return 
createStorageObjectPolicySet(IdentifierCasePolicyFactory.newInsensitivePolicySet());
         }
     }
     
-    private IdentifierCasePolicySet 
createStorageObjectSensitivePolicySet(final IdentifierCasePolicySet policySet) {
+    private IdentifierCasePolicySet createStorageObjectPolicySet(final 
IdentifierCasePolicySet policySet) {
         Map<IdentifierScope, IdentifierCasePolicy> scopedPolicies = new 
EnumMap<>(IdentifierScope.class);
         for (IdentifierScope each : IdentifierScope.values()) {
             scopedPolicies.put(each, policySet.getPolicy(each));
         }
-        IdentifierCasePolicy sensitivePolicy = 
IdentifierCasePolicyFactory.newSensitivePolicySet().getPolicy(IdentifierScope.COLUMN);
-        scopedPolicies.put(IdentifierScope.COLUMN, sensitivePolicy);
-        scopedPolicies.put(IdentifierScope.INDEX, sensitivePolicy);
-        scopedPolicies.put(IdentifierScope.CONSTRAINT, sensitivePolicy);
+        IdentifierCasePolicy storageObjectPolicy = 
IdentifierCasePolicyFactory.newCasePreservingInsensitivePolicySet().getPolicy(IdentifierScope.COLUMN);
+        scopedPolicies.put(IdentifierScope.COLUMN, storageObjectPolicy);
+        scopedPolicies.put(IdentifierScope.INDEX, storageObjectPolicy);
+        scopedPolicies.put(IdentifierScope.CONSTRAINT, storageObjectPolicy);
         return new 
IdentifierCasePolicySet(policySet.getPolicy(IdentifierScope.TABLE), 
scopedPolicies);
     }
     
     private IdentifierCasePolicySet createPolicySet(final int 
lowerCaseTableNames) {
-        if (1 == lowerCaseTableNames || 2 == lowerCaseTableNames) {
-            return IdentifierCasePolicyFactory.newMySQLInsensitivePolicySet();
-        }
         if (0 == lowerCaseTableNames) {
+            return IdentifierCasePolicyFactory.newSensitivePolicySet();
+        }
+        if (1 == lowerCaseTableNames) {
+            return 
IdentifierCasePolicyFactory.newLowerCaseInsensitivePolicySet();
+        }
+        if (2 == lowerCaseTableNames) {
             Map<IdentifierScope, IdentifierCasePolicy> scopedPolicies = new 
EnumMap<>(IdentifierScope.class);
-            scopedPolicies.put(IdentifierScope.SCHEMA, 
IdentifierCasePolicyFactory.newMySQLInsensitivePolicySet().getPolicy(IdentifierScope.SCHEMA));
-            scopedPolicies.put(IdentifierScope.TABLE, 
IdentifierCasePolicyFactory.newSensitivePolicySet().getPolicy(IdentifierScope.TABLE));
-            scopedPolicies.put(IdentifierScope.VIEW, 
IdentifierCasePolicyFactory.newSensitivePolicySet().getPolicy(IdentifierScope.VIEW));
-            return new 
IdentifierCasePolicySet(IdentifierCasePolicyFactory.newInsensitivePolicySet().getPolicy(IdentifierScope.TABLE),
 scopedPolicies);
+            scopedPolicies.put(IdentifierScope.VIEW, 
IdentifierCasePolicyFactory.newLowerCaseInsensitivePolicySet().getPolicy(IdentifierScope.VIEW));
+            return new 
IdentifierCasePolicySet(IdentifierCasePolicyFactory.newCasePreservingInsensitivePolicySet().getPolicy(IdentifierScope.TABLE),
 scopedPolicies);
         }
         return IdentifierCasePolicyFactory.newInsensitivePolicySet();
     }
diff --git 
a/database/connector/dialect/mysql/src/test/java/org/apache/shardingsphere/database/connector/mysql/metadata/identifier/MySQLIdentifierCasePolicyProviderTest.java
 
b/database/connector/dialect/mysql/src/test/java/org/apache/shardingsphere/database/connector/mysql/metadata/identifier/MySQLIdentifierCasePolicyProviderTest.java
index 820305e27ce..8fe438090e9 100644
--- 
a/database/connector/dialect/mysql/src/test/java/org/apache/shardingsphere/database/connector/mysql/metadata/identifier/MySQLIdentifierCasePolicyProviderTest.java
+++ 
b/database/connector/dialect/mysql/src/test/java/org/apache/shardingsphere/database/connector/mysql/metadata/identifier/MySQLIdentifierCasePolicyProviderTest.java
@@ -64,6 +64,9 @@ class MySQLIdentifierCasePolicyProviderTest {
         
assertThat(actual.getPolicy(IdentifierScope.COLUMN).normalizeForDefinition("FooColumn",
 QuoteCharacter.NONE), is("FooColumn"));
         
assertThat(actual.getPolicy(IdentifierScope.INDEX).normalizeForDefinition("FooIndex",
 QuoteCharacter.NONE), is("FooIndex"));
         
assertThat(actual.getPolicy(IdentifierScope.CONSTRAINT).normalizeForDefinition("FooConstraint",
 QuoteCharacter.NONE), is("FooConstraint"));
+        
assertThat(actual.getPolicy(IdentifierScope.COLUMN).matches("foo_column", 
"FOO_COLUMN", QuoteCharacter.NONE), is(Boolean.TRUE));
+        
assertThat(actual.getPolicy(IdentifierScope.INDEX).matches("foo_index", 
"FOO_INDEX", QuoteCharacter.NONE), is(Boolean.TRUE));
+        
assertThat(actual.getPolicy(IdentifierScope.CONSTRAINT).matches("foo_constraint",
 "FOO_CONSTRAINT", QuoteCharacter.NONE), is(Boolean.TRUE));
     }
     
     @Test
@@ -93,12 +96,45 @@ class MySQLIdentifierCasePolicyProviderTest {
     void assertProvideWithLowerCaseTableNamesZeroUsesScopedPolicies() {
         IdentifierCasePolicyProviderContext context = new 
IdentifierCasePolicyProviderContext(DATABASE_TYPE, new FixtureDataSource(true, 
0));
         IdentifierCasePolicySet actual = provider.provide(context);
-        
assertThat(actual.getPolicy(IdentifierScope.SCHEMA).matches("foo_schema", 
"FOO_SCHEMA", QuoteCharacter.NONE), is(Boolean.TRUE));
+        
assertThat(actual.getPolicy(IdentifierScope.DATABASE).matches("foo_db", 
"FOO_DB", QuoteCharacter.NONE), is(Boolean.FALSE));
+        
assertThat(actual.getPolicy(IdentifierScope.SCHEMA).matches("foo_schema", 
"FOO_SCHEMA", QuoteCharacter.NONE), is(Boolean.FALSE));
         assertThat(actual.getPolicy(IdentifierScope.TABLE).matches("foo_tbl", 
"FOO_TBL", QuoteCharacter.NONE), is(Boolean.FALSE));
         assertThat(actual.getPolicy(IdentifierScope.VIEW).matches("foo_view", 
"FOO_VIEW", QuoteCharacter.NONE), is(Boolean.FALSE));
-        assertThat(actual.getPolicy(IdentifierScope.COLUMN).matches("foo_col", 
"FOO_COL", QuoteCharacter.NONE), is(Boolean.FALSE));
-        assertThat(actual.getPolicy(IdentifierScope.INDEX).matches("foo_idx", 
"FOO_IDX", QuoteCharacter.NONE), is(Boolean.FALSE));
-        
assertThat(actual.getPolicy(IdentifierScope.CONSTRAINT).matches("foo_fk", 
"FOO_FK", QuoteCharacter.NONE), is(Boolean.FALSE));
+        assertThat(actual.getPolicy(IdentifierScope.COLUMN).matches("foo_col", 
"FOO_COL", QuoteCharacter.NONE), is(Boolean.TRUE));
+        assertThat(actual.getPolicy(IdentifierScope.INDEX).matches("foo_idx", 
"FOO_IDX", QuoteCharacter.NONE), is(Boolean.TRUE));
+        
assertThat(actual.getPolicy(IdentifierScope.CONSTRAINT).matches("foo_fk", 
"FOO_FK", QuoteCharacter.NONE), is(Boolean.TRUE));
+    }
+    
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("tableDefinitionArguments")
+    void assertTableDefinition(final String name, final int 
lowerCaseTableNames, final String expected) {
+        IdentifierCasePolicy actual = provider.provide(new 
IdentifierCasePolicyProviderContext(DATABASE_TYPE,
+                new FixtureDataSource(true, 
lowerCaseTableNames))).getPolicy(IdentifierScope.TABLE);
+        assertThat(actual.normalizeForDefinition("FooTable", 
QuoteCharacter.NONE), is(expected));
+        assertThat(actual.normalizeForDefinition("FooTable", 
QuoteCharacter.BACK_QUOTE), is(expected));
+    }
+    
+    private static Stream<Arguments> tableDefinitionArguments() {
+        return Stream.of(
+                Arguments.of("lower_case_table_names_0", 0, "FooTable"),
+                Arguments.of("lower_case_table_names_1", 1, "footable"),
+                Arguments.of("lower_case_table_names_2", 2, "FooTable"));
+    }
+    
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("viewDefinitionArguments")
+    void assertViewDefinition(final String name, final int 
lowerCaseTableNames, final String expected) {
+        IdentifierCasePolicy actual = provider.provide(new 
IdentifierCasePolicyProviderContext(DATABASE_TYPE,
+                new FixtureDataSource(true, 
lowerCaseTableNames))).getPolicy(IdentifierScope.VIEW);
+        assertThat(actual.normalizeForDefinition("FooView", 
QuoteCharacter.NONE), is(expected));
+        assertThat(actual.normalizeForDefinition("FooView", 
QuoteCharacter.BACK_QUOTE), is(expected));
+    }
+    
+    private static Stream<Arguments> viewDefinitionArguments() {
+        return Stream.of(
+                Arguments.of("lower_case_table_names_0", 0, "FooView"),
+                Arguments.of("lower_case_table_names_1", 1, "fooview"),
+                Arguments.of("lower_case_table_names_2", 2, "fooview"));
     }
     
     private static Object getDefaultValue(final Class<?> returnType) {

Reply via email to