You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by me...@apache.org on 2026/07/15 10:18:21 UTC
(shardingsphere) branch master updated: Simplify and unify identifier case policy resolution (#39129)
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 85f4887b659 Simplify and unify identifier case policy resolution (#39129)
85f4887b659 is described below
commit 85f4887b659c942246dcfc976b321fd846bf5a50
Author: Haoran Meng <me...@gmail.com>
AuthorDate: Wed Jul 15 18:18:14 2026 +0800
Simplify and unify identifier case policy resolution (#39129)
---
.../MySQLIdentifierCasePolicyProvider.java | 2 +-
.../MySQLIdentifierCasePolicyProviderTest.java | 2 +-
.../DatabaseIdentifierContextFactory.java | 116 +++++++--------------
.../identifier/IdentifierCasePolicyResolver.java | 29 ++++--
.../DatabaseIdentifierContextFactoryTest.java | 55 ++++++----
.../IdentifierCasePolicyResolverTest.java | 13 +--
.../jdbc/MCPJdbcDatabaseProfileLoader.java | 2 +-
.../jdbc/MCPJdbcDatabaseProfileLoaderTest.java | 36 +++----
.../manager/resource/StorageUnitManagerTest.java | 6 ++
9 files changed, 128 insertions(+), 133 deletions(-)
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 e316cfd51b0..bb7ed87faf0 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,7 +41,7 @@ public final class MySQLIdentifierCasePolicyProvider implements IdentifierCasePo
@Override
public IdentifierCasePolicySet provide(final IdentifierCasePolicyProviderContext context) {
if (null == context.getDataSource()) {
- return IdentifierCasePolicyFactory.newInsensitivePolicySet();
+ return IdentifierCasePolicyFactory.newMySQLInsensitivePolicySet();
}
try (Connection connection = context.getDataSource().getConnection()) {
if (null == connection) {
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 ea2d56898f6..3df6585b7c8 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
@@ -72,7 +72,7 @@ class MySQLIdentifierCasePolicyProviderTest {
private static Stream<Arguments> provideArguments() {
return Stream.of(
- Arguments.of("null_data_source", new IdentifierCasePolicyProviderContext(DATABASE_TYPE, null), LookupMode.EXACT, LookupMode.NORMALIZED, true),
+ Arguments.of("null_data_source", new IdentifierCasePolicyProviderContext(DATABASE_TYPE, null), LookupMode.NORMALIZED, LookupMode.NORMALIZED, true),
Arguments.of("null_connection", new IdentifierCasePolicyProviderContext(DATABASE_TYPE, new NullConnectionFixtureDataSource()), LookupMode.EXACT, LookupMode.NORMALIZED, true),
Arguments.of("lower_case_table_names_0", new IdentifierCasePolicyProviderContext(DATABASE_TYPE, new FixtureDataSource(true, 0)),
LookupMode.EXACT, LookupMode.EXACT, false),
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 d69014b32df..f5715e5aa07 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
@@ -19,23 +19,20 @@ package org.apache.shardingsphere.infra.metadata.identifier;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
+import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicy;
-import org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicySet;
-import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
import org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyFactory;
+import org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicySet;
import org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierScope;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
import org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
import org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit;
-import javax.sql.DataSource;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
-import java.util.LinkedHashSet;
import java.util.Map;
-import java.util.Optional;
-import java.util.Properties;
/**
* Database identifier context factory.
@@ -60,11 +57,8 @@ public final class DatabaseIdentifierContextFactory {
* @return identifier context
*/
public static DatabaseIdentifierContext create(final DatabaseType protocolType, final ConfigurationProperties props) {
- ConfigurationProperties actualProps = getProps(props);
- IdentifierCasePolicyResolver resolver = new IdentifierCasePolicyResolver();
- IdentifierCasePolicySet protocolPolicySet = resolver.resolve(protocolType, actualProps, null);
- IdentifierCasePolicySet scopeAwarePolicySet = createScopeAwarePolicySet(protocolPolicySet, protocolPolicySet);
- return new DatabaseIdentifierContext(scopeAwarePolicySet, false);
+ ResolvedIdentifierContext resolvedContext = resolve(protocolType, null, props);
+ return new DatabaseIdentifierContext(resolvedContext.policySet, resolvedContext.heterogeneousTableLookupEnabled);
}
/**
@@ -76,27 +70,8 @@ public final class DatabaseIdentifierContextFactory {
* @return identifier context
*/
public static DatabaseIdentifierContext create(final DatabaseType protocolType, final ResourceMetaData resourceMetaData, final ConfigurationProperties props) {
- ConfigurationProperties actualProps = getProps(props);
- IdentifierCasePolicyResolver resolver = new IdentifierCasePolicyResolver();
- IdentifierCasePolicySet protocolPolicySet = resolver.resolve(protocolType, actualProps, getFirstDataSource(resourceMetaData));
- Optional<DatabaseType> storageDatabaseType = getIdentifierPolicyDatabaseType(resourceMetaData);
- IdentifierCasePolicySet storagePolicySet = resolver.resolve(storageDatabaseType.orElse(protocolType), actualProps, getFirstDataSource(resourceMetaData));
- IdentifierCasePolicySet scopeAwarePolicySet = createScopeAwarePolicySet(protocolPolicySet, storagePolicySet);
- return new DatabaseIdentifierContext(scopeAwarePolicySet, isHeterogeneous(protocolType, getStorageDatabaseTypes(resourceMetaData)));
- }
-
- /**
- * Refresh identifier context with protocol-aware identifier policies.
- *
- * @param identifierContext identifier context
- * @param protocolType protocol type
- * @param props configuration properties
- */
- public static void refresh(final DatabaseIdentifierContext identifierContext, final DatabaseType protocolType, final ConfigurationProperties props) {
- ConfigurationProperties actualProps = getProps(props);
- IdentifierCasePolicyResolver resolver = new IdentifierCasePolicyResolver();
- IdentifierCasePolicySet protocolPolicySet = resolver.resolve(protocolType, actualProps, null);
- identifierContext.refresh(createScopeAwarePolicySet(protocolPolicySet, protocolPolicySet), false);
+ ResolvedIdentifierContext resolvedContext = resolve(protocolType, resourceMetaData, props);
+ return new DatabaseIdentifierContext(resolvedContext.policySet, resolvedContext.heterogeneousTableLookupEnabled);
}
/**
@@ -108,70 +83,57 @@ public final class DatabaseIdentifierContextFactory {
* @param props configuration properties
*/
public static void refresh(final DatabaseIdentifierContext identifierContext, final DatabaseType protocolType, final ResourceMetaData resourceMetaData, final ConfigurationProperties props) {
- ConfigurationProperties actualProps = getProps(props);
- IdentifierCasePolicyResolver resolver = new IdentifierCasePolicyResolver();
- IdentifierCasePolicySet protocolPolicySet = resolver.resolve(protocolType, actualProps, getFirstDataSource(resourceMetaData));
- Optional<DatabaseType> storageDatabaseType = getIdentifierPolicyDatabaseType(resourceMetaData);
- IdentifierCasePolicySet storagePolicySet = resolver.resolve(storageDatabaseType.orElse(protocolType), actualProps, getFirstDataSource(resourceMetaData));
- identifierContext.refresh(createScopeAwarePolicySet(protocolPolicySet, storagePolicySet), isHeterogeneous(protocolType, getStorageDatabaseTypes(resourceMetaData)));
+ ResolvedIdentifierContext resolvedContext = resolve(protocolType, resourceMetaData, props);
+ identifierContext.refresh(resolvedContext.policySet, resolvedContext.heterogeneousTableLookupEnabled);
}
- private static ConfigurationProperties getProps(final ConfigurationProperties props) {
- return null == props ? new ConfigurationProperties(new Properties()) : props;
+ private static ResolvedIdentifierContext resolve(final DatabaseType protocolType, final ResourceMetaData resourceMetaData, final ConfigurationProperties props) {
+ Collection<StorageUnit> storageUnits = getStorageUnits(resourceMetaData);
+ StorageUnit storageUnit = storageUnits.stream().findFirst().orElse(null);
+ IdentifierCasePolicySet protocolPolicySet = IdentifierCasePolicyResolver.resolveProtocol(protocolType, props);
+ IdentifierCasePolicySet storagePolicySet = null == storageUnit
+ ? protocolPolicySet
+ : IdentifierCasePolicyResolver.resolveStorage(storageUnit.getStorageType(), props, storageUnit.getDataSource());
+ return new ResolvedIdentifierContext(createScopeAwarePolicySet(protocolPolicySet, storagePolicySet), isHeterogeneous(protocolType, storageUnits));
}
- private static DataSource getFirstDataSource(final ResourceMetaData resourceMetaData) {
+ private static Collection<StorageUnit> getStorageUnits(final ResourceMetaData resourceMetaData) {
if (null == resourceMetaData || null == resourceMetaData.getStorageUnits() || resourceMetaData.getStorageUnits().isEmpty()) {
- return null;
+ return Collections.emptyList();
}
- return resourceMetaData.getStorageUnits().values().iterator().next().getDataSource();
+ return resourceMetaData.getStorageUnits().values();
}
private static IdentifierCasePolicySet createScopeAwarePolicySet(final IdentifierCasePolicySet protocolPolicySet, final IdentifierCasePolicySet storagePolicySet) {
- IdentifierCasePolicySet databasePolicySet = IdentifierCasePolicyFactory.newInsensitivePolicySet();
- IdentifierCasePolicySet storageObjectPolicySet = IdentifierCasePolicyFactory.newQuotedInsensitivePolicySet();
Map<IdentifierScope, IdentifierCasePolicy> scopedPolicies = new EnumMap<>(IdentifierScope.class);
for (IdentifierScope each : IdentifierScope.values()) {
- if (IdentifierScope.DATABASE == each) {
- scopedPolicies.put(each, databasePolicySet.getPolicy(each));
- continue;
- }
- if (isStorageObjectScope(each)) {
- scopedPolicies.put(each, storageObjectPolicySet.getPolicy(each));
- continue;
- }
- scopedPolicies.put(each, IdentifierScope.SCHEMA == each ? protocolPolicySet.getPolicy(each) : storagePolicySet.getPolicy(each));
+ scopedPolicies.put(each, storagePolicySet.getPolicy(each));
}
+ IdentifierCasePolicy databasePolicy = IdentifierCasePolicyFactory.newInsensitivePolicySet().getPolicy(IdentifierScope.DATABASE);
+ IdentifierCasePolicy storageObjectPolicy = IdentifierCasePolicyFactory.newQuotedInsensitivePolicySet().getPolicy(IdentifierScope.COLUMN);
+ scopedPolicies.put(IdentifierScope.DATABASE, databasePolicy);
+ scopedPolicies.put(IdentifierScope.SCHEMA, protocolPolicySet.getPolicy(IdentifierScope.SCHEMA));
scopedPolicies.put(IdentifierScope.LOGICAL_TABLE, protocolPolicySet.getPolicy(IdentifierScope.LOGICAL_TABLE));
+ scopedPolicies.put(IdentifierScope.COLUMN, storageObjectPolicy);
+ scopedPolicies.put(IdentifierScope.INDEX, storageObjectPolicy);
+ scopedPolicies.put(IdentifierScope.CONSTRAINT, storageObjectPolicy);
return new IdentifierCasePolicySet(storagePolicySet.getPolicy(IdentifierScope.TABLE), scopedPolicies);
}
- private static boolean isStorageObjectScope(final IdentifierScope identifierScope) {
- return IdentifierScope.COLUMN == identifierScope || IdentifierScope.INDEX == identifierScope || IdentifierScope.CONSTRAINT == identifierScope;
- }
-
- private static Optional<DatabaseType> getIdentifierPolicyDatabaseType(final ResourceMetaData resourceMetaData) {
- Collection<DatabaseType> storageDatabaseTypes = getStorageDatabaseTypes(resourceMetaData);
- return storageDatabaseTypes.stream().findFirst();
- }
-
- private static Collection<DatabaseType> getStorageDatabaseTypes(final ResourceMetaData resourceMetaData) {
- if (null == resourceMetaData || null == resourceMetaData.getStorageUnits() || resourceMetaData.getStorageUnits().isEmpty()) {
- return Collections.emptyList();
- }
- Collection<DatabaseType> storageDatabaseTypes = new LinkedHashSet<>(resourceMetaData.getStorageUnits().size(), 1F);
- for (StorageUnit each : resourceMetaData.getStorageUnits().values()) {
- storageDatabaseTypes.add(each.getStorageType());
- }
- return storageDatabaseTypes;
- }
-
- private static boolean isHeterogeneous(final DatabaseType protocolType, final Collection<DatabaseType> storageDatabaseTypes) {
- return null != protocolType && null != protocolType.getType() && storageDatabaseTypes.stream()
- .anyMatch(each -> null != each && null != each.getType() && !isSameProtocolType(protocolType, each));
+ private static boolean isHeterogeneous(final DatabaseType protocolType, final Collection<StorageUnit> storageUnits) {
+ return null != protocolType && null != protocolType.getType() && storageUnits.stream()
+ .map(StorageUnit::getStorageType).anyMatch(each -> null != each && null != each.getType() && !isSameProtocolType(protocolType, each));
}
private static boolean isSameProtocolType(final DatabaseType protocolType, final DatabaseType storageType) {
return protocolType.getType().equalsIgnoreCase(storageType.getType());
}
+
+ @RequiredArgsConstructor
+ private static final class ResolvedIdentifierContext {
+
+ private final IdentifierCasePolicySet policySet;
+
+ private final boolean heterogeneousTableLookupEnabled;
+ }
}
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/identifier/IdentifierCasePolicyResolver.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/identifier/IdentifierCasePolicyResolver.java
index ec4fd4b7aba..9acb706a46e 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/identifier/IdentifierCasePolicyResolver.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/identifier/IdentifierCasePolicyResolver.java
@@ -17,6 +17,8 @@
package org.apache.shardingsphere.infra.metadata.identifier;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
import org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyProvider;
import org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyProviderContext;
import org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicySet;
@@ -33,20 +35,33 @@ import javax.sql.DataSource;
/**
* Resolver of identifier case policy.
*/
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class IdentifierCasePolicyResolver {
/**
- * Resolve identifier case policy.
+ * Resolve protocol identifier case policy.
*
- * @param databaseType database type
+ * @param protocolType protocol type
* @param props configuration properties
- * @param dataSource data source
* @return identifier case policy set
*/
- public IdentifierCasePolicySet resolve(final DatabaseType databaseType, final ConfigurationProperties props, final DataSource dataSource) {
- if (null == databaseType || null == databaseType.getType()) {
- return IdentifierCasePolicyFactory.newInsensitivePolicySet();
- }
+ public static IdentifierCasePolicySet resolveProtocol(final DatabaseType protocolType, final ConfigurationProperties props) {
+ return resolve(protocolType, props, null);
+ }
+
+ /**
+ * Resolve storage identifier case policy.
+ *
+ * @param storageType storage type
+ * @param props configuration properties
+ * @param dataSource storage data source
+ * @return identifier case policy set
+ */
+ public static IdentifierCasePolicySet resolveStorage(final DatabaseType storageType, final ConfigurationProperties props, final DataSource dataSource) {
+ return resolve(storageType, props, dataSource);
+ }
+
+ private static IdentifierCasePolicySet resolve(final DatabaseType databaseType, final ConfigurationProperties props, final DataSource dataSource) {
MetadataIdentifierCaseSensitivity configuredCaseSensitivity = new TemporaryConfigurationProperties(props.getProps())
.getValue(TemporaryConfigurationPropertyKey.METADATA_IDENTIFIER_CASE_SENSITIVITY);
if (MetadataIdentifierCaseSensitivity.INSENSITIVE == configuredCaseSensitivity) {
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 dcbb5c2db4e..65e7b1af2c2 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
@@ -121,17 +121,6 @@ class DatabaseIdentifierContextFactoryTest {
assertThat(actualRule.matches(actualIdentifier, logicIdentifier, QuoteCharacter.NONE), is(expectedMatched));
}
- @ParameterizedTest(name = "{0}")
- @MethodSource("refreshWithProtocolTypeAndPropsArguments")
- void assertRefreshWithProtocolTypeAndProps(final String name, final DatabaseType protocolType, final ConfigurationProperties props, final LookupMode expectedLookupMode,
- final String actualIdentifier, final String logicIdentifier, final boolean expectedMatched) {
- DatabaseIdentifierContext actual = DatabaseIdentifierContextFactory.createDefault();
- DatabaseIdentifierContextFactory.refresh(actual, protocolType, props);
- IdentifierCasePolicy actualRule = actual.getPolicy(IdentifierScope.TABLE);
- assertThat(actualRule.getLookupMode(QuoteCharacter.NONE), is(expectedLookupMode));
- assertThat(actualRule.matches(actualIdentifier, logicIdentifier, QuoteCharacter.NONE), is(expectedMatched));
- }
-
@ParameterizedTest(name = "{0}")
@MethodSource("refreshWithResourceMetaDataAndPropsArguments")
void assertRefreshWithResourceMetaDataAndProps(final String name, final DatabaseType protocolType, final ResourceMetaData resourceMetaData,
@@ -184,6 +173,21 @@ class DatabaseIdentifierContextFactoryTest {
assertTrue(actualTableRule.matches("T_ORDER", "t_order", QuoteCharacter.NONE));
}
+ @Test
+ void assertCreateDoesNotUseStorageDataSourceForProtocolPolicy() {
+ DatabaseIdentifierContext actual = DatabaseIdentifierContextFactory.create(MYSQL_DATABASE_TYPE,
+ createResourceMetaDataWithStorageUnit("jdbc:oracle:thin:@localhost:1521:xe", createDataSourceFailingOnConnection()), new ConfigurationProperties(new Properties()));
+ assertTrue(actual.getPolicy(IdentifierScope.LOGICAL_TABLE).matches("t_order", "T_ORDER", QuoteCharacter.NONE));
+ }
+
+ @Test
+ void assertRefreshDoesNotUseStorageDataSourceForProtocolPolicy() {
+ DatabaseIdentifierContext actual = DatabaseIdentifierContextFactory.createDefault();
+ DatabaseIdentifierContextFactory.refresh(actual, MYSQL_DATABASE_TYPE,
+ createResourceMetaDataWithStorageUnit("jdbc:oracle:thin:@localhost:1521:xe", createDataSourceFailingOnConnection()), new ConfigurationProperties(new Properties()));
+ assertTrue(actual.getPolicy(IdentifierScope.LOGICAL_TABLE).matches("t_order", "T_ORDER", QuoteCharacter.NONE));
+ }
+
@Test
void assertCreateUsesInsensitiveRuleForLogicalTableWhenMySQLLowerCaseTableNamesIsZero() {
DatabaseIdentifierContext actual = DatabaseIdentifierContextFactory.create(MYSQL_DATABASE_TYPE, MYSQL_SENSITIVE_STORAGE_RESOURCE_META_DATA, new ConfigurationProperties(new Properties()));
@@ -389,25 +393,19 @@ class DatabaseIdentifierContextFactoryTest {
private static Stream<Arguments> createWithProtocolTypeAndPropsArguments() {
return Stream.of(
- Arguments.of("null protocol type and null props use insensitive rules", null, null, LookupMode.NORMALIZED, "Foo", "foo", true),
+ Arguments.of("empty props use insensitive rules", DATABASE_TYPE, new ConfigurationProperties(new Properties()), LookupMode.NORMALIZED, "Foo", "foo", true),
Arguments.of("insensitive props normalize identifiers", DATABASE_TYPE,
createConfigurationProperties(MetadataIdentifierCaseSensitivity.INSENSITIVE), LookupMode.NORMALIZED, "Foo", "foo", true));
}
private static Stream<Arguments> createWithResourceMetaDataAndPropsArguments() {
return Stream.of(
- Arguments.of("null resource metadata and null props use insensitive rules", null, null, null, LookupMode.NORMALIZED, "Foo", "foo", true),
+ Arguments.of("null resource metadata and empty props use insensitive rules", DATABASE_TYPE, null, new ConfigurationProperties(new Properties()), LookupMode.NORMALIZED, "Foo", "foo",
+ true),
Arguments.of("storage type overrides protocol type for oracle backend", MYSQL_DATABASE_TYPE, createResourceMetaDataWithStorageUrls("jdbc:oracle:thin:@localhost:1521:xe"),
new ConfigurationProperties(new Properties()), LookupMode.NORMALIZED, "T_ORDER", "t_order", true));
}
- private static Stream<Arguments> refreshWithProtocolTypeAndPropsArguments() {
- return Stream.of(
- Arguments.of("null protocol type and null props refresh to insensitive rules", null, null, LookupMode.NORMALIZED, "Foo", "foo", true),
- Arguments.of("insensitive props refresh to normalized lookup", DATABASE_TYPE,
- createConfigurationProperties(MetadataIdentifierCaseSensitivity.INSENSITIVE), LookupMode.NORMALIZED, "Foo", "foo", true));
- }
-
private static Stream<Arguments> createWithSupportedDatabaseSchemaLookupArguments() {
return Stream.of(
createNormalizedLookupArguments("mysql schema", MYSQL_DATABASE_TYPE, MYSQL_INSENSITIVE_RESOURCE_META_DATA, "foo_schema", "`"),
@@ -439,7 +437,9 @@ class DatabaseIdentifierContextFactoryTest {
private static Stream<Arguments> refreshWithResourceMetaDataAndPropsArguments() {
return Stream.of(
- Arguments.of("null resource metadata and null props refresh to insensitive rules", null, null, null, LookupMode.NORMALIZED, "Foo", "foo", true),
+ Arguments.of("null resource metadata and empty props refresh to insensitive rules", DATABASE_TYPE, null, new ConfigurationProperties(new Properties()), LookupMode.NORMALIZED, "Foo",
+ "foo",
+ true),
Arguments.of("refresh uses oracle storage type when protocol type is mysql", MYSQL_DATABASE_TYPE, createResourceMetaDataWithStorageUrls("jdbc:oracle:thin:@localhost:1521:xe"),
new ConfigurationProperties(new Properties()), LookupMode.NORMALIZED, "T_ORDER", "t_order", true));
}
@@ -680,6 +680,19 @@ class DatabaseIdentifierContextFactoryTest {
return new ResourceMetaData(Collections.emptyMap(), storageUnits);
}
+ private static ResourceMetaData createResourceMetaDataWithStorageUnit(final String url, final DataSource dataSource) {
+ return new ResourceMetaData(Collections.emptyMap(), Collections.singletonMap("ds_0", createStorageUnit("ds_0", url, dataSource)));
+ }
+
+ private static DataSource createDataSourceFailingOnConnection() {
+ return (DataSource) Proxy.newProxyInstance(DataSource.class.getClassLoader(), new Class[]{DataSource.class}, (proxy, method, args) -> {
+ if ("getConnection".equals(method.getName())) {
+ throw new AssertionError("Storage data source must not be used to resolve protocol policy.");
+ }
+ return null;
+ });
+ }
+
private static StorageUnit createStorageUnit(final String name, final String url) {
return createStorageUnit(name, url, new FixtureDataSource());
}
diff --git a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/identifier/IdentifierCasePolicyResolverTest.java b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/identifier/IdentifierCasePolicyResolverTest.java
index 12e46c1518a..6b439f120fa 100644
--- a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/identifier/IdentifierCasePolicyResolverTest.java
+++ b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/identifier/IdentifierCasePolicyResolverTest.java
@@ -38,12 +38,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
class IdentifierCasePolicyResolverTest {
- private final IdentifierCasePolicyResolver resolver = new IdentifierCasePolicyResolver();
-
@Test
void assertResolveWithInsensitiveConfiguration() {
IdentifierCasePolicy actual =
- resolver.resolve(TypedSPILoader.getService(DatabaseType.class, "Oracle"), new ConfigurationProperties(createProperties("insensitive")), null)
+ IdentifierCasePolicyResolver.resolveProtocol(TypedSPILoader.getService(DatabaseType.class, "Oracle"), new ConfigurationProperties(createProperties("insensitive")))
.getPolicy(IdentifierScope.TABLE);
assertThat(actual.getLookupMode(QuoteCharacter.NONE), is(LookupMode.NORMALIZED));
assertTrue(actual.matches("Foo", "foo", QuoteCharacter.NONE));
@@ -51,7 +49,7 @@ class IdentifierCasePolicyResolverTest {
@Test
void assertResolveWithAutoPostgreSQLRule() {
- IdentifierCasePolicy actual = resolver.resolve(TypedSPILoader.getService(DatabaseType.class, "PostgreSQL"), new ConfigurationProperties(new Properties()), null)
+ IdentifierCasePolicy actual = IdentifierCasePolicyResolver.resolveProtocol(TypedSPILoader.getService(DatabaseType.class, "PostgreSQL"), new ConfigurationProperties(new Properties()))
.getPolicy(IdentifierScope.TABLE);
assertTrue(actual.matches("foo", "FOO", QuoteCharacter.NONE));
assertFalse(actual.matches("Foo", "foo", QuoteCharacter.NONE));
@@ -59,15 +57,18 @@ class IdentifierCasePolicyResolverTest {
@Test
void assertResolveWithAutoOracleRule() {
- IdentifierCasePolicy actual = resolver.resolve(TypedSPILoader.getService(DatabaseType.class, "Oracle"), new ConfigurationProperties(new Properties()), null).getPolicy(IdentifierScope.TABLE);
+ IdentifierCasePolicy actual = IdentifierCasePolicyResolver.resolveProtocol(TypedSPILoader.getService(DatabaseType.class, "Oracle"), new ConfigurationProperties(new Properties()))
+ .getPolicy(IdentifierScope.TABLE);
assertTrue(actual.matches("FOO", "foo", QuoteCharacter.NONE));
assertFalse(actual.matches("Foo", "foo", QuoteCharacter.NONE));
}
@Test
void assertResolveWithAutoMySQLRule() {
- IdentifierCasePolicy actual = resolver.resolve(TypedSPILoader.getService(DatabaseType.class, "MySQL"), new ConfigurationProperties(new Properties()), null).getPolicy(IdentifierScope.TABLE);
+ IdentifierCasePolicy actual = IdentifierCasePolicyResolver.resolveProtocol(TypedSPILoader.getService(DatabaseType.class, "MySQL"), new ConfigurationProperties(new Properties()))
+ .getPolicy(IdentifierScope.TABLE);
assertTrue(actual.matches("Foo", "foo", QuoteCharacter.NONE));
+ assertTrue(actual.matches("Foo", "foo", QuoteCharacter.BACK_QUOTE));
}
private Properties createProperties(final String value) {
diff --git a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/database/metadata/jdbc/MCPJdbcDatabaseProfileLoader.java b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/database/metadata/jdbc/MCPJdbcDatabaseProfileLoader.java
index 58632b6d7e0..f09564e64cb 100644
--- a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/database/metadata/jdbc/MCPJdbcDatabaseProfileLoader.java
+++ b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/database/metadata/jdbc/MCPJdbcDatabaseProfileLoader.java
@@ -91,7 +91,7 @@ public final class MCPJdbcDatabaseProfileLoader {
private IdentifierCasePolicySet resolveIdentifierCasePolicySet(final String databaseName, final DatabaseType databaseType,
final RuntimeDatabaseConfiguration runtimeDatabaseConfig) {
- return new IdentifierCasePolicyResolver().resolve(databaseType, new ConfigurationProperties(new Properties()),
+ return IdentifierCasePolicyResolver.resolveStorage(databaseType, new ConfigurationProperties(new Properties()),
new RuntimeDatabaseDataSource(databaseName, runtimeDatabaseConfig));
}
diff --git a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/database/metadata/jdbc/MCPJdbcDatabaseProfileLoaderTest.java b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/database/metadata/jdbc/MCPJdbcDatabaseProfileLoaderTest.java
index 112c38c34bc..efcc8c4ad7e 100644
--- a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/database/metadata/jdbc/MCPJdbcDatabaseProfileLoaderTest.java
+++ b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/database/metadata/jdbc/MCPJdbcDatabaseProfileLoaderTest.java
@@ -27,7 +27,6 @@ import org.apache.shardingsphere.infra.metadata.identifier.IdentifierCasePolicyR
import org.apache.shardingsphere.mcp.support.database.metadata.TransactionCapability;
import org.apache.shardingsphere.mcp.support.fixture.SupportDatabaseTypeFactoryMocker;
import org.junit.jupiter.api.Test;
-import org.mockito.MockedConstruction;
import org.mockito.MockedStatic;
import javax.sql.DataSource;
@@ -45,7 +44,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.mockConstruction;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
@@ -59,8 +57,8 @@ class MCPJdbcDatabaseProfileLoaderTest {
IdentifierCasePolicySet expectedIdentifierCasePolicySet = IdentifierCasePolicyFactory.newSensitivePolicySet();
try (
MockedStatic<DatabaseTypeFactory> ignored = SupportDatabaseTypeFactoryMocker.mockByConnectionMetadata();
- MockedConstruction<IdentifierCasePolicyResolver> ignoredResolver = mockConstruction(IdentifierCasePolicyResolver.class,
- (mock, context) -> when(mock.resolve(any(), any(), any())).thenReturn(expectedIdentifierCasePolicySet))) {
+ MockedStatic<IdentifierCasePolicyResolver> ignoredResolver = mockStatic(IdentifierCasePolicyResolver.class)) {
+ ignoredResolver.when(() -> IdentifierCasePolicyResolver.resolveStorage(any(), any(), any())).thenReturn(expectedIdentifierCasePolicySet);
RuntimeDatabaseProfile actual =
new MCPJdbcDatabaseProfileLoader().load("logic_db", createRuntimeDatabaseConfiguration(SupportDatabaseTypeFactoryMocker.createJdbcUrl("FixtureDB"), "1.0", true, true));
assertThat(actual.getDatabase(), is("logic_db"));
@@ -108,12 +106,12 @@ class MCPJdbcDatabaseProfileLoaderTest {
firstConnection, IdentifierCasePolicyFactory.newSensitivePolicySet(), secondConnection, IdentifierCasePolicyFactory.newInsensitivePolicySet());
try (
MockedStatic<DatabaseTypeFactory> ignored = SupportDatabaseTypeFactoryMocker.mockByConnectionMetadata();
- MockedConstruction<IdentifierCasePolicyResolver> ignoredResolver = mockConstruction(IdentifierCasePolicyResolver.class,
- (mock, context) -> when(mock.resolve(any(), any(), any())).thenAnswer(invocation -> {
- try (Connection connection = invocation.getArgument(2, DataSource.class).getConnection()) {
- return policies.get(connection);
- }
- }))) {
+ MockedStatic<IdentifierCasePolicyResolver> ignoredResolver = mockStatic(IdentifierCasePolicyResolver.class)) {
+ ignoredResolver.when(() -> IdentifierCasePolicyResolver.resolveStorage(any(), any(), any())).thenAnswer(invocation -> {
+ try (Connection connection = invocation.getArgument(2, DataSource.class).getConnection()) {
+ return policies.get(connection);
+ }
+ });
Map<String, RuntimeDatabaseProfile> actual = new MCPJdbcDatabaseProfileLoader().load(runtimeDatabases);
assertFalse(actual.get("first_db").getIdentifierCasePolicySet().getPolicy(IdentifierScope.TABLE).matches("phone", "Phone", QuoteCharacter.NONE));
assertTrue(actual.get("second_db").getIdentifierCasePolicySet().getPolicy(IdentifierScope.TABLE).matches("phone", "Phone", QuoteCharacter.NONE));
@@ -134,15 +132,15 @@ class MCPJdbcDatabaseProfileLoaderTest {
.thenThrow(RuntimeDatabaseConnectionException.connectionFailed("logic_db", connectionFailure));
try (
MockedStatic<DatabaseTypeFactory> ignored = SupportDatabaseTypeFactoryMocker.mockByConnectionMetadata();
- MockedConstruction<IdentifierCasePolicyResolver> ignoredResolver = mockConstruction(IdentifierCasePolicyResolver.class,
- (mock, context) -> when(mock.resolve(any(), any(), any())).thenAnswer(invocation -> {
- try (Connection ignoredConnection = invocation.getArgument(2, DataSource.class).getConnection()) {
- return IdentifierCasePolicyFactory.newSensitivePolicySet();
- } catch (final SQLException ex) {
- assertThat(ex, is(connectionFailure));
- return IdentifierCasePolicyFactory.newInsensitivePolicySet();
- }
- }))) {
+ MockedStatic<IdentifierCasePolicyResolver> ignoredResolver = mockStatic(IdentifierCasePolicyResolver.class)) {
+ ignoredResolver.when(() -> IdentifierCasePolicyResolver.resolveStorage(any(), any(), any())).thenAnswer(invocation -> {
+ try (Connection ignoredConnection = invocation.getArgument(2, DataSource.class).getConnection()) {
+ return IdentifierCasePolicyFactory.newSensitivePolicySet();
+ } catch (final SQLException ex) {
+ assertThat(ex, is(connectionFailure));
+ return IdentifierCasePolicyFactory.newInsensitivePolicySet();
+ }
+ });
RuntimeDatabaseProfile actual = new MCPJdbcDatabaseProfileLoader().load("logic_db", runtimeDatabaseConfig);
assertTrue(actual.getIdentifierCasePolicySet().getPolicy(IdentifierScope.TABLE).matches("phone", "Phone", QuoteCharacter.NONE));
verify(runtimeDatabaseConfig, times(2)).openConnection("logic_db");
diff --git a/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/manager/resource/StorageUnitManagerTest.java b/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/manager/resource/StorageUnitManagerTest.java
index 6b421260cd4..7ea570598c0 100644
--- a/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/manager/resource/StorageUnitManagerTest.java
+++ b/mode/core/src/test/java/org/apache/shardingsphere/mode/metadata/manager/resource/StorageUnitManagerTest.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.mode.metadata.manager.resource;
import lombok.SneakyThrows;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
import org.apache.shardingsphere.infra.config.props.temporary.TemporaryConfigurationProperties;
import org.apache.shardingsphere.infra.instance.ComputeNodeInstanceContext;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
@@ -27,6 +28,7 @@ import org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaDa
import org.apache.shardingsphere.infra.metadata.database.resource.node.StorageNode;
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
import org.apache.shardingsphere.mode.metadata.factory.MetaDataContextsFactory;
import org.apache.shardingsphere.mode.metadata.persist.MetaDataPersistFacade;
@@ -76,8 +78,10 @@ class StorageUnitManagerTest {
when(resourceSwitchManager.switchByRegisterStorageUnit(any(ResourceMetaData.class), any(Map.class), anyBoolean())).thenReturn(switchingResource);
ShardingSphereDatabase reloadDatabase = mock(ShardingSphereDatabase.class);
when(reloadDatabase.getAllSchemas()).thenReturn(Collections.singleton(new ShardingSphereSchema("foo_schema", mock(DatabaseType.class))));
+ when(reloadDatabase.getProtocolType()).thenReturn(TypedSPILoader.getService(DatabaseType.class, "FIXTURE"));
MetaDataContexts reloadMetaDataContexts = mock(MetaDataContexts.class, RETURNS_DEEP_STUBS);
when(reloadMetaDataContexts.getMetaData().getDatabase(DATABASE_NAME)).thenReturn(reloadDatabase);
+ when(reloadMetaDataContexts.getMetaData().getProps()).thenReturn(new ConfigurationProperties(new Properties()));
try (
MockedConstruction<MetaDataContextsFactory> ignored = mockConstruction(MetaDataContextsFactory.class,
(mock, context) -> when(mock.createBySwitchResource(DATABASE_NAME, switchingResource, metaDataContexts)).thenReturn(reloadMetaDataContexts))) {
@@ -127,6 +131,7 @@ class StorageUnitManagerTest {
ShardingSphereDatabase reloadDatabase = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS);
MetaDataContexts reloadMetaDataContexts = mock(MetaDataContexts.class, RETURNS_DEEP_STUBS);
when(reloadMetaDataContexts.getMetaData().getDatabase(DATABASE_NAME)).thenReturn(reloadDatabase);
+ when(reloadMetaDataContexts.getMetaData().getProps()).thenReturn(new ConfigurationProperties(new Properties()));
when(reloadDatabase.getAllSchemas()).thenReturn(Collections.singleton(new ShardingSphereSchema("foo_schema", mock(DatabaseType.class))));
try (
MockedConstruction<MetaDataContextsFactory> ignored = mockConstruction(MetaDataContextsFactory.class,
@@ -158,6 +163,7 @@ class StorageUnitManagerTest {
ShardingSphereDatabase reloadDatabase = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS);
MetaDataContexts reloadMetaDataContexts = mock(MetaDataContexts.class, RETURNS_DEEP_STUBS);
when(reloadMetaDataContexts.getMetaData().getDatabase(DATABASE_NAME)).thenReturn(reloadDatabase);
+ when(reloadMetaDataContexts.getMetaData().getProps()).thenReturn(new ConfigurationProperties(new Properties()));
when(reloadDatabase.getAllSchemas()).thenReturn(Collections.singleton(new ShardingSphereSchema("foo_schema", mock(DatabaseType.class))));
try (
MockedConstruction<MetaDataContextsFactory> ignored = mockConstruction(MetaDataContextsFactory.class,