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