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/30 02:41:35 UTC

(shardingsphere) branch master updated: Use actual name for single table and single rule (#38573)

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 76614974608 Use actual name for single table and single rule (#38573)
76614974608 is described below

commit 766149746087a0deaa121cc6676302512b26b5eb
Author: Haoran Meng <me...@gmail.com>
AuthorDate: Mon Mar 30 10:41:27 2026 +0800

    Use actual name for single table and single rule (#38573)
---
 .../sharding/rule/ShardingTableTest.java           | 20 ++++++++++----------
 .../shardingsphere/infra/datanode/DataNode.java    |  9 ++-------
 .../infra/datanode/DataNodeTest.java               | 18 ++++++++++++++----
 .../shardingsphere/single/rule/SingleRule.java     |  2 +-
 .../SingleMutableDataNodeRuleAttribute.java        |  6 +++---
 .../datanode/SingleTableDataNodeLoaderTest.java    | 13 +++++++++++++
 .../shardingsphere/single/rule/SingleRuleTest.java |  1 +
 .../SingleMutableDataNodeRuleAttributeTest.java    | 22 ++++++++++++++++++++--
 8 files changed, 64 insertions(+), 27 deletions(-)

diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rule/ShardingTableTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rule/ShardingTableTest.java
index 541d665ef30..730399991f7 100644
--- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rule/ShardingTableTest.java
+++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rule/ShardingTableTest.java
@@ -54,8 +54,8 @@ class ShardingTableTest {
         ShardingTable actual = new ShardingTable(shardingTableRuleConfig, Arrays.asList("ds0", "ds1"), null);
         assertThat(actual.getLogicTable(), is("LOGIC_TABLE"));
         assertThat(actual.getActualDataNodes().size(), is(2));
-        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds0", (String) null, "LOGIC_TABLE")));
-        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds1", (String) null, "LOGIC_TABLE")));
+        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds0", (String) null, "logic_table")));
+        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds1", (String) null, "logic_table")));
     }
     
     @Test
@@ -90,10 +90,10 @@ class ShardingTableTest {
         ShardingTable actual = new ShardingTable(shardingAutoTableRuleConfig, Arrays.asList("ds0", "ds1", "ds2"), shardingAlgorithm, null);
         assertThat(actual.getLogicTable(), is("LOGIC_TABLE"));
         assertThat(actual.getActualDataNodes().size(), is(4));
-        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds0", (String) null, "logic_table_0")));
-        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds1", (String) null, "logic_table_1")));
-        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds0", (String) null, "logic_table_2")));
-        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds1", (String) null, "logic_table_3")));
+        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds0", (String) null, "LOGIC_TABLE_0")));
+        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds1", (String) null, "LOGIC_TABLE_1")));
+        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds0", (String) null, "LOGIC_TABLE_2")));
+        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds1", (String) null, "LOGIC_TABLE_3")));
     }
     
     @Test
@@ -104,10 +104,10 @@ class ShardingTableTest {
         ShardingTable actual = new ShardingTable(shardingAutoTableRuleConfig, Arrays.asList("ds0", "ds1", "ds2"), shardingAlgorithm, null);
         assertThat(actual.getLogicTable(), is("LOGIC_TABLE"));
         assertThat(actual.getActualDataNodes().size(), is(4));
-        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds0", (String) null, "logic_table_0")));
-        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds1", (String) null, "logic_table_1")));
-        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds2", (String) null, "logic_table_2")));
-        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds0", (String) null, "logic_table_3")));
+        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds0", (String) null, "LOGIC_TABLE_0")));
+        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds1", (String) null, "LOGIC_TABLE_1")));
+        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds2", (String) null, "LOGIC_TABLE_2")));
+        assertTrue(actual.getActualDataNodes().contains(new DataNode("ds0", (String) null, "LOGIC_TABLE_3")));
     }
     
     @Test
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 e8b64705998..4a8602fcfb6 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
@@ -17,7 +17,6 @@
 
 package org.apache.shardingsphere.infra.datanode;
 
-import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString;
 import com.google.common.base.Objects;
 import com.google.common.base.Splitter;
 import lombok.Getter;
@@ -30,7 +29,6 @@ import org.apache.shardingsphere.infra.exception.ShardingSpherePreconditions;
 import org.apache.shardingsphere.infra.exception.kernel.metadata.datanode.InvalidDataNodeFormatException;
 
 import java.util.List;
-import java.util.Optional;
 
 /**
  * Data node.
@@ -163,14 +161,11 @@ public final class DataNode {
             return false;
         }
         DataNode dataNode = (DataNode) object;
-        return Objects.equal(Optional.ofNullable(dataSourceName).map(CaseInsensitiveString::of).orElse(null), Optional.ofNullable(dataNode.dataSourceName).map(CaseInsensitiveString::of).orElse(null))
-                && Objects.equal(Optional.ofNullable(tableName).map(CaseInsensitiveString::of).orElse(null), Optional.ofNullable(dataNode.tableName).map(CaseInsensitiveString::of).orElse(null))
-                && Objects.equal(Optional.ofNullable(schemaName).map(CaseInsensitiveString::of).orElse(null), Optional.ofNullable(dataNode.schemaName).map(CaseInsensitiveString::of).orElse(null));
+        return Objects.equal(dataSourceName, dataNode.dataSourceName) && Objects.equal(tableName, dataNode.tableName) && Objects.equal(schemaName, dataNode.schemaName);
     }
     
     @Override
     public int hashCode() {
-        return Objects.hashCode(Optional.ofNullable(dataSourceName).map(CaseInsensitiveString::of).orElse(null), Optional.ofNullable(tableName).map(CaseInsensitiveString::of).orElse(null),
-                Optional.ofNullable(schemaName).map(CaseInsensitiveString::of).orElse(null));
+        return Objects.hashCode(dataSourceName, tableName, schemaName);
     }
 }
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 519b0c110c5..738e2a5de21 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
@@ -25,6 +25,8 @@ import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 
+import java.util.Collection;
+import java.util.LinkedHashSet;
 import java.util.stream.Stream;
 
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -101,6 +103,14 @@ class DataNodeTest {
         assertThat(dataNode.hashCode(), is(other.hashCode()));
     }
     
+    @Test
+    void assertCaseSensitiveDataNodesRemainDistinctInSet() {
+        Collection<DataNode> actual = new LinkedHashSet<>();
+        actual.add(new DataNode("foo_ds", "public", "Test3"));
+        actual.add(new DataNode("foo_ds", "public", "test3"));
+        assertThat(actual.size(), is(2));
+    }
+    
     private static Stream<Arguments> dataNodeWithoutSchemaArguments() {
         return Stream.of(
                 Arguments.of("simple_names", "ds_0.tbl_0", "ds_0", "tbl_0"),
@@ -160,7 +170,7 @@ class DataNodeTest {
                 Arguments.of("self", self, self, true),
                 Arguments.of("null_object", new DataNode("ds_0.tbl_0"), null, false),
                 Arguments.of("different_type", new DataNode("ds_0.tbl_0"), "ds.tbl", false),
-                Arguments.of("ignore_case", new DataNode("ds_0.tbl_0"), new DataNode("DS_0.TBL_0"), true),
+                Arguments.of("different_case", new DataNode("ds_0.tbl_0"), new DataNode("DS_0.TBL_0"), false),
                 Arguments.of("different_data_source", new DataNode("ds_0.tbl_0"), new DataNode("ds_1.tbl_0"), false),
                 Arguments.of("different_table", new DataNode("ds_0.tbl_0"), new DataNode("ds_0.tbl_1"), false),
                 Arguments.of("different_schema", new DataNode("ds", "schema1", "tbl"), new DataNode("ds", "schema2", "tbl"), false));
@@ -168,8 +178,8 @@ class DataNodeTest {
     
     private static Stream<Arguments> hashCodeArguments() {
         return Stream.of(
-                Arguments.of("without_schema_ignore_case", new DataNode("ds_0.tbl_0"), new DataNode("DS_0.TBL_0")),
-                Arguments.of("with_schema_ignore_case", new DataNode("ds_0.db_0.tbl_0"), new DataNode("DS_0.DB_0.TBL_0")),
-                Arguments.of("manual_constructor_ignore_case", new DataNode("DS", "SCHEMA", "TBL"), new DataNode("ds", "schema", "tbl")));
+                Arguments.of("without_schema", new DataNode("ds_0.tbl_0"), new DataNode("ds_0.tbl_0")),
+                Arguments.of("with_schema", new DataNode("ds_0.db_0.tbl_0"), new DataNode("ds_0.db_0.tbl_0")),
+                Arguments.of("manual_constructor", new DataNode("ds", "schema", "tbl"), new DataNode("ds", "schema", "tbl")));
     }
 }
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 09a19a0b229..a68bdeebeb9 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
@@ -163,7 +163,7 @@ public final class SingleRule implements DatabaseRule {
     
     private boolean containsDataNode(final QualifiedTable qualifiedTable, final Collection<DataNode> dataNodes) {
         for (DataNode each : dataNodes) {
-            if (qualifiedTable.getSchemaName().equalsIgnoreCase(each.getSchemaName())) {
+            if (qualifiedTable.getSchemaName().equals(each.getSchemaName())) {
                 return true;
             }
         }
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 004afaf45c3..6bf31cba426 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
@@ -79,7 +79,7 @@ public final class SingleMutableDataNodeRuleAttribute implements MutableDataNode
     
     @Override
     public void remove(final String schemaName, final String tableName) {
-        remove(Collections.singleton(schemaName.toLowerCase()), tableName);
+        remove(Collections.singleton(schemaName), tableName);
     }
     
     @Override
@@ -92,7 +92,7 @@ public final class SingleMutableDataNodeRuleAttribute implements MutableDataNode
             Iterator<DataNode> iterator = dataNodes.iterator();
             while (iterator.hasNext()) {
                 DataNode dataNode = iterator.next();
-                if (schemaNames.contains(dataNode.getSchemaName().toLowerCase())) {
+                if (schemaNames.contains(dataNode.getSchemaName())) {
                     iterator.remove();
                     configuration.getTables().remove(SingleTableLoadUtils.getDataNodeString(protocolType, dataNode.getDataSourceName(), dataNode.getSchemaName(), each));
                 }
@@ -109,7 +109,7 @@ public final class SingleMutableDataNodeRuleAttribute implements MutableDataNode
     public Optional<DataNode> findTableDataNode(final String schemaName, final String tableName) {
         Collection<DataNode> dataNodes = findTableDataNodes(tableName);
         for (DataNode each : dataNodes) {
-            if (schemaName.equalsIgnoreCase(each.getSchemaName())) {
+            if (schemaName.equals(each.getSchemaName())) {
                 return Optional.of(each);
             }
         }
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 02ec07589d0..a5edc6c0a81 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
@@ -153,6 +153,19 @@ class SingleTableDataNodeLoaderTest {
         Map<String, Collection<DataNode>> actual = SingleTableDataNodeLoader.load("foo_db", localDataSourceMap, Collections.emptyList());
         assertTrue(actual.containsKey("Test3"));
         assertTrue(actual.containsKey("test3"));
+        assertThat(actual.get("Test3").iterator().next().getTableName(), is("Test3"));
+        assertThat(actual.get("test3").iterator().next().getTableName(), is("test3"));
+    }
+    
+    @Test
+    void assertLoadWithDataSourceMapPreservesCaseSensitiveDataNodes() throws SQLException {
+        Map<String, DataSource> localDataSourceMap = new LinkedHashMap<>(2, 1F);
+        localDataSourceMap.put("foo_ds", mockDataSource("foo_ds", Collections.singletonList("foo_tbl")));
+        localDataSourceMap.put("FOO_DS", mockDataSource("FOO_DS", Collections.singletonList("foo_tbl")));
+        Map<String, Collection<DataNode>> actual = SingleTableDataNodeLoader.load("foo_db", localDataSourceMap, Collections.emptyList());
+        assertThat(actual.get("foo_tbl").size(), is(2));
+        assertThat(actual.get("foo_tbl").stream().map(DataNode::getDataSourceName).collect(Collectors.toCollection(LinkedHashSet::new)),
+                is(new LinkedHashSet<>(Arrays.asList("foo_ds", "FOO_DS"))));
     }
     
     @Test
diff --git a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/SingleRuleTest.java b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/SingleRuleTest.java
index 28e42e5caef..de1b9b88559 100644
--- a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/SingleRuleTest.java
+++ b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/SingleRuleTest.java
@@ -391,6 +391,7 @@ class SingleRuleTest {
     private static Stream<Arguments> getSingleTablesArguments() {
         return Stream.of(
                 Arguments.of("table exists in same schema", new QualifiedTable("foo_db", "employee"), true, "foo_db", "employee"),
+                Arguments.of("table exists in schema with different case", new QualifiedTable("FOO_DB", "employee"), false, null, null),
                 Arguments.of("table exists in different schema", new QualifiedTable("bar_db", "employee"), false, null, null),
                 Arguments.of("table does not exist", new QualifiedTable("foo_db", "missing_table"), false, null, null));
     }
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 fde01f3b9d5..4af16930726 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
@@ -79,12 +79,27 @@ class SingleMutableDataNodeRuleAttributeTest {
         Map<String, Collection<DataNode>> singleTableDataNodes = createSingleTableDataNodes(Collections.singleton(dataNode));
         SingleTableMapperRuleAttribute tableMapperRuleAttribute = new SingleTableMapperRuleAttribute(singleTableDataNodes.values());
         SingleMutableDataNodeRuleAttribute ruleAttribute = createRuleAttribute(ruleConfig, Collections.singleton("foo_ds"), singleTableDataNodes, tableMapperRuleAttribute);
-        ruleAttribute.remove("foo_schema".toUpperCase(), "foo_tbl");
+        ruleAttribute.remove("foo_schema", "foo_tbl");
         assertFalse(singleTableDataNodes.containsKey("foo_tbl"));
         assertFalse(ruleConfig.getTables().contains(SingleTableLoadUtils.getDataNodeString(DATABASE_TYPE, "foo_ds", "foo_schema", "foo_tbl")));
         assertFalse(tableMapperRuleAttribute.getLogicTableNames().contains("foo_tbl"));
     }
     
+    @Test
+    void assertRemoveWithSchemaNameDifferentCase() {
+        DataNode dataNode = new DataNode("foo_ds", "foo_schema", "foo_tbl");
+        String dataNodeString = SingleTableLoadUtils.getDataNodeString(DATABASE_TYPE, "foo_ds", "foo_schema", "foo_tbl");
+        SingleRuleConfiguration ruleConfig = new SingleRuleConfiguration(new LinkedList<>(Collections.singleton(dataNodeString)), null);
+        Map<String, Collection<DataNode>> singleTableDataNodes = createSingleTableDataNodes(Collections.singleton(dataNode));
+        SingleTableMapperRuleAttribute tableMapperRuleAttribute = new SingleTableMapperRuleAttribute(singleTableDataNodes.values());
+        SingleMutableDataNodeRuleAttribute ruleAttribute = createRuleAttribute(ruleConfig, Collections.singleton("foo_ds"), singleTableDataNodes, tableMapperRuleAttribute);
+        ruleAttribute.remove("FOO_SCHEMA", "foo_tbl");
+        assertTrue(singleTableDataNodes.containsKey("foo_tbl"));
+        assertThat(singleTableDataNodes.get("foo_tbl").size(), is(1));
+        assertTrue(ruleConfig.getTables().contains(dataNodeString));
+        assertTrue(tableMapperRuleAttribute.getLogicTableNames().contains("foo_tbl"));
+    }
+    
     @ParameterizedTest(name = "{0}")
     @MethodSource("removeWithSchemaNamesArguments")
     void assertRemoveWithSchemaNames(final String name, final Collection<DataNode> initialDataNodes, final Collection<String> schemaNames,
@@ -181,6 +196,8 @@ class SingleMutableDataNodeRuleAttributeTest {
         return Stream.of(
                 Arguments.of("keep data node when schema not matched", Collections.singleton(fooDataNode), Collections.singleton("baz_schema"), 1,
                         Collections.singleton(SingleTableLoadUtils.getDataNodeString(DATABASE_TYPE, "foo_ds", "foo_schema", "foo_tbl")), true, true),
+                Arguments.of("keep data node when schema differs only by case", Collections.singleton(fooDataNode), Collections.singleton("FOO_SCHEMA"), 1,
+                        Collections.singleton(SingleTableLoadUtils.getDataNodeString(DATABASE_TYPE, "foo_ds", "foo_schema", "foo_tbl")), true, true),
                 Arguments.of("remove matched schema and keep others", Arrays.asList(fooDataNode, barDataNode), Collections.singleton("foo_schema"), 1,
                         Collections.singleton(SingleTableLoadUtils.getDataNodeString(DATABASE_TYPE, "foo_ds", "bar_schema", "foo_tbl")), true, true),
                 Arguments.of("remove all matched schemas", Collections.singleton(fooDataNode), Collections.singleton("foo_schema"), 0, Collections.emptyList(), false, false));
@@ -189,7 +206,8 @@ class SingleMutableDataNodeRuleAttributeTest {
     private static Stream<Arguments> findTableDataNodeArguments() {
         DataNode dataNode = new DataNode("foo_ds", "foo_schema", "foo_tbl");
         return Stream.of(
-                Arguments.of("return data node when schema matched", Collections.singleton(dataNode), "foo_schema".toUpperCase(), "foo_tbl".toUpperCase(), true, "foo_ds"),
+                Arguments.of("return data node when schema matched", Collections.singleton(dataNode), "foo_schema", "foo_tbl".toUpperCase(), true, "foo_ds"),
+                Arguments.of("return empty when schema differs only by case", Collections.singleton(dataNode), "FOO_SCHEMA", "foo_tbl", false, ""),
                 Arguments.of("return empty when schema mismatched", Collections.singleton(dataNode), "bar_schema", "foo_tbl", false, ""),
                 Arguments.of("return empty when table not exists", Collections.emptyList(), "foo_schema", "bar_table", false, ""));
     }