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 <[email protected]>
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();

Reply via email to