You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by me...@apache.org on 2026/03/20 06:30:40 UTC
(shardingsphere) branch master updated: Supports loading single tables with case-insensitive names (#38524)
This is an automated email from the ASF dual-hosted git repository.
menghaoran 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 59ea12e0d02 Supports loading single tables with case-insensitive names (#38524)
59ea12e0d02 is described below
commit 59ea12e0d02b889e8e8f8f13d880c64e2264914c
Author: Haoran Meng <me...@gmail.com>
AuthorDate: Fri Mar 20 14:30:34 2026 +0800
Supports loading single tables with case-insensitive names (#38524)
---
.../data/loader/type/SchemaMetaDataLoader.java | 8 +--
.../data/loader/type/SchemaMetaDataLoaderTest.java | 36 ++++++++++-
.../shardingsphere/infra/datanode/DataNode.java | 2 +-
.../infra/datanode/DataNodeTest.java | 2 +-
.../single/datanode/SingleTableDataNodeLoader.java | 11 ++--
.../shardingsphere/single/rule/SingleRule.java | 2 +-
.../attribute/SingleDataNodeRuleAttribute.java | 11 +++-
.../SingleMutableDataNodeRuleAttribute.java | 72 +++++++++++++++++-----
.../attribute/SingleTableMapperRuleAttribute.java | 4 +-
.../single/util/SingleTableLoadUtils.java | 3 +-
.../datanode/SingleTableDataNodeLoaderTest.java | 9 +++
.../single/route/engine/SingleRouteEngineTest.java | 6 +-
.../SingleMutableDataNodeRuleAttributeTest.java | 13 ++++
.../SingleTableMapperRuleAttributeTest.java | 9 +++
.../single/util/SingleTableLoadUtilsTest.java | 3 +-
15 files changed, 151 insertions(+), 40 deletions(-)
diff --git a/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/type/SchemaMetaDataLoader.java b/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/type/SchemaMetaDataLoader.java
index f7f39abc5be..099e16e1fa2 100644
--- a/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/type/SchemaMetaDataLoader.java
+++ b/database/connector/core/src/main/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/type/SchemaMetaDataLoader.java
@@ -17,8 +17,6 @@
package org.apache.shardingsphere.database.connector.core.metadata.data.loader.type;
-import com.cedarsoftware.util.CaseInsensitiveMap;
-import com.cedarsoftware.util.CaseInsensitiveSet;
import org.apache.shardingsphere.database.connector.core.metadata.data.loader.MetaDataLoaderConnection;
import org.apache.shardingsphere.database.connector.core.metadata.database.metadata.DialectDatabaseMetaData;
import org.apache.shardingsphere.database.connector.core.metadata.database.metadata.option.schema.DialectSchemaOption;
@@ -32,6 +30,8 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Map;
@@ -76,7 +76,7 @@ public final class SchemaMetaDataLoader {
public Map<String, Collection<String>> loadSchemaTableNames(final String databaseName, final DataSource dataSource, final Collection<String> excludedTables) throws SQLException {
try (MetaDataLoaderConnection connection = new MetaDataLoaderConnection(databaseType, dataSource.getConnection())) {
Collection<String> schemaNames = loadSchemaNames(connection);
- Map<String, Collection<String>> result = new CaseInsensitiveMap<>(schemaNames.size(), 1F);
+ Map<String, Collection<String>> result = new LinkedHashMap<>(schemaNames.size(), 1F);
for (String each : schemaNames) {
String schemaName = schemaOption.getDefaultSchema().isPresent() ? each : databaseName;
result.put(schemaName, loadTableNames(connection, each, excludedTables));
@@ -110,7 +110,7 @@ public final class SchemaMetaDataLoader {
}
private Collection<String> loadTableNames(final Connection connection, final String schemaName, final Collection<String> excludedTables) throws SQLException {
- Collection<String> result = new CaseInsensitiveSet<>();
+ Collection<String> result = new LinkedHashSet<>();
String[] tableTypes = new String[]{TABLE_TYPE, PARTITIONED_TABLE_TYPE, VIEW_TYPE, SYSTEM_TABLE_TYPE, SYSTEM_VIEW_TYPE};
try (ResultSet resultSet = connection.getMetaData().getTables(connection.getCatalog(), schemaName, null, tableTypes)) {
while (resultSet.next()) {
diff --git a/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/type/SchemaMetaDataLoaderTest.java b/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/type/SchemaMetaDataLoaderTest.java
index f14e2ff1b84..a89ba8ef5aa 100644
--- a/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/type/SchemaMetaDataLoaderTest.java
+++ b/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/type/SchemaMetaDataLoaderTest.java
@@ -17,7 +17,6 @@
package org.apache.shardingsphere.database.connector.core.metadata.data.loader.type;
-import com.cedarsoftware.util.CaseInsensitiveSet;
import org.apache.shardingsphere.database.connector.core.metadata.database.metadata.DialectDatabaseMetaData;
import org.apache.shardingsphere.database.connector.core.metadata.database.metadata.option.schema.DialectSchemaOption;
import org.apache.shardingsphere.database.connector.core.metadata.database.system.DialectSystemDatabase;
@@ -36,7 +35,9 @@ import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Optional;
@@ -80,7 +81,7 @@ class SchemaMetaDataLoaderTest {
when(connection.getMetaData().getTables("catalog", "public", null, TABLE_TYPES)).thenReturn(tableResultSet);
Map<String, Collection<String>> actual = new SchemaMetaDataLoader(databaseType)
.loadSchemaTableNames("logic_db", dataSourceWithoutDefaultSchema, Collections.singleton("excluded_tbl"));
- Map<String, Collection<String>> expected = Collections.singletonMap("logic_db", new CaseInsensitiveSet<>(Collections.singleton("tbl")));
+ Map<String, Collection<String>> expected = Collections.singletonMap("logic_db", new LinkedHashSet<>(Collections.singleton("tbl")));
assertThat(actual, is(expected));
}
}
@@ -110,12 +111,41 @@ class SchemaMetaDataLoaderTest {
when(tableResultSet.getString("TABLE_NAME")).thenReturn("tbl_visible");
when(connection.getMetaData().getTables("catalog_2", "user_schema", null, TABLE_TYPES)).thenReturn(tableResultSet);
Map<String, Collection<String>> actual = new SchemaMetaDataLoader(databaseType).loadSchemaTableNames("logic_db_2", dataSourceWithDefaultSchema, Collections.emptyList());
- Map<String, Collection<String>> expected = Collections.singletonMap("user_schema", new CaseInsensitiveSet<>(Collections.singleton("tbl_visible")));
+ Map<String, Collection<String>> expected = Collections.singletonMap("user_schema", new LinkedHashSet<>(Collections.singleton("tbl_visible")));
assertThat(actual, is(expected));
}
}
}
+ @Test
+ void assertLoadSchemaTableNamesPreservesCaseSensitiveTableNames() throws SQLException {
+ DialectSchemaOption schemaOption = mock(DialectSchemaOption.class);
+ when(schemaOption.getDefaultSchema()).thenReturn(Optional.of("public"));
+ DialectDatabaseMetaData dialectDatabaseMetaData = mock(DialectDatabaseMetaData.class);
+ when(dialectDatabaseMetaData.getSchemaOption()).thenReturn(schemaOption);
+ DialectSystemDatabase dialectSystemDatabase = mock(DialectSystemDatabase.class);
+ when(dialectSystemDatabase.getSystemSchemas()).thenReturn(Collections.emptySet());
+ try (MockedStatic<DatabaseTypedSPILoader> databaseTypedSPILoader = mockStatic(DatabaseTypedSPILoader.class)) {
+ databaseTypedSPILoader.when(() -> DatabaseTypedSPILoader.getService(DialectDatabaseMetaData.class, databaseType)).thenReturn(dialectDatabaseMetaData);
+ databaseTypedSPILoader.when(() -> DatabaseTypedSPILoader.findService(DialectSystemDatabase.class, databaseType)).thenReturn(Optional.of(dialectSystemDatabase));
+ try (MockedStatic<TypedSPILoader> typedSPILoader = mockStatic(TypedSPILoader.class)) {
+ typedSPILoader.when(() -> TypedSPILoader.getService(DialectDatabaseMetaData.class, null)).thenReturn(dialectDatabaseMetaData);
+ Connection connection = dataSourceWithDefaultSchema.getConnection();
+ when(connection.getCatalog()).thenReturn("catalog_3");
+ ResultSet schemaResultSet = mock(ResultSet.class);
+ when(schemaResultSet.next()).thenReturn(true, false);
+ when(schemaResultSet.getString("TABLE_SCHEM")).thenReturn("public");
+ when(connection.getMetaData().getSchemas()).thenReturn(schemaResultSet);
+ ResultSet tableResultSet = mock(ResultSet.class);
+ when(tableResultSet.next()).thenReturn(true, true, false);
+ when(tableResultSet.getString("TABLE_NAME")).thenReturn("Test3", "test3");
+ when(connection.getMetaData().getTables("catalog_3", "public", null, TABLE_TYPES)).thenReturn(tableResultSet);
+ Map<String, Collection<String>> actual = new SchemaMetaDataLoader(databaseType).loadSchemaTableNames("logic_db_3", dataSourceWithDefaultSchema, Collections.emptyList());
+ assertThat(actual.get("public"), is(new LinkedHashSet<>(Arrays.asList("Test3", "test3"))));
+ }
+ }
+ }
+
@Test
void assertLoadSchemaNames() throws SQLException {
DialectSchemaOption schemaOption = mock(DialectSchemaOption.class);
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/datanode/DataNode.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/datanode/DataNode.java
index 034af2eb099..e8b64705998 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/datanode/DataNode.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/datanode/DataNode.java
@@ -78,7 +78,7 @@ public final class DataNode {
List<String> segments = Splitter.on(DELIMITER).limit(containsSchema ? 3 : 2).splitToList(dataNode);
dataSourceName = segments.get(0);
schemaName = getSchemaName(databaseName, dialectDatabaseMetaData, containsSchema, segments);
- tableName = containsSchema ? segments.get(2).toLowerCase() : segments.get(1).toLowerCase();
+ tableName = containsSchema ? segments.get(2) : segments.get(1);
}
private String getSchemaName(final String databaseName, final DialectDatabaseMetaData dialectDatabaseMetaData, final boolean containsSchema, final List<String> segments) {
diff --git a/infra/common/src/test/java/org/apache/shardingsphere/infra/datanode/DataNodeTest.java b/infra/common/src/test/java/org/apache/shardingsphere/infra/datanode/DataNodeTest.java
index df10653d8dd..519b0c110c5 100644
--- a/infra/common/src/test/java/org/apache/shardingsphere/infra/datanode/DataNodeTest.java
+++ b/infra/common/src/test/java/org/apache/shardingsphere/infra/datanode/DataNodeTest.java
@@ -138,7 +138,7 @@ class DataNodeTest {
Arguments.of("postgresql_without_schema_segment", "test_db", POSTGRESQL_DATABASE_TYPE, "ds.tbl", "ds", "*", "tbl"),
Arguments.of("mysql_without_schema_support", "test_db", MYSQL_DATABASE_TYPE, "ds.tbl", "ds", "test_db", "tbl"),
Arguments.of("mysql_three_segments_kept_as_table_suffix", "test_db", MYSQL_DATABASE_TYPE, "ds.schema.tbl", "ds", "test_db", "schema.tbl"),
- Arguments.of("postgresql_lowercases_table", "test_db", POSTGRESQL_DATABASE_TYPE, "ds.schema.TABLE", "ds", "schema", "table"));
+ Arguments.of("postgresql_preserves_table_case", "test_db", POSTGRESQL_DATABASE_TYPE, "ds.schema.TABLE", "ds", "schema", "TABLE"));
}
private static Stream<Arguments> formatArguments() {
diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoader.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoader.java
index 052b4f4ccd7..0983df1d11a 100644
--- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoader.java
+++ b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoader.java
@@ -17,7 +17,6 @@
package org.apache.shardingsphere.single.datanode;
-import com.cedarsoftware.util.CaseInsensitiveMap;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.shardingsphere.database.connector.core.metadata.data.loader.type.SchemaMetaDataLoader;
@@ -85,14 +84,14 @@ public final class SingleTableDataNodeLoader {
* @return single table data node map
*/
public static Map<String, Collection<DataNode>> load(final String databaseName, final Map<String, DataSource> dataSourceMap, final Collection<String> excludedTables) {
- Map<String, Collection<DataNode>> result = new ConcurrentHashMap<>();
+ Map<String, Collection<DataNode>> result = new LinkedHashMap<>(dataSourceMap.size(), 1F);
for (Entry<String, DataSource> entry : dataSourceMap.entrySet()) {
Map<String, Collection<DataNode>> dataNodeMap = load(databaseName, DatabaseTypeEngine.getStorageType(entry.getValue()), entry.getKey(), entry.getValue(), excludedTables);
for (Entry<String, Collection<DataNode>> each : dataNodeMap.entrySet()) {
Collection<DataNode> addedDataNodes = each.getValue();
- Collection<DataNode> existDataNodes = result.getOrDefault(each.getKey().toLowerCase(), new LinkedHashSet<>(addedDataNodes.size(), 1F));
+ Collection<DataNode> existDataNodes = result.getOrDefault(each.getKey(), new LinkedHashSet<>(addedDataNodes.size(), 1F));
existDataNodes.addAll(addedDataNodes);
- result.putIfAbsent(each.getKey().toLowerCase(), existDataNodes);
+ result.putIfAbsent(each.getKey(), existDataNodes);
}
}
return result;
@@ -101,7 +100,7 @@ public final class SingleTableDataNodeLoader {
private static Map<String, Collection<DataNode>> load(final String databaseName, final DatabaseType storageType, final String dataSourceName,
final DataSource dataSource, final Collection<String> excludedTables) {
Map<String, Collection<String>> schemaTableNames = loadSchemaTableNames(databaseName, storageType, dataSource, dataSourceName, excludedTables);
- Map<String, Collection<DataNode>> result = new CaseInsensitiveMap<>();
+ Map<String, Collection<DataNode>> result = new LinkedHashMap<>(schemaTableNames.size(), 1F);
for (Entry<String, Collection<String>> entry : schemaTableNames.entrySet()) {
for (String each : entry.getValue()) {
Collection<DataNode> dataNodes = result.getOrDefault(each, new LinkedList<>());
@@ -144,7 +143,7 @@ public final class SingleTableDataNodeLoader {
if (null == configuredTablesForSchema) {
continue;
}
- if (configuredTablesForSchema.contains(SingleTableConstants.ASTERISK) || configuredTablesForSchema.contains(each.getTableName().toLowerCase())) {
+ if (configuredTablesForSchema.contains(SingleTableConstants.ASTERISK) || configuredTablesForSchema.contains(each.getTableName())) {
result.add(each);
}
}
diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/SingleRule.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/SingleRule.java
index c3fbcfefa71..09a19a0b229 100644
--- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/SingleRule.java
+++ b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/SingleRule.java
@@ -153,7 +153,7 @@ public final class SingleRule implements DatabaseRule {
public Collection<QualifiedTable> getSingleTables(final Collection<QualifiedTable> qualifiedTables) {
Collection<QualifiedTable> result = new LinkedList<>();
for (QualifiedTable each : qualifiedTables) {
- Collection<DataNode> dataNodes = singleTableDataNodes.getOrDefault(each.getTableName().toLowerCase(), new LinkedList<>());
+ Collection<DataNode> dataNodes = mutableDataNodeRuleAttribute.findTableDataNodes(each.getTableName());
if (!dataNodes.isEmpty() && containsDataNode(each, dataNodes)) {
result.add(each);
}
diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/attribute/SingleDataNodeRuleAttribute.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/attribute/SingleDataNodeRuleAttribute.java
index 9451ae702df..85ceefcd6eb 100644
--- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/attribute/SingleDataNodeRuleAttribute.java
+++ b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/attribute/SingleDataNodeRuleAttribute.java
@@ -23,6 +23,7 @@ import org.apache.shardingsphere.infra.rule.attribute.datanode.DataNodeRuleAttri
import java.util.Collection;
import java.util.Collections;
+import java.util.Map.Entry;
import java.util.Map;
import java.util.Optional;
@@ -41,7 +42,15 @@ public final class SingleDataNodeRuleAttribute implements DataNodeRuleAttribute
@Override
public Collection<DataNode> getDataNodesByTableName(final String tableName) {
- return tableDataNodes.getOrDefault(tableName.toLowerCase(), Collections.emptyList());
+ if (tableDataNodes.containsKey(tableName)) {
+ return tableDataNodes.get(tableName);
+ }
+ for (Entry<String, Collection<DataNode>> entry : tableDataNodes.entrySet()) {
+ if (entry.getKey().equalsIgnoreCase(tableName)) {
+ return entry.getValue();
+ }
+ }
+ return Collections.emptyList();
}
@Override
diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/attribute/SingleMutableDataNodeRuleAttribute.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/attribute/SingleMutableDataNodeRuleAttribute.java
index d0b03eca632..004afaf45c3 100644
--- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/attribute/SingleMutableDataNodeRuleAttribute.java
+++ b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/attribute/SingleMutableDataNodeRuleAttribute.java
@@ -18,6 +18,7 @@
package org.apache.shardingsphere.single.rule.attribute;
import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseTypeRegistry;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
import org.apache.shardingsphere.infra.datanode.DataNode;
@@ -30,9 +31,11 @@ import org.apache.shardingsphere.single.util.SingleTableLoadUtils;
import javax.sql.DataSource;
import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Optional;
/**
@@ -55,7 +58,7 @@ public final class SingleMutableDataNodeRuleAttribute implements MutableDataNode
@Override
public void put(final String dataSourceName, final String schemaName, final String tableName) {
if (dataSourceNames.contains(dataSourceName)) {
- Collection<DataNode> dataNodes = singleTableDataNodes.computeIfAbsent(tableName.toLowerCase(), key -> new LinkedHashSet<>());
+ Collection<DataNode> dataNodes = singleTableDataNodes.computeIfAbsent(tableName, key -> new LinkedHashSet<>());
dataNodes.add(new DataNode(dataSourceName, schemaName, tableName));
tableMapperRuleAttribute.getLogicTableNames().add(tableName);
addTableConfiguration(dataSourceName, schemaName, tableName);
@@ -81,28 +84,30 @@ public final class SingleMutableDataNodeRuleAttribute implements MutableDataNode
@Override
public void remove(final Collection<String> schemaNames, final String tableName) {
- if (!singleTableDataNodes.containsKey(tableName.toLowerCase())) {
- return;
- }
- Collection<DataNode> dataNodes = singleTableDataNodes.get(tableName.toLowerCase());
- Iterator<DataNode> iterator = dataNodes.iterator();
- while (iterator.hasNext()) {
- DataNode each = iterator.next();
- if (schemaNames.contains(each.getSchemaName().toLowerCase())) {
- iterator.remove();
- configuration.getTables().remove(SingleTableLoadUtils.getDataNodeString(protocolType, each.getDataSourceName(), each.getSchemaName(), tableName));
+ for (String each : findMatchedTableKeys(tableName)) {
+ Collection<DataNode> dataNodes = singleTableDataNodes.get(each);
+ if (null == dataNodes) {
+ continue;
+ }
+ Iterator<DataNode> iterator = dataNodes.iterator();
+ while (iterator.hasNext()) {
+ DataNode dataNode = iterator.next();
+ if (schemaNames.contains(dataNode.getSchemaName().toLowerCase())) {
+ iterator.remove();
+ configuration.getTables().remove(SingleTableLoadUtils.getDataNodeString(protocolType, dataNode.getDataSourceName(), dataNode.getSchemaName(), each));
+ }
+ }
+ if (dataNodes.isEmpty()) {
+ singleTableDataNodes.remove(each);
+ tableMapperRuleAttribute.getLogicTableNames().remove(each);
}
- }
- if (dataNodes.isEmpty()) {
- singleTableDataNodes.remove(tableName.toLowerCase());
- tableMapperRuleAttribute.getLogicTableNames().remove(tableName);
}
}
@SuppressWarnings("CollectionWithoutInitialCapacity")
@Override
public Optional<DataNode> findTableDataNode(final String schemaName, final String tableName) {
- Collection<DataNode> dataNodes = singleTableDataNodes.getOrDefault(tableName.toLowerCase(), new LinkedHashSet<>());
+ Collection<DataNode> dataNodes = findTableDataNodes(tableName);
for (DataNode each : dataNodes) {
if (schemaName.equalsIgnoreCase(each.getSchemaName())) {
return Optional.of(each);
@@ -111,6 +116,41 @@ public final class SingleMutableDataNodeRuleAttribute implements MutableDataNode
return Optional.empty();
}
+ /**
+ * Find table data nodes.
+ *
+ * @param tableName table name
+ * @return table data nodes
+ */
+ public Collection<DataNode> findTableDataNodes(final String tableName) {
+ for (String each : findMatchedTableKeys(tableName)) {
+ Collection<DataNode> dataNodes = singleTableDataNodes.get(each);
+ if (null != dataNodes) {
+ return dataNodes;
+ }
+ }
+ return Collections.emptyList();
+ }
+
+ private Collection<String> findMatchedTableKeys(final String tableName) {
+ Collection<String> result = new LinkedList<>();
+ String formattedTableName = new DatabaseTypeRegistry(protocolType).formatIdentifierPattern(tableName);
+ if (singleTableDataNodes.containsKey(formattedTableName)) {
+ result.add(formattedTableName);
+ return result;
+ }
+ if (singleTableDataNodes.containsKey(tableName)) {
+ result.add(tableName);
+ return result;
+ }
+ for (Entry<String, Collection<DataNode>> entry : singleTableDataNodes.entrySet()) {
+ if (entry.getKey().equalsIgnoreCase(tableName)) {
+ result.add(entry.getKey());
+ }
+ }
+ return result;
+ }
+
@Override
public ShardingSphereRule reloadRule(final RuleConfiguration ruleConfig, final String databaseName, final Map<String, DataSource> dataSourceMap,
final Collection<ShardingSphereRule> builtRules) {
diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/attribute/SingleTableMapperRuleAttribute.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/attribute/SingleTableMapperRuleAttribute.java
index e338d4a410a..4e3de843b71 100644
--- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/attribute/SingleTableMapperRuleAttribute.java
+++ b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/attribute/SingleTableMapperRuleAttribute.java
@@ -17,12 +17,12 @@
package org.apache.shardingsphere.single.rule.attribute;
-import com.cedarsoftware.util.CaseInsensitiveSet;
import org.apache.shardingsphere.infra.datanode.DataNode;
import org.apache.shardingsphere.infra.rule.attribute.table.TableMapperRuleAttribute;
import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedHashSet;
/**
* Single table mapper rule attribute.
@@ -36,7 +36,7 @@ public final class SingleTableMapperRuleAttribute implements TableMapperRuleAttr
}
private Collection<String> createLogicalTableNames(final Collection<Collection<DataNode>> singleTableDataNodes) {
- Collection<String> result = new CaseInsensitiveSet<>(singleTableDataNodes.size(), 1F);
+ Collection<String> result = new LinkedHashSet<>(singleTableDataNodes.size(), 1F);
singleTableDataNodes.forEach(each -> result.add(each.iterator().next().getTableName()));
return result;
}
diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/util/SingleTableLoadUtils.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/util/SingleTableLoadUtils.java
index c790fae9458..c9782810ec7 100644
--- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/util/SingleTableLoadUtils.java
+++ b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/util/SingleTableLoadUtils.java
@@ -30,6 +30,7 @@ import org.apache.shardingsphere.infra.rule.attribute.table.TableMapperRuleAttri
import org.apache.shardingsphere.single.constant.SingleTableConstants;
import java.util.Collection;
+import java.util.LinkedList;
import java.util.LinkedHashSet;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -107,7 +108,7 @@ public final class SingleTableLoadUtils {
* @return data nodes
*/
public static Collection<DataNode> convertToDataNodes(final String databaseName, final DatabaseType databaseType, final Collection<String> dataNodes) {
- return dataNodes.stream().map(each -> new DataNode(databaseName, databaseType, each)).collect(Collectors.toCollection(() -> new LinkedHashSet<>(dataNodes.size(), 1F)));
+ return dataNodes.stream().map(each -> new DataNode(databaseName, databaseType, each)).collect(Collectors.toCollection(LinkedList::new));
}
/**
diff --git a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoaderTest.java b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoaderTest.java
index 8e8b04f07b7..02ec07589d0 100644
--- a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoaderTest.java
+++ b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoaderTest.java
@@ -146,6 +146,15 @@ class SingleTableDataNodeLoaderTest {
assertThat(new TreeSet<>(actual.get("bar_tbl1").stream().map(DataNode::getDataSourceName).collect(Collectors.toList())), is(new TreeSet<>(Collections.singleton("bar_ds"))));
}
+ @Test
+ void assertLoadWithDataSourceMapPreservesCaseSensitiveTableNames() throws SQLException {
+ Map<String, DataSource> localDataSourceMap = new LinkedHashMap<>(1, 1F);
+ localDataSourceMap.put("foo_ds", mockDataSource("foo_ds", Arrays.asList("Test3", "test3")));
+ Map<String, Collection<DataNode>> actual = SingleTableDataNodeLoader.load("foo_db", localDataSourceMap, Collections.emptyList());
+ assertTrue(actual.containsKey("Test3"));
+ assertTrue(actual.containsKey("test3"));
+ }
+
@Test
void assertLoadSchemaTableNames() {
Map<String, Collection<String>> actual = SingleTableDataNodeLoader.loadSchemaTableNames("foo_db", databaseType, dataSourceMap.get("foo_ds"), "foo_ds", Collections.singleton("foo_tbl2"));
diff --git a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngineTest.java b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngineTest.java
index 78a8e44943f..850e709a745 100644
--- a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngineTest.java
+++ b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngineTest.java
@@ -75,7 +75,7 @@ class SingleRouteEngineTest {
@Test
void assertRouteInSameDataSource() throws SQLException {
SingleRouteEngine engine = new SingleRouteEngine(Arrays.asList(new QualifiedTable("foo_db", "t_order"), new QualifiedTable("foo_db", "t_order_item")), null, mock());
- SingleRule singleRule = new SingleRule(new SingleRuleConfiguration(), "foo_db", mock(), createDataSourceMap(), Collections.emptyList());
+ SingleRule singleRule = new SingleRule(new SingleRuleConfiguration(), "foo_db", databaseType, createDataSourceMap(), Collections.emptyList());
singleRule.getAttributes().getAttribute(DataNodeRuleAttribute.class).getAllDataNodes().put("t_order", Collections.singleton(new DataNode("ds_0", "foo_db", "t_order")));
singleRule.getAttributes().getAttribute(DataNodeRuleAttribute.class).getAllDataNodes().put("t_order_item", Collections.singleton(new DataNode("ds_0", "foo_db", "t_order_item")));
RouteContext routeContext = new RouteContext();
@@ -97,7 +97,7 @@ class SingleRouteEngineTest {
void assertRouteWithoutSingleRule() throws SQLException {
CreateTableStatement sqlStatement = CreateTableStatement.builder().databaseType(databaseType).build();
SingleRouteEngine engine = new SingleRouteEngine(Arrays.asList(new QualifiedTable("foo_db", "t_order"), new QualifiedTable("foo_db", "t_order_item")), sqlStatement, mock());
- SingleRule singleRule = new SingleRule(new SingleRuleConfiguration(), "foo_db", mock(), createDataSourceMap(), Collections.emptyList());
+ SingleRule singleRule = new SingleRule(new SingleRuleConfiguration(), "foo_db", databaseType, createDataSourceMap(), Collections.emptyList());
RouteContext routeContext = new RouteContext();
assertThat(routeContext.getOriginalDataNodes().size(), is(0));
engine.route(routeContext, singleRule);
@@ -114,7 +114,7 @@ class SingleRouteEngineTest {
void assertRouteWithDefaultSingleRule() throws SQLException {
CreateTableStatement sqlStatement = CreateTableStatement.builder().databaseType(databaseType).build();
SingleRouteEngine engine = new SingleRouteEngine(Arrays.asList(new QualifiedTable("foo_db", "t_order"), new QualifiedTable("foo_db", "t_order_item")), sqlStatement, mock());
- SingleRule singleRule = new SingleRule(new SingleRuleConfiguration(Collections.emptyList(), "ds_0"), "foo_db", mock(), createDataSourceMap(), Collections.emptyList());
+ SingleRule singleRule = new SingleRule(new SingleRuleConfiguration(Collections.emptyList(), "ds_0"), "foo_db", databaseType, createDataSourceMap(), Collections.emptyList());
RouteContext routeContext = new RouteContext();
assertThat(routeContext.getRouteUnits().size(), is(0));
engine.route(routeContext, singleRule);
diff --git a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/attribute/SingleMutableDataNodeRuleAttributeTest.java b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/attribute/SingleMutableDataNodeRuleAttributeTest.java
index ced44f028a7..fde01f3b9d5 100644
--- a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/attribute/SingleMutableDataNodeRuleAttributeTest.java
+++ b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/attribute/SingleMutableDataNodeRuleAttributeTest.java
@@ -134,6 +134,19 @@ class SingleMutableDataNodeRuleAttributeTest {
}
}
+ @Test
+ void assertFindTableDataNodesWithCaseSensitiveTables() {
+ SingleRuleConfiguration ruleConfig = new SingleRuleConfiguration(new LinkedList<>(Arrays.asList("foo_ds.public.Test3", "foo_ds.public.test3")), null);
+ Map<String, Collection<DataNode>> singleTableDataNodes = new LinkedHashMap<>(2, 1F);
+ singleTableDataNodes.put("Test3", new LinkedHashSet<>(Collections.singleton(new DataNode("foo_ds", "public", "Test3"))));
+ singleTableDataNodes.put("test3", new LinkedHashSet<>(Collections.singleton(new DataNode("foo_ds", "public", "test3"))));
+ SingleTableMapperRuleAttribute tableMapperRuleAttribute = new SingleTableMapperRuleAttribute(singleTableDataNodes.values());
+ SingleMutableDataNodeRuleAttribute ruleAttribute = createRuleAttribute(ruleConfig, Collections.singleton("foo_ds"), singleTableDataNodes, tableMapperRuleAttribute);
+ Collection<DataNode> actual = ruleAttribute.findTableDataNodes("Test3");
+ assertThat(actual.size(), is(1));
+ assertThat(actual.iterator().next().getTableName(), is("Test3"));
+ }
+
@Test
void assertReloadRule() {
SingleRuleConfiguration ruleConfig = new SingleRuleConfiguration(new LinkedList<>(Collections.emptyList()), null);
diff --git a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/attribute/SingleTableMapperRuleAttributeTest.java b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/attribute/SingleTableMapperRuleAttributeTest.java
index 5dab754d9cf..b473b9e24fa 100644
--- a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/attribute/SingleTableMapperRuleAttributeTest.java
+++ b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/attribute/SingleTableMapperRuleAttributeTest.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.single.rule.attribute;
import org.apache.shardingsphere.infra.datanode.DataNode;
import org.junit.jupiter.api.Test;
+import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
@@ -35,6 +36,14 @@ class SingleTableMapperRuleAttributeTest {
assertThat(new LinkedList<>(ruleAttribute.getLogicTableNames()), is(Collections.singletonList("foo_tbl")));
}
+ @Test
+ void assertGetLogicTableMapperWithCaseSensitiveTables() {
+ SingleTableMapperRuleAttribute actual = new SingleTableMapperRuleAttribute(Arrays.asList(
+ Collections.singleton(new DataNode("foo_ds", "public", "Test3")),
+ Collections.singleton(new DataNode("foo_ds", "public", "test3"))));
+ assertThat(new LinkedList<>(actual.getLogicTableNames()), is(Arrays.asList("Test3", "test3")));
+ }
+
@Test
void assertGetDistributedTableMapper() {
assertThat(new LinkedList<>(ruleAttribute.getDistributedTableNames()), is(Collections.emptyList()));
diff --git a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/util/SingleTableLoadUtilsTest.java b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/util/SingleTableLoadUtilsTest.java
index 2d2d3eaa794..f646959551b 100644
--- a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/util/SingleTableLoadUtilsTest.java
+++ b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/util/SingleTableLoadUtilsTest.java
@@ -36,6 +36,7 @@ import org.mockito.MockedConstruction;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.LinkedHashSet;
import java.util.Optional;
import java.util.TreeSet;
@@ -89,7 +90,7 @@ class SingleTableLoadUtilsTest {
DataNode expectedDataNode1 = new DataNode("foo_ds", "foo_db", "foo_tbl");
DataNode expectedDataNode2 = new DataNode("bar_ds", "foo_db", "bar_tbl");
assertThat(SingleTableLoadUtils.convertToDataNodes("foo_db", databaseType, Arrays.asList("foo_ds.foo_tbl", "bar_ds.bar_tbl")),
- is(new LinkedHashSet<>(Arrays.asList(expectedDataNode1, expectedDataNode2))));
+ is(new LinkedList<>(Arrays.asList(expectedDataNode1, expectedDataNode2))));
}
@Test