You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by ji...@apache.org on 2022/12/26 03:38:43 UTC

[shardingsphere] branch master updated: Add `IF NOT EXISTS` for `create sharding table rule` (#23093)

This is an automated email from the ASF dual-hosted git repository.

jianglongtao 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 d1873a0787a Add `IF NOT EXISTS` for `create sharding table rule` (#23093)
d1873a0787a is described below

commit d1873a0787aabc4dd7f1def9cd1fe9df15a3ecb5
Author: Zichao <57...@users.noreply.github.com>
AuthorDate: Mon Dec 26 16:38:37 2022 +1300

    Add `IF NOT EXISTS` for `create sharding table rule` (#23093)
    
    * Add `IF NOT EXISTS` to `create sharding table rule`
    
    * Add `IF NOT EXISTS` to `create sharding table rule`
---
 .../checker/ShardingTableRuleStatementChecker.java | 36 +++++++------
 .../CreateShardingTableRuleStatementUpdater.java   | 18 ++++++-
 .../checker/ShardingRuleStatementCheckerTest.java  | 44 +++++++++-------
 ...reateShardingTableRuleStatementUpdaterTest.java | 59 ++++++++++++++++++++--
 .../src/main/antlr4/imports/sharding/Keyword.g4    |  4 ++
 .../main/antlr4/imports/sharding/RDLStatement.g4   |  6 ++-
 .../core/ShardingDistSQLStatementVisitor.java      |  2 +-
 .../CreateShardingTableRuleStatement.java          |  7 ++-
 8 files changed, 135 insertions(+), 41 deletions(-)

diff --git a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/checker/ShardingTableRuleStatementChecker.java b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/checker/ShardingTableRuleStatementChecker.java
index 3ceae987112..90abdd16198 100644
--- a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/checker/ShardingTableRuleStatementChecker.java
+++ b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/checker/ShardingTableRuleStatementChecker.java
@@ -89,10 +89,12 @@ public final class ShardingTableRuleStatementChecker {
      *
      * @param database database
      * @param rules rules
+     * @param ifNotExists if not exists
      * @param currentRuleConfig current rule configuration
      */
-    public static void checkCreation(final ShardingSphereDatabase database, final Collection<AbstractTableRuleSegment> rules, final ShardingRuleConfiguration currentRuleConfig) {
-        check(database, rules, currentRuleConfig, true);
+    public static void checkCreation(final ShardingSphereDatabase database, final Collection<AbstractTableRuleSegment> rules, final boolean ifNotExists,
+                                     final ShardingRuleConfiguration currentRuleConfig) {
+        check(database, rules, ifNotExists, currentRuleConfig, true);
     }
     
     /**
@@ -103,7 +105,7 @@ public final class ShardingTableRuleStatementChecker {
      * @param currentRuleConfig current rule configuration
      */
     public static void checkAlteration(final ShardingSphereDatabase database, final Collection<AbstractTableRuleSegment> rules, final ShardingRuleConfiguration currentRuleConfig) {
-        check(database, rules, currentRuleConfig, false);
+        check(database, rules, false, currentRuleConfig, false);
     }
     
     /**
@@ -121,9 +123,10 @@ public final class ShardingTableRuleStatementChecker {
         return check(toBeCheckedRuleConfig, dataSourceNames);
     }
     
-    private static void check(final ShardingSphereDatabase database, final Collection<AbstractTableRuleSegment> rules, final ShardingRuleConfiguration currentRuleConfig, final boolean isCreated) {
+    private static void check(final ShardingSphereDatabase database, final Collection<AbstractTableRuleSegment> rules, final boolean ifNotExists, final ShardingRuleConfiguration currentRuleConfig,
+                              final boolean isCreated) {
         String databaseName = database.getName();
-        checkTables(databaseName, rules, currentRuleConfig, isCreated);
+        checkTables(databaseName, rules, currentRuleConfig, isCreated, ifNotExists);
         checkResources(databaseName, rules, database);
         checkKeyGenerators(rules, currentRuleConfig);
         checkAuditors(rules);
@@ -205,31 +208,34 @@ public final class ShardingTableRuleStatementChecker {
         return dataNodeStr.contains(DELIMITER) && 2 == Splitter.on(DELIMITER).omitEmptyStrings().splitToList(dataNodeStr).size();
     }
     
-    private static void checkTables(final String databaseName, final Collection<AbstractTableRuleSegment> rules, final ShardingRuleConfiguration currentRuleConfig, final boolean isCreate) {
+    private static void checkTables(final String databaseName, final Collection<AbstractTableRuleSegment> rules, final ShardingRuleConfiguration currentRuleConfig, final boolean isCreate,
+                                    final boolean ifNotExists) {
         Collection<String> requiredTables = rules.stream().map(AbstractTableRuleSegment::getLogicTable).collect(Collectors.toList());
-        Collection<String> duplicatedTables = getDuplicate(requiredTables);
-        ShardingSpherePreconditions.checkState(duplicatedTables.isEmpty(), () -> new DuplicateRuleException("sharding", databaseName, duplicatedTables));
+        Collection<String> duplicatedRuleNames = getDuplicatedRuleNames(requiredTables);
+        ShardingSpherePreconditions.checkState(duplicatedRuleNames.isEmpty(), () -> new DuplicateRuleException("sharding", databaseName, duplicatedRuleNames));
         Collection<String> currentShardingTables = null == currentRuleConfig ? Collections.emptyList() : getCurrentShardingTables(currentRuleConfig);
         if (isCreate) {
-            Collection<String> identical = getIdentical(requiredTables, currentShardingTables);
-            ShardingSpherePreconditions.checkState(identical.isEmpty(), () -> new DuplicateRuleException("sharding", databaseName, identical));
+            if (!ifNotExists) {
+                duplicatedRuleNames.addAll(getDuplicatedRuleNames(requiredTables, currentShardingTables));
+                ShardingSpherePreconditions.checkState(duplicatedRuleNames.isEmpty(), () -> new DuplicateRuleException("sharding", databaseName, duplicatedRuleNames));
+            }
         } else {
-            Collection<String> different = getDifferent(requiredTables, currentShardingTables);
-            ShardingSpherePreconditions.checkState(different.isEmpty(), () -> new MissingRequiredRuleException("sharding", databaseName, different));
+            Collection<String> notExistsRules = getNotExistsRules(requiredTables, currentShardingTables);
+            ShardingSpherePreconditions.checkState(notExistsRules.isEmpty(), () -> new MissingRequiredRuleException("sharding", databaseName, notExistsRules));
         }
     }
     
-    private static Collection<String> getDuplicate(final Collection<String> collection) {
+    private static Collection<String> getDuplicatedRuleNames(final Collection<String> collection) {
         Collection<String> duplicate = collection.stream().collect(Collectors.groupingBy(String::toLowerCase, Collectors.counting())).entrySet().stream()
                 .filter(each -> each.getValue() > 1).map(Entry::getKey).collect(Collectors.toSet());
         return collection.stream().filter(each -> containsIgnoreCase(duplicate, each)).collect(Collectors.toSet());
     }
     
-    private static Collection<String> getIdentical(final Collection<String> require, final Collection<String> current) {
+    private static Collection<String> getDuplicatedRuleNames(final Collection<String> require, final Collection<String> current) {
         return require.stream().filter(each -> containsIgnoreCase(current, each)).collect(Collectors.toSet());
     }
     
-    private static Set<String> getDifferent(final Collection<String> require, final Collection<String> current) {
+    private static Set<String> getNotExistsRules(final Collection<String> require, final Collection<String> current) {
         return require.stream().filter(each -> !containsIgnoreCase(current, each)).collect(Collectors.toSet());
     }
     
diff --git a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/CreateShardingTableRuleStatementUpdater.java b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/CreateShardingTableRuleStatementUpdater.java
index d6d7e9cd297..4934086d4ff 100644
--- a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/CreateShardingTableRuleStatementUpdater.java
+++ b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/CreateShardingTableRuleStatementUpdater.java
@@ -24,14 +24,20 @@ import org.apache.shardingsphere.sharding.distsql.handler.checker.ShardingTableR
 import org.apache.shardingsphere.sharding.distsql.handler.converter.ShardingTableRuleStatementConverter;
 import org.apache.shardingsphere.sharding.distsql.parser.statement.CreateShardingTableRuleStatement;
 
+import java.util.Collection;
+import java.util.LinkedList;
+
 /**
  * Create sharding table rule statement updater.
  */
 public final class CreateShardingTableRuleStatementUpdater implements RuleDefinitionCreateUpdater<CreateShardingTableRuleStatement, ShardingRuleConfiguration> {
     
+    private boolean ifNotExists;
+    
     @Override
     public void checkSQLStatement(final ShardingSphereDatabase database, final CreateShardingTableRuleStatement sqlStatement, final ShardingRuleConfiguration currentRuleConfig) {
-        ShardingTableRuleStatementChecker.checkCreation(database, sqlStatement.getRules(), currentRuleConfig);
+        ifNotExists = sqlStatement.isIfNotExists();
+        ShardingTableRuleStatementChecker.checkCreation(database, sqlStatement.getRules(), ifNotExists, currentRuleConfig);
     }
     
     @Override
@@ -41,6 +47,16 @@ public final class CreateShardingTableRuleStatementUpdater implements RuleDefini
     
     @Override
     public void updateCurrentRuleConfiguration(final ShardingRuleConfiguration currentRuleConfig, final ShardingRuleConfiguration toBeCreatedRuleConfig) {
+        if (ifNotExists) {
+            Collection<String> currentTables = new LinkedList<>();
+            currentRuleConfig.getTables().forEach(each -> currentTables.add(each.getLogicTable()));
+            currentRuleConfig.getAutoTables().forEach(each -> currentTables.add(each.getLogicTable()));
+            toBeCreatedRuleConfig.getTables().removeIf(each -> currentTables.contains(each.getLogicTable()));
+            toBeCreatedRuleConfig.getAutoTables().removeIf(each -> currentTables.contains(each.getLogicTable()));
+            if (toBeCreatedRuleConfig.getTables().isEmpty() && toBeCreatedRuleConfig.getAutoTables().isEmpty()) {
+                return;
+            }
+        }
         currentRuleConfig.getTables().addAll(toBeCreatedRuleConfig.getTables());
         currentRuleConfig.getAutoTables().addAll(toBeCreatedRuleConfig.getAutoTables());
         currentRuleConfig.getShardingAlgorithms().putAll(toBeCreatedRuleConfig.getShardingAlgorithms());
diff --git a/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/checker/ShardingRuleStatementCheckerTest.java b/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/checker/ShardingRuleStatementCheckerTest.java
index e483fda2230..6cf2907c611 100644
--- a/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/checker/ShardingRuleStatementCheckerTest.java
+++ b/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/checker/ShardingRuleStatementCheckerTest.java
@@ -87,7 +87,7 @@ public final class ShardingRuleStatementCheckerTest {
         Collection<AbstractTableRuleSegment> rules = new LinkedList<>();
         rules.add(createCompleteAutoTableRule());
         rules.add(createCompleteTableRule());
-        ShardingTableRuleStatementChecker.checkCreation(database, rules, shardingRuleConfig);
+        ShardingTableRuleStatementChecker.checkCreation(database, rules, false, shardingRuleConfig);
         rules.clear();
         rules.add(new AutoTableRuleSegment("t_order", Arrays.asList("ds_0", "ds_1")));
         ShardingTableRuleStatementChecker.checkAlteration(database, rules, shardingRuleConfig);
@@ -110,13 +110,13 @@ public final class ShardingRuleStatementCheckerTest {
         List<AbstractTableRuleSegment> rules = Arrays.asList(
                 new AutoTableRuleSegment("t_order_duplicated", Arrays.asList("ds_0", "ds_1")),
                 new AutoTableRuleSegment("t_order_duplicated", Arrays.asList("ds_0", "ds_1")));
-        ShardingTableRuleStatementChecker.checkCreation(database, rules, shardingRuleConfig);
+        ShardingTableRuleStatementChecker.checkCreation(database, rules, false, shardingRuleConfig);
     }
     
     @Test(expected = DuplicateRuleException.class)
     public void assertCheckCreationWithIdentical() {
         List<AbstractTableRuleSegment> rules = Collections.singletonList(new AutoTableRuleSegment("t_order", Arrays.asList("ds_0", "ds_1")));
-        ShardingTableRuleStatementChecker.checkCreation(database, rules, shardingRuleConfig);
+        ShardingTableRuleStatementChecker.checkCreation(database, rules, false, shardingRuleConfig);
     }
     
     @Test(expected = MissingRequiredRuleException.class)
@@ -128,14 +128,14 @@ public final class ShardingRuleStatementCheckerTest {
     @Test(expected = MissingRequiredResourcesException.class)
     public void assertCheckCreationWithResourceRequiredMissed() {
         List<AbstractTableRuleSegment> rules = Collections.singletonList(new AutoTableRuleSegment("t_product", Arrays.asList("ds_required_missed", "ds_1")));
-        ShardingTableRuleStatementChecker.checkCreation(database, rules, shardingRuleConfig);
+        ShardingTableRuleStatementChecker.checkCreation(database, rules, false, shardingRuleConfig);
     }
     
     @Test(expected = InvalidAlgorithmConfigurationException.class)
     public void assertCheckCreationWithInvalidKeyGenerateAlgorithm() {
         AutoTableRuleSegment autoTableRuleSegment = new AutoTableRuleSegment("t_product", Arrays.asList("ds_0", "ds_1"));
         autoTableRuleSegment.setKeyGenerateStrategySegment(new KeyGenerateStrategySegment("product_id", new AlgorithmSegment("invalid", newProperties("invalid", "invalid"))));
-        ShardingTableRuleStatementChecker.checkCreation(database, Collections.singleton(autoTableRuleSegment), shardingRuleConfig);
+        ShardingTableRuleStatementChecker.checkCreation(database, Collections.singleton(autoTableRuleSegment), false, shardingRuleConfig);
     }
     
     @Test(expected = InvalidAlgorithmConfigurationException.class)
@@ -143,7 +143,7 @@ public final class ShardingRuleStatementCheckerTest {
         AutoTableRuleSegment autoTableRuleSegment = new AutoTableRuleSegment("t_product", Arrays.asList("ds_0", "ds_1"));
         autoTableRuleSegment.setAuditStrategySegment(new AuditStrategySegment(Collections.singletonList(new ShardingAuditorSegment("sharding_key_required_auditor",
                 new AlgorithmSegment("invalid", new Properties()))), true));
-        ShardingTableRuleStatementChecker.checkCreation(database, Collections.singleton(autoTableRuleSegment), shardingRuleConfig);
+        ShardingTableRuleStatementChecker.checkCreation(database, Collections.singleton(autoTableRuleSegment), false, shardingRuleConfig);
     }
     
     @Test(expected = InvalidAlgorithmConfigurationException.class)
@@ -152,9 +152,9 @@ public final class ShardingRuleStatementCheckerTest {
         autoTableRuleSegment.setShardingColumn("product_id");
         autoTableRuleSegment.setShardingAlgorithmSegment(new AlgorithmSegment("not_exist", newProperties("", "")));
         List<AbstractTableRuleSegment> rules = Collections.singletonList(autoTableRuleSegment);
-        ShardingTableRuleStatementChecker.checkCreation(database, rules, shardingRuleConfig);
+        ShardingTableRuleStatementChecker.checkCreation(database, rules, false, shardingRuleConfig);
         autoTableRuleSegment.setShardingAlgorithmSegment(new AlgorithmSegment("complex", newProperties("", "")));
-        ShardingTableRuleStatementChecker.checkCreation(database, rules, shardingRuleConfig);
+        ShardingTableRuleStatementChecker.checkCreation(database, rules, false, shardingRuleConfig);
     }
     
     @Test(expected = InvalidAlgorithmConfigurationException.class)
@@ -163,7 +163,7 @@ public final class ShardingRuleStatementCheckerTest {
         autoTableRuleSegment.setShardingColumn("product_id");
         autoTableRuleSegment.setShardingAlgorithmSegment(new AlgorithmSegment("complex", newProperties("", "")));
         List<AbstractTableRuleSegment> rules = Collections.singletonList(autoTableRuleSegment);
-        ShardingTableRuleStatementChecker.checkCreation(database, rules, shardingRuleConfig);
+        ShardingTableRuleStatementChecker.checkCreation(database, rules, false, shardingRuleConfig);
     }
     
     @Test(expected = UnsupportedSQLOperationException.class)
@@ -171,7 +171,7 @@ public final class ShardingRuleStatementCheckerTest {
         TableRuleSegment tableRuleSegment = new TableRuleSegment("t_product", Arrays.asList("ds_0", "ds_1"));
         tableRuleSegment.setTableStrategySegment(new ShardingStrategySegment("invalid", "product_id", null));
         List<AbstractTableRuleSegment> rules = Collections.singletonList(tableRuleSegment);
-        ShardingTableRuleStatementChecker.checkCreation(database, rules, shardingRuleConfig);
+        ShardingTableRuleStatementChecker.checkCreation(database, rules, false, shardingRuleConfig);
     }
     
     @Test(expected = InvalidAlgorithmConfigurationException.class)
@@ -179,7 +179,7 @@ public final class ShardingRuleStatementCheckerTest {
         TableRuleSegment tableRuleSegment = new TableRuleSegment("t_product", Arrays.asList("ds_0", "ds_1"));
         tableRuleSegment.setTableStrategySegment(new ShardingStrategySegment("complex", "product_id", null));
         List<AbstractTableRuleSegment> rules = Collections.singletonList(tableRuleSegment);
-        ShardingTableRuleStatementChecker.checkCreation(database, rules, shardingRuleConfig);
+        ShardingTableRuleStatementChecker.checkCreation(database, rules, false, shardingRuleConfig);
     }
     
     @Test(expected = InvalidAlgorithmConfigurationException.class)
@@ -187,7 +187,7 @@ public final class ShardingRuleStatementCheckerTest {
         TableRuleSegment tableRuleSegment = new TableRuleSegment("t_product", Arrays.asList("ds_0", "ds_1"));
         tableRuleSegment.setTableStrategySegment(new ShardingStrategySegment("standard", "product_id,user_id", null));
         List<AbstractTableRuleSegment> rules = Collections.singletonList(tableRuleSegment);
-        ShardingTableRuleStatementChecker.checkCreation(database, rules, shardingRuleConfig);
+        ShardingTableRuleStatementChecker.checkCreation(database, rules, false, shardingRuleConfig);
     }
     
     @Test(expected = InvalidAlgorithmConfigurationException.class)
@@ -195,7 +195,7 @@ public final class ShardingRuleStatementCheckerTest {
         TableRuleSegment tableRuleSegment = new TableRuleSegment("t_product", Arrays.asList("ds_0", "ds_1"));
         tableRuleSegment.setTableStrategySegment(new ShardingStrategySegment("hint", "product_id", null));
         List<AbstractTableRuleSegment> rules = Collections.singletonList(tableRuleSegment);
-        ShardingTableRuleStatementChecker.checkCreation(database, rules, shardingRuleConfig);
+        ShardingTableRuleStatementChecker.checkCreation(database, rules, false, shardingRuleConfig);
     }
     
     @Test(expected = InvalidAlgorithmConfigurationException.class)
@@ -203,7 +203,7 @@ public final class ShardingRuleStatementCheckerTest {
         TableRuleSegment tableRuleSegment = new TableRuleSegment("t_product", Arrays.asList("ds_0", "ds_1"));
         tableRuleSegment.setTableStrategySegment(new ShardingStrategySegment("hint", "product_id", null));
         List<AbstractTableRuleSegment> rules = Collections.singletonList(tableRuleSegment);
-        ShardingTableRuleStatementChecker.checkCreation(database, rules, null);
+        ShardingTableRuleStatementChecker.checkCreation(database, rules, false, null);
     }
     
     @Test
@@ -212,7 +212,7 @@ public final class ShardingRuleStatementCheckerTest {
         AlgorithmSegment databaseAlgorithmSegment = new AlgorithmSegment("inline", newProperties("algorithm-expression", "ds_${product_id% 2}"));
         tableRuleSegment.setTableStrategySegment(new ShardingStrategySegment("standard", "product_id", databaseAlgorithmSegment));
         List<AbstractTableRuleSegment> rules = Collections.singletonList(tableRuleSegment);
-        ShardingTableRuleStatementChecker.checkCreation(database, rules, shardingRuleConfig);
+        ShardingTableRuleStatementChecker.checkCreation(database, rules, false, shardingRuleConfig);
     }
     
     @Test(expected = InvalidAlgorithmConfigurationException.class)
@@ -220,7 +220,7 @@ public final class ShardingRuleStatementCheckerTest {
         TableRuleSegment tableRuleSegment = new TableRuleSegment("t_product", Arrays.asList("ds_0", "ds_1"));
         tableRuleSegment.setTableStrategySegment(new ShardingStrategySegment("standard", "product_id", null));
         List<AbstractTableRuleSegment> rules = Collections.singletonList(tableRuleSegment);
-        ShardingTableRuleStatementChecker.checkCreation(database, rules, shardingRuleConfig);
+        ShardingTableRuleStatementChecker.checkCreation(database, rules, false, shardingRuleConfig);
     }
     
     @Test(expected = InvalidAlgorithmConfigurationException.class)
@@ -228,7 +228,7 @@ public final class ShardingRuleStatementCheckerTest {
         AutoTableRuleSegment autoTableRuleSegment = new AutoTableRuleSegment("t_product", Arrays.asList("ds_0", "ds_1"));
         autoTableRuleSegment.setShardingAlgorithmSegment(new AlgorithmSegment("INLINE", newProperties("algorithm-expression", "ds_${product_id% 2}")));
         List<AbstractTableRuleSegment> rules = Collections.singletonList(autoTableRuleSegment);
-        ShardingTableRuleStatementChecker.checkCreation(database, rules, shardingRuleConfig);
+        ShardingTableRuleStatementChecker.checkCreation(database, rules, false, shardingRuleConfig);
     }
     
     @Test
@@ -236,7 +236,15 @@ public final class ShardingRuleStatementCheckerTest {
         AutoTableRuleSegment autoTableRuleSegment = new AutoTableRuleSegment("t_product", Arrays.asList("ds_0", "ds_1"));
         autoTableRuleSegment.setShardingAlgorithmSegment(new AlgorithmSegment("MOD", newProperties("sharding-count", "4")));
         List<AbstractTableRuleSegment> rules = Collections.singletonList(autoTableRuleSegment);
-        ShardingTableRuleStatementChecker.checkCreation(database, rules, shardingRuleConfig);
+        ShardingTableRuleStatementChecker.checkCreation(database, rules, false, shardingRuleConfig);
+    }
+    
+    @Test
+    public void assertCheckStatementWithIfNotExists() {
+        Collection<AbstractTableRuleSegment> rules = new LinkedList<>();
+        rules.add(createCompleteAutoTableRule());
+        rules.add(createCompleteTableRule());
+        ShardingTableRuleStatementChecker.checkCreation(database, rules, true, shardingRuleConfig);
     }
     
     private static ShardingRuleConfiguration createShardingRuleConfiguration() {
diff --git a/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/update/CreateShardingTableRuleStatementUpdaterTest.java b/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/update/CreateShardingTableRuleStatementUpdaterTest.java
index 6bcf39ce25e..1830ba418d5 100644
--- a/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/update/CreateShardingTableRuleStatementUpdaterTest.java
+++ b/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/update/CreateShardingTableRuleStatementUpdaterTest.java
@@ -92,10 +92,10 @@ public final class CreateShardingTableRuleStatementUpdaterTest {
     
     @Test
     public void assertUpdate() {
-        CreateShardingTableRuleStatement statement = new CreateShardingTableRuleStatement(Arrays.asList(createCompleteAutoTableRule(), createCompleteTableRule()));
+        CreateShardingTableRuleStatement statement = new CreateShardingTableRuleStatement(false, Arrays.asList(createCompleteAutoTableRule(), createCompleteTableRule()));
         updater.checkSQLStatement(database, statement, currentRuleConfig);
-        ShardingRuleConfiguration toBeAlteredRuleConfig = updater.buildToBeCreatedRuleConfiguration(statement);
-        updater.updateCurrentRuleConfiguration(currentRuleConfig, toBeAlteredRuleConfig);
+        ShardingRuleConfiguration toBeCreatedRuleConfig = updater.buildToBeCreatedRuleConfiguration(statement);
+        updater.updateCurrentRuleConfiguration(currentRuleConfig, toBeCreatedRuleConfig);
         assertThat(currentRuleConfig.getTables().size(), is(2));
         Iterator<ShardingTableRuleConfiguration> tableRuleIterator = currentRuleConfig.getTables().iterator();
         ShardingTableRuleConfiguration tableRule = tableRuleIterator.next();
@@ -152,6 +152,59 @@ public final class CreateShardingTableRuleStatementUpdaterTest {
         updater.checkSQLStatement(database, distSQLStatement, null);
     }
     
+    @Test
+    public void assertUpdateWithIfNotExistsStatement() {
+        CreateShardingTableRuleStatement statement = new CreateShardingTableRuleStatement(false, Arrays.asList(createCompleteAutoTableRule(), createCompleteTableRule()));
+        updater.checkSQLStatement(database, statement, currentRuleConfig);
+        ShardingRuleConfiguration toBeCreatedRuleConfig = updater.buildToBeCreatedRuleConfiguration(statement);
+        updater.updateCurrentRuleConfiguration(currentRuleConfig, toBeCreatedRuleConfig);
+        AutoTableRuleSegment autoTableRuleSegment = new AutoTableRuleSegment("t_order_item_input", Collections.singletonList("logic_ds"));
+        autoTableRuleSegment.setKeyGenerateStrategySegment(new KeyGenerateStrategySegment("test_product_id", new AlgorithmSegment("DISTSQL.FIXTURE", new Properties())));
+        autoTableRuleSegment.setShardingColumn("custom_id");
+        autoTableRuleSegment.setShardingAlgorithmSegment(new AlgorithmSegment("FOO.DISTSQL.FIXTURE", createProperties("", "")));
+        TableRuleSegment tableRuleSegment = new TableRuleSegment("t_order_input", Collections.singletonList("ds_${0..1}.t_order_${0..5}"));
+        tableRuleSegment.setTableStrategySegment(new ShardingStrategySegment("standard", "user_id", new AlgorithmSegment("algorithm", new Properties())));
+        AlgorithmSegment databaseAlgorithmSegment = new AlgorithmSegment("inline", createProperties("algorithm-expression", "ds_${user_id% 2}"));
+        tableRuleSegment.setDatabaseStrategySegment(new ShardingStrategySegment("standard", "order_id", databaseAlgorithmSegment));
+        tableRuleSegment.setKeyGenerateStrategySegment(new KeyGenerateStrategySegment("order_id", new AlgorithmSegment("DISTSQL.FIXTURE", new Properties())));
+        CreateShardingTableRuleStatement statementWithIfNotExists = new CreateShardingTableRuleStatement(true, Arrays.asList(autoTableRuleSegment, tableRuleSegment));
+        updater.checkSQLStatement(database, statementWithIfNotExists, currentRuleConfig);
+        ShardingRuleConfiguration toBeCreatedRuleConfigWithIfNotExists = updater.buildToBeCreatedRuleConfiguration(statement);
+        updater.updateCurrentRuleConfiguration(currentRuleConfig, toBeCreatedRuleConfigWithIfNotExists);
+        assertThat(currentRuleConfig.getTables().size(), is(2));
+        Iterator<ShardingTableRuleConfiguration> tableRuleIterator = currentRuleConfig.getTables().iterator();
+        ShardingTableRuleConfiguration tableRule = tableRuleIterator.next();
+        assertThat(tableRule.getTableShardingStrategy(), instanceOf(StandardShardingStrategyConfiguration.class));
+        assertThat(tableRule.getLogicTable(), is("t_order"));
+        assertThat(tableRule.getActualDataNodes(), is("ds_${0..1}.t_order_${0..1}"));
+        assertThat(((StandardShardingStrategyConfiguration) tableRule.getTableShardingStrategy()).getShardingColumn(), is("order_id"));
+        assertThat(tableRule.getTableShardingStrategy().getShardingAlgorithmName(), is("t_order_algorithm"));
+        tableRule = tableRuleIterator.next();
+        assertThat(tableRule.getTableShardingStrategy(), instanceOf(StandardShardingStrategyConfiguration.class));
+        assertThat(tableRule.getLogicTable(), is("t_order_input"));
+        assertThat(tableRule.getActualDataNodes(), is("ds_${0..1}.t_order_${0..1}"));
+        assertThat(((StandardShardingStrategyConfiguration) tableRule.getTableShardingStrategy()).getShardingColumn(), is("product_id"));
+        assertThat(tableRule.getTableShardingStrategy().getShardingAlgorithmName(), is("t_order_input_table_algorithm"));
+        assertThat(tableRule.getDatabaseShardingStrategy(), instanceOf(StandardShardingStrategyConfiguration.class));
+        assertThat(tableRule.getDatabaseShardingStrategy().getShardingAlgorithmName(), is("t_order_input_database_inline"));
+        assertThat(currentRuleConfig.getTables().size(), is(2));
+        Iterator<ShardingAutoTableRuleConfiguration> autoTableIterator = currentRuleConfig.getAutoTables().iterator();
+        ShardingAutoTableRuleConfiguration autoTableRule = autoTableIterator.next();
+        assertThat(autoTableRule.getLogicTable(), is("t_order_item"));
+        assertThat(autoTableRule.getActualDataSources(), is("ds_0"));
+        assertThat(autoTableRule.getShardingStrategy().getShardingAlgorithmName(), is("t_order_mod_test"));
+        assertThat(((StandardShardingStrategyConfiguration) autoTableRule.getShardingStrategy()).getShardingColumn(), is("order_id"));
+        assertThat(autoTableRule.getKeyGenerateStrategy().getColumn(), is("product_id"));
+        assertThat(autoTableRule.getKeyGenerateStrategy().getKeyGeneratorName(), is("product_id_DISTSQL.FIXTURE"));
+        autoTableRule = autoTableIterator.next();
+        assertThat(autoTableRule.getLogicTable(), is("t_order_item_input"));
+        assertThat(autoTableRule.getActualDataSources(), is("logic_ds"));
+        assertThat(autoTableRule.getShardingStrategy().getShardingAlgorithmName(), is("t_order_item_input_foo.distsql.fixture"));
+        assertThat(((StandardShardingStrategyConfiguration) autoTableRule.getShardingStrategy()).getShardingColumn(), is("order_id"));
+        assertThat(autoTableRule.getKeyGenerateStrategy().getColumn(), is("product_id"));
+        assertThat(autoTableRule.getKeyGenerateStrategy().getKeyGeneratorName(), is("t_order_item_input_distsql.fixture"));
+    }
+    
     private AutoTableRuleSegment createCompleteAutoTableRule() {
         AutoTableRuleSegment result = new AutoTableRuleSegment("t_order_item_input", Collections.singletonList("logic_ds"));
         result.setKeyGenerateStrategySegment(new KeyGenerateStrategySegment("product_id", new AlgorithmSegment("DISTSQL.FIXTURE", new Properties())));
diff --git a/features/sharding/distsql/parser/src/main/antlr4/imports/sharding/Keyword.g4 b/features/sharding/distsql/parser/src/main/antlr4/imports/sharding/Keyword.g4
index b836015c101..80749198f99 100644
--- a/features/sharding/distsql/parser/src/main/antlr4/imports/sharding/Keyword.g4
+++ b/features/sharding/distsql/parser/src/main/antlr4/imports/sharding/Keyword.g4
@@ -322,3 +322,7 @@ COMPLEX
 DML_SHARDING_CONDITIONS
     : D M L UL_ S H A R D I N G UL_ C O N D I T I O N S
     ;
+
+NOT
+    : N O T
+    ;
diff --git a/features/sharding/distsql/parser/src/main/antlr4/imports/sharding/RDLStatement.g4 b/features/sharding/distsql/parser/src/main/antlr4/imports/sharding/RDLStatement.g4
index 83524de9301..49e09875b5a 100644
--- a/features/sharding/distsql/parser/src/main/antlr4/imports/sharding/RDLStatement.g4
+++ b/features/sharding/distsql/parser/src/main/antlr4/imports/sharding/RDLStatement.g4
@@ -20,7 +20,7 @@ grammar RDLStatement;
 import BaseRule;
 
 createShardingTableRule
-    : CREATE SHARDING TABLE RULE shardingTableRuleDefinition (COMMA_ shardingTableRuleDefinition)*
+    : CREATE SHARDING TABLE RULE ifNotExists? shardingTableRuleDefinition (COMMA_ shardingTableRuleDefinition)*
     ;
 
 alterShardingTableRule
@@ -188,3 +188,7 @@ buildInStrategyType
 ifExists
     : IF EXISTS
     ;
+
+ifNotExists
+    : IF NOT EXISTS
+    ;
diff --git a/features/sharding/distsql/parser/src/main/java/org/apache/shardingsphere/sharding/distsql/parser/core/ShardingDistSQLStatementVisitor.java b/features/sharding/distsql/parser/src/main/java/org/apache/shardingsphere/sharding/distsql/parser/core/ShardingDistSQLStatementVisitor.java
index 14ef66815d2..4488c3a11a2 100644
--- a/features/sharding/distsql/parser/src/main/java/org/apache/shardingsphere/sharding/distsql/parser/core/ShardingDistSQLStatementVisitor.java
+++ b/features/sharding/distsql/parser/src/main/java/org/apache/shardingsphere/sharding/distsql/parser/core/ShardingDistSQLStatementVisitor.java
@@ -136,7 +136,7 @@ public final class ShardingDistSQLStatementVisitor extends ShardingDistSQLStatem
     public ASTNode visitCreateShardingTableRule(final CreateShardingTableRuleContext ctx) {
         Collection<AbstractTableRuleSegment> tableRuleSegments = ctx.shardingTableRuleDefinition().stream()
                 .map(each -> (AbstractTableRuleSegment) visit(each)).filter(Objects::nonNull).collect(Collectors.toList());
-        return new CreateShardingTableRuleStatement(tableRuleSegments);
+        return new CreateShardingTableRuleStatement(null != ctx.ifNotExists(), tableRuleSegments);
     }
     
     @Override
diff --git a/features/sharding/distsql/statement/src/main/java/org/apache/shardingsphere/sharding/distsql/parser/statement/CreateShardingTableRuleStatement.java b/features/sharding/distsql/statement/src/main/java/org/apache/shardingsphere/sharding/distsql/parser/statement/CreateShardingTableRuleStatement.java
index 10c6eb61bf2..4dbe1de84c4 100644
--- a/features/sharding/distsql/statement/src/main/java/org/apache/shardingsphere/sharding/distsql/parser/statement/CreateShardingTableRuleStatement.java
+++ b/features/sharding/distsql/statement/src/main/java/org/apache/shardingsphere/sharding/distsql/parser/statement/CreateShardingTableRuleStatement.java
@@ -18,7 +18,6 @@
 package org.apache.shardingsphere.sharding.distsql.parser.statement;
 
 import lombok.Getter;
-import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.distsql.parser.statement.rdl.create.CreateRuleStatement;
 import org.apache.shardingsphere.sharding.distsql.parser.segment.table.AbstractTableRuleSegment;
 
@@ -27,9 +26,13 @@ import java.util.Collection;
 /**
  * Create sharding table rule statement.
  */
-@RequiredArgsConstructor
 @Getter
 public final class CreateShardingTableRuleStatement extends CreateRuleStatement {
     
     private final Collection<AbstractTableRuleSegment> rules;
+    
+    public CreateShardingTableRuleStatement(final boolean ifNotExists, final Collection<AbstractTableRuleSegment> rules) {
+        super(ifNotExists);
+        this.rules = rules;
+    }
 }