You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2021/08/11 10:16:50 UTC
[shardingsphere] branch master updated: Insert clause not support
routing to multiple dataNodes when is not broadcastTable. #11623 (#11750)
This is an automated email from the ASF dual-hosted git repository.
duanzhengqiang 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 382e6a6 Insert clause not support routing to multiple dataNodes when is not broadcastTable. #11623 (#11750)
382e6a6 is described below
commit 382e6a6a7c3a2363a9522038ab808e861d1353c9
Author: chengh1 <39...@users.noreply.github.com>
AuthorDate: Wed Aug 11 18:16:19 2021 +0800
Insert clause not support routing to multiple dataNodes when is not broadcastTable. #11623 (#11750)
* Insert clause not support routing to multiple dataNodes when is not broadcastTable. #11623
* change exception message and variable name. #11750
---
.../dml/impl/ShardingInsertStatementValidator.java | 16 ++++--
.../dml/ShardingInsertStatementValidatorTest.java | 63 +++++++++++++++++++++-
2 files changed, 75 insertions(+), 4 deletions(-)
diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingInsertStatementValidator.java b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingInsertStatementValidator.java
index 29e9d3d..aacc2aa 100644
--- a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingInsertStatementValidator.java
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingInsertStatementValidator.java
@@ -41,11 +41,11 @@ import java.util.Optional;
* Sharding insert statement validator.
*/
public final class ShardingInsertStatementValidator extends ShardingDMLStatementValidator<InsertStatement> {
-
+
private boolean needCheckDatabaseInstance;
@Override
- public void preValidate(final ShardingRule shardingRule, final SQLStatementContext<InsertStatement> sqlStatementContext,
+ public void preValidate(final ShardingRule shardingRule, final SQLStatementContext<InsertStatement> sqlStatementContext,
final List<Object> parameters, final ShardingSphereSchema schema) {
if (null == ((InsertStatementContext) sqlStatementContext).getInsertSelectContext()) {
validateShardingMultipleTable(shardingRule, sqlStatementContext);
@@ -92,10 +92,20 @@ public final class ShardingInsertStatementValidator extends ShardingDMLStatement
}
@Override
- public void postValidate(final ShardingRule shardingRule, final SQLStatementContext<InsertStatement> sqlStatementContext,
+ public void postValidate(final ShardingRule shardingRule, final SQLStatementContext<InsertStatement> sqlStatementContext,
final RouteContext routeContext, final ShardingSphereSchema schema) {
if (needCheckDatabaseInstance) {
Preconditions.checkState(routeContext.isSingleRouting(), "Sharding value must same with subquery.");
}
+ if (routeContext.isSingleRouting()) {
+ return;
+ }
+ String tableName = sqlStatementContext.getSqlStatement().getTable().getTableName().getIdentifier().getValue();
+ if (shardingRule.isBroadcastTable(tableName)) {
+ return;
+ }
+ if (routeContext.getOriginalDataNodes().stream().anyMatch(dataNodes -> dataNodes.size() > 1)) {
+ throw new ShardingSphereException("Insert statement does not support sharding table routing to multiple data nodes.");
+ }
}
}
diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/ShardingInsertStatementValidatorTest.java b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/ShardingInsertStatementValidatorTest.java
index 71447b7..91c8321 100644
--- a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/ShardingInsertStatementValidatorTest.java
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/ShardingInsertStatementValidatorTest.java
@@ -21,9 +21,11 @@ import org.apache.shardingsphere.infra.binder.segment.table.TablesContext;
import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.binder.statement.dml.InsertStatementContext;
import org.apache.shardingsphere.infra.database.DefaultSchema;
+import org.apache.shardingsphere.infra.datanode.DataNode;
import org.apache.shardingsphere.infra.exception.ShardingSphereException;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
+import org.apache.shardingsphere.infra.route.context.RouteContext;
import org.apache.shardingsphere.sharding.route.engine.validator.dml.impl.ShardingInsertStatementValidator;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment;
@@ -61,6 +63,9 @@ public final class ShardingInsertStatementValidatorTest {
@Mock
private ShardingRule shardingRule;
+ @Mock
+ private RouteContext routeContext;
+
@Test(expected = ShardingSphereException.class)
public void assertValidateInsertModifyMultiTables() {
SQLStatementContext<InsertStatement> sqlStatementContext = createInsertStatementContext(Collections.singletonList(1), createInsertStatement());
@@ -130,6 +135,62 @@ public final class ShardingInsertStatementValidatorTest {
new ShardingInsertStatementValidator().preValidate(shardingRule, sqlStatementContext, Collections.emptyList(), mock(ShardingSphereSchema.class));
}
+ @Test
+ public void assertValidateInsertWithSingleRouting() {
+ SQLStatementContext<InsertStatement> sqlStatementContext = createInsertStatementContext(Collections.singletonList(1), createInsertStatement());
+ when(routeContext.isSingleRouting()).thenReturn(true);
+ new ShardingInsertStatementValidator().postValidate(shardingRule, sqlStatementContext, routeContext, mock(ShardingSphereSchema.class));
+ }
+
+ @Test
+ public void assertValidateInsertWithBroadcastTable() {
+ SQLStatementContext<InsertStatement> sqlStatementContext = createInsertStatementContext(Collections.singletonList(1), createInsertStatement());
+ when(routeContext.isSingleRouting()).thenReturn(false);
+ when(shardingRule.isBroadcastTable(sqlStatementContext.getSqlStatement().getTable().getTableName().getIdentifier().getValue())).thenReturn(true);
+ new ShardingInsertStatementValidator().postValidate(shardingRule, sqlStatementContext, routeContext, mock(ShardingSphereSchema.class));
+ }
+
+ @Test
+ public void assertValidateInsertWithRoutingToSingleDataNode() {
+ SQLStatementContext<InsertStatement> sqlStatementContext = createInsertStatementContext(Collections.singletonList(1), createInsertStatement());
+ when(routeContext.isSingleRouting()).thenReturn(false);
+ when(shardingRule.isBroadcastTable(sqlStatementContext.getSqlStatement().getTable().getTableName().getIdentifier().getValue())).thenReturn(false);
+ when(routeContext.getOriginalDataNodes()).thenReturn(getSingleRouteDataNodes());
+ new ShardingInsertStatementValidator().postValidate(shardingRule, sqlStatementContext, routeContext, mock(ShardingSphereSchema.class));
+ }
+
+ @Test(expected = ShardingSphereException.class)
+ public void assertValidateInsertWithRoutingToMultipleDataNodes() {
+ SQLStatementContext<InsertStatement> sqlStatementContext = createInsertStatementContext(Collections.singletonList(1), createInsertStatement());
+ when(routeContext.isSingleRouting()).thenReturn(false);
+ when(shardingRule.isBroadcastTable(sqlStatementContext.getSqlStatement().getTable().getTableName().getIdentifier().getValue())).thenReturn(false);
+ when(routeContext.getOriginalDataNodes()).thenReturn(getMultipleRouteDataNodes());
+ new ShardingInsertStatementValidator().postValidate(shardingRule, sqlStatementContext, routeContext, mock(ShardingSphereSchema.class));
+ }
+
+ private Collection<Collection<DataNode>> getMultipleRouteDataNodes() {
+ Collection<DataNode> value1DataNodes = new LinkedList<>();
+ value1DataNodes.add(new DataNode("ds_0", "user_0"));
+ Collection<DataNode> value2DataNodes = new LinkedList<>();
+ value2DataNodes.add(new DataNode("ds_0", "user_0"));
+ value2DataNodes.add(new DataNode("ds_0", "user_1"));
+ Collection<Collection<DataNode>> result = new LinkedList<>();
+ result.add(value1DataNodes);
+ result.add(value2DataNodes);
+ return result;
+ }
+
+ private Collection<Collection<DataNode>> getSingleRouteDataNodes() {
+ Collection<DataNode> value1DataNodes = new LinkedList<>();
+ value1DataNodes.add(new DataNode("ds_0", "user_0"));
+ Collection<DataNode> value2DataNodes = new LinkedList<>();
+ value2DataNodes.add(new DataNode("ds_0", "user_0"));
+ Collection<Collection<DataNode>> result = new LinkedList<>();
+ result.add(value1DataNodes);
+ result.add(value2DataNodes);
+ return result;
+ }
+
private InsertStatement createInsertStatement() {
MySQLInsertStatement result = new MySQLInsertStatement();
result.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("user"))));
@@ -141,7 +202,7 @@ public final class ShardingInsertStatementValidatorTest {
result.setInsertColumns(new InsertColumnsSegment(0, 0, columns));
return result;
}
-
+
private InsertStatement createInsertSelectStatement() {
InsertStatement result = createInsertStatement();
SelectStatement selectStatement = new MySQLSelectStatement();