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 5200b7d0a15 Enforce case sensitivity for mysql columns, indexes, and
constraints (#39210)
5200b7d0a15 is described below
commit 5200b7d0a155dbea6043f889d5d2179a3fb2dd92
Author: Haoran Meng <[email protected]>
AuthorDate: Wed Jul 22 17:07:49 2026 +0800
Enforce case sensitivity for mysql columns, indexes, and constraints
(#39210)
* Enforce case sensitivity for mysql columns, indexes, and constraints
* Replace IdentifierCasePolicySet with DatabaseIdentifierContext for mcp
---
.../MySQLIdentifierCasePolicyProvider.java | 20 ++++++++---
.../MySQLIdentifierCasePolicyProviderTest.java | 16 +++++----
.../DatabaseIdentifierContextFactory.java | 16 +++++++++
.../DatabaseIdentifierContextFactoryTest.java | 9 +++++
.../MCPCompletionSpecificationFactoryTest.java | 7 ++--
.../handler/execute/MCPSQLExecutionFacade.java | 13 +++----
.../core/workflow/WorkflowProxyQueryService.java | 2 +-
.../core/completion/MCPCompletionServiceTest.java | 7 ++--
.../handler/MetadataCompletionHandlerTest.java | 7 ++--
.../metadata/MetadataResourceHandlerTest.java | 10 ++++--
.../MetadataResourcePayloadMapperTest.java | 4 ++-
.../handler/execute/MCPSQLExecutionFacadeTest.java | 5 +--
.../metadata/SearchMetadataPayloadBuilderTest.java | 4 ++-
.../workflow/WorkflowProxyQueryServiceTest.java | 5 +--
.../EncryptWorkflowPlanningServiceTest.java | 4 ++-
.../service/MaskWorkflowPlanningServiceTest.java | 4 ++-
.../database/capability/MCPDatabaseCapability.java | 6 ++--
.../jdbc/MCPJdbcDatabaseProfileLoader.java | 12 +++----
.../metadata/jdbc/RuntimeDatabaseProfile.java | 4 +--
.../service/RuntimeDatabaseValidationService.java | 41 ++++++++++------------
.../support/workflow/service/WorkflowSQLUtils.java | 12 ++++---
.../MCPDatabaseCapabilityProviderTest.java | 13 +++----
.../jdbc/MCPJdbcDatabaseProfileLoaderTest.java | 39 ++++++++++----------
.../jdbc/MCPJdbcMetadataLoaderFailureTest.java | 4 ++-
.../RuntimeDatabaseValidationServiceTest.java | 16 ++++++---
.../WorkflowPlanningContextValidatorTest.java | 4 ++-
.../service/WorkflowPlanningSupportTest.java | 4 ++-
.../workflow/service/WorkflowSQLUtilsTest.java | 11 +++---
28 files changed, 190 insertions(+), 109 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 bb7ed87faf0..678d0bb3460 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,20 +41,32 @@ public final class MySQLIdentifierCasePolicyProvider
implements IdentifierCasePo
@Override
public IdentifierCasePolicySet provide(final
IdentifierCasePolicyProviderContext context) {
if (null == context.getDataSource()) {
- return IdentifierCasePolicyFactory.newMySQLInsensitivePolicySet();
+ return
createStorageObjectSensitivePolicySet(IdentifierCasePolicyFactory.newMySQLInsensitivePolicySet());
}
try (Connection connection = context.getDataSource().getConnection()) {
if (null == connection) {
- return IdentifierCasePolicyFactory.newInsensitivePolicySet();
+ return
createStorageObjectSensitivePolicySet(IdentifierCasePolicyFactory.newInsensitivePolicySet());
}
try (
PreparedStatement preparedStatement =
connection.prepareStatement(QUERY_LOWER_CASE_TABLE_NAMES);
ResultSet resultSet = preparedStatement.executeQuery()) {
- return resultSet.next() ? createPolicySet(resultSet.getInt(1))
: IdentifierCasePolicyFactory.newInsensitivePolicySet();
+ return createStorageObjectSensitivePolicySet(resultSet.next()
? createPolicySet(resultSet.getInt(1)) :
IdentifierCasePolicyFactory.newInsensitivePolicySet());
}
} catch (final SQLException ignored) {
- return IdentifierCasePolicyFactory.newInsensitivePolicySet();
+ return
createStorageObjectSensitivePolicySet(IdentifierCasePolicyFactory.newInsensitivePolicySet());
+ }
+ }
+
+ private IdentifierCasePolicySet
createStorageObjectSensitivePolicySet(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);
+ return new
IdentifierCasePolicySet(policySet.getPolicy(IdentifierScope.TABLE),
scopedPolicies);
}
private IdentifierCasePolicySet createPolicySet(final int
lowerCaseTableNames) {
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 3df6585b7c8..d69368f9b90 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
@@ -57,10 +57,13 @@ class MySQLIdentifierCasePolicyProviderTest {
@MethodSource("provideArguments")
void assertProvide(final String name, final
IdentifierCasePolicyProviderContext context, final LookupMode
expectedQuotedLookupMode,
final LookupMode expectedUnquotedLookupMode, final
boolean expectedMatch) {
- IdentifierCasePolicy actual =
provider.provide(context).getPolicy(IdentifierScope.TABLE);
- assertThat(actual.getLookupMode(QuoteCharacter.BACK_QUOTE),
is(expectedQuotedLookupMode));
- assertThat(actual.getLookupMode(QuoteCharacter.NONE),
is(expectedUnquotedLookupMode));
- assertThat(actual.matches("foo", "FOO", QuoteCharacter.NONE),
is(expectedMatch));
+ IdentifierCasePolicySet actual = provider.provide(context);
+
assertThat(actual.getPolicy(IdentifierScope.TABLE).getLookupMode(QuoteCharacter.BACK_QUOTE),
is(expectedQuotedLookupMode));
+
assertThat(actual.getPolicy(IdentifierScope.TABLE).getLookupMode(QuoteCharacter.NONE),
is(expectedUnquotedLookupMode));
+ assertThat(actual.getPolicy(IdentifierScope.TABLE).matches("foo",
"FOO", QuoteCharacter.NONE), is(expectedMatch));
+
assertThat(actual.getPolicy(IdentifierScope.COLUMN).normalize("FooColumn"),
is("FooColumn"));
+
assertThat(actual.getPolicy(IdentifierScope.INDEX).normalize("FooIndex"),
is("FooIndex"));
+
assertThat(actual.getPolicy(IdentifierScope.CONSTRAINT).normalize("FooConstraint"),
is("FooConstraint"));
}
@Test
@@ -93,8 +96,9 @@ class MySQLIdentifierCasePolicyProviderTest {
assertThat(actual.getPolicy(IdentifierScope.SCHEMA).matches("foo_schema",
"FOO_SCHEMA", QuoteCharacter.NONE), is(Boolean.TRUE));
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.TRUE));
- assertThat(actual.getPolicy(IdentifierScope.INDEX).matches("foo_idx",
"FOO_IDX", QuoteCharacter.NONE), is(Boolean.TRUE));
+ 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));
}
private static Object getDefaultValue(final Class<?> returnType) {
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 ebb79be0547..8112db798be 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
@@ -32,10 +32,12 @@ import
org.apache.shardingsphere.infra.config.props.temporary.TemporaryConfigura
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.Map;
+import java.util.Properties;
/**
* Database identifier context factory.
@@ -52,6 +54,20 @@ public final class DatabaseIdentifierContextFactory {
return new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet());
}
+ /**
+ * Create identifier context for a single database type and data source.
+ *
+ * @param databaseType database type
+ * @param dataSource data source
+ * @return identifier context
+ */
+ public static DatabaseIdentifierContext create(final DatabaseType
databaseType, final DataSource dataSource) {
+ IdentifierCasePolicySet protocolPolicySet =
IdentifierCasePolicyResolver.resolveProtocol(databaseType);
+ IdentifierCasePolicySet storagePolicySet =
IdentifierCasePolicyResolver.resolveStorage(databaseType, dataSource);
+ IdentifierCasePolicySet metaDataPolicySet =
createMetaDataPolicySet(protocolPolicySet, storagePolicySet, new
ConfigurationProperties(new Properties()));
+ return new DatabaseIdentifierContext(protocolPolicySet,
storagePolicySet, metaDataPolicySet, false);
+ }
+
/**
* Create identifier context with protocol-aware identifier policies.
*
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 33486a9b3a8..cac5d8909dd 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
@@ -100,6 +100,15 @@ class DatabaseIdentifierContextFactoryTest {
assertTrue(actualRule.matches("Foo", "foo", QuoteCharacter.NONE));
}
+ @Test
+ void assertCreateWithSingleDatabase() {
+ DatabaseIdentifierContext actual =
DatabaseIdentifierContextFactory.create(MYSQL_DATABASE_TYPE, new
LowerCaseTableNamesDataSource(0));
+ assertThat(actual.normalizeStorage(IdentifierScope.COLUMN, new
IdentifierValue("FooColumn")), is("FooColumn"));
+ assertTrue(actual.matchesMetaData(IdentifierScope.COLUMN,
"foo_column", new IdentifierValue("FOO_COLUMN")));
+ assertFalse(actual.matchesMetaData(IdentifierScope.TABLE, "foo_table",
new IdentifierValue("FOO_TABLE")));
+ assertFalse(actual.isHeterogeneousTableLookupEnabled());
+ }
+
@ParameterizedTest(name = "{0}")
@MethodSource("createWithProtocolTypeAndPropsArguments")
void assertCreateWithProtocolTypeAndProps(final String name, final
DatabaseType protocolType, final ConfigurationProperties props, final
LookupMode expectedLookupMode,
diff --git
a/mcp/bootstrap/src/test/java/org/apache/shardingsphere/mcp/bootstrap/transport/capability/completion/MCPCompletionSpecificationFactoryTest.java
b/mcp/bootstrap/src/test/java/org/apache/shardingsphere/mcp/bootstrap/transport/capability/completion/MCPCompletionSpecificationFactoryTest.java
index ee8bb6d1ec5..d28d73cf6ae 100644
---
a/mcp/bootstrap/src/test/java/org/apache/shardingsphere/mcp/bootstrap/transport/capability/completion/MCPCompletionSpecificationFactoryTest.java
+++
b/mcp/bootstrap/src/test/java/org/apache/shardingsphere/mcp/bootstrap/transport/capability/completion/MCPCompletionSpecificationFactoryTest.java
@@ -21,6 +21,7 @@ import
org.apache.shardingsphere.mcp.api.session.MCPSessionIdentity;
import
org.apache.shardingsphere.mcp.support.database.metadata.TransactionCapability;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyFactory;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import
io.modelcontextprotocol.server.McpServerFeatures.SyncCompletionSpecification;
import io.modelcontextprotocol.server.McpSyncServerExchange;
import io.modelcontextprotocol.spec.McpError;
@@ -200,8 +201,10 @@ class MCPCompletionSpecificationFactoryTest {
private MCPRuntimeContext createRuntimeContext(final
WorkflowSessionContext workflowSessionContext) {
MCPDatabaseCapabilityProvider databaseCapabilityProvider =
mock(MCPDatabaseCapabilityProvider.class);
when(databaseCapabilityProvider.getDatabaseProfiles()).thenReturn(List.of(
- new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newInsensitivePolicySet()),
- new RuntimeDatabaseProfile("warehouse", "FixtureWarehouseDB",
"2.0", TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newInsensitivePolicySet())));
+ new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet())),
+ new RuntimeDatabaseProfile("warehouse", "FixtureWarehouseDB",
"2.0", TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet()))));
MCPSessionManager sessionManager = new MCPSessionManager(Map.of());
sessionManager.createSession(new MCPSessionIdentity("session-1", "",
"", Map.of()));
MCPRuntimeContext result = mock(MCPRuntimeContext.class);
diff --git
a/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPSQLExecutionFacade.java
b/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPSQLExecutionFacade.java
index afa73276c5a..8ef4301b41b 100644
---
a/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPSQLExecutionFacade.java
+++
b/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPSQLExecutionFacade.java
@@ -19,9 +19,9 @@ package
org.apache.shardingsphere.mcp.core.tool.handler.execute;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
-import org.apache.shardingsphere.infra.exception.ShardingSpherePreconditions;
-import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicy;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierScope;
+import org.apache.shardingsphere.infra.exception.ShardingSpherePreconditions;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import org.apache.shardingsphere.mcp.api.exception.MCPInvalidRequestException;
import org.apache.shardingsphere.mcp.api.exception.MCPQueryFailedException;
import org.apache.shardingsphere.mcp.api.exception.MCPUnsupportedException;
@@ -40,6 +40,7 @@ import
org.apache.shardingsphere.mcp.support.database.exception.StatementClassNo
import
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureExecutionFacade;
import
org.apache.shardingsphere.mcp.support.database.tool.request.SQLExecutionRequest;
import
org.apache.shardingsphere.mcp.support.database.tool.result.SQLExecutionResult;
+import
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
import java.util.Optional;
@@ -154,18 +155,18 @@ public final class MCPSQLExecutionFacade implements
MCPFeatureExecutionFacade {
if (SchemaExecutionSemantics.BEST_EFFORT ==
databaseCapability.getSchemaExecutionSemantics()) {
return;
}
- IdentifierCasePolicy identifierCasePolicy =
databaseCapability.getIdentifierCasePolicySet().getPolicy(IdentifierScope.SCHEMA);
for (SQLStatementObjectName each :
classificationResult.getReferencedObjects()) {
- if (isCrossSchemaReference(each, executionRequest.getDatabase(),
identifierCasePolicy)) {
+ if (isCrossSchemaReference(each, executionRequest.getDatabase(),
databaseCapability.getIdentifierContext())) {
throw recordFailure(executionRequest,
classificationResult.getTraceStatementMarker(), new MCPInvalidRequestException(
String.format("Cross-schema SQL is not supported for
database `%s`: `%s`.", executionRequest.getDatabase(), each.getObjectName())));
}
}
}
- private boolean isCrossSchemaReference(final SQLStatementObjectName
objectName, final String databaseName, final IdentifierCasePolicy
identifierCasePolicy) {
+ private boolean isCrossSchemaReference(final SQLStatementObjectName
objectName, final String databaseName, final DatabaseIdentifierContext
identifierContext) {
return (objectName.isQualified() || objectName.isNamespaceTarget())
- && !identifierCasePolicy.matches(databaseName,
objectName.getFirstIdentifier(), objectName.getFirstIdentifierQuoteCharacter());
+ && !identifierContext.matchesMetaData(IdentifierScope.SCHEMA,
databaseName,
+ new IdentifierValue(objectName.getFirstIdentifier(),
objectName.getFirstIdentifierQuoteCharacter()));
}
private <T extends RuntimeException> T recordFailure(final
SQLExecutionRequest executionRequest, final String statementMarker, final T ex)
{
diff --git
a/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/workflow/WorkflowProxyQueryService.java
b/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/workflow/WorkflowProxyQueryService.java
index d61efa1e7f6..b27d2216dcf 100644
---
a/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/workflow/WorkflowProxyQueryService.java
+++
b/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/workflow/WorkflowProxyQueryService.java
@@ -79,7 +79,7 @@ public final class WorkflowProxyQueryService implements
MCPFeatureQueryFacade {
@Override
public boolean isSameIdentifier(final String databaseName, final
IdentifierScope identifierScope, final String identifier, final String
existingIdentifier) {
- return
WorkflowSQLUtils.isSameIdentifier(getDatabaseCapability(databaseName).getIdentifierCasePolicySet().getPolicy(identifierScope),
identifier, existingIdentifier);
+ return
WorkflowSQLUtils.isSameIdentifier(getDatabaseCapability(databaseName).getIdentifierContext(),
identifierScope, identifier, existingIdentifier);
}
private MCPDatabaseQueryFailedException createQueryFailedException(final
String databaseName, final SQLException cause) {
diff --git
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/completion/MCPCompletionServiceTest.java
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/completion/MCPCompletionServiceTest.java
index 5babe7f81fb..879f4bb1f28 100644
---
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/completion/MCPCompletionServiceTest.java
+++
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/completion/MCPCompletionServiceTest.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.mcp.core.completion;
import
org.apache.shardingsphere.mcp.support.database.metadata.TransactionCapability;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyFactory;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import org.apache.shardingsphere.infra.spi.ShardingSphereServiceLoader;
import
org.apache.shardingsphere.mcp.api.capability.completion.MCPCompletionHandler;
import
org.apache.shardingsphere.mcp.api.capability.completion.MCPCompletionHandlerResult;
@@ -215,8 +216,10 @@ class MCPCompletionServiceTest {
private MCPRuntimeContext createRuntimeContext(final
WorkflowSessionContext workflowSessionContext) {
MCPDatabaseCapabilityProvider databaseCapabilityProvider =
mock(MCPDatabaseCapabilityProvider.class);
when(databaseCapabilityProvider.getDatabaseProfiles()).thenReturn(List.of(
- new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newInsensitivePolicySet()),
- new RuntimeDatabaseProfile("warehouse", "FixtureWarehouseDB",
"2.0", TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newInsensitivePolicySet())));
+ new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet())),
+ new RuntimeDatabaseProfile("warehouse", "FixtureWarehouseDB",
"2.0", TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet()))));
MCPSessionManager sessionManager = new
MCPSessionManager(Collections.emptyMap());
sessionManager.createSession(new MCPSessionIdentity("session-1", "",
"", Map.of()));
MCPRuntimeContext result = mock(MCPRuntimeContext.class);
diff --git
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/completion/handler/MetadataCompletionHandlerTest.java
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/completion/handler/MetadataCompletionHandlerTest.java
index e4df84a950e..382999e1e4e 100644
---
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/completion/handler/MetadataCompletionHandlerTest.java
+++
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/completion/handler/MetadataCompletionHandlerTest.java
@@ -18,6 +18,7 @@
package org.apache.shardingsphere.mcp.core.completion.handler;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyFactory;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import
org.apache.shardingsphere.database.connector.core.metadata.database.enums.TableType;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereIndex;
@@ -263,11 +264,13 @@ class MetadataCompletionHandlerTest {
}
private RuntimeDatabaseProfile createDatabaseProfile(final String
database) {
- return new RuntimeDatabaseProfile(database, "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newInsensitivePolicySet());
+ return new RuntimeDatabaseProfile(database, "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet()));
}
private RuntimeDatabaseProfile createDatabaseMetadata() {
- return new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newInsensitivePolicySet());
+ return new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet()));
}
private ShardingSphereSchema createSchemaMetadata() {
diff --git
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/resource/handler/metadata/MetadataResourceHandlerTest.java
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/resource/handler/metadata/MetadataResourceHandlerTest.java
index 158849d6042..ebc15274fc0 100644
---
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/resource/handler/metadata/MetadataResourceHandlerTest.java
+++
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/resource/handler/metadata/MetadataResourceHandlerTest.java
@@ -18,6 +18,7 @@
package org.apache.shardingsphere.mcp.core.resource.handler.metadata;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyFactory;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import org.apache.shardingsphere.mcp.api.payload.MCPSuccessPayload;
import
org.apache.shardingsphere.mcp.api.capability.resource.MCPResourceURIVariables;
import
org.apache.shardingsphere.mcp.api.capability.resource.MCPResourceDescriptor;
@@ -94,7 +95,8 @@ class MetadataResourceHandlerTest {
void assertHandleListResourceWithEmptyScope() {
MetadataResourceHandler handler = new
MetadataResourceHandler("shardingsphere://databases/{database}/schemas",
(requestContext, uriVariables) -> List.of());
MCPSuccessPayload actual =
handler.handle(createDatabaseContext(Optional.of(
- new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newInsensitivePolicySet()))),
+ new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet())))),
new MCPResourceURIVariables(Map.of("database", "logic_db")));
Map<?, ?> actualEmptyState = (Map<?, ?>)
actual.toPayload().get("empty_state");
assertThat(actualEmptyState.get("category"), is("empty_scope"));
@@ -108,7 +110,8 @@ class MetadataResourceHandlerTest {
void assertHandleSchemaDetailResourceNotVisible() {
MetadataResourceHandler handler = new
MetadataResourceHandler("shardingsphere://databases/{database}/schemas/{schema}",
(requestContext, uriVariables) -> List.of());
MCPSuccessPayload actual =
handler.handle(createDatabaseContext(Optional.of(
- new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newInsensitivePolicySet()))),
+ new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet())))),
new MCPResourceURIVariables(Map.of("database", "logic_db",
"schema", "missing_schema")));
Map<?, ?> actualEmptyState = (Map<?, ?>)
actual.toPayload().get("empty_state");
assertThat(actualEmptyState.get("category"), is("schema_not_visible"));
@@ -121,7 +124,8 @@ class MetadataResourceHandlerTest {
void assertHandleObjectDetailResourceNotVisible() {
MetadataResourceHandler handler = new
MetadataResourceHandler("shardingsphere://databases/{database}/schemas/{schema}/tables/{table}",
(requestContext, uriVariables) -> List.of());
MCPSuccessPayload actual =
handler.handle(createDatabaseContext(Optional.of(
- new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newInsensitivePolicySet()))),
+ new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet())))),
new MCPResourceURIVariables(Map.of("database", "logic_db",
"schema", "public", "table", "missing_table")));
Map<?, ?> actualEmptyState = (Map<?, ?>)
actual.toPayload().get("empty_state");
assertThat(actualEmptyState.get("category"), is("object_not_visible"));
diff --git
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/resource/handler/metadata/MetadataResourcePayloadMapperTest.java
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/resource/handler/metadata/MetadataResourcePayloadMapperTest.java
index 79a8c112190..e82f9671252 100644
---
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/resource/handler/metadata/MetadataResourcePayloadMapperTest.java
+++
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/resource/handler/metadata/MetadataResourcePayloadMapperTest.java
@@ -20,6 +20,7 @@ package
org.apache.shardingsphere.mcp.core.resource.handler.metadata;
import
org.apache.shardingsphere.mcp.support.database.metadata.TransactionCapability;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyFactory;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import
org.apache.shardingsphere.database.connector.core.metadata.database.enums.TableType;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereIndex;
@@ -52,7 +53,8 @@ class MetadataResourcePayloadMapperTest {
when(metadataQueryFacade.querySchemas("logic_db")).thenReturn(List.of(createSchemaMetadata()));
List<?> actual = new
MetadataResourcePayloadMapper(metadataQueryFacade, new
MCPResourceURIVariables(Map.of()), true)
.map(createMetadata("logical-database"), List.of(
- new RuntimeDatabaseProfile("logic_db", "FixtureDB",
"1.0", TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newInsensitivePolicySet())));
+ new RuntimeDatabaseProfile("logic_db", "FixtureDB",
"1.0", TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet()))));
Map<?, ?> actualDatabase = (Map<?, ?>) actual.getFirst();
assertThat(actualDatabase.get("database"), is("logic_db"));
assertThat(actualDatabase.get("databaseType"), is("FixtureDB"));
diff --git
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPSQLExecutionFacadeTest.java
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPSQLExecutionFacadeTest.java
index b45988a96ba..a10508d1b39 100644
---
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPSQLExecutionFacadeTest.java
+++
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPSQLExecutionFacadeTest.java
@@ -19,6 +19,7 @@ package
org.apache.shardingsphere.mcp.core.tool.handler.execute;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyFactory;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicySet;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import org.apache.shardingsphere.mcp.api.exception.MCPInvalidRequestException;
import org.apache.shardingsphere.mcp.api.exception.MCPQueryFailedException;
import
org.apache.shardingsphere.mcp.core.protocol.exception.MCPBannedSQLStatementException;
@@ -349,7 +350,7 @@ class MCPSQLExecutionFacadeTest {
MCPDatabaseCapabilityProvider capabilityProvider =
mock(MCPDatabaseCapabilityProvider.class);
MCPSessionExecutionCoordinator coordinator =
mock(MCPSessionExecutionCoordinator.class);
MCPDatabaseCapability capability =
createCapability(Set.of(SupportedMCPStatement.QUERY));
-
when(capability.getIdentifierCasePolicySet()).thenReturn(identifierCasePolicySet);
+ when(capability.getIdentifierContext()).thenReturn(new
DatabaseIdentifierContext(identifierCasePolicySet));
mockSessionLock(coordinator);
when(capabilityProvider.provide("logic_db")).thenReturn(Optional.of(capability));
MCPSQLExecutionFacade facade = createFacade(capabilityProvider,
coordinator, mock(MCPJdbcTransactionStatementExecutor.class),
mock(MCPJdbcStatementExecutor.class),
@@ -488,7 +489,7 @@ class MCPSQLExecutionFacadeTest {
MCPDatabaseCapability result = mock(MCPDatabaseCapability.class);
when(result.getSupportedStatementClasses()).thenReturn(supportedStatementClasses);
when(result.getSchemaExecutionSemantics()).thenReturn(schemaExecutionSemantics);
-
when(result.getIdentifierCasePolicySet()).thenReturn(IdentifierCasePolicyFactory.newInsensitivePolicySet());
+ when(result.getIdentifierContext()).thenReturn(new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet()));
when(result.getDatabaseType()).thenReturn("MySQL");
return result;
}
diff --git
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/metadata/SearchMetadataPayloadBuilderTest.java
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/metadata/SearchMetadataPayloadBuilderTest.java
index d18c0f3e8da..347b6215db1 100644
---
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/metadata/SearchMetadataPayloadBuilderTest.java
+++
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/metadata/SearchMetadataPayloadBuilderTest.java
@@ -20,6 +20,7 @@ package
org.apache.shardingsphere.mcp.core.tool.handler.metadata;
import
org.apache.shardingsphere.mcp.support.database.metadata.TransactionCapability;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyFactory;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
import org.apache.shardingsphere.mcp.core.tool.request.MetadataSearchRequest;
import org.apache.shardingsphere.mcp.core.tool.payload.MetadataSearchHit;
@@ -138,7 +139,8 @@ class SearchMetadataPayloadBuilderTest {
when(result.getMetadataQueryFacade()).thenReturn(metadataQueryFacade);
when(result.getCapabilityFacade()).thenReturn(capabilityFacade);
when(metadataQueryFacade.queryDatabases()).thenReturn(
- List.of(new RuntimeDatabaseProfile("logic_db", "FixtureDB",
"1.0", TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newInsensitivePolicySet())));
+ List.of(new RuntimeDatabaseProfile("logic_db", "FixtureDB",
"1.0", TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet()))));
when(metadataQueryFacade.querySchema("logic_db",
"public")).thenReturn(Optional.of(mock(ShardingSphereSchema.class)));
when(capabilityFacade.findDatabaseProfile("logic_db")).thenReturn(Optional.of(mock(RuntimeDatabaseProfile.class)));
return result;
diff --git
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/workflow/WorkflowProxyQueryServiceTest.java
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/workflow/WorkflowProxyQueryServiceTest.java
index 7396a8186dd..a35cc2dd38d 100644
---
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/workflow/WorkflowProxyQueryServiceTest.java
+++
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/workflow/WorkflowProxyQueryServiceTest.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.mcp.core.workflow;
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.infra.metadata.identifier.DatabaseIdentifierContext;
import org.apache.shardingsphere.mcp.api.exception.MCPUnavailableException;
import org.apache.shardingsphere.mcp.core.session.MCPSessionManager;
import
org.apache.shardingsphere.mcp.support.database.capability.MCPDatabaseCapability;
@@ -144,9 +145,9 @@ class WorkflowProxyQueryServiceTest {
MCPDatabaseCapability databaseCapability =
mock(MCPDatabaseCapability.class);
when(databaseCapability.getDatabaseType()).thenReturn(databaseType);
IdentifierCasePolicySet insensitivePolicySet =
IdentifierCasePolicyFactory.newInsensitivePolicySet();
- when(databaseCapability.getIdentifierCasePolicySet()).thenReturn(new
IdentifierCasePolicySet(
+ when(databaseCapability.getIdentifierContext()).thenReturn(new
DatabaseIdentifierContext(new IdentifierCasePolicySet(
IdentifierCasePolicyFactory.newSensitivePolicySet().getPolicy(IdentifierScope.TABLE),
- Map.of(IdentifierScope.COLUMN,
insensitivePolicySet.getPolicy(IdentifierScope.COLUMN))));
+ Map.of(IdentifierScope.COLUMN,
insensitivePolicySet.getPolicy(IdentifierScope.COLUMN)))));
MCPDatabaseCapabilityProvider databaseCapabilityProvider =
mock(MCPDatabaseCapabilityProvider.class);
when(databaseCapabilityProvider.provide("logic_db")).thenReturn(Optional.of(databaseCapability));
return new WorkflowProxyQueryService(new
MCPSessionManager(runtimeDatabases), databaseCapabilityProvider);
diff --git
a/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/tool/service/EncryptWorkflowPlanningServiceTest.java
b/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/tool/service/EncryptWorkflowPlanningServiceTest.java
index 5ff699c5617..b0c0cf30cb2 100644
---
a/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/tool/service/EncryptWorkflowPlanningServiceTest.java
+++
b/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/tool/service/EncryptWorkflowPlanningServiceTest.java
@@ -20,6 +20,7 @@ package
org.apache.shardingsphere.mcp.feature.encrypt.tool.service;
import
org.apache.shardingsphere.mcp.support.database.metadata.TransactionCapability;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyFactory;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import
org.apache.shardingsphere.database.connector.core.metadata.database.enums.TableType;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierScope;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
@@ -380,7 +381,8 @@ class EncryptWorkflowPlanningServiceTest {
}
private RuntimeDatabaseProfile createDatabaseMetadata() {
- return new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newInsensitivePolicySet());
+ return new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet()));
}
private ShardingSphereSchema createSchemaMetadata() {
diff --git
a/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/tool/service/MaskWorkflowPlanningServiceTest.java
b/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/tool/service/MaskWorkflowPlanningServiceTest.java
index adc99906fa0..363de26165c 100644
---
a/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/tool/service/MaskWorkflowPlanningServiceTest.java
+++
b/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/tool/service/MaskWorkflowPlanningServiceTest.java
@@ -20,6 +20,7 @@ package
org.apache.shardingsphere.mcp.feature.mask.tool.service;
import
org.apache.shardingsphere.mcp.support.database.metadata.TransactionCapability;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyFactory;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import
org.apache.shardingsphere.database.connector.core.metadata.database.enums.TableType;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierScope;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
@@ -311,7 +312,8 @@ class MaskWorkflowPlanningServiceTest {
}
private RuntimeDatabaseProfile createDatabaseMetadata() {
- return new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newInsensitivePolicySet());
+ return new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet()));
}
private ShardingSphereSchema createSchemaMetadata() {
diff --git
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/database/capability/MCPDatabaseCapability.java
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/database/capability/MCPDatabaseCapability.java
index 66deb9e09b7..775aa498e42 100644
---
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/database/capability/MCPDatabaseCapability.java
+++
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/database/capability/MCPDatabaseCapability.java
@@ -19,7 +19,7 @@ package
org.apache.shardingsphere.mcp.support.database.capability;
import lombok.Getter;
import
org.apache.shardingsphere.database.connector.core.metadata.database.metadata.option.schema.DialectSchemaSemantics;
-import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicySet;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import
org.apache.shardingsphere.mcp.support.database.metadata.TransactionCapability;
import
org.apache.shardingsphere.mcp.support.database.metadata.jdbc.RuntimeDatabaseProfile;
@@ -46,7 +46,7 @@ public final class MCPDatabaseCapability {
private final SchemaExecutionSemantics schemaExecutionSemantics;
- private final IdentifierCasePolicySet identifierCasePolicySet;
+ private final DatabaseIdentifierContext identifierContext;
MCPDatabaseCapability(final RuntimeDatabaseProfile databaseProfile, final
MCPDatabaseCapabilityOption option) {
databaseName = databaseProfile.getDatabase();
@@ -57,7 +57,7 @@ public final class MCPDatabaseCapability {
supportedStatementClasses =
createSupportedStatementClasses(transactionCapability,
option.isExplainSupported());
defaultSchemaSemantics = databaseDialect.getDefaultSchemaSemantics();
schemaExecutionSemantics =
createSchemaExecutionSemantics(defaultSchemaSemantics);
- identifierCasePolicySet = databaseProfile.getIdentifierCasePolicySet();
+ identifierContext = databaseProfile.getIdentifierContext();
}
private static SchemaExecutionSemantics
createSchemaExecutionSemantics(final DialectSchemaSemantics
defaultSchemaSemantics) {
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 edc560226c4..669d352e092 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
@@ -18,11 +18,11 @@
package org.apache.shardingsphere.mcp.support.database.metadata.jdbc;
import lombok.RequiredArgsConstructor;
-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.type.DatabaseTypeFactory;
import
org.apache.shardingsphere.infra.exception.external.ShardingSphereExternalException;
-import
org.apache.shardingsphere.infra.metadata.identifier.IdentifierCasePolicyResolver;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContextFactory;
import
org.apache.shardingsphere.mcp.support.database.metadata.TransactionCapability;
import javax.sql.DataSource;
@@ -77,7 +77,7 @@ public final class MCPJdbcDatabaseProfileLoader {
throw
RuntimeDatabaseConnectionException.connectionFailed(databaseName, ex);
}
return new RuntimeDatabaseProfile(databaseName,
databaseType.getType(), databaseVersion, transactionCapability,
- resolveIdentifierCasePolicySet(databaseName, databaseType,
runtimeDatabaseConfig));
+ createIdentifierContext(databaseName, databaseType,
runtimeDatabaseConfig));
}
private TransactionCapability loadTransactionCapability(final
DatabaseMetaData databaseMetaData) throws SQLException {
@@ -87,9 +87,9 @@ public final class MCPJdbcDatabaseProfileLoader {
return databaseMetaData.supportsSavepoints() ?
TransactionCapability.LOCAL_WITH_SAVEPOINT : TransactionCapability.LOCAL;
}
- private IdentifierCasePolicySet resolveIdentifierCasePolicySet(final
String databaseName, final DatabaseType databaseType,
- final
RuntimeDatabaseConfiguration runtimeDatabaseConfig) {
- return IdentifierCasePolicyResolver.resolveStorage(databaseType, new
RuntimeDatabaseDataSource(databaseName, runtimeDatabaseConfig));
+ private DatabaseIdentifierContext createIdentifierContext(final String
databaseName, final DatabaseType databaseType,
+ final
RuntimeDatabaseConfiguration runtimeDatabaseConfig) {
+ return DatabaseIdentifierContextFactory.create(databaseType, new
RuntimeDatabaseDataSource(databaseName, runtimeDatabaseConfig));
}
private DatabaseType loadDatabaseType(final String databaseName, final
DatabaseMetaData databaseMetaData) throws SQLException {
diff --git
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/database/metadata/jdbc/RuntimeDatabaseProfile.java
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/database/metadata/jdbc/RuntimeDatabaseProfile.java
index 9d999b762ec..1f43ae51011 100644
---
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/database/metadata/jdbc/RuntimeDatabaseProfile.java
+++
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/database/metadata/jdbc/RuntimeDatabaseProfile.java
@@ -19,7 +19,7 @@ package
org.apache.shardingsphere.mcp.support.database.metadata.jdbc;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
-import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicySet;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import
org.apache.shardingsphere.mcp.support.database.metadata.TransactionCapability;
/**
@@ -37,5 +37,5 @@ public final class RuntimeDatabaseProfile {
private final TransactionCapability transactionCapability;
- private final IdentifierCasePolicySet identifierCasePolicySet;
+ private final DatabaseIdentifierContext identifierContext;
}
diff --git
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/database/tool/service/RuntimeDatabaseValidationService.java
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/database/tool/service/RuntimeDatabaseValidationService.java
index 0078d87243a..3d431d61472 100644
---
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/database/tool/service/RuntimeDatabaseValidationService.java
+++
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/database/tool/service/RuntimeDatabaseValidationService.java
@@ -17,11 +17,9 @@
package org.apache.shardingsphere.mcp.support.database.tool.service;
-import
org.apache.shardingsphere.database.connector.core.metadata.database.enums.QuoteCharacter;
-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.metadata.identifier.IdentifierScope;
import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import
org.apache.shardingsphere.mcp.support.database.metadata.jdbc.MCPJdbcDatabaseProfileLoader;
import
org.apache.shardingsphere.mcp.support.database.metadata.jdbc.MCPJdbcMetadataLoader;
import
org.apache.shardingsphere.mcp.support.database.metadata.jdbc.RuntimeDatabaseConfiguration;
@@ -30,6 +28,7 @@ import
org.apache.shardingsphere.mcp.support.database.metadata.jdbc.RuntimeDatab
import
org.apache.shardingsphere.mcp.support.database.tool.request.RuntimeDatabaseValidationRequest;
import
org.apache.shardingsphere.mcp.support.database.tool.result.RuntimeDatabaseValidationCheckResult;
import
org.apache.shardingsphere.mcp.support.database.tool.result.RuntimeDatabaseValidationResult;
+import
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
@@ -94,7 +93,7 @@ public final class RuntimeDatabaseValidationService {
return RuntimeDatabaseValidationResult.failed(database, checks,
ex.getCategory());
}
try {
- validateDatabaseVisibility(database, runtimeDatabaseConfig.get(),
schemas, databaseProfile.getDatabaseType(),
databaseProfile.getIdentifierCasePolicySet());
+ validateDatabaseVisibility(database, runtimeDatabaseConfig.get(),
schemas, databaseProfile.getDatabaseType(),
databaseProfile.getIdentifierContext());
checks.add(RuntimeDatabaseValidationCheckResult.passed("database_visibility",
"Validated the requested database name against visible JDBC metadata and
connection context."));
} catch (final RuntimeDatabaseConnectionException ex) {
checks.add(RuntimeDatabaseValidationCheckResult.failed("database_visibility",
ex.getCategory(), "The requested database name is not visible to the configured
JDBC connection."));
@@ -123,12 +122,12 @@ public final class RuntimeDatabaseValidationService {
}
private void validateDatabaseVisibility(final String database, final
RuntimeDatabaseConfiguration runtimeDatabaseConfig, final
Collection<ShardingSphereSchema> schemas,
- final String databaseType, final
IdentifierCasePolicySet identifierCasePolicySet) {
- if (containsVisibleSchema(schemas, database,
identifierCasePolicySet.getPolicy(IdentifierScope.SCHEMA))) {
+ final String databaseType, final
DatabaseIdentifierContext identifierContext) {
+ if (containsVisibleSchema(schemas, database, identifierContext)) {
return;
}
try (Connection connection =
runtimeDatabaseConfig.openConnection(database)) {
- if (isVisibleDatabase(connection, database,
identifierCasePolicySet)) {
+ if (isVisibleDatabase(connection, database, identifierContext)) {
return;
}
} catch (final SQLException ex) {
@@ -138,28 +137,26 @@ public final class RuntimeDatabaseValidationService {
new IllegalStateException(String.format("Requested database
`%s` is not visible to the configured JDBC connection.", database)));
}
- private boolean containsVisibleSchema(final
Collection<ShardingSphereSchema> schemas, final String database, final
IdentifierCasePolicy identifierCasePolicy) {
+ private boolean containsVisibleSchema(final
Collection<ShardingSphereSchema> schemas, final String database, final
DatabaseIdentifierContext identifierContext) {
for (ShardingSphereSchema each : schemas) {
- if (matches(each.getName(), database, identifierCasePolicy)) {
+ if (matches(each.getName(), database, identifierContext,
IdentifierScope.SCHEMA)) {
return true;
}
}
return false;
}
- private boolean isVisibleDatabase(final Connection connection, final
String database, final IdentifierCasePolicySet identifierCasePolicySet) throws
SQLException {
- IdentifierCasePolicy databasePolicy =
identifierCasePolicySet.getPolicy(IdentifierScope.DATABASE);
- IdentifierCasePolicy schemaPolicy =
identifierCasePolicySet.getPolicy(IdentifierScope.SCHEMA);
- return matches(connection.getCatalog(), database, databasePolicy)
- || matches(connection.getSchema(), database, schemaPolicy)
- || containsCatalog(connection.getMetaData(), database,
databasePolicy)
- || containsSchema(connection.getMetaData(), database,
schemaPolicy);
+ private boolean isVisibleDatabase(final Connection connection, final
String database, final DatabaseIdentifierContext identifierContext) throws
SQLException {
+ return matches(connection.getCatalog(), database, identifierContext,
IdentifierScope.DATABASE)
+ || matches(connection.getSchema(), database,
identifierContext, IdentifierScope.SCHEMA)
+ || containsCatalog(connection.getMetaData(), database,
identifierContext)
+ || containsSchema(connection.getMetaData(), database,
identifierContext);
}
- private boolean containsCatalog(final DatabaseMetaData databaseMetaData,
final String database, final IdentifierCasePolicy identifierCasePolicy) throws
SQLException {
+ private boolean containsCatalog(final DatabaseMetaData databaseMetaData,
final String database, final DatabaseIdentifierContext identifierContext)
throws SQLException {
try (ResultSet resultSet = databaseMetaData.getCatalogs()) {
while (resultSet.next()) {
- if (matches(resultSet.getString(1), database,
identifierCasePolicy)) {
+ if (matches(resultSet.getString(1), database,
identifierContext, IdentifierScope.DATABASE)) {
return true;
}
}
@@ -167,10 +164,10 @@ public final class RuntimeDatabaseValidationService {
return false;
}
- private boolean containsSchema(final DatabaseMetaData databaseMetaData,
final String database, final IdentifierCasePolicy identifierCasePolicy) throws
SQLException {
+ private boolean containsSchema(final DatabaseMetaData databaseMetaData,
final String database, final DatabaseIdentifierContext identifierContext)
throws SQLException {
try (ResultSet resultSet = databaseMetaData.getSchemas()) {
while (resultSet.next()) {
- if (matches(resultSet.getString("TABLE_SCHEM"), database,
identifierCasePolicy)) {
+ if (matches(resultSet.getString("TABLE_SCHEM"), database,
identifierContext, IdentifierScope.SCHEMA)) {
return true;
}
}
@@ -178,9 +175,9 @@ public final class RuntimeDatabaseValidationService {
return false;
}
- private boolean matches(final String storedName, final String identifier,
final IdentifierCasePolicy identifierCasePolicy) {
+ private boolean matches(final String storedName, final String identifier,
final DatabaseIdentifierContext identifierContext, final IdentifierScope
identifierScope) {
String actualStoredName = Objects.toString(storedName, "").trim();
- return !actualStoredName.isEmpty() &&
identifierCasePolicy.matches(actualStoredName, identifier, QuoteCharacter.NONE);
+ return !actualStoredName.isEmpty() &&
identifierContext.matchesMetaData(identifierScope, actualStoredName, new
IdentifierValue(identifier));
}
private String normalize(final String value) {
diff --git
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowSQLUtils.java
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowSQLUtils.java
index 72699b3baaa..d2316b3d947 100644
---
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowSQLUtils.java
+++
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowSQLUtils.java
@@ -20,9 +20,11 @@ package
org.apache.shardingsphere.mcp.support.workflow.service;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import
org.apache.shardingsphere.database.connector.core.metadata.database.enums.QuoteCharacter;
-import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicy;
+import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierScope;
import org.apache.shardingsphere.infra.exception.ShardingSpherePreconditions;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import org.apache.shardingsphere.mcp.api.exception.MCPInvalidRequestException;
+import
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
import java.util.Locale;
import java.util.Map;
@@ -123,15 +125,17 @@ public final class WorkflowSQLUtils {
/**
* Judge whether a workflow identifier token references an existing
identifier under the target database policy.
*
- * @param identifierCasePolicy identifier case policy
+ * @param identifierContext identifier context
+ * @param identifierScope identifier scope
* @param identifier identifier token
* @param existingIdentifier existing identifier
* @return whether the identifier references the existing identifier
*/
- public static boolean isSameIdentifier(final IdentifierCasePolicy
identifierCasePolicy, final String identifier, final String existingIdentifier)
{
+ public static boolean isSameIdentifier(final DatabaseIdentifierContext
identifierContext, final IdentifierScope identifierScope,
+ final String identifier, final
String existingIdentifier) {
String actualIdentifier = normalizeIdentifier(identifier);
String actualExistingIdentifier =
normalizeIdentifier(existingIdentifier);
- return identifierCasePolicy.matches(actualExistingIdentifier,
actualIdentifier, getQuoteCharacter(identifier));
+ return identifierContext.matchesMetaData(identifierScope,
actualExistingIdentifier, new IdentifierValue(actualIdentifier,
getQuoteCharacter(identifier)));
}
static boolean requiresExactIdentifierMatch(final String identifier) {
diff --git
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/database/capability/MCPDatabaseCapabilityProviderTest.java
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/database/capability/MCPDatabaseCapabilityProviderTest.java
index 9cc3e39963b..2b94e8dff3e 100644
---
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/database/capability/MCPDatabaseCapabilityProviderTest.java
+++
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/database/capability/MCPDatabaseCapabilityProviderTest.java
@@ -21,7 +21,6 @@ import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import
org.apache.shardingsphere.mcp.support.database.metadata.TransactionCapability;
-import
org.apache.shardingsphere.database.connector.core.metadata.database.enums.QuoteCharacter;
import
org.apache.shardingsphere.database.connector.core.metadata.database.metadata.DialectDatabaseMetaData;
import
org.apache.shardingsphere.database.connector.core.metadata.database.metadata.option.schema.DefaultSchemaOption;
import
org.apache.shardingsphere.database.connector.core.metadata.database.metadata.option.schema.DialectSchemaSemantics;
@@ -31,10 +30,12 @@ import
org.apache.shardingsphere.database.connector.core.metadata.identifier.Ide
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierScope;
import
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
import
org.apache.shardingsphere.mcp.support.database.metadata.jdbc.MCPJdbcDatabaseProfileLoader;
import
org.apache.shardingsphere.mcp.support.database.metadata.jdbc.RuntimeDatabaseConfiguration;
import
org.apache.shardingsphere.mcp.support.database.metadata.jdbc.RuntimeDatabaseProfile;
+import
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
@@ -78,7 +79,7 @@ class MCPDatabaseCapabilityProviderTest {
assertThat(actual.get().getSchemaExecutionSemantics(),
is(SchemaExecutionSemantics.FIXED_TO_DATABASE));
assertFalse(actual.get().supportsCrossSchemaSql());
assertTrue(actual.get().supportsExplain());
-
assertFalse(actual.get().getIdentifierCasePolicySet().getPolicy(IdentifierScope.TABLE).matches("phone",
"Phone", QuoteCharacter.NONE));
+
assertFalse(actual.get().getIdentifierContext().matchesMetaData(IdentifierScope.TABLE,
"phone", new IdentifierValue("Phone")));
}
@Test
@@ -111,9 +112,9 @@ class MCPDatabaseCapabilityProviderTest {
CapabilityFixture capabilityFixture = new CapabilityFixture(true,
true, false, DialectSchemaSemantics.DATABASE_AS_SCHEMA);
MCPDatabaseCapabilityProvider provider = createCapabilityProvider(
Map.of("logic_db", createDatabaseProfile("logic_db", "MySQL",
capabilityFixture, scopedPolicySet)), Map.of("MySQL", capabilityFixture));
- IdentifierCasePolicySet actual =
provider.provide("logic_db").orElseThrow().getIdentifierCasePolicySet();
- assertFalse(actual.getPolicy(IdentifierScope.TABLE).matches("phone",
"Phone", QuoteCharacter.NONE));
- assertTrue(actual.getPolicy(IdentifierScope.COLUMN).matches("phone",
"Phone", QuoteCharacter.NONE));
+ DatabaseIdentifierContext actual =
provider.provide("logic_db").orElseThrow().getIdentifierContext();
+ assertFalse(actual.matchesMetaData(IdentifierScope.TABLE, "phone", new
IdentifierValue("Phone")));
+ assertTrue(actual.matchesMetaData(IdentifierScope.COLUMN, "phone", new
IdentifierValue("Phone")));
}
@ParameterizedTest(name = "{0}")
@@ -187,7 +188,7 @@ class MCPDatabaseCapabilityProviderTest {
TransactionCapability transactionCapability =
capabilityFixture.transactionSupported
? capabilityFixture.savepointSupported ?
TransactionCapability.LOCAL_WITH_SAVEPOINT : TransactionCapability.LOCAL
: TransactionCapability.NONE;
- return new RuntimeDatabaseProfile(databaseName, databaseType, "",
transactionCapability, identifierCasePolicySet);
+ return new RuntimeDatabaseProfile(databaseName, databaseType, "",
transactionCapability, new DatabaseIdentifierContext(identifierCasePolicySet));
}
private static Stream<Arguments> provideCapabilityMatrixArguments() {
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 55d71887d54..e1db7576f1b 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
@@ -17,15 +17,15 @@
package org.apache.shardingsphere.mcp.support.database.metadata.jdbc;
-import
org.apache.shardingsphere.database.connector.core.metadata.database.enums.QuoteCharacter;
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.DatabaseTypeFactory;
import
org.apache.shardingsphere.infra.exception.external.ShardingSphereExternalException;
-import
org.apache.shardingsphere.infra.metadata.identifier.IdentifierCasePolicyResolver;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContextFactory;
import
org.apache.shardingsphere.mcp.support.database.metadata.TransactionCapability;
import
org.apache.shardingsphere.mcp.support.fixture.SupportDatabaseTypeFactoryMocker;
+import
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
@@ -54,18 +54,18 @@ class MCPJdbcDatabaseProfileLoaderTest {
@Test
void assertLoad() throws SQLException {
- IdentifierCasePolicySet expectedIdentifierCasePolicySet =
IdentifierCasePolicyFactory.newSensitivePolicySet();
+ DatabaseIdentifierContext expectedIdentifierContext = new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newSensitivePolicySet());
try (
MockedStatic<DatabaseTypeFactory> ignored =
SupportDatabaseTypeFactoryMocker.mockByConnectionMetadata();
- MockedStatic<IdentifierCasePolicyResolver> ignoredResolver =
mockStatic(IdentifierCasePolicyResolver.class)) {
- ignoredResolver.when(() ->
IdentifierCasePolicyResolver.resolveStorage(any(),
any())).thenReturn(expectedIdentifierCasePolicySet);
+ MockedStatic<DatabaseIdentifierContextFactory> ignoredFactory
= mockStatic(DatabaseIdentifierContextFactory.class)) {
+ ignoredFactory.when(() ->
DatabaseIdentifierContextFactory.create(any(),
any(DataSource.class))).thenReturn(expectedIdentifierContext);
RuntimeDatabaseProfile actual =
new MCPJdbcDatabaseProfileLoader().load("logic_db",
createRuntimeDatabaseConfiguration(SupportDatabaseTypeFactoryMocker.createJdbcUrl("FixtureDB"),
"1.0", true, true));
assertThat(actual.getDatabase(), is("logic_db"));
assertThat(actual.getDatabaseType(), is("FixtureDB"));
assertThat(actual.getDatabaseVersion(), is("1.0"));
assertThat(actual.getTransactionCapability(),
is(TransactionCapability.LOCAL_WITH_SAVEPOINT));
- assertThat(actual.getIdentifierCasePolicySet(),
is(expectedIdentifierCasePolicySet));
+ assertThat(actual.getIdentifierContext(),
is(expectedIdentifierContext));
}
}
@@ -102,19 +102,20 @@ class MCPJdbcDatabaseProfileLoaderTest {
Map<String, RuntimeDatabaseConfiguration> runtimeDatabases = new
LinkedHashMap<>(2, 1F);
runtimeDatabases.put("first_db", firstRuntimeDatabase);
runtimeDatabases.put("second_db", secondRuntimeDatabase);
- Map<Connection, IdentifierCasePolicySet> policies = Map.of(
- firstConnection,
IdentifierCasePolicyFactory.newSensitivePolicySet(), secondConnection,
IdentifierCasePolicyFactory.newInsensitivePolicySet());
+ Map<Connection, DatabaseIdentifierContext> identifierContexts = Map.of(
+ firstConnection, new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newSensitivePolicySet()),
+ secondConnection, new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet()));
try (
MockedStatic<DatabaseTypeFactory> ignored =
SupportDatabaseTypeFactoryMocker.mockByConnectionMetadata();
- MockedStatic<IdentifierCasePolicyResolver> ignoredResolver =
mockStatic(IdentifierCasePolicyResolver.class)) {
- ignoredResolver.when(() ->
IdentifierCasePolicyResolver.resolveStorage(any(),
any())).thenAnswer(invocation -> {
+ MockedStatic<DatabaseIdentifierContextFactory> ignoredFactory
= mockStatic(DatabaseIdentifierContextFactory.class)) {
+ ignoredFactory.when(() ->
DatabaseIdentifierContextFactory.create(any(),
any(DataSource.class))).thenAnswer(invocation -> {
try (Connection connection = invocation.getArgument(1,
DataSource.class).getConnection()) {
- return policies.get(connection);
+ return identifierContexts.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));
+
assertFalse(actual.get("first_db").getIdentifierContext().matchesMetaData(IdentifierScope.TABLE,
"phone", new IdentifierValue("Phone")));
+
assertTrue(actual.get("second_db").getIdentifierContext().matchesMetaData(IdentifierScope.TABLE,
"phone", new IdentifierValue("Phone")));
verify(firstRuntimeDatabase, times(2)).openConnection("first_db");
verify(firstRuntimeDatabase, never()).openConnection("second_db");
verify(secondRuntimeDatabase,
times(2)).openConnection("second_db");
@@ -132,17 +133,17 @@ class MCPJdbcDatabaseProfileLoaderTest {
.thenThrow(RuntimeDatabaseConnectionException.connectionFailed("logic_db",
connectionFailure));
try (
MockedStatic<DatabaseTypeFactory> ignored =
SupportDatabaseTypeFactoryMocker.mockByConnectionMetadata();
- MockedStatic<IdentifierCasePolicyResolver> ignoredResolver =
mockStatic(IdentifierCasePolicyResolver.class)) {
- ignoredResolver.when(() ->
IdentifierCasePolicyResolver.resolveStorage(any(),
any())).thenAnswer(invocation -> {
+ MockedStatic<DatabaseIdentifierContextFactory> ignoredFactory
= mockStatic(DatabaseIdentifierContextFactory.class)) {
+ ignoredFactory.when(() ->
DatabaseIdentifierContextFactory.create(any(),
any(DataSource.class))).thenAnswer(invocation -> {
try (Connection ignoredConnection = invocation.getArgument(1,
DataSource.class).getConnection()) {
- return IdentifierCasePolicyFactory.newSensitivePolicySet();
+ return new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newSensitivePolicySet());
} catch (final SQLException ex) {
assertThat(ex, is(connectionFailure));
- return
IdentifierCasePolicyFactory.newInsensitivePolicySet();
+ return new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet());
}
});
RuntimeDatabaseProfile actual = new
MCPJdbcDatabaseProfileLoader().load("logic_db", runtimeDatabaseConfig);
-
assertTrue(actual.getIdentifierCasePolicySet().getPolicy(IdentifierScope.TABLE).matches("phone",
"Phone", QuoteCharacter.NONE));
+
assertTrue(actual.getIdentifierContext().matchesMetaData(IdentifierScope.TABLE,
"phone", new IdentifierValue("Phone")));
verify(runtimeDatabaseConfig, times(2)).openConnection("logic_db");
}
}
diff --git
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/database/metadata/jdbc/MCPJdbcMetadataLoaderFailureTest.java
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/database/metadata/jdbc/MCPJdbcMetadataLoaderFailureTest.java
index 9c5ca149fd4..1ce009e5d9f 100644
---
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/database/metadata/jdbc/MCPJdbcMetadataLoaderFailureTest.java
+++
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/database/metadata/jdbc/MCPJdbcMetadataLoaderFailureTest.java
@@ -20,6 +20,7 @@ package
org.apache.shardingsphere.mcp.support.database.metadata.jdbc;
import
org.apache.shardingsphere.mcp.support.database.metadata.TransactionCapability;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyFactory;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import org.junit.jupiter.api.Test;
import java.sql.SQLException;
@@ -72,6 +73,7 @@ class MCPJdbcMetadataLoaderFailureTest {
}
private static RuntimeDatabaseProfile createDatabaseProfile() {
- return new RuntimeDatabaseProfile("logic_db", "Firebird", "",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newInsensitivePolicySet());
+ return new RuntimeDatabaseProfile("logic_db", "Firebird", "",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet()));
}
}
diff --git
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/database/tool/service/RuntimeDatabaseValidationServiceTest.java
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/database/tool/service/RuntimeDatabaseValidationServiceTest.java
index 4bf0f1a3f7e..2ddcdc31d64 100644
---
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/database/tool/service/RuntimeDatabaseValidationServiceTest.java
+++
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/database/tool/service/RuntimeDatabaseValidationServiceTest.java
@@ -22,6 +22,7 @@ import
org.apache.shardingsphere.mcp.support.database.metadata.TransactionCapabi
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.infra.metadata.identifier.DatabaseIdentifierContext;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
import
org.apache.shardingsphere.mcp.support.database.metadata.jdbc.MCPJdbcDatabaseProfileLoader;
@@ -129,7 +130,8 @@ class RuntimeDatabaseValidationServiceTest {
IdentifierCasePolicyFactory.newSensitivePolicySet().getPolicy(IdentifierScope.TABLE),
Map.of(IdentifierScope.SCHEMA,
IdentifierCasePolicyFactory.newInsensitivePolicySet().getPolicy(IdentifierScope.SCHEMA)));
when(profileLoader.load(any(),
any(RuntimeDatabaseConfiguration.class)))
- .thenReturn(new RuntimeDatabaseProfile("logic_db",
"FixtureDB", "1.0", TransactionCapability.LOCAL_WITH_SAVEPOINT,
identifierCasePolicySet));
+ .thenReturn(new RuntimeDatabaseProfile("logic_db",
"FixtureDB", "1.0", TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(identifierCasePolicySet)));
when(metadataLoader.load(any(),
any(RuntimeDatabaseConfiguration.class),
any(RuntimeDatabaseProfile.class))).thenReturn(createMetadata("Logic_DB"));
RuntimeDatabaseValidationResult actual = service.validate(new
RuntimeDatabaseValidationRequest("logic_db"), ignored ->
Optional.of(runtimeDatabaseConfig));
assertThat(actual.getStatus(), is("ready"));
@@ -143,7 +145,8 @@ class RuntimeDatabaseValidationServiceTest {
MCPJdbcMetadataLoader metadataLoader = getMetadataLoader();
RuntimeDatabaseConfiguration runtimeDatabaseConfig = new
RuntimeDatabaseConfiguration(InvisibleDatabaseDriver.JDBC_URL, "demo", "",
InvisibleDatabaseDriver.class.getName());
when(profileLoader.load(any(),
any(RuntimeDatabaseConfiguration.class))).thenReturn(
- new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newSensitivePolicySet()));
+ new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newSensitivePolicySet())));
when(metadataLoader.load(any(),
any(RuntimeDatabaseConfiguration.class),
any(RuntimeDatabaseProfile.class))).thenReturn(createMetadata("Logic_DB"));
RuntimeDatabaseValidationResult actual = service.validate(new
RuntimeDatabaseValidationRequest("logic_db"), ignored ->
Optional.of(runtimeDatabaseConfig));
assertThat(actual.getStatus(), is("failed"));
@@ -162,7 +165,8 @@ class RuntimeDatabaseValidationServiceTest {
IdentifierCasePolicyFactory.newInsensitivePolicySet().getPolicy(IdentifierScope.TABLE),
Map.of(IdentifierScope.SCHEMA,
IdentifierCasePolicyFactory.newSensitivePolicySet().getPolicy(IdentifierScope.SCHEMA)));
when(getProfileLoader().load(any(),
any(RuntimeDatabaseConfiguration.class)))
- .thenReturn(new RuntimeDatabaseProfile("logic_db",
"FixtureDB", "1.0", TransactionCapability.LOCAL_WITH_SAVEPOINT,
identifierCasePolicySet));
+ .thenReturn(new RuntimeDatabaseProfile("logic_db",
"FixtureDB", "1.0", TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(identifierCasePolicySet)));
when(getMetadataLoader().load(any(),
any(RuntimeDatabaseConfiguration.class),
any(RuntimeDatabaseProfile.class))).thenReturn(createMetadata("public"));
RuntimeDatabaseValidationResult actual = service.validate(new
RuntimeDatabaseValidationRequest("logic_db"), ignored ->
Optional.of(runtimeDatabaseConfig));
assertThat(actual.getStatus(), is("ready"));
@@ -176,7 +180,8 @@ class RuntimeDatabaseValidationServiceTest {
when(runtimeDatabaseConfig.openConnection("logic_db")).thenReturn(connection);
when(connection.getCatalog()).thenThrow(new SQLException("permission
denied", "28000", 335544352));
when(getProfileLoader().load(any(),
any(RuntimeDatabaseConfiguration.class))).thenReturn(
- new RuntimeDatabaseProfile("logic_db", "Firebird", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newSensitivePolicySet()));
+ new RuntimeDatabaseProfile("logic_db", "Firebird", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newSensitivePolicySet())));
when(getMetadataLoader().load(any(),
any(RuntimeDatabaseConfiguration.class),
any(RuntimeDatabaseProfile.class))).thenReturn(createMetadata("public"));
RuntimeDatabaseValidationResult actual = service.validate(new
RuntimeDatabaseValidationRequest("logic_db"), ignored ->
Optional.of(runtimeDatabaseConfig));
assertThat(actual.getCategory(),
is(RuntimeDatabaseConnectionException.CATEGORY_AUTHORIZATION_FAILED));
@@ -240,7 +245,8 @@ class RuntimeDatabaseValidationServiceTest {
}
private static RuntimeDatabaseProfile createProfile() {
- return new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newInsensitivePolicySet());
+ return new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet()));
}
private static RuntimeDatabaseConfiguration
createRuntimeDatabaseConfiguration() {
diff --git
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowPlanningContextValidatorTest.java
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowPlanningContextValidatorTest.java
index 248b5d521f2..1495d479459 100644
---
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowPlanningContextValidatorTest.java
+++
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowPlanningContextValidatorTest.java
@@ -20,6 +20,7 @@ package
org.apache.shardingsphere.mcp.support.workflow.service;
import
org.apache.shardingsphere.mcp.support.database.metadata.TransactionCapability;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyFactory;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import
org.apache.shardingsphere.database.connector.core.metadata.database.enums.TableType;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierScope;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
@@ -191,7 +192,8 @@ class WorkflowPlanningContextValidatorTest {
}
private RuntimeDatabaseProfile createDatabaseMetadata() {
- return new RuntimeDatabaseProfile("logic_db", "Fixture", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newInsensitivePolicySet());
+ return new RuntimeDatabaseProfile("logic_db", "Fixture", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet()));
}
private ShardingSphereSchema createSchemaMetadata() {
diff --git
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowPlanningSupportTest.java
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowPlanningSupportTest.java
index 331d3fb7f44..f41af3b360d 100644
---
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowPlanningSupportTest.java
+++
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowPlanningSupportTest.java
@@ -20,6 +20,7 @@ package
org.apache.shardingsphere.mcp.support.workflow.service;
import
org.apache.shardingsphere.mcp.support.database.metadata.TransactionCapability;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyFactory;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import
org.apache.shardingsphere.database.connector.core.metadata.database.enums.TableType;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierScope;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
@@ -379,7 +380,8 @@ class WorkflowPlanningSupportTest {
}
private RuntimeDatabaseProfile createDatabaseMetadata() {
- return new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
IdentifierCasePolicyFactory.newInsensitivePolicySet());
+ return new RuntimeDatabaseProfile("logic_db", "FixtureDB", "1.0",
TransactionCapability.LOCAL_WITH_SAVEPOINT,
+ new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet()));
}
private ShardingSphereSchema createSchemaMetadata(final String schemaName,
final String tableName) {
diff --git
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowSQLUtilsTest.java
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowSQLUtilsTest.java
index b661a9a7d28..137f404805d 100644
---
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowSQLUtilsTest.java
+++
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowSQLUtilsTest.java
@@ -19,6 +19,7 @@ package
org.apache.shardingsphere.mcp.support.workflow.service;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyFactory;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierScope;
+import
org.apache.shardingsphere.infra.metadata.identifier.DatabaseIdentifierContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
@@ -134,27 +135,27 @@ class WorkflowSQLUtilsTest {
@Test
void assertIsSameIdentifierWithCaseInsensitiveDatabase() {
-
assertTrue(WorkflowSQLUtils.isSameIdentifier(IdentifierCasePolicyFactory.newInsensitivePolicySet().getPolicy(IdentifierScope.TABLE),
"Phone", "phone"));
+ assertTrue(WorkflowSQLUtils.isSameIdentifier(new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newInsensitivePolicySet()),
IdentifierScope.TABLE, "Phone", "phone"));
}
@Test
void assertIsSameIdentifierFoldsPostgreSQLUnquotedIdentifier() {
-
assertTrue(WorkflowSQLUtils.isSameIdentifier(IdentifierCasePolicyFactory.newLowerCasePolicySet().getPolicy(IdentifierScope.TABLE),
"Phone", "phone"));
+ assertTrue(WorkflowSQLUtils.isSameIdentifier(new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newLowerCasePolicySet()),
IdentifierScope.TABLE, "Phone", "phone"));
}
@Test
void assertIsSameIdentifierPreservesPostgreSQLDelimitedIdentifier() {
-
assertFalse(WorkflowSQLUtils.isSameIdentifier(IdentifierCasePolicyFactory.newLowerCasePolicySet().getPolicy(IdentifierScope.TABLE),
"\"Phone\"", "phone"));
+ assertFalse(WorkflowSQLUtils.isSameIdentifier(new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newLowerCasePolicySet()),
IdentifierScope.TABLE, "\"Phone\"", "phone"));
}
@Test
void assertIsSameIdentifierRejectsUnquotedPostgreSQLQuotedName() {
-
assertFalse(WorkflowSQLUtils.isSameIdentifier(IdentifierCasePolicyFactory.newLowerCasePolicySet().getPolicy(IdentifierScope.TABLE),
"Phone", "Phone"));
+ assertFalse(WorkflowSQLUtils.isSameIdentifier(new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newLowerCasePolicySet()),
IdentifierScope.TABLE, "Phone", "Phone"));
}
@Test
void assertIsSameIdentifierMatchesQuotedPostgreSQLName() {
-
assertTrue(WorkflowSQLUtils.isSameIdentifier(IdentifierCasePolicyFactory.newLowerCasePolicySet().getPolicy(IdentifierScope.TABLE),
"\"Phone\"", "Phone"));
+ assertTrue(WorkflowSQLUtils.isSameIdentifier(new
DatabaseIdentifierContext(IdentifierCasePolicyFactory.newLowerCasePolicySet()),
IdentifierScope.TABLE, "\"Phone\"", "Phone"));
}
@Test