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 07cc23297ea Add IF NOT EXISTS to CREATE READWRITE_SPLITTING RULE. 
(#23126)
07cc23297ea is described below

commit 07cc23297eac1b43a8e81dd4869d3ff0b7f309e2
Author: yx9o <[email protected]>
AuthorDate: Thu Dec 29 11:01:18 2022 +0800

    Add IF NOT EXISTS to CREATE READWRITE_SPLITTING RULE. (#23126)
    
    * Add IF NOT EXISTS to CREATE READWRITE_SPLITTING RULE.
    
    * Update.
    
    * Update.
---
 .../ReadwriteSplittingRuleStatementChecker.java    | 86 ++++++++++++----------
 ...eateReadwriteSplittingRuleStatementUpdater.java | 16 +++-
 ...ReadwriteSplittingRuleStatementUpdaterTest.java | 47 ++++++------
 .../antlr4/imports/readwrite-splitting/Keyword.g4  |  5 +-
 .../imports/readwrite-splitting/RDLStatement.g4    |  6 +-
 .../ReadwriteSplittingDistSQLStatementVisitor.java |  3 +-
 .../CreateReadwriteSplittingRuleStatement.java     |  9 ++-
 7 files changed, 100 insertions(+), 72 deletions(-)

diff --git 
a/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/checker/ReadwriteSplittingRuleStatementChecker.java
 
b/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/checker/ReadwriteSplittingRuleStatementChecker.java
index 83ef736316c..abb311e4053 100644
--- 
a/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/checker/ReadwriteSplittingRuleStatementChecker.java
+++ 
b/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/checker/ReadwriteSplittingRuleStatementChecker.java
@@ -18,16 +18,16 @@
 package org.apache.shardingsphere.readwritesplitting.distsql.handler.checker;
 
 import com.google.common.base.Strings;
-import 
org.apache.shardingsphere.infra.rule.identifier.type.exportable.constant.ExportableConstants;
-import 
org.apache.shardingsphere.distsql.handler.exception.storageunit.MissingRequiredStorageUnitsException;
-import 
org.apache.shardingsphere.distsql.handler.exception.rule.DuplicateRuleException;
 import 
org.apache.shardingsphere.distsql.handler.exception.algorithm.InvalidAlgorithmConfigurationException;
+import 
org.apache.shardingsphere.distsql.handler.exception.rule.DuplicateRuleException;
 import 
org.apache.shardingsphere.distsql.handler.exception.rule.InvalidRuleConfigurationException;
 import 
org.apache.shardingsphere.distsql.handler.exception.rule.MissingRequiredRuleException;
+import 
org.apache.shardingsphere.distsql.handler.exception.storageunit.MissingRequiredStorageUnitsException;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.infra.metadata.database.resource.ShardingSphereResourceMetaData;
 import 
org.apache.shardingsphere.infra.rule.identifier.type.exportable.ExportableRule;
 import 
org.apache.shardingsphere.infra.rule.identifier.type.exportable.RuleExportEngine;
+import 
org.apache.shardingsphere.infra.rule.identifier.type.exportable.constant.ExportableConstants;
 import 
org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
 import 
org.apache.shardingsphere.readwritesplitting.api.ReadwriteSplittingRuleConfiguration;
 import 
org.apache.shardingsphere.readwritesplitting.api.rule.ReadwriteSplittingDataSourceRuleConfiguration;
@@ -55,18 +55,21 @@ public final class ReadwriteSplittingRuleStatementChecker {
      * @param database database
      * @param segments segments
      * @param currentRuleConfig current rule config
+     * @param duplicatedRuleNames duplicated rule names
+     * @param ifNotExists rule if not exists
      */
-    public static void checkCreation(final ShardingSphereDatabase database, 
final Collection<ReadwriteSplittingRuleSegment> segments, final 
ReadwriteSplittingRuleConfiguration currentRuleConfig) {
+    public static void checkCreation(final ShardingSphereDatabase database, 
final Collection<ReadwriteSplittingRuleSegment> segments,
+                                     final ReadwriteSplittingRuleConfiguration 
currentRuleConfig, final Collection<String> duplicatedRuleNames, final boolean 
ifNotExists) {
         String databaseName = database.getName();
-        checkDuplicateRuleNames(databaseName, segments, currentRuleConfig, 
database.getResourceMetaData());
+        checkDuplicateRuleNames(databaseName, segments, currentRuleConfig, 
database.getResourceMetaData(), duplicatedRuleNames, ifNotExists);
         checkDataSourcesExist(databaseName, segments, database);
         checkDuplicatedDataSourceNames(databaseName, segments, 
currentRuleConfig, true);
         checkLoadBalancers(segments);
     }
     
     /**
-     *  Check alter readwrite splitting rule statement.
-     * 
+     * Check alter readwrite splitting rule statement.
+     *
      * @param database database
      * @param segments segments
      * @param currentRuleConfig current rule config
@@ -82,8 +85,8 @@ public final class ReadwriteSplittingRuleStatementChecker {
     }
     
     /**
-     *  Check current rule configuration exist.
-     * 
+     * Check current rule configuration exist.
+     *
      * @param database database
      * @param currentRuleConfig current rule config
      */
@@ -94,46 +97,54 @@ public final class ReadwriteSplittingRuleStatementChecker {
     private static void checkRuleNamesExist(final 
Collection<ReadwriteSplittingRuleSegment> segments, final 
ReadwriteSplittingRuleConfiguration currentRuleConfig, final String 
databaseName) {
         Collection<String> requiredRuleNames = 
segments.stream().map(ReadwriteSplittingRuleSegment::getName).collect(Collectors.toList());
         Collection<String> currentRuleNames = 
currentRuleConfig.getDataSources().stream().map(ReadwriteSplittingDataSourceRuleConfiguration::getName).collect(Collectors.toList());
-        Collection<String> notExistRuleNames = 
requiredRuleNames.stream().filter(each -> 
!currentRuleNames.contains(each)).collect(Collectors.toSet());
-        ShardingSpherePreconditions.checkState(notExistRuleNames.isEmpty(), () 
-> new MissingRequiredRuleException(databaseName, notExistRuleNames));
+        Collection<String> notExistedRuleNames = 
requiredRuleNames.stream().filter(each -> 
!currentRuleNames.contains(each)).collect(Collectors.toSet());
+        ShardingSpherePreconditions.checkState(notExistedRuleNames.isEmpty(), 
() -> new MissingRequiredRuleException(databaseName, notExistedRuleNames));
     }
     
-    private static void checkDuplicateRuleNames(final String databaseName, 
final Collection<ReadwriteSplittingRuleSegment> segments,
-                                                final 
ReadwriteSplittingRuleConfiguration currentRuleConfig, final 
ShardingSphereResourceMetaData resourceMetaData) {
+    private static void checkDuplicateRuleNames(final String databaseName, 
final Collection<ReadwriteSplittingRuleSegment> segments, final 
ReadwriteSplittingRuleConfiguration currentRuleConfig,
+                                                final 
ShardingSphereResourceMetaData resourceMetaData, final Collection<String> 
duplicatedRuleNames, final boolean ifNotExists) {
         checkDuplicateRuleNamesWithSelf(databaseName, segments);
-        checkDuplicateRuleNamesWithResourceMetaData(segments, 
resourceMetaData);
-        checkDuplicateRuleNamesWithRuleConfiguration(databaseName, segments, 
currentRuleConfig);
+        checkDuplicateRuleNamesWithResourceMetaData(resourceMetaData, 
ifNotExists, duplicatedRuleNames, segments);
+        checkDuplicateRuleNamesWithRuleConfiguration(databaseName, 
currentRuleConfig, ifNotExists, duplicatedRuleNames, segments);
     }
     
     private static void checkDuplicateRuleNamesWithSelf(final String 
databaseName, final Collection<ReadwriteSplittingRuleSegment> segments) {
-        Collection<String> requiredRuleNames = 
segments.stream().map(ReadwriteSplittingRuleSegment::getName).collect(Collectors.toList());
-        Collection<String> duplicateRuleNames = 
getDuplicate(requiredRuleNames);
-        ShardingSpherePreconditions.checkState(duplicateRuleNames.isEmpty(), 
() -> new DuplicateRuleException("Readwrite splitting", databaseName, 
duplicateRuleNames));
+        Collection<String> duplicatedRuleNames = 
getDuplicated(segments.stream().map(ReadwriteSplittingRuleSegment::getName).collect(Collectors.toList()));
+        ShardingSpherePreconditions.checkState(duplicatedRuleNames.isEmpty(), 
() -> new DuplicateRuleException("Readwrite splitting", databaseName, 
duplicatedRuleNames));
     }
     
-    private static Collection<String> getDuplicate(final Collection<String> 
require) {
-        return require.stream().collect(Collectors.groupingBy(each -> each, 
Collectors.counting())).entrySet().stream()
+    private static Collection<String> getDuplicated(final Collection<String> 
required) {
+        return required.stream().collect(Collectors.groupingBy(each -> each, 
Collectors.counting())).entrySet().stream()
                 .filter(each -> each.getValue() > 
1).map(Map.Entry::getKey).collect(Collectors.toSet());
     }
     
-    private static void checkDuplicateRuleNamesWithResourceMetaData(final 
Collection<ReadwriteSplittingRuleSegment> segments, final 
ShardingSphereResourceMetaData resourceMetaData) {
+    private static void checkDuplicateRuleNamesWithResourceMetaData(final 
ShardingSphereResourceMetaData resourceMetaData, final boolean ifNotExists, 
final Collection<String> duplicatedRuleNames,
+                                                                    final 
Collection<ReadwriteSplittingRuleSegment> segments) {
         Collection<String> currentRuleNames = new LinkedList<>();
         if (null != resourceMetaData && null != 
resourceMetaData.getDataSources()) {
             
currentRuleNames.addAll(resourceMetaData.getDataSources().keySet());
         }
-        Collection<String> duplicateRuleNames = 
segments.stream().map(ReadwriteSplittingRuleSegment::getName).filter(currentRuleNames::contains).collect(Collectors.toList());
-        ShardingSpherePreconditions.checkState(duplicateRuleNames.isEmpty(), 
() -> new InvalidRuleConfigurationException("Readwrite splitting", 
duplicateRuleNames,
-                Collections.singleton(String.format("%s already exists in 
storage unit", duplicateRuleNames))));
+        Collection<String> toBeCreatedRuleNames = 
segments.stream().map(ReadwriteSplittingRuleSegment::getName).filter(currentRuleNames::contains).collect(Collectors.toList());
+        if (ifNotExists) {
+            duplicatedRuleNames.addAll(toBeCreatedRuleNames);
+            return;
+        }
+        ShardingSpherePreconditions.checkState(toBeCreatedRuleNames.isEmpty(), 
() -> new InvalidRuleConfigurationException("Readwrite splitting", 
toBeCreatedRuleNames,
+                Collections.singleton(String.format("%s already exists in 
storage unit", toBeCreatedRuleNames))));
     }
     
-    private static void checkDuplicateRuleNamesWithRuleConfiguration(final 
String databaseName, final Collection<ReadwriteSplittingRuleSegment> segments,
-                                                                     final 
ReadwriteSplittingRuleConfiguration currentRuleConfig) {
+    private static void checkDuplicateRuleNamesWithRuleConfiguration(final 
String databaseName, final ReadwriteSplittingRuleConfiguration 
currentRuleConfig, final boolean ifNotExists,
+                                                                     final 
Collection<String> duplicatedRuleNames, final 
Collection<ReadwriteSplittingRuleSegment> segments) {
         Collection<String> currentRuleNames = new LinkedList<>();
         if (null != currentRuleConfig) {
             
currentRuleNames.addAll(currentRuleConfig.getDataSources().stream().map(ReadwriteSplittingDataSourceRuleConfiguration::getName).collect(Collectors.toList()));
         }
-        Collection<String> duplicateRuleNames = 
segments.stream().map(ReadwriteSplittingRuleSegment::getName).filter(currentRuleNames::contains).collect(Collectors.toList());
-        ShardingSpherePreconditions.checkState(duplicateRuleNames.isEmpty(), 
() -> new DuplicateRuleException("Readwrite splitting", databaseName, 
duplicateRuleNames));
+        Collection<String> toBeCreatedRuleNames = 
segments.stream().map(ReadwriteSplittingRuleSegment::getName).filter(currentRuleNames::contains).collect(Collectors.toList());
+        if (ifNotExists) {
+            duplicatedRuleNames.addAll(toBeCreatedRuleNames);
+            return;
+        }
+        ShardingSpherePreconditions.checkState(toBeCreatedRuleNames.isEmpty(), 
() -> new DuplicateRuleException("Readwrite splitting", databaseName, 
toBeCreatedRuleNames));
     }
     
     private static void checkDataSourcesExist(final String databaseName, final 
Collection<ReadwriteSplittingRuleSegment> segments, final 
ShardingSphereDatabase database) {
@@ -173,12 +184,12 @@ public final class ReadwriteSplittingRuleStatementChecker 
{
         Collection<String> existedReadDataSourceNames = new HashSet<>();
         if (null != currentRuleConfig) {
             Collection<String> toBeAlteredRuleNames = isCreating ? 
Collections.emptySet() : getToBeAlteredRuleNames(segments);
-            for (ReadwriteSplittingDataSourceRuleConfiguration each : 
currentRuleConfig.getDataSources()) {
+            currentRuleConfig.getDataSources().forEach(each -> {
                 if (null != each.getStaticStrategy() && 
!toBeAlteredRuleNames.contains(each.getName())) {
                     
existedWriteDataSourceNames.add(each.getStaticStrategy().getWriteDataSourceName());
                     
existedReadDataSourceNames.addAll(each.getStaticStrategy().getReadDataSourceNames());
                 }
-            }
+            });
         }
         checkDuplicateWriteDataSourceNames(databaseName, segments, 
existedWriteDataSourceNames);
         checkDuplicateReadDataSourceNames(databaseName, segments, 
existedReadDataSourceNames);
@@ -189,25 +200,24 @@ public final class ReadwriteSplittingRuleStatementChecker 
{
     }
     
     private static void checkDuplicateWriteDataSourceNames(final String 
databaseName, final Collection<ReadwriteSplittingRuleSegment> segments, final 
Collection<String> writeDataSourceNames) {
-        for (final ReadwriteSplittingRuleSegment each : segments) {
+        segments.forEach(each -> {
             if (!Strings.isNullOrEmpty(each.getWriteDataSource())) {
                 String writeDataSource = each.getWriteDataSource();
                 
ShardingSpherePreconditions.checkState(writeDataSourceNames.add(writeDataSource),
 () -> new InvalidRuleConfigurationException("Readwrite splitting", 
each.getName(),
                         String.format("Can not config duplicate write storage 
unit `%s` in database `%s`", writeDataSource, databaseName)));
             }
-        }
+        });
     }
     
-    private static void checkDuplicateReadDataSourceNames(final String 
databaseName, final Collection<ReadwriteSplittingRuleSegment> segments,
-                                                          final 
Collection<String> readDataSourceNames) {
-        for (ReadwriteSplittingRuleSegment each : segments) {
+    private static void checkDuplicateReadDataSourceNames(final String 
databaseName, final Collection<ReadwriteSplittingRuleSegment> segments, final 
Collection<String> readDataSourceNames) {
+        segments.forEach(each -> {
             if (null != each.getReadDataSources()) {
-                for (String readDataSource : each.getReadDataSources()) {
+                each.getReadDataSources().forEach(readDataSource -> {
                     
ShardingSpherePreconditions.checkState(readDataSourceNames.add(readDataSource), 
() -> new InvalidRuleConfigurationException("Readwrite splitting", 
each.getName(),
                             String.format("Can not config duplicate read 
storage unit `%s` in database `%s`", readDataSource, databaseName)));
-                }
+                });
             }
-        }
+        });
     }
     
     private static void checkLoadBalancers(final 
Collection<ReadwriteSplittingRuleSegment> segments) {
diff --git 
a/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleStatementUpdater.java
 
b/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleStatementUpdater.java
index c8ad8836c93..16518701820 100644
--- 
a/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleStatementUpdater.java
+++ 
b/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleStatementUpdater.java
@@ -22,21 +22,33 @@ import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.readwritesplitting.api.ReadwriteSplittingRuleConfiguration;
 import 
org.apache.shardingsphere.readwritesplitting.distsql.handler.checker.ReadwriteSplittingRuleStatementChecker;
 import 
org.apache.shardingsphere.readwritesplitting.distsql.handler.converter.ReadwriteSplittingRuleStatementConverter;
+import 
org.apache.shardingsphere.readwritesplitting.distsql.parser.segment.ReadwriteSplittingRuleSegment;
 import 
org.apache.shardingsphere.readwritesplitting.distsql.parser.statement.CreateReadwriteSplittingRuleStatement;
 
+import java.util.Collection;
+import java.util.LinkedList;
+
 /**
  * Create readwrite-splitting rule statement updater.
  */
 public final class CreateReadwriteSplittingRuleStatementUpdater implements 
RuleDefinitionCreateUpdater<CreateReadwriteSplittingRuleStatement, 
ReadwriteSplittingRuleConfiguration> {
     
+    private Collection<String> duplicatedRuleNames = new LinkedList<>();
+    
     @Override
     public void checkSQLStatement(final ShardingSphereDatabase database, final 
CreateReadwriteSplittingRuleStatement sqlStatement, final 
ReadwriteSplittingRuleConfiguration currentRuleConfig) {
-        ReadwriteSplittingRuleStatementChecker.checkCreation(database, 
sqlStatement.getRules(), currentRuleConfig);
+        Collection<String> duplicatedRuleNames = new LinkedList<>();
+        ReadwriteSplittingRuleStatementChecker.checkCreation(database, 
sqlStatement.getRules(), currentRuleConfig, duplicatedRuleNames, 
sqlStatement.isIfNotExists());
+        this.duplicatedRuleNames = duplicatedRuleNames;
     }
     
     @Override
     public ReadwriteSplittingRuleConfiguration 
buildToBeCreatedRuleConfiguration(final CreateReadwriteSplittingRuleStatement 
sqlStatement) {
-        return 
ReadwriteSplittingRuleStatementConverter.convert(sqlStatement.getRules());
+        Collection<ReadwriteSplittingRuleSegment> segments = 
sqlStatement.getRules();
+        if (!duplicatedRuleNames.isEmpty()) {
+            segments.removeIf(each -> 
duplicatedRuleNames.contains(each.getName()));
+        }
+        return ReadwriteSplittingRuleStatementConverter.convert(segments);
     }
     
     @Override
diff --git 
a/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleStatementUpdaterTest.java
 
b/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleStatementUpdaterTest.java
index 4952ee460dd..f3b4a494136 100644
--- 
a/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleStatementUpdaterTest.java
+++ 
b/features/readwrite-splitting/distsql/handler/src/test/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleStatementUpdaterTest.java
@@ -17,14 +17,14 @@
 
 package org.apache.shardingsphere.readwritesplitting.distsql.handler.update;
 
-import 
org.apache.shardingsphere.infra.rule.identifier.type.exportable.constant.ExportableConstants;
-import 
org.apache.shardingsphere.distsql.handler.exception.storageunit.MissingRequiredStorageUnitsException;
-import 
org.apache.shardingsphere.distsql.handler.exception.rule.DuplicateRuleException;
 import 
org.apache.shardingsphere.distsql.handler.exception.algorithm.InvalidAlgorithmConfigurationException;
+import 
org.apache.shardingsphere.distsql.handler.exception.rule.DuplicateRuleException;
 import 
org.apache.shardingsphere.distsql.handler.exception.rule.InvalidRuleConfigurationException;
+import 
org.apache.shardingsphere.distsql.handler.exception.storageunit.MissingRequiredStorageUnitsException;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.infra.metadata.database.resource.ShardingSphereResourceMetaData;
 import 
org.apache.shardingsphere.infra.rule.identifier.type.exportable.ExportableRule;
+import 
org.apache.shardingsphere.infra.rule.identifier.type.exportable.constant.ExportableConstants;
 import org.apache.shardingsphere.infra.util.spi.ShardingSphereServiceLoader;
 import 
org.apache.shardingsphere.readwritesplitting.api.ReadwriteSplittingRuleConfiguration;
 import 
org.apache.shardingsphere.readwritesplitting.api.rule.ReadwriteSplittingDataSourceRuleConfiguration;
@@ -52,7 +52,6 @@ import java.util.Properties;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.when;
@@ -75,15 +74,12 @@ public final class 
CreateReadwriteSplittingRuleStatementUpdaterTest {
     
     @Test(expected = DuplicateRuleException.class)
     public void assertCheckSQLStatementWithDuplicateRuleNames() {
-        ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, 
RETURNS_DEEP_STUBS);
-        
when(database.getResourceMetaData().getDataSources().keySet()).thenReturn(Collections.emptySet());
+        
when(resourceMetaData.getDataSources()).thenReturn(Collections.emptyMap());
         updater.checkSQLStatement(database, createSQLStatement("TEST"), 
createCurrentRuleConfiguration());
     }
     
     @Test(expected = InvalidRuleConfigurationException.class)
     public void assertCheckSQLStatementWithDuplicateResource() {
-        ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, 
RETURNS_DEEP_STUBS);
-        when(database.getResourceMetaData()).thenReturn(resourceMetaData);
         
when(resourceMetaData.getDataSources()).thenReturn(Collections.singletonMap("write_ds",
 null));
         updater.checkSQLStatement(database, createSQLStatement("write_ds", 
"TEST"), createCurrentRuleConfiguration());
     }
@@ -100,7 +96,7 @@ public final class 
CreateReadwriteSplittingRuleStatementUpdaterTest {
         
when(exportableRule.getExportData()).thenReturn(Collections.singletonMap(ExportableConstants.EXPORT_DB_DISCOVERY_PRIMARY_DATA_SOURCES,
 Collections.singletonMap("ms_group", "ds_0")));
         
when(database.getRuleMetaData().findRules(ExportableRule.class)).thenReturn(Collections.singleton(exportableRule));
         ReadwriteSplittingRuleSegment ruleSegment = new 
ReadwriteSplittingRuleSegment("dynamic_rule", "ha_group", "false", "TEST", new 
Properties());
-        updater.checkSQLStatement(database, new 
CreateReadwriteSplittingRuleStatement(Collections.singleton(ruleSegment)), 
null);
+        updater.checkSQLStatement(database, createSQLStatement(false, 
ruleSegment), null);
     }
     
     @Test(expected = InvalidAlgorithmConfigurationException.class)
@@ -111,32 +107,30 @@ public final class 
CreateReadwriteSplittingRuleStatementUpdaterTest {
     
     @Test(expected = InvalidRuleConfigurationException.class)
     public void 
assertCheckSQLStatementWithDuplicateWriteResourceNamesInStatement() {
-        ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, 
RETURNS_DEEP_STUBS);
-        when(database.getResourceMetaData()).thenReturn(resourceMetaData);
         updater.checkSQLStatement(database, 
createSQLStatementWithDuplicateWriteResourceNames("write_ds_0", "write_ds_1", 
"TEST"), null);
     }
     
     @Test(expected = InvalidRuleConfigurationException.class)
     public void assertCheckSQLStatementWithDuplicateWriteResourceNames() {
-        ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, 
RETURNS_DEEP_STUBS);
-        when(database.getResourceMetaData()).thenReturn(resourceMetaData);
         updater.checkSQLStatement(database, 
createSQLStatement("readwrite_ds_1", "ds_write", Arrays.asList("read_ds_0", 
"read_ds_1"), "TEST"), createCurrentRuleConfiguration());
     }
     
     @Test(expected = InvalidRuleConfigurationException.class)
     public void 
assertCheckSQLStatementWithDuplicateReadResourceNamesInStatement() {
-        ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, 
RETURNS_DEEP_STUBS);
-        when(database.getResourceMetaData()).thenReturn(resourceMetaData);
         updater.checkSQLStatement(database, 
createSQLStatementWithDuplicateReadResourceNames("write_ds_0", "write_ds_1", 
"TEST"), null);
     }
     
     @Test(expected = InvalidRuleConfigurationException.class)
     public void assertCheckSQLStatementWithDuplicateReadResourceNames() {
-        ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, 
RETURNS_DEEP_STUBS);
-        when(database.getResourceMetaData()).thenReturn(resourceMetaData);
         updater.checkSQLStatement(database, 
createSQLStatement("readwrite_ds_1", "write_ds_1", Arrays.asList("read_ds_0", 
"read_ds_1"), "TEST"), createCurrentRuleConfiguration());
     }
     
+    @Test
+    public void assertCheckSQLStatementWithIfNotExists() {
+        ReadwriteSplittingRuleSegment staticSegment = new 
ReadwriteSplittingRuleSegment("readwrite_ds_0", "write_ds_0", 
Arrays.asList("read_ds_2", "read_ds_3"), null, new Properties());
+        updater.checkSQLStatement(database, createSQLStatement(true, 
staticSegment), createCurrentRuleConfiguration());
+    }
+    
     @Test
     public void assertUpdateSuccess() {
         ExportableRule exportableRule = mock(ExportableRule.class);
@@ -147,7 +141,7 @@ public final class 
CreateReadwriteSplittingRuleStatementUpdaterTest {
             ReadwriteSplittingRuleSegment dynamicSegment = new 
ReadwriteSplittingRuleSegment("dynamic_rule", "ms_group", "false", "TEST", new 
Properties());
             ReadwriteSplittingRuleSegment staticSegment = new 
ReadwriteSplittingRuleSegment("static_rule", "write_ds_0", 
Arrays.asList("read_ds_0", "read_ds_1"), "TEST", new Properties());
             
ShardingSphereServiceLoader.register(ReadQueryLoadBalanceAlgorithm.class);
-            CreateReadwriteSplittingRuleStatement statement = new 
CreateReadwriteSplittingRuleStatement(Arrays.asList(dynamicSegment, 
staticSegment));
+            CreateReadwriteSplittingRuleStatement statement = 
createSQLStatement(false, dynamicSegment, staticSegment);
             updater.checkSQLStatement(database, statement, null);
             ReadwriteSplittingRuleConfiguration toBeCreatedRuleConfig = 
updater.buildToBeCreatedRuleConfiguration(statement);
             ReadwriteSplittingRuleConfiguration currentRuleConfig = new 
ReadwriteSplittingRuleConfiguration(new ArrayList<>(), new HashMap<>());
@@ -157,30 +151,31 @@ public final class 
CreateReadwriteSplittingRuleStatementUpdaterTest {
     }
     
     private CreateReadwriteSplittingRuleStatement createSQLStatement(final 
String loadBalancerName) {
-        ReadwriteSplittingRuleSegment ruleSegment = new 
ReadwriteSplittingRuleSegment("readwrite_ds_0", "write_ds", 
Arrays.asList("read_ds_0", "read_ds_1"), loadBalancerName, new Properties());
-        return new 
CreateReadwriteSplittingRuleStatement(Collections.singleton(ruleSegment));
+        return createSQLStatement(false, new 
ReadwriteSplittingRuleSegment("readwrite_ds_0", "write_ds", 
Arrays.asList("read_ds_0", "read_ds_1"), loadBalancerName, new Properties()));
     }
     
     private CreateReadwriteSplittingRuleStatement createSQLStatement(final 
String ruleName, final String loadBalancerName) {
-        ReadwriteSplittingRuleSegment ruleSegment = new 
ReadwriteSplittingRuleSegment(ruleName, "write_ds", Arrays.asList("read_ds_0", 
"read_ds_1"), loadBalancerName, new Properties());
-        return new 
CreateReadwriteSplittingRuleStatement(Collections.singleton(ruleSegment));
+        return createSQLStatement(false, new 
ReadwriteSplittingRuleSegment(ruleName, "write_ds", Arrays.asList("read_ds_0", 
"read_ds_1"), loadBalancerName, new Properties()));
     }
     
     private CreateReadwriteSplittingRuleStatement createSQLStatement(final 
String ruleName, final String writeDataSource, final Collection<String> 
readDataSources, final String loadBalancerName) {
-        ReadwriteSplittingRuleSegment ruleSegment = new 
ReadwriteSplittingRuleSegment(ruleName, writeDataSource, readDataSources, 
loadBalancerName, new Properties());
-        return new 
CreateReadwriteSplittingRuleStatement(Collections.singleton(ruleSegment));
+        return createSQLStatement(false, new 
ReadwriteSplittingRuleSegment(ruleName, writeDataSource, readDataSources, 
loadBalancerName, new Properties()));
+    }
+    
+    private CreateReadwriteSplittingRuleStatement createSQLStatement(final 
boolean ifNotExists, final ReadwriteSplittingRuleSegment... ruleSegments) {
+        return new CreateReadwriteSplittingRuleStatement(ifNotExists, 
Arrays.asList(ruleSegments));
     }
     
     private CreateReadwriteSplittingRuleStatement 
createSQLStatementWithDuplicateWriteResourceNames(final String ruleName0, final 
String ruleName1, final String loadBalancerName) {
         ReadwriteSplittingRuleSegment ruleSegment0 = new 
ReadwriteSplittingRuleSegment(ruleName0, "write_ds", Arrays.asList("read_ds_0", 
"read_ds_1"), loadBalancerName, new Properties());
         ReadwriteSplittingRuleSegment ruleSegment1 = new 
ReadwriteSplittingRuleSegment(ruleName1, "write_ds", Arrays.asList("read_ds_2", 
"read_ds_3"), loadBalancerName, new Properties());
-        return new 
CreateReadwriteSplittingRuleStatement(Arrays.asList(ruleSegment0, 
ruleSegment1));
+        return createSQLStatement(false, ruleSegment0, ruleSegment1);
     }
     
     private CreateReadwriteSplittingRuleStatement 
createSQLStatementWithDuplicateReadResourceNames(final String ruleName0, final 
String ruleName1, final String loadBalancerName) {
         ReadwriteSplittingRuleSegment ruleSegment0 = new 
ReadwriteSplittingRuleSegment(ruleName0, "write_ds_0", 
Arrays.asList("read_ds_0", "read_ds_1"), loadBalancerName, new Properties());
         ReadwriteSplittingRuleSegment ruleSegment1 = new 
ReadwriteSplittingRuleSegment(ruleName1, "write_ds_1", 
Arrays.asList("read_ds_0", "read_ds_1"), loadBalancerName, new Properties());
-        return new 
CreateReadwriteSplittingRuleStatement(Arrays.asList(ruleSegment0, 
ruleSegment1));
+        return createSQLStatement(false, ruleSegment0, ruleSegment1);
     }
     
     private ReadwriteSplittingRuleConfiguration 
createCurrentRuleConfiguration() {
diff --git 
a/features/readwrite-splitting/distsql/parser/src/main/antlr4/imports/readwrite-splitting/Keyword.g4
 
b/features/readwrite-splitting/distsql/parser/src/main/antlr4/imports/readwrite-splitting/Keyword.g4
index 5b9ce7fab0a..2cd6d3dfae9 100644
--- 
a/features/readwrite-splitting/distsql/parser/src/main/antlr4/imports/readwrite-splitting/Keyword.g4
+++ 
b/features/readwrite-splitting/distsql/parser/src/main/antlr4/imports/readwrite-splitting/Keyword.g4
@@ -123,7 +123,6 @@ EXISTS
     : E X I S T S
     ;  
 
-
 COUNT
     : C O U N T
     ;
@@ -179,3 +178,7 @@ FIXED_REPLICA_WEIGHT
 FIXED_PRIMARY
     : F I X E D UL_ P R I M A R Y
     ;
+
+NOT
+    : N O T
+    ;
diff --git 
a/features/readwrite-splitting/distsql/parser/src/main/antlr4/imports/readwrite-splitting/RDLStatement.g4
 
b/features/readwrite-splitting/distsql/parser/src/main/antlr4/imports/readwrite-splitting/RDLStatement.g4
index a3c2f4ad6bc..5d503885599 100644
--- 
a/features/readwrite-splitting/distsql/parser/src/main/antlr4/imports/readwrite-splitting/RDLStatement.g4
+++ 
b/features/readwrite-splitting/distsql/parser/src/main/antlr4/imports/readwrite-splitting/RDLStatement.g4
@@ -20,7 +20,7 @@ grammar RDLStatement;
 import BaseRule;
 
 createReadwriteSplittingRule
-    : CREATE READWRITE_SPLITTING RULE readwriteSplittingRuleDefinition (COMMA_ 
readwriteSplittingRuleDefinition)*
+    : CREATE READWRITE_SPLITTING RULE ifNotExists? 
readwriteSplittingRuleDefinition (COMMA_ readwriteSplittingRuleDefinition)*
     ;
 
 alterReadwriteSplittingRule
@@ -62,3 +62,7 @@ ifExists
 writeDataSourceQueryEnabled
     : TRUE | FALSE
     ;
+
+ifNotExists
+    : IF NOT EXISTS
+    ;
diff --git 
a/features/readwrite-splitting/distsql/parser/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/parser/core/ReadwriteSplittingDistSQLStatementVisitor.java
 
b/features/readwrite-splitting/distsql/parser/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/parser/core/ReadwriteSplittingDistSQLStatementVisitor.java
index b013904efbb..69e60b46d2b 100644
--- 
a/features/readwrite-splitting/distsql/parser/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/parser/core/ReadwriteSplittingDistSQLStatementVisitor.java
+++ 
b/features/readwrite-splitting/distsql/parser/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/parser/core/ReadwriteSplittingDistSQLStatementVisitor.java
@@ -63,7 +63,8 @@ public final class ReadwriteSplittingDistSQLStatementVisitor 
extends ReadwriteSp
     
     @Override
     public ASTNode visitCreateReadwriteSplittingRule(final 
CreateReadwriteSplittingRuleContext ctx) {
-        return new 
CreateReadwriteSplittingRuleStatement(ctx.readwriteSplittingRuleDefinition().stream().map(each
 -> (ReadwriteSplittingRuleSegment) visit(each)).collect(Collectors.toList()));
+        return new CreateReadwriteSplittingRuleStatement(null != 
ctx.ifNotExists(),
+                ctx.readwriteSplittingRuleDefinition().stream().map(each -> 
(ReadwriteSplittingRuleSegment) visit(each)).collect(Collectors.toList()));
     }
     
     @Override
diff --git 
a/features/readwrite-splitting/distsql/statement/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/parser/statement/CreateReadwriteSplittingRuleStatement.java
 
b/features/readwrite-splitting/distsql/statement/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/parser/statement/CreateReadwriteSplittingRuleStatement.java
index 87ac6f260ca..5e609a82e1e 100644
--- 
a/features/readwrite-splitting/distsql/statement/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/parser/statement/CreateReadwriteSplittingRuleStatement.java
+++ 
b/features/readwrite-splitting/distsql/statement/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/parser/statement/CreateReadwriteSplittingRuleStatement.java
@@ -18,18 +18,21 @@
 package org.apache.shardingsphere.readwritesplitting.distsql.parser.statement;
 
 import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import 
org.apache.shardingsphere.readwritesplitting.distsql.parser.segment.ReadwriteSplittingRuleSegment;
 import 
org.apache.shardingsphere.distsql.parser.statement.rdl.create.CreateRuleStatement;
+import 
org.apache.shardingsphere.readwritesplitting.distsql.parser.segment.ReadwriteSplittingRuleSegment;
 
 import java.util.Collection;
 
 /**
  * Create readwrite-splitting rule statement.
  */
-@RequiredArgsConstructor
 @Getter
 public final class CreateReadwriteSplittingRuleStatement extends 
CreateRuleStatement {
     
     private final Collection<ReadwriteSplittingRuleSegment> rules;
+    
+    public CreateReadwriteSplittingRuleStatement(final boolean ifNotExists, 
final Collection<ReadwriteSplittingRuleSegment> rules) {
+        super(ifNotExists);
+        this.rules = rules;
+    }
 }


Reply via email to