You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2025/12/26 12:50:27 UTC
(shardingsphere) branch master updated: Support unique key first string column exact splitting (#37543)
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 <zh...@apache.org>
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"));
}
}