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 ef14e2d8076 Add validate for duplicated single table. (#21748)
ef14e2d8076 is described below

commit ef14e2d807647957adfd4aa3ecc731ffa3ac1888
Author: Chuxin Chen <[email protected]>
AuthorDate: Wed Oct 26 09:38:10 2022 +0800

    Add validate for duplicated single table. (#21748)
    
    * Add validate for duplicated single table.
    
    * Add validate for duplicated single table.
    
    * Add validate for duplicated single table.
    
    * Add validate for duplicated single table.
---
 .../engine/SingleTableStandardRouteEngine.java     | 12 +++++++++--
 .../route/SingleTableSQLRouterTest.java            |  1 -
 .../engine/SingleTableStandardRouteEngineTest.java | 25 ++++++++++++++++++++++
 .../AbstractSQLRewriterParameterizedTest.java      | 13 +++++------
 .../EncryptSQLRewriterParameterizedTest.java       |  8 ++++---
 .../scenario/MixSQLRewriterParameterizedTest.java  |  3 ++-
 .../ShardingSQLRewriterParameterizedTest.java      |  6 ++++--
 .../scenario/sharding/case/ddl/create-table.xml    |  4 ++--
 8 files changed, 55 insertions(+), 17 deletions(-)

diff --git 
a/kernel/single-table/core/src/main/java/org/apache/shardingsphere/singletable/route/engine/SingleTableStandardRouteEngine.java
 
b/kernel/single-table/core/src/main/java/org/apache/shardingsphere/singletable/route/engine/SingleTableStandardRouteEngine.java
index 3ababa5b823..9a75ce8881e 100644
--- 
a/kernel/single-table/core/src/main/java/org/apache/shardingsphere/singletable/route/engine/SingleTableStandardRouteEngine.java
+++ 
b/kernel/single-table/core/src/main/java/org/apache/shardingsphere/singletable/route/engine/SingleTableStandardRouteEngine.java
@@ -18,6 +18,7 @@
 package org.apache.shardingsphere.singletable.route.engine;
 
 import lombok.RequiredArgsConstructor;
+import 
org.apache.shardingsphere.dialect.exception.syntax.table.TableExistsException;
 import org.apache.shardingsphere.infra.datanode.DataNode;
 import org.apache.shardingsphere.infra.metadata.database.schema.QualifiedTable;
 import org.apache.shardingsphere.infra.route.context.RouteContext;
@@ -80,13 +81,20 @@ public final class SingleTableStandardRouteEngine 
implements SingleTableRouteEng
     private void route0(final RouteContext routeContext, final SingleTableRule 
rule) {
         if (sqlStatement instanceof CreateTableStatement) {
             String dataSourceName = rule.assignNewDataSourceName();
-            String tableName = 
singleTableNames.iterator().next().getTableName();
-            routeContext.getRouteUnits().add(new RouteUnit(new 
RouteMapper(dataSourceName, dataSourceName), Collections.singleton(new 
RouteMapper(tableName, tableName))));
+            QualifiedTable table = singleTableNames.iterator().next();
+            if (isTableExists(table, rule)) {
+                throw new TableExistsException(table.getTableName());
+            }
+            routeContext.getRouteUnits().add(new RouteUnit(new 
RouteMapper(dataSourceName, dataSourceName), Collections.singleton(new 
RouteMapper(table.getTableName(), table.getTableName()))));
         } else if (sqlStatement instanceof AlterTableStatement || sqlStatement 
instanceof DropTableStatement || rule.isAllTablesInSameDataSource(routeContext, 
singleTableNames)) {
             fillRouteContext(rule, routeContext, 
rule.getSingleTableNames(singleTableNames));
         }
     }
     
+    private boolean isTableExists(final QualifiedTable table, final 
SingleTableRule rule) {
+        return rule.findSingleTableDataNode(table.getSchemaName(), 
table.getTableName()).isPresent();
+    }
+    
     private void fillRouteContext(final SingleTableRule singleTableRule, final 
RouteContext routeContext, final Collection<QualifiedTable> logicTables) {
         for (QualifiedTable each : logicTables) {
             String tableName = each.getTableName();
diff --git 
a/kernel/single-table/core/src/test/java/org/apache/shardingsphere/singletable/route/SingleTableSQLRouterTest.java
 
b/kernel/single-table/core/src/test/java/org/apache/shardingsphere/singletable/route/SingleTableSQLRouterTest.java
index 772e0e1b803..c0963fba2d9 100644
--- 
a/kernel/single-table/core/src/test/java/org/apache/shardingsphere/singletable/route/SingleTableSQLRouterTest.java
+++ 
b/kernel/single-table/core/src/test/java/org/apache/shardingsphere/singletable/route/SingleTableSQLRouterTest.java
@@ -106,7 +106,6 @@ public final class SingleTableSQLRouterTest {
     @Test
     public void assertCreateRouteContextWithMultiDataSource() throws 
SQLException {
         SingleTableRule rule = new SingleTableRule(new 
SingleTableRuleConfiguration(), DefaultDatabase.LOGIC_NAME, 
createMultiDataSourceMap(), Collections.emptyList());
-        rule.getSingleTableDataNodes().put("t_order", 
Collections.singleton(createDataNode("ds_0")));
         ShardingSphereDatabase database = mockDatabaseWithMultipleResources();
         RouteContext actual = new 
SingleTableSQLRouter().createRouteContext(createQueryContext(), database, rule, 
new ConfigurationProperties(new Properties()), new ConnectionContext());
         List<RouteUnit> routeUnits = new ArrayList<>(actual.getRouteUnits());
diff --git 
a/kernel/single-table/core/src/test/java/org/apache/shardingsphere/singletable/route/engine/SingleTableStandardRouteEngineTest.java
 
b/kernel/single-table/core/src/test/java/org/apache/shardingsphere/singletable/route/engine/SingleTableStandardRouteEngineTest.java
index 0626905cfeb..a2775005b6d 100644
--- 
a/kernel/single-table/core/src/test/java/org/apache/shardingsphere/singletable/route/engine/SingleTableStandardRouteEngineTest.java
+++ 
b/kernel/single-table/core/src/test/java/org/apache/shardingsphere/singletable/route/engine/SingleTableStandardRouteEngineTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.singletable.route.engine;
 
+import 
org.apache.shardingsphere.dialect.exception.syntax.table.TableExistsException;
 import org.apache.shardingsphere.infra.database.DefaultDatabase;
 import org.apache.shardingsphere.infra.datanode.DataNode;
 import org.apache.shardingsphere.infra.metadata.database.schema.QualifiedTable;
@@ -25,6 +26,10 @@ import 
org.apache.shardingsphere.infra.route.context.RouteMapper;
 import org.apache.shardingsphere.infra.route.context.RouteUnit;
 import 
org.apache.shardingsphere.singletable.config.SingleTableRuleConfiguration;
 import org.apache.shardingsphere.singletable.rule.SingleTableRule;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.ddl.MySQLCreateTableStatement;
 import org.apache.shardingsphere.test.mock.MockedDataSource;
 import org.junit.Test;
@@ -40,6 +45,7 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -119,4 +125,23 @@ public final class SingleTableStandardRouteEngineTest {
         result.put("ds_1", new MockedDataSource(connection));
         return result;
     }
+    
+    @Test(expected = TableExistsException.class)
+    public void assertRouteDuplicateSingleTable() {
+        SingleTableStandardRouteEngine engine = new 
SingleTableStandardRouteEngine(Collections.singletonList(new 
QualifiedTable(DefaultDatabase.LOGIC_NAME, "t_order")), mockStatement());
+        engine.route(new RouteContext(), mockSingleTableRule());
+    }
+    
+    private SQLStatement mockStatement() {
+        MySQLCreateTableStatement result = new 
MySQLCreateTableStatement(false);
+        result.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new 
IdentifierValue("t_order"))));
+        return result;
+    }
+    
+    private SingleTableRule mockSingleTableRule() {
+        SingleTableRule result = mock(SingleTableRule.class);
+        DataNode dataNode = mock(DataNode.class);
+        when(result.findSingleTableDataNode(DefaultDatabase.LOGIC_NAME, 
"t_order")).thenReturn(Optional.of(dataNode));
+        return result;
+    }
 }
diff --git 
a/test/rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/engine/AbstractSQLRewriterParameterizedTest.java
 
b/test/rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/engine/AbstractSQLRewriterParameterizedTest.java
index eb7ff52a83e..658155cefca 100644
--- 
a/test/rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/engine/AbstractSQLRewriterParameterizedTest.java
+++ 
b/test/rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/engine/AbstractSQLRewriterParameterizedTest.java
@@ -56,6 +56,7 @@ import 
org.apache.shardingsphere.parser.config.SQLParserRuleConfiguration;
 import org.apache.shardingsphere.parser.rule.SQLParserRule;
 import 
org.apache.shardingsphere.parser.rule.builder.DefaultSQLParserRuleConfigurationBuilder;
 import 
org.apache.shardingsphere.sharding.rewrite.parameterized.engine.parameter.SQLRewriteEngineTestParameters;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
 import 
org.apache.shardingsphere.sqltranslator.api.config.SQLTranslatorRuleConfiguration;
 import org.apache.shardingsphere.sqltranslator.rule.SQLTranslatorRule;
 import org.junit.Test;
@@ -114,15 +115,15 @@ public abstract class 
AbstractSQLRewriterParameterizedTest {
         String schemaName = 
DatabaseTypeEngine.getDefaultSchemaName(databaseType, 
DefaultDatabase.LOGIC_NAME);
         Map<String, ShardingSphereSchema> schemas = mockSchemas(schemaName);
         Collection<ShardingSphereRule> databaseRules = 
DatabaseRulesBuilder.build(DefaultDatabase.LOGIC_NAME, databaseConfig, 
mock(InstanceContext.class));
-        mockRules(databaseRules, schemaName);
+        SQLStatementParserEngine sqlStatementParserEngine = new 
SQLStatementParserEngine(getTestParameters().getDatabaseType(),
+                sqlParserRule.getSqlStatementCache(), 
sqlParserRule.getParseTreeCache(), sqlParserRule.isSqlCommentParseEnabled());
+        SQLStatement sqlStatement = 
sqlStatementParserEngine.parse(getTestParameters().getInputSQL(), false);
+        mockRules(databaseRules, schemaName, sqlStatement);
         databaseRules.add(sqlParserRule);
         ShardingSphereDatabase database = new 
ShardingSphereDatabase(schemaName, databaseType, resourceMetaData, new 
ShardingSphereRuleMetaData(databaseRules), schemas);
         Map<String, ShardingSphereDatabase> databases = new HashMap<>(2, 1);
         databases.put(schemaName, database);
-        SQLStatementParserEngine sqlStatementParserEngine = new 
SQLStatementParserEngine(getTestParameters().getDatabaseType(),
-                sqlParserRule.getSqlStatementCache(), 
sqlParserRule.getParseTreeCache(), sqlParserRule.isSqlCommentParseEnabled());
-        SQLStatementContext<?> sqlStatementContext = 
SQLStatementContextFactory.newInstance(databases,
-                
sqlStatementParserEngine.parse(getTestParameters().getInputSQL(), false), 
schemaName);
+        SQLStatementContext<?> sqlStatementContext = 
SQLStatementContextFactory.newInstance(databases, sqlStatement, schemaName);
         if (sqlStatementContext instanceof ParameterAware) {
             ((ParameterAware) 
sqlStatementContext).setUpParameters(getTestParameters().getInputParameters());
         }
@@ -160,5 +161,5 @@ public abstract class AbstractSQLRewriterParameterizedTest {
     
     protected abstract Map<String, ShardingSphereSchema> mockSchemas(String 
schemaName);
     
-    protected abstract void mockRules(Collection<ShardingSphereRule> rules, 
String schemaName);
+    protected abstract void mockRules(Collection<ShardingSphereRule> rules, 
String schemaName, SQLStatement sqlStatement);
 }
diff --git 
a/test/rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/scenario/EncryptSQLRewriterParameterizedTest.java
 
b/test/rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/scenario/EncryptSQLRewriterParameterizedTest.java
index 93469f02c90..52fcd819c4b 100644
--- 
a/test/rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/scenario/EncryptSQLRewriterParameterizedTest.java
+++ 
b/test/rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/scenario/EncryptSQLRewriterParameterizedTest.java
@@ -21,12 +21,14 @@ import com.google.common.base.Preconditions;
 import 
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereSchema;
 import 
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereTable;
 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
-import org.apache.shardingsphere.infra.yaml.config.pojo.YamlRootConfiguration;
 import org.apache.shardingsphere.infra.util.yaml.YamlEngine;
+import org.apache.shardingsphere.infra.yaml.config.pojo.YamlRootConfiguration;
 import 
org.apache.shardingsphere.sharding.rewrite.parameterized.engine.AbstractSQLRewriterParameterizedTest;
 import 
org.apache.shardingsphere.sharding.rewrite.parameterized.engine.parameter.SQLRewriteEngineTestParameters;
 import 
org.apache.shardingsphere.sharding.rewrite.parameterized.engine.parameter.SQLRewriteEngineTestParametersBuilder;
 import org.apache.shardingsphere.singletable.rule.SingleTableRule;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.CreateTableStatement;
 import org.apache.shardingsphere.test.mock.MockedDataSource;
 import org.junit.runners.Parameterized.Parameters;
 
@@ -85,9 +87,9 @@ public final class EncryptSQLRewriterParameterizedTest 
extends AbstractSQLRewrit
     }
     
     @Override
-    protected void mockRules(final Collection<ShardingSphereRule> rules, final 
String schemaName) {
+    protected void mockRules(final Collection<ShardingSphereRule> rules, final 
String schemaName, final SQLStatement sqlStatement) {
         Optional<SingleTableRule> singleTableRule = rules.stream().filter(each 
-> each instanceof SingleTableRule).map(each -> (SingleTableRule) 
each).findFirst();
-        if (singleTableRule.isPresent()) {
+        if (singleTableRule.isPresent() && !(sqlStatement instanceof 
CreateTableStatement)) {
             singleTableRule.get().put("encrypt_ds", schemaName, "t_account");
             singleTableRule.get().put("encrypt_ds", schemaName, 
"t_account_bak");
             singleTableRule.get().put("encrypt_ds", schemaName, 
"t_account_detail");
diff --git 
a/test/rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/scenario/MixSQLRewriterParameterizedTest.java
 
b/test/rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/scenario/MixSQLRewriterParameterizedTest.java
index efdf1db2919..284605cbf33 100644
--- 
a/test/rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/scenario/MixSQLRewriterParameterizedTest.java
+++ 
b/test/rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/scenario/MixSQLRewriterParameterizedTest.java
@@ -28,6 +28,7 @@ import 
org.apache.shardingsphere.infra.yaml.config.pojo.YamlRootConfiguration;
 import 
org.apache.shardingsphere.sharding.rewrite.parameterized.engine.AbstractSQLRewriterParameterizedTest;
 import 
org.apache.shardingsphere.sharding.rewrite.parameterized.engine.parameter.SQLRewriteEngineTestParameters;
 import 
org.apache.shardingsphere.sharding.rewrite.parameterized.engine.parameter.SQLRewriteEngineTestParametersBuilder;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
 import org.junit.runners.Parameterized.Parameters;
 
 import javax.sql.DataSource;
@@ -87,7 +88,7 @@ public final class MixSQLRewriterParameterizedTest extends 
AbstractSQLRewriterPa
     }
     
     @Override
-    protected void mockRules(final Collection<ShardingSphereRule> rules, final 
String schemaName) {
+    protected void mockRules(final Collection<ShardingSphereRule> rules, final 
String schemaName, final SQLStatement sqlStatement) {
     }
     
     @Override
diff --git 
a/test/rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/scenario/ShardingSQLRewriterParameterizedTest.java
 
b/test/rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/scenario/ShardingSQLRewriterParameterizedTest.java
index 68348ad9195..4a163d96a0b 100644
--- 
a/test/rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/scenario/ShardingSQLRewriterParameterizedTest.java
+++ 
b/test/rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/scenario/ShardingSQLRewriterParameterizedTest.java
@@ -29,6 +29,8 @@ import 
org.apache.shardingsphere.sharding.rewrite.parameterized.engine.AbstractS
 import 
org.apache.shardingsphere.sharding.rewrite.parameterized.engine.parameter.SQLRewriteEngineTestParameters;
 import 
org.apache.shardingsphere.sharding.rewrite.parameterized.engine.parameter.SQLRewriteEngineTestParametersBuilder;
 import org.apache.shardingsphere.singletable.rule.SingleTableRule;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.CreateTableStatement;
 import org.junit.runners.Parameterized.Parameters;
 
 import javax.sql.DataSource;
@@ -69,9 +71,9 @@ public final class ShardingSQLRewriterParameterizedTest 
extends AbstractSQLRewri
     }
     
     @Override
-    protected void mockRules(final Collection<ShardingSphereRule> rules, final 
String schemaName) {
+    protected void mockRules(final Collection<ShardingSphereRule> rules, final 
String schemaName, final SQLStatement sqlStatement) {
         Optional<SingleTableRule> singleTableRule = rules.stream().filter(each 
-> each instanceof SingleTableRule).map(each -> (SingleTableRule) 
each).findFirst();
-        if (singleTableRule.isPresent()) {
+        if (singleTableRule.isPresent() && !(sqlStatement instanceof 
CreateTableStatement)) {
             singleTableRule.get().put("db", schemaName, "t_single");
             singleTableRule.get().put("db", schemaName, "t_single_extend");
         }
diff --git 
a/test/rewrite/src/test/resources/scenario/sharding/case/ddl/create-table.xml 
b/test/rewrite/src/test/resources/scenario/sharding/case/ddl/create-table.xml
index 635adc101ba..b732c6b7bd5 100644
--- 
a/test/rewrite/src/test/resources/scenario/sharding/case/ddl/create-table.xml
+++ 
b/test/rewrite/src/test/resources/scenario/sharding/case/ddl/create-table.xml
@@ -67,11 +67,11 @@
     </rewrite-assertion>
     <rewrite-assertion 
id="create_table_with_single_and_single_data_node_table_with_add_foreign_constraint"
 db-types="MySQL,PostgreSQL,openGauss">
         <input sql="CREATE TABLE t_single(order_id INT PRIMARY KEY, CONSTRAINT 
t_single_fk FOREIGN KEY (order_id) REFERENCES t_order (order_id))" />
-        <output sql="CREATE TABLE t_single(order_id INT PRIMARY KEY, 
CONSTRAINT t_single_fk_t_single FOREIGN KEY (order_id) REFERENCES t_order_0 
(order_id))" />
+        <output sql="CREATE TABLE t_single(order_id INT PRIMARY KEY, 
CONSTRAINT t_single_fk FOREIGN KEY (order_id) REFERENCES t_order_0 (order_id))" 
/>
     </rewrite-assertion>
     <rewrite-assertion 
id="create_table_with_single_and_broadcast_table_with_add_foreign_constraint" 
db-types="MySQL,PostgreSQL,openGauss">
         <input sql="CREATE TABLE t_single(order_id INT PRIMARY KEY, CONSTRAINT 
t_single_fk FOREIGN KEY (order_id) REFERENCES t_config (order_id))" />
-        <output sql="CREATE TABLE t_single(order_id INT PRIMARY KEY, 
CONSTRAINT t_single_fk_t_single FOREIGN KEY (order_id) REFERENCES t_config 
(order_id))" />
+        <output sql="CREATE TABLE t_single(order_id INT PRIMARY KEY, 
CONSTRAINT t_single_fk FOREIGN KEY (order_id) REFERENCES t_config (order_id))" 
/>
     </rewrite-assertion>
     <rewrite-assertion 
id="create_table_with_single_table_with_add_foreign_constraint" 
db-types="MySQL,PostgreSQL,openGauss">
         <input sql="CREATE TABLE t_single(order_id INT PRIMARY KEY, CONSTRAINT 
t_single_fk FOREIGN KEY (order_id) REFERENCES t_single_extend (order_id))" />

Reply via email to