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 dad38461489 Unify identifier normalization with policy-based engine
(#39168)
dad38461489 is described below
commit dad38461489d1def0d4ff5183e5f37b2a9b6c6b2
Author: Haoran Meng <[email protected]>
AuthorDate: Fri Jul 17 17:44:22 2026 +0800
Unify identifier normalization with policy-based engine (#39168)
* Unify identifier normalization with policy-based engine
* Add Firebird identifier case policy provider
* Add Apache license header to IdentifierCasePolicyProvider file
---
.../core/metadata/data/loader/MetaDataLoader.java | 2 +-
.../data/loader/MetaDataLoaderMaterial.java | 19 ++++++
.../data/loader/type/TableMetaDataLoader.java | 21 ++++++-
.../identifier/IdentifierNormalizeEngine.java | 67 ++++++++++++++++++++++
.../metadata/data/loader/MetaDataLoaderTest.java | 9 +++
.../identifier/IdentifierNormalizeEngineTest.java | 55 ++++++++++++++++++
.../data/loader/FirebirdBlobColumnLoader.java | 5 +-
.../data/loader/FirebirdMetaDataLoader.java | 2 +-
.../FirebirdNonFixedLengthColumnSizeLoader.java | 5 +-
.../FirebirdIdentifierCasePolicyProvider.java | 46 +++++++++++++++
...etadata.identifier.IdentifierCasePolicyProvider | 18 ++++++
.../data/loader/FirebirdMetaDataLoaderTest.java | 5 +-
.../FirebirdIdentifierCasePolicyProviderTest.java | 58 +++++++++++++++++++
.../metadata/data/loader/HiveMetaDataLoader.java | 2 +-
.../data/loader/HiveMetaDataLoaderTest.java | 7 ++-
15 files changed, 307 insertions(+), 14 deletions(-)
diff --git
a/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/MetaDataLoader.java
b/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/MetaDataLoader.java
index 89a06490ebe..fe62e92816e 100644
---
a/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/MetaDataLoader.java
+++
b/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/MetaDataLoader.java
@@ -95,7 +95,7 @@ public final class MetaDataLoader {
private static Collection<SchemaMetaData> loadByDefault(final
MetaDataLoaderMaterial material) throws SQLException {
Collection<TableMetaData> tableMetaData = new LinkedList<>();
for (String each : material.getActualTableNames()) {
- TableMetaDataLoader.load(material.getDataSource(), each,
material.getStorageType()).ifPresent(tableMetaData::add);
+ TableMetaDataLoader.load(material.getDataSource(), each,
material.getStorageType(),
material.getTableIdentifierPolicy()).ifPresent(tableMetaData::add);
}
return Collections.singleton(new
SchemaMetaData(material.getDefaultSchemaName(), tableMetaData));
}
diff --git
a/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/MetaDataLoaderMaterial.java
b/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/MetaDataLoaderMaterial.java
index 8cfefafdc49..3f03dbcb37e 100644
---
a/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/MetaDataLoaderMaterial.java
+++
b/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/MetaDataLoaderMaterial.java
@@ -17,8 +17,12 @@
package org.apache.shardingsphere.database.connector.core.metadata.data.loader;
+import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
+import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicy;
+import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierNormalizeEngine;
+import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierScope;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
import javax.sql.DataSource;
@@ -40,4 +44,19 @@ public final class MetaDataLoaderMaterial {
private final DatabaseType storageType;
private final String defaultSchemaName;
+
+ @Getter(AccessLevel.NONE)
+ private volatile IdentifierCasePolicy tableIdentifierPolicy;
+
+ /**
+ * Get table identifier case policy.
+ *
+ * @return table identifier case policy
+ */
+ public synchronized IdentifierCasePolicy getTableIdentifierPolicy() {
+ if (null == tableIdentifierPolicy) {
+ tableIdentifierPolicy =
IdentifierNormalizeEngine.resolvePolicy(storageType, dataSource,
IdentifierScope.TABLE);
+ }
+ return tableIdentifierPolicy;
+ }
}
diff --git
a/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/type/TableMetaDataLoader.java
b/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/type/TableMetaDataLoader.java
index ba15eaaf5f2..872ee837070 100644
---
a/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/type/TableMetaDataLoader.java
+++
b/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/type/TableMetaDataLoader.java
@@ -21,8 +21,10 @@ import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import
org.apache.shardingsphere.database.connector.core.metadata.data.loader.MetaDataLoaderConnection;
import
org.apache.shardingsphere.database.connector.core.metadata.data.model.TableMetaData;
+import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicy;
+import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierNormalizeEngine;
+import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierScope;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
-import
org.apache.shardingsphere.database.connector.core.type.DatabaseTypeRegistry;
import javax.sql.DataSource;
import java.sql.Connection;
@@ -47,8 +49,23 @@ public final class TableMetaDataLoader {
* @throws SQLException SQL exception
*/
public static Optional<TableMetaData> load(final DataSource dataSource,
final String tableNamePattern, final DatabaseType databaseType) throws
SQLException {
+ return load(dataSource, tableNamePattern, databaseType,
IdentifierNormalizeEngine.resolvePolicy(databaseType, dataSource,
IdentifierScope.TABLE));
+ }
+
+ /**
+ * Load table meta data.
+ *
+ * @param dataSource data source
+ * @param tableNamePattern table name pattern
+ * @param databaseType database type
+ * @param tableIdentifierPolicy table identifier case policy
+ * @return table meta data
+ * @throws SQLException SQL exception
+ */
+ public static Optional<TableMetaData> load(final DataSource dataSource,
final String tableNamePattern, final DatabaseType databaseType,
+ final IdentifierCasePolicy
tableIdentifierPolicy) throws SQLException {
try (MetaDataLoaderConnection connection = new
MetaDataLoaderConnection(databaseType, dataSource.getConnection())) {
- String formattedTableNamePattern = new
DatabaseTypeRegistry(databaseType).formatIdentifierPattern(tableNamePattern);
+ String formattedTableNamePattern =
IdentifierNormalizeEngine.normalize(tableIdentifierPolicy, tableNamePattern);
return isTableExist(connection, formattedTableNamePattern)
? Optional.of(new TableMetaData(tableNamePattern,
ColumnMetaDataLoader.load(
connection, formattedTableNamePattern,
databaseType), IndexMetaDataLoader.load(connection, formattedTableNamePattern),
Collections.emptyList()))
diff --git
a/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierNormalizeEngine.java
b/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierNormalizeEngine.java
new file mode 100644
index 00000000000..c14c3ab2c78
--- /dev/null
+++
b/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierNormalizeEngine.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.database.connector.core.metadata.identifier;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import
org.apache.shardingsphere.database.connector.core.metadata.database.enums.QuoteCharacter;
+import
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+
+import javax.sql.DataSource;
+
+/**
+ * Identifier normalize engine.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class IdentifierNormalizeEngine {
+
+ /**
+ * Resolve identifier case policy.
+ *
+ * @param databaseType database type
+ * @param dataSource data source
+ * @param identifierScope identifier scope
+ * @return identifier case policy
+ */
+ public static IdentifierCasePolicy resolvePolicy(final DatabaseType
databaseType, final DataSource dataSource, final IdentifierScope
identifierScope) {
+ return
DatabaseTypedSPILoader.findService(IdentifierCasePolicyProvider.class,
databaseType)
+ .map(each -> each.provide(new
IdentifierCasePolicyProviderContext(databaseType, dataSource)))
+
.orElseGet(IdentifierCasePolicyFactory::newInsensitivePolicySet)
+ .getPolicy(identifierScope);
+ }
+
+ /**
+ * Normalize identifier.
+ *
+ * @param policy identifier case policy
+ * @param identifier identifier
+ * @return normalized identifier
+ */
+ public static String normalize(final IdentifierCasePolicy policy, final
String identifier) {
+ if (null == identifier) {
+ return null;
+ }
+ QuoteCharacter quoteCharacter =
QuoteCharacter.getQuoteCharacter(identifier);
+ String unwrappedIdentifier = quoteCharacter.unwrap(identifier);
+ if (QuoteCharacter.NONE != quoteCharacter) {
+ return unwrappedIdentifier;
+ }
+ return LookupMode.NORMALIZED ==
policy.getLookupMode(QuoteCharacter.NONE) ?
policy.normalize(unwrappedIdentifier) : unwrappedIdentifier;
+ }
+}
diff --git
a/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/MetaDataLoaderTest.java
b/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/MetaDataLoaderTest.java
index f0e60a19844..93ba7c6acd6 100644
---
a/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/MetaDataLoaderTest.java
+++
b/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/MetaDataLoaderTest.java
@@ -20,6 +20,7 @@ package
org.apache.shardingsphere.database.connector.core.metadata.data.loader;
import lombok.SneakyThrows;
import
org.apache.shardingsphere.database.connector.core.metadata.data.model.SchemaMetaData;
import
org.apache.shardingsphere.database.connector.core.metadata.data.model.TableMetaData;
+import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicy;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
import org.apache.shardingsphere.infra.spi.ShardingSphereServiceLoader;
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
@@ -41,6 +42,7 @@ import java.util.concurrent.TimeUnit;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isA;
+import static org.hamcrest.Matchers.sameInstance;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -96,6 +98,13 @@ class MetaDataLoaderTest {
assertTrue(actual.get("foo_db").getTables().isEmpty());
}
+ @Test
+ void assertGetTableIdentifierPolicyCachesResolvedPolicy() {
+ MetaDataLoaderMaterial material = new
MetaDataLoaderMaterial(Collections.emptyList(), "foo_ds",
mock(DataSource.class), databaseType, "foo_db");
+ IdentifierCasePolicy actual = material.getTableIdentifierPolicy();
+ assertThat(material.getTableIdentifierPolicy(), sameInstance(actual));
+ }
+
@Test
void assertLoadWhenInterrupted() throws Exception {
MetaDataLoaderMaterial material = new
MetaDataLoaderMaterial(Collections.emptyList(), "foo_ds",
mock(DataSource.class, RETURNS_DEEP_STUBS), databaseType, "foo_db");
diff --git
a/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierNormalizeEngineTest.java
b/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierNormalizeEngineTest.java
new file mode 100644
index 00000000000..a3f50b9a7ea
--- /dev/null
+++
b/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/identifier/IdentifierNormalizeEngineTest.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.database.connector.core.metadata.identifier;
+
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+class IdentifierNormalizeEngineTest {
+
+ private final DatabaseType databaseType =
TypedSPILoader.getService(DatabaseType.class, "TRUNK");
+
+ @Test
+ void assertNormalizeQuotedIdentifier() {
+ IdentifierCasePolicy policy =
IdentifierNormalizeEngine.resolvePolicy(databaseType, null,
IdentifierScope.TABLE);
+ assertThat(IdentifierNormalizeEngine.normalize(policy, "\"Foo_Tbl\""),
is("Foo_Tbl"));
+ }
+
+ @Test
+ void assertNormalizeWithResolvedPolicy() {
+ IdentifierCasePolicy policy =
IdentifierNormalizeEngine.resolvePolicy(databaseType, null,
IdentifierScope.TABLE);
+ assertThat(IdentifierNormalizeEngine.normalize(policy, "Foo_Tbl"),
is("foo_tbl"));
+ }
+
+ @Test
+ void assertNormalizeExactPolicy() {
+ IdentifierCasePolicy policy =
IdentifierCasePolicyFactory.newSensitivePolicySet().getPolicy(IdentifierScope.TABLE);
+ assertThat(IdentifierNormalizeEngine.normalize(policy, "Foo_Tbl"),
is("Foo_Tbl"));
+ }
+
+ @Test
+ void assertNormalizeNullIdentifier() {
+ IdentifierCasePolicy policy =
IdentifierNormalizeEngine.resolvePolicy(databaseType, null,
IdentifierScope.TABLE);
+ assertNull(IdentifierNormalizeEngine.normalize(policy, null));
+ }
+}
diff --git
a/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/loader/FirebirdBlobColumnLoader.java
b/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/loader/FirebirdBlobColumnLoader.java
index 653613d0558..da091a3f3d0 100644
---
a/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/loader/FirebirdBlobColumnLoader.java
+++
b/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/loader/FirebirdBlobColumnLoader.java
@@ -20,7 +20,7 @@ package
org.apache.shardingsphere.database.connector.firebird.metadata.data.load
import lombok.RequiredArgsConstructor;
import
org.apache.shardingsphere.database.connector.core.metadata.data.loader.MetaDataLoaderConnection;
import
org.apache.shardingsphere.database.connector.core.metadata.data.loader.MetaDataLoaderMaterial;
-import
org.apache.shardingsphere.database.connector.core.type.DatabaseTypeRegistry;
+import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierNormalizeEngine;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@@ -50,12 +50,11 @@ final class FirebirdBlobColumnLoader {
return Collections.emptyMap();
}
Map<String, Map<String, Integer>> result = new
HashMap<>(material.getActualTableNames().size(), 1F);
- DatabaseTypeRegistry databaseTypeRegistry = new
DatabaseTypeRegistry(material.getStorageType());
try (
MetaDataLoaderConnection connection = new
MetaDataLoaderConnection(
material.getStorageType(),
material.getDataSource().getConnection())) {
for (String each : material.getActualTableNames()) {
- String formattedTableName =
databaseTypeRegistry.formatIdentifierPattern(each);
+ String formattedTableName =
IdentifierNormalizeEngine.normalize(material.getTableIdentifierPolicy(), each);
Map<String, Integer> blobColumns =
loadTableBlobColumns(connection, formattedTableName);
result.put(each, blobColumns);
}
diff --git
a/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/loader/FirebirdMetaDataLoader.java
b/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/loader/FirebirdMetaDataLoader.java
index ddff5308a28..9ac3b39d549 100644
---
a/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/loader/FirebirdMetaDataLoader.java
+++
b/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/loader/FirebirdMetaDataLoader.java
@@ -40,7 +40,7 @@ public final class FirebirdMetaDataLoader implements
DialectMetaDataLoader {
public Collection<SchemaMetaData> load(final MetaDataLoaderMaterial
material) throws SQLException {
Collection<TableMetaData> tableMetaData = new LinkedList<>();
for (String each : material.getActualTableNames()) {
- TableMetaDataLoader.load(material.getDataSource(), each,
material.getStorageType()).ifPresent(tableMetaData::add);
+ TableMetaDataLoader.load(material.getDataSource(), each,
material.getStorageType(),
material.getTableIdentifierPolicy()).ifPresent(tableMetaData::add);
}
loadBlobColumns(material);
loadNonFixedLengthColumnSizes(material);
diff --git
a/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/loader/FirebirdNonFixedLengthColumnSizeLoader.java
b/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/loader/FirebirdNonFixedLengthColumnSizeLoader.java
index 7fb2157c863..2acc8a4c671 100644
---
a/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/loader/FirebirdNonFixedLengthColumnSizeLoader.java
+++
b/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/loader/FirebirdNonFixedLengthColumnSizeLoader.java
@@ -20,7 +20,7 @@ package
org.apache.shardingsphere.database.connector.firebird.metadata.data.load
import lombok.RequiredArgsConstructor;
import
org.apache.shardingsphere.database.connector.core.metadata.data.loader.MetaDataLoaderConnection;
import
org.apache.shardingsphere.database.connector.core.metadata.data.loader.MetaDataLoaderMaterial;
-import
org.apache.shardingsphere.database.connector.core.type.DatabaseTypeRegistry;
+import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierNormalizeEngine;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -44,10 +44,9 @@ final class FirebirdNonFixedLengthColumnSizeLoader {
return Collections.emptyMap();
}
Map<String, Map<String, Integer>> result = new
HashMap<>(material.getActualTableNames().size(), 1F);
- DatabaseTypeRegistry databaseTypeRegistry = new
DatabaseTypeRegistry(material.getStorageType());
try (MetaDataLoaderConnection connection = new
MetaDataLoaderConnection(material.getStorageType(),
material.getDataSource().getConnection())) {
for (String each : material.getActualTableNames()) {
- String formattedTableName =
databaseTypeRegistry.formatIdentifierPattern(each);
+ String formattedTableName =
IdentifierNormalizeEngine.normalize(material.getTableIdentifierPolicy(), each);
Map<String, Integer> columnSizes =
loadTableColumnSizes(connection, formattedTableName);
result.put(each, columnSizes);
}
diff --git
a/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/identifier/FirebirdIdentifierCasePolicyProvider.java
b/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/identifier/FirebirdIdentifierCasePolicyProvider.java
new file mode 100644
index 00000000000..9bf8291d9f9
--- /dev/null
+++
b/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/identifier/FirebirdIdentifierCasePolicyProvider.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package
org.apache.shardingsphere.database.connector.firebird.metadata.identifier;
+
+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;
+import
org.apache.shardingsphere.database.connector.core.metadata.identifier.LookupMode;
+import
org.apache.shardingsphere.database.connector.core.metadata.identifier.StandardIdentifierCasePolicy;
+
+import java.util.Locale;
+
+/**
+ * Firebird provider of identifier case rules.
+ */
+public final class FirebirdIdentifierCasePolicyProvider implements
IdentifierCasePolicyProvider {
+
+ @Override
+ public IdentifierCasePolicySet provide(final
IdentifierCasePolicyProviderContext context) {
+ return new IdentifierCasePolicySet(new
StandardIdentifierCasePolicy(LookupMode.EXACT, LookupMode.NORMALIZED,
FirebirdIdentifierCasePolicyProvider::toUpperCase, each -> true));
+ }
+
+ @Override
+ public String getDatabaseType() {
+ return "Firebird";
+ }
+
+ private static String toUpperCase(final String value) {
+ return value.toUpperCase(Locale.ENGLISH);
+ }
+}
diff --git
a/database/connector/dialect/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyProvider
b/database/connector/dialect/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyProvider
new file mode 100644
index 00000000000..e6c59302cb9
--- /dev/null
+++
b/database/connector/dialect/firebird/src/main/resources/META-INF/services/org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyProvider
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+org.apache.shardingsphere.database.connector.firebird.metadata.identifier.FirebirdIdentifierCasePolicyProvider
diff --git
a/database/connector/dialect/firebird/src/test/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/loader/FirebirdMetaDataLoaderTest.java
b/database/connector/dialect/firebird/src/test/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/loader/FirebirdMetaDataLoaderTest.java
index 75bf3e1afc1..01e3b61876b 100644
---
a/database/connector/dialect/firebird/src/test/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/loader/FirebirdMetaDataLoaderTest.java
+++
b/database/connector/dialect/firebird/src/test/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/loader/FirebirdMetaDataLoaderTest.java
@@ -22,6 +22,7 @@ import
org.apache.shardingsphere.database.connector.core.metadata.data.loader.Me
import
org.apache.shardingsphere.database.connector.core.metadata.data.loader.type.TableMetaDataLoader;
import
org.apache.shardingsphere.database.connector.core.metadata.data.model.SchemaMetaData;
import
org.apache.shardingsphere.database.connector.core.metadata.data.model.TableMetaData;
+import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicy;
import
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
import
org.apache.shardingsphere.database.connector.firebird.metadata.data.FirebirdBlobInfoRegistry;
@@ -42,6 +43,8 @@ import static org.hamcrest.Matchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.hasSize;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockConstruction;
import static org.mockito.Mockito.mockStatic;
@@ -71,7 +74,7 @@ class FirebirdMetaDataLoaderTest {
mockConstruction(FirebirdNonFixedLengthColumnSizeLoader.class, (mock, context)
-> when(mock.load()).thenReturn(allSizes));
MockedConstruction<FirebirdBlobColumnLoader>
blobColumnLoaderMocked =
mockConstruction(FirebirdBlobColumnLoader.class,
(mock, context) -> when(mock.load()).thenReturn(allBlobColumns))) {
- tableLoaderMocked.when(() -> TableMetaDataLoader.load(dataSource,
"test_table", databaseType)).thenReturn(Optional.of(tableMetaData));
+ tableLoaderMocked.when(() ->
TableMetaDataLoader.load(eq(dataSource), eq("test_table"), eq(databaseType),
any(IdentifierCasePolicy.class))).thenReturn(Optional.of(tableMetaData));
Collection<SchemaMetaData> actual =
dialectMetaDataLoader.load(material);
assertThat(actual, hasSize(1));
SchemaMetaData schema = actual.iterator().next();
diff --git
a/database/connector/dialect/firebird/src/test/java/org/apache/shardingsphere/database/connector/firebird/metadata/identifier/FirebirdIdentifierCasePolicyProviderTest.java
b/database/connector/dialect/firebird/src/test/java/org/apache/shardingsphere/database/connector/firebird/metadata/identifier/FirebirdIdentifierCasePolicyProviderTest.java
new file mode 100644
index 00000000000..011a1711d41
--- /dev/null
+++
b/database/connector/dialect/firebird/src/test/java/org/apache/shardingsphere/database/connector/firebird/metadata/identifier/FirebirdIdentifierCasePolicyProviderTest.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package
org.apache.shardingsphere.database.connector.firebird.metadata.identifier;
+
+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.IdentifierCasePolicyProvider;
+import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicyProviderContext;
+import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierScope;
+import
org.apache.shardingsphere.database.connector.core.metadata.identifier.LookupMode;
+import
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.isA;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class FirebirdIdentifierCasePolicyProviderTest {
+
+ private final DatabaseType databaseType =
TypedSPILoader.getService(DatabaseType.class, "Firebird");
+
+ private final IdentifierCasePolicyProvider provider =
DatabaseTypedSPILoader.getService(IdentifierCasePolicyProvider.class,
databaseType);
+
+ @Test
+ void assertGetDatabaseType() {
+ assertThat(provider, isA(FirebirdIdentifierCasePolicyProvider.class));
+ assertThat(provider.getDatabaseType(), is("Firebird"));
+ }
+
+ @Test
+ void assertProvide() {
+ IdentifierCasePolicy actual = provider.provide(new
IdentifierCasePolicyProviderContext(databaseType,
null)).getPolicy(IdentifierScope.TABLE);
+ assertThat(actual.getLookupMode(QuoteCharacter.NONE),
is(LookupMode.NORMALIZED));
+ assertThat(actual.normalize("Foo"), is("FOO"));
+ assertTrue(actual.matches("FOO", "foo", QuoteCharacter.NONE));
+ assertTrue(actual.matches("Foo", "foo", QuoteCharacter.NONE));
+ assertFalse(actual.matches("Foo", "foo", QuoteCharacter.QUOTE));
+ }
+}
diff --git
a/database/connector/dialect/hive/src/main/java/org/apache/shardingsphere/database/connector/hive/metadata/data/loader/HiveMetaDataLoader.java
b/database/connector/dialect/hive/src/main/java/org/apache/shardingsphere/database/connector/hive/metadata/data/loader/HiveMetaDataLoader.java
index aacc80c7d25..b5386fc3992 100644
---
a/database/connector/dialect/hive/src/main/java/org/apache/shardingsphere/database/connector/hive/metadata/data/loader/HiveMetaDataLoader.java
+++
b/database/connector/dialect/hive/src/main/java/org/apache/shardingsphere/database/connector/hive/metadata/data/loader/HiveMetaDataLoader.java
@@ -60,7 +60,7 @@ public final class HiveMetaDataLoader implements
DialectMetaDataLoader {
return Collections.singleton(new
SchemaMetaData(material.getDefaultSchemaName(), tableMetaData));
}
for (String each : material.getActualTableNames()) {
- TableMetaDataLoader.load(material.getDataSource(), each,
material.getStorageType()).ifPresent(tableMetaData::add);
+ TableMetaDataLoader.load(material.getDataSource(), each,
material.getStorageType(),
material.getTableIdentifierPolicy()).ifPresent(tableMetaData::add);
}
return Collections.singleton(new
SchemaMetaData(material.getDefaultSchemaName(), tableMetaData));
}
diff --git
a/database/connector/dialect/hive/src/test/java/org/apache/shardingsphere/database/connector/hive/metadata/data/loader/HiveMetaDataLoaderTest.java
b/database/connector/dialect/hive/src/test/java/org/apache/shardingsphere/database/connector/hive/metadata/data/loader/HiveMetaDataLoaderTest.java
index f8ddc4a6b10..f2fefbf1d36 100644
---
a/database/connector/dialect/hive/src/test/java/org/apache/shardingsphere/database/connector/hive/metadata/data/loader/HiveMetaDataLoaderTest.java
+++
b/database/connector/dialect/hive/src/test/java/org/apache/shardingsphere/database/connector/hive/metadata/data/loader/HiveMetaDataLoaderTest.java
@@ -26,6 +26,7 @@ import
org.apache.shardingsphere.database.connector.core.metadata.data.model.Col
import
org.apache.shardingsphere.database.connector.core.metadata.data.model.SchemaMetaData;
import
org.apache.shardingsphere.database.connector.core.metadata.data.model.TableMetaData;
import
org.apache.shardingsphere.database.connector.core.metadata.database.datatype.DataTypeRegistry;
+import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicy;
import
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
@@ -55,6 +56,8 @@ import static org.hamcrest.Matchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -116,8 +119,8 @@ class HiveMetaDataLoaderTest {
void assertLoadWithoutInformationSchemaFallbackToDefaultLoader() throws
SQLException {
DataSource dataSource =
mockDataSource(mockInformationSchemaConnection(false));
TableMetaData tableMetaData = new TableMetaData("present_table",
Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
- when(TableMetaDataLoader.load(dataSource, "missing_table",
databaseType)).thenReturn(Optional.empty());
- when(TableMetaDataLoader.load(dataSource, "present_table",
databaseType)).thenReturn(Optional.of(tableMetaData));
+ when(TableMetaDataLoader.load(eq(dataSource), eq("missing_table"),
eq(databaseType),
any(IdentifierCasePolicy.class))).thenReturn(Optional.empty());
+ when(TableMetaDataLoader.load(eq(dataSource), eq("present_table"),
eq(databaseType),
any(IdentifierCasePolicy.class))).thenReturn(Optional.of(tableMetaData));
Collection<SchemaMetaData> fallbackSchemas = loader.load(new
MetaDataLoaderMaterial(Arrays.asList("missing_table", "present_table"), "ds_2",
dataSource, databaseType, "fallback_schema"));
TableMetaData defaultLoadedTable =
fallbackSchemas.iterator().next().getTables().iterator().next();
assertThat(defaultLoadedTable.getName(), is("present_table"));