This is an automated email from the ASF dual-hosted git repository.

zhonghongsheng 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 5358b2372f0 Support unique key first string column exact splitting 
(#37543)
5358b2372f0 is described below

commit 5358b2372f01bf8da23cb0182bed6357b2c06bec
Author: Hongsheng Zhong <[email protected]>
AuthorDate: Fri Dec 26 20:50:20 2025 +0800

    Support unique key first string column exact splitting (#37543)
    
    * Support unique key first string column exact splitting
    
    * Update RELEASE-NOTES.md
---
 RELEASE-NOTES.md                                   |  1 +
 .../position/exact/StringPositionHandler.java      | 46 +++++++++++++++
 ...nventoryIntegerPositionExactCalculatorTest.java |  9 +--
 ...nventoryStringPositionExactCalculatorTest.java} | 65 ++++++++++------------
 4 files changed, 79 insertions(+), 42 deletions(-)

diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index 3ff8a3bfa8a..ae51ea0bc79 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -69,6 +69,7 @@
 1. Pipeline: Support unique key first integer column exact splitting - 
[#37517](https://github.com/apache/shardingsphere/pull/37517)
 1. Pipeline: Improve InventoryPositionEstimatedCalculator: support possible 
null unique key value - 
[#37522](https://github.com/apache/shardingsphere/pull/37522)
 1. Pipeline: Support unique key first integer column exact or estimated 
splitting based on data sparseness - 
[#37542](https://github.com/apache/shardingsphere/pull/37542)
+1. Pipeline: Support unique key first string column exact splitting - 
[#37543](https://github.com/apache/shardingsphere/pull/37543)
 1. Encrypt: Support handling show create view result decoration in encrypt - 
[#37299](https://github.com/apache/shardingsphere/pull/37299)
 1. JDBC: Enhance ResultSetUtils to support flexible string date/time 
conversions - [37424](https://github.com/apache/shardingsphere/pull/37424)
 
diff --git 
a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/preparer/inventory/calculator/position/exact/StringPositionHandler.java
 
b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/preparer/inventory/calculator/position/exact/StringPositionHandler.java
new file mode 100644
index 00000000000..331503f7c24
--- /dev/null
+++ 
b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/preparer/inventory/calculator/position/exact/StringPositionHandler.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.data.pipeline.core.preparer.inventory.calculator.position.exact;
+
+import 
org.apache.shardingsphere.data.pipeline.core.ingest.position.type.pk.PrimaryKeyIngestPosition;
+import 
org.apache.shardingsphere.data.pipeline.core.ingest.position.type.pk.type.StringPrimaryKeyIngestPosition;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * String position handler.
+ */
+public final class StringPositionHandler implements 
DataTypePositionHandler<String> {
+    
+    @Override
+    public String readColumnValue(final ResultSet resultSet, final int 
columnIndex) throws SQLException {
+        return resultSet.getString(columnIndex);
+    }
+    
+    @Override
+    public void setPreparedStatementValue(final PreparedStatement 
preparedStatement, final int parameterIndex, final String value) throws 
SQLException {
+        preparedStatement.setString(parameterIndex, value);
+    }
+    
+    @Override
+    public PrimaryKeyIngestPosition<String> createIngestPosition(final String 
lowerBound, final String upperBound) {
+        return new StringPrimaryKeyIngestPosition(lowerBound, upperBound);
+    }
+}
diff --git 
a/test/it/pipeline/src/test/java/org/apache/shardingsphere/data/pipeline/core/preparer/inventory/calculator/position/exact/InventoryIntegerPositionExactCalculatorTest.java
 
b/test/it/pipeline/src/test/java/org/apache/shardingsphere/data/pipeline/core/preparer/inventory/calculator/position/exact/InventoryIntegerPositionExactCalculatorTest.java
index f155cd679fe..1ae08bb757d 100644
--- 
a/test/it/pipeline/src/test/java/org/apache/shardingsphere/data/pipeline/core/preparer/inventory/calculator/position/exact/InventoryIntegerPositionExactCalculatorTest.java
+++ 
b/test/it/pipeline/src/test/java/org/apache/shardingsphere/data/pipeline/core/preparer/inventory/calculator/position/exact/InventoryIntegerPositionExactCalculatorTest.java
@@ -34,9 +34,9 @@ import java.sql.PreparedStatement;
 import java.sql.SQLException;
 import java.util.List;
 
-import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.isA;
 
 class InventoryIntegerPositionExactCalculatorTest {
     
@@ -84,9 +84,6 @@ class InventoryIntegerPositionExactCalculatorTest {
     void assertGetPositionsWithOrderIdUniqueKey() {
         List<IngestPosition> actual = 
InventoryPositionExactCalculator.getPositions(new QualifiedTable(null, 
"t_order"), "order_id", 3, dataSource, new IntegerPositionHandler());
         assertThat(actual.size(), is(4));
-        for (IngestPosition each : actual) {
-            assertThat(each, 
instanceOf(IntegerPrimaryKeyIngestPosition.class));
-        }
         assertIntegerPrimaryKeyIngestPosition0(actual.get(0), new 
IntegerPrimaryKeyIngestPosition(1L, 3L));
         assertIntegerPrimaryKeyIngestPosition0(actual.get(1), new 
IntegerPrimaryKeyIngestPosition(4L, 6L));
         assertIntegerPrimaryKeyIngestPosition0(actual.get(2), new 
IntegerPrimaryKeyIngestPosition(7L, 9L));
@@ -94,6 +91,7 @@ class InventoryIntegerPositionExactCalculatorTest {
     }
     
     private void assertIntegerPrimaryKeyIngestPosition0(final IngestPosition 
actual, final IntegerPrimaryKeyIngestPosition expected) {
+        assertThat(actual, isA(IntegerPrimaryKeyIngestPosition.class));
         IntegerPrimaryKeyIngestPosition position = 
(IntegerPrimaryKeyIngestPosition) actual;
         assertThat(position.getType(), is(expected.getType()));
         assertThat(position.getBeginValue(), is(expected.getBeginValue()));
@@ -104,9 +102,6 @@ class InventoryIntegerPositionExactCalculatorTest {
     void assertGetPositionsWithMultiColumnUniqueKeys() {
         List<IngestPosition> actual = 
InventoryPositionExactCalculator.getPositions(new QualifiedTable(null, 
"t_order"), "user_id", 3, dataSource, new IntegerPositionHandler());
         assertThat(actual.size(), is(2));
-        for (IngestPosition each : actual) {
-            assertThat(each, 
instanceOf(IntegerPrimaryKeyIngestPosition.class));
-        }
         assertIntegerPrimaryKeyIngestPosition0(actual.get(0), new 
IntegerPrimaryKeyIngestPosition(1L, 3L));
         assertIntegerPrimaryKeyIngestPosition0(actual.get(1), new 
IntegerPrimaryKeyIngestPosition(4L, 6L));
     }
diff --git 
a/test/it/pipeline/src/test/java/org/apache/shardingsphere/data/pipeline/core/preparer/inventory/calculator/position/exact/InventoryIntegerPositionExactCalculatorTest.java
 
b/test/it/pipeline/src/test/java/org/apache/shardingsphere/data/pipeline/core/preparer/inventory/calculator/position/exact/InventoryStringPositionExactCalculatorTest.java
similarity index 60%
copy from 
test/it/pipeline/src/test/java/org/apache/shardingsphere/data/pipeline/core/preparer/inventory/calculator/position/exact/InventoryIntegerPositionExactCalculatorTest.java
copy to 
test/it/pipeline/src/test/java/org/apache/shardingsphere/data/pipeline/core/preparer/inventory/calculator/position/exact/InventoryStringPositionExactCalculatorTest.java
index f155cd679fe..60ab751c35b 100644
--- 
a/test/it/pipeline/src/test/java/org/apache/shardingsphere/data/pipeline/core/preparer/inventory/calculator/position/exact/InventoryIntegerPositionExactCalculatorTest.java
+++ 
b/test/it/pipeline/src/test/java/org/apache/shardingsphere/data/pipeline/core/preparer/inventory/calculator/position/exact/InventoryStringPositionExactCalculatorTest.java
@@ -20,7 +20,7 @@ package 
org.apache.shardingsphere.data.pipeline.core.preparer.inventory.calculat
 import org.apache.commons.text.RandomStringGenerator;
 import 
org.apache.shardingsphere.data.pipeline.core.datasource.PipelineDataSource;
 import 
org.apache.shardingsphere.data.pipeline.core.ingest.position.IngestPosition;
-import 
org.apache.shardingsphere.data.pipeline.core.ingest.position.type.pk.type.IntegerPrimaryKeyIngestPosition;
+import 
org.apache.shardingsphere.data.pipeline.core.ingest.position.type.pk.type.StringPrimaryKeyIngestPosition;
 import org.apache.shardingsphere.data.pipeline.core.util.DataSourceTestUtils;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import org.apache.shardingsphere.infra.metadata.database.schema.QualifiedTable;
@@ -34,17 +34,17 @@ import java.sql.PreparedStatement;
 import java.sql.SQLException;
 import java.util.List;
 
-import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.isA;
 
-class InventoryIntegerPositionExactCalculatorTest {
+class InventoryStringPositionExactCalculatorTest {
     
     private static PipelineDataSource dataSource;
     
     @BeforeAll
     static void setUp() throws Exception {
-        String databaseName = "pos_i_calc_" + 
RandomStringGenerator.builder().withinRange('a', 'z').build().generate(9);
+        String databaseName = "pos_s_calc_" + 
RandomStringGenerator.builder().withinRange('a', 'z').build().generate(9);
         dataSource = new 
PipelineDataSource(DataSourceTestUtils.createHikariDataSource(databaseName), 
TypedSPILoader.getService(DatabaseType.class, "H2"));
         createTableAndInitData(dataSource);
     }
@@ -56,45 +56,43 @@ class InventoryIntegerPositionExactCalculatorTest {
     
     private static void createTableAndInitData(final PipelineDataSource 
dataSource) throws SQLException {
         try (Connection connection = dataSource.getConnection()) {
-            String sql = "CREATE TABLE t_order (user_id INT NOT NULL, order_id 
INT, status VARCHAR(12), PRIMARY KEY (user_id, order_id))";
+            String sql = "CREATE TABLE t_order (user_id VARCHAR(12) NOT NULL, 
order_id VARCHAR(12), status VARCHAR(12), PRIMARY KEY (user_id, order_id))";
             connection.createStatement().execute(sql);
             PreparedStatement preparedStatement = 
connection.prepareStatement("INSERT INTO t_order (user_id, order_id, status) 
VALUES (?, ?, ?)");
-            insertRecord(preparedStatement, 1, 1);
-            insertRecord(preparedStatement, 2, 2);
-            insertRecord(preparedStatement, 3, 3);
-            insertRecord(preparedStatement, 3, 4);
-            insertRecord(preparedStatement, 3, 5);
-            insertRecord(preparedStatement, 3, 6);
-            insertRecord(preparedStatement, 3, 7);
-            insertRecord(preparedStatement, 4, 8);
-            insertRecord(preparedStatement, 5, 9);
-            insertRecord(preparedStatement, 6, 10);
-            insertRecord(preparedStatement, 6, 11);
+            insertRecord(preparedStatement, "a", "a");
+            insertRecord(preparedStatement, "b", "b");
+            insertRecord(preparedStatement, "c", "c");
+            insertRecord(preparedStatement, "c", "d");
+            insertRecord(preparedStatement, "c", "e");
+            insertRecord(preparedStatement, "c", "f");
+            insertRecord(preparedStatement, "c", "g");
+            insertRecord(preparedStatement, "d", "h");
+            insertRecord(preparedStatement, "e", "i");
+            insertRecord(preparedStatement, "f", "j");
+            insertRecord(preparedStatement, "f", "k");
         }
     }
     
-    private static void insertRecord(final PreparedStatement 
preparedStatement, final int userId, final int orderId) throws SQLException {
-        preparedStatement.setInt(1, userId);
-        preparedStatement.setInt(2, orderId);
+    private static void insertRecord(final PreparedStatement 
preparedStatement, final String userId, final String orderId) throws 
SQLException {
+        preparedStatement.setString(1, userId);
+        preparedStatement.setString(2, orderId);
         preparedStatement.setString(3, "OK");
         preparedStatement.executeUpdate();
     }
     
     @Test
     void assertGetPositionsWithOrderIdUniqueKey() {
-        List<IngestPosition> actual = 
InventoryPositionExactCalculator.getPositions(new QualifiedTable(null, 
"t_order"), "order_id", 3, dataSource, new IntegerPositionHandler());
+        List<IngestPosition> actual = 
InventoryPositionExactCalculator.getPositions(new QualifiedTable(null, 
"t_order"), "order_id", 3, dataSource, new StringPositionHandler());
         assertThat(actual.size(), is(4));
-        for (IngestPosition each : actual) {
-            assertThat(each, 
instanceOf(IntegerPrimaryKeyIngestPosition.class));
-        }
-        assertIntegerPrimaryKeyIngestPosition0(actual.get(0), new 
IntegerPrimaryKeyIngestPosition(1L, 3L));
-        assertIntegerPrimaryKeyIngestPosition0(actual.get(1), new 
IntegerPrimaryKeyIngestPosition(4L, 6L));
-        assertIntegerPrimaryKeyIngestPosition0(actual.get(2), new 
IntegerPrimaryKeyIngestPosition(7L, 9L));
-        assertIntegerPrimaryKeyIngestPosition0(actual.get(3), new 
IntegerPrimaryKeyIngestPosition(10L, 11L));
+        assertStringPrimaryKeyIngestPosition0(actual.get(0), new 
StringPrimaryKeyIngestPosition("a", "c"));
+        assertStringPrimaryKeyIngestPosition0(actual.get(1), new 
StringPrimaryKeyIngestPosition("d", "f"));
+        assertStringPrimaryKeyIngestPosition0(actual.get(2), new 
StringPrimaryKeyIngestPosition("g", "i"));
+        assertStringPrimaryKeyIngestPosition0(actual.get(3), new 
StringPrimaryKeyIngestPosition("j", "k"));
     }
     
-    private void assertIntegerPrimaryKeyIngestPosition0(final IngestPosition 
actual, final IntegerPrimaryKeyIngestPosition expected) {
-        IntegerPrimaryKeyIngestPosition position = 
(IntegerPrimaryKeyIngestPosition) actual;
+    private void assertStringPrimaryKeyIngestPosition0(final IngestPosition 
actual, final StringPrimaryKeyIngestPosition expected) {
+        assertThat(actual, isA(StringPrimaryKeyIngestPosition.class));
+        StringPrimaryKeyIngestPosition position = 
(StringPrimaryKeyIngestPosition) actual;
         assertThat(position.getType(), is(expected.getType()));
         assertThat(position.getBeginValue(), is(expected.getBeginValue()));
         assertThat(position.getEndValue(), is(expected.getEndValue()));
@@ -102,12 +100,9 @@ class InventoryIntegerPositionExactCalculatorTest {
     
     @Test
     void assertGetPositionsWithMultiColumnUniqueKeys() {
-        List<IngestPosition> actual = 
InventoryPositionExactCalculator.getPositions(new QualifiedTable(null, 
"t_order"), "user_id", 3, dataSource, new IntegerPositionHandler());
+        List<IngestPosition> actual = 
InventoryPositionExactCalculator.getPositions(new QualifiedTable(null, 
"t_order"), "user_id", 3, dataSource, new StringPositionHandler());
         assertThat(actual.size(), is(2));
-        for (IngestPosition each : actual) {
-            assertThat(each, 
instanceOf(IntegerPrimaryKeyIngestPosition.class));
-        }
-        assertIntegerPrimaryKeyIngestPosition0(actual.get(0), new 
IntegerPrimaryKeyIngestPosition(1L, 3L));
-        assertIntegerPrimaryKeyIngestPosition0(actual.get(1), new 
IntegerPrimaryKeyIngestPosition(4L, 6L));
+        assertStringPrimaryKeyIngestPosition0(actual.get(0), new 
StringPrimaryKeyIngestPosition("a", "c"));
+        assertStringPrimaryKeyIngestPosition0(actual.get(1), new 
StringPrimaryKeyIngestPosition("d", "f"));
     }
 }

Reply via email to