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();