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 2474744  Refactor Shadow DistSQL and adapt the new data structure of 
tableConfiguration (#12623)
2474744 is described below

commit 2474744a801370b49cf6083e9034d397e16c986c
Author: lanchengx <[email protected]>
AuthorDate: Thu Sep 23 21:44:12 2021 -0500

    Refactor Shadow DistSQL and adapt the new data structure of 
tableConfiguration (#12623)
    
    * Refactored shadow DistSQL
    
    * Refactored Shadow DistSQL, added `checker` and `supporter`
    
    * Refactored Shadow DistSQL, Modify the naming in test
    
    * Adapt to Shadow's new data structure
    
    * Add license.
    
    * Revert local configuration files.
    
    * Fix problems that occurred during compare》
    
    * Modify the aggregateData() to mergeConfiguration().
    
    * Adjust the check method
    
    * Use string.format() to replace '+'
---
 .../checker/ShadowRuleStatementChecker.java        | 148 ++++++++++++++++++++
 .../converter/ShadowRuleStatementConverter.java    |  18 ++-
 .../supporter/ShadowRuleStatementSupporter.java    | 151 +++++++++++++++++++++
 .../AlterShadowAlgorithmStatementUpdater.java      |  40 +-----
 .../update/AlterShadowRuleStatementUpdater.java    | 141 ++++++-------------
 .../update/CreateShadowRuleStatementUpdater.java   |  88 ++++--------
 .../DropShadowAlgorithmStatementUpdater.java       |  60 ++++----
 .../update/DropShadowRuleStatementUpdater.java     |   9 +-
 .../AlterShadowAlgorithmStatementUpdaterTest.java  |   8 +-
 .../AlterShadowRuleStatementUpdaterTest.java       |  16 +--
 .../CreateShadowRuleStatementUpdaterTest.java      |  34 +----
 .../parser/core/ShadowDistSQLStatementVisitor.java |  16 ++-
 .../src/main/resources/case/rdl/alter.xml          |   2 +-
 .../src/main/resources/case/rdl/create.xml         |   2 +-
 14 files changed, 436 insertions(+), 297 deletions(-)

diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/checker/ShadowRuleStatementChecker.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/checker/ShadowRuleStatementChecker.java
new file mode 100644
index 0000000..6248605
--- /dev/null
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/checker/ShadowRuleStatementChecker.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.shadow.distsql.handler.checker;
+
+import org.apache.shardingsphere.infra.config.scope.SchemaRuleConfiguration;
+import org.apache.shardingsphere.infra.distsql.exception.DistSQLException;
+import 
org.apache.shardingsphere.infra.distsql.exception.resource.RequiredResourceMissedException;
+import 
org.apache.shardingsphere.infra.distsql.exception.rule.InvalidAlgorithmConfigurationException;
+import 
org.apache.shardingsphere.infra.distsql.exception.rule.RequiredRuleMissedException;
+import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
+import 
org.apache.shardingsphere.shadow.distsql.parser.segment.ShadowAlgorithmSegment;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * Shadow rule statement checker.
+ */
+public class ShadowRuleStatementChecker {
+    
+    public static final String SHADOW = "shadow";
+    
+    /**
+     * Check if the configuration exists.
+     *
+     * @param schemaName schema name
+     * @param configuration configuration
+     * @throws DistSQLException DistSQL exception
+     */
+    public static void checkConfigurationExist(final String schemaName, final 
SchemaRuleConfiguration configuration) throws DistSQLException {
+        DistSQLException.predictionThrow(null != configuration, new 
RequiredRuleMissedException(SHADOW, schemaName));
+    }
+    
+    /**
+     * Check if resources exist in meta data.
+     *
+     * @param resources resource being checked
+     * @param metaData meta rules
+     * @param schemaName schema name
+     * @throws DistSQLException DistSQL exception
+     */
+    public static void checkResourceExist(final Collection<String> resources, 
final ShardingSphereMetaData metaData, final String schemaName) throws 
DistSQLException {
+        Collection<String> notExistedResources = 
metaData.getResource().getNotExistedResources(resources);
+        DistSQLException.predictionThrow(notExistedResources.isEmpty(), new 
RequiredResourceMissedException(schemaName, notExistedResources));
+    }
+    
+    /**
+     * Check the completeness of the algorithm.
+     *
+     * @param algorithmSegments algorithmSegments to be checked
+     * @throws DistSQLException DistSQL exception
+     */
+    public static void checkAlgorithmCompleteness(final 
Collection<ShadowAlgorithmSegment> algorithmSegments) throws DistSQLException {
+        Set<ShadowAlgorithmSegment> incompleteAlgorithms = 
algorithmSegments.stream().filter(each -> 
!each.isComplete()).collect(Collectors.toSet());
+        DistSQLException.predictionThrow(incompleteAlgorithms.isEmpty(), new 
InvalidAlgorithmConfigurationException(SHADOW));
+    }
+    
+    /**
+     * Check if the rules exist.
+     * @param requireRules require rules
+     * @param currentRules current rules
+     * @param thrower thrower
+     * @throws DistSQLException DistSQL exception
+     */
+    public static void checkRulesExist(final Collection<String> requireRules, 
final Collection<String> currentRules, final Function<Set<String>, 
DistSQLException> thrower) throws DistSQLException {
+        ShadowRuleStatementChecker.checkAnyDifferent(requireRules, 
currentRules, thrower);
+    }
+    
+    /**
+     * Check if the algorithms exist.
+     * @param requireAlgorithms require algorithms
+     * @param currentAlgorithms current algorithms
+     * @param thrower thrower
+     * @throws DistSQLException DistSQL exception
+     */
+    public static void checkAlgorithmExist(final Collection<String> 
requireAlgorithms, final Collection<String> currentAlgorithms, 
+                                           final Function<Set<String>, 
DistSQLException> thrower) throws DistSQLException {
+        ShadowRuleStatementChecker.checkAnyDifferent(requireAlgorithms, 
currentAlgorithms, thrower);
+    }
+    
+    /**
+     * Check for any duplicate data in the rules, and throw the specified 
exception.
+     * @param rules rules to be checked
+     * @param thrower exception thrower
+     * @throws DistSQLException DistSQL exception
+     */
+    public static void checkAnyDuplicate(final Collection<String> rules, final 
Function<Set<String>, DistSQLException> thrower) throws DistSQLException {
+        Set<String> duplicateRequire = getDuplicate(rules);
+        DistSQLException.predictionThrow(duplicateRequire.isEmpty(), 
thrower.apply(duplicateRequire));
+    }
+    
+    /**
+     * Check if there are duplicates in the rules, and throw the specified 
exception.
+     *
+     * @param requireRules rules to be checked
+     * @param currentRules rules to be checked
+     * @param thrower exception thrower
+     * @throws DistSQLException DistSQL exception
+     */
+    public static void checkAnyDuplicate(final Collection<String> 
requireRules, final Collection<String> currentRules, final 
Function<Set<String>, DistSQLException> thrower) throws DistSQLException {
+        Set<String> identical = getIdentical(requireRules, currentRules);
+        DistSQLException.predictionThrow(identical.isEmpty(), 
thrower.apply(identical));
+    }
+    
+    /**
+     * Check for any different data in the rules, and throw the specified 
exception.
+     *
+     * @param requireRules rules to be checked
+     * @param currentRules rules to be checked
+     * @param thrower exception thrower
+     * @throws DistSQLException DistSQL exception
+     */
+    public static void checkAnyDifferent(final Collection<String> 
requireRules, final Collection<String> currentRules, final 
Function<Set<String>, DistSQLException> thrower) throws DistSQLException {
+        Set<String> different = getDifferent(requireRules, currentRules);
+        DistSQLException.predictionThrow(different.isEmpty(), 
thrower.apply(different));
+    }
+    
+    private static Set<String> getDuplicate(final Collection<String> require) {
+        return require.stream().collect(Collectors.groupingBy(each -> each, 
Collectors.counting())).entrySet().stream()
+                .filter(each -> each.getValue() > 
1).map(Map.Entry::getKey).collect(Collectors.toSet());
+    }
+    
+    private static Set<String> getDifferent(final Collection<String> require, 
final Collection<String> current) {
+        return require.stream().filter(each -> 
!current.contains(each)).collect(Collectors.toSet());
+    }
+    
+    private static Set<String> getIdentical(final Collection<String> require, 
final Collection<String> current) {
+        return 
require.stream().filter(current::contains).collect(Collectors.toSet());
+    }
+}
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/converter/ShadowRuleStatementConverter.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/converter/ShadowRuleStatementConverter.java
index c87315b..e266b12 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/converter/ShadowRuleStatementConverter.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/converter/ShadowRuleStatementConverter.java
@@ -23,12 +23,14 @@ import 
org.apache.shardingsphere.infra.config.algorithm.ShardingSphereAlgorithmC
 import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration;
 import 
org.apache.shardingsphere.shadow.api.config.datasource.ShadowDataSourceConfiguration;
 import 
org.apache.shardingsphere.shadow.api.config.table.ShadowTableConfiguration;
+import 
org.apache.shardingsphere.shadow.distsql.handler.supporter.ShadowRuleStatementSupporter;
 import 
org.apache.shardingsphere.shadow.distsql.parser.segment.ShadowAlgorithmSegment;
 import 
org.apache.shardingsphere.shadow.distsql.parser.segment.ShadowRuleSegment;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.LinkedList;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.stream.Collectors;
@@ -55,13 +57,17 @@ public final class ShadowRuleStatementConverter {
     }
     
     private static Map<String, ShadowTableConfiguration> getTables(final 
Collection<ShadowRuleSegment> rules) {
-        return rules.stream().flatMap(each -> 
each.getShadowTableRules().entrySet().stream()).collect(Collectors.toMap(Entry::getKey,
 ShadowRuleStatementConverter::buildShadowTableConfiguration));
+        Map<String, ShadowTableConfiguration> result = new HashMap<>();
+        rules.forEach(each -> {
+            Map<String, ShadowTableConfiguration> currentRuleTableConfig = 
each.getShadowTableRules().entrySet().stream()
+                    .collect(Collectors.toMap(Entry::getKey, entry -> 
buildShadowTableConfiguration(each.getRuleName(), entry), 
ShadowRuleStatementSupporter::mergeConfiguration));
+            currentRuleTableConfig.forEach((key, value) -> result.merge(key, 
value, ShadowRuleStatementSupporter::mergeConfiguration));
+        });
+        return result;
     }
     
-    private static ShadowTableConfiguration 
buildShadowTableConfiguration(final Entry<String, 
Collection<ShadowAlgorithmSegment>> entry) {
-        // FIXME replace empty collection
-        Collection<String> dataSourceNames = new LinkedList<>();
-        return new ShadowTableConfiguration(dataSourceNames, 
entry.getValue().stream().map(ShadowAlgorithmSegment::getAlgorithmName).collect(Collectors.toList()));
+    private static ShadowTableConfiguration 
buildShadowTableConfiguration(final String ruleName, final Entry<String, 
Collection<ShadowAlgorithmSegment>> entry) {
+        return new ShadowTableConfiguration(new 
ArrayList<>(Collections.singletonList(ruleName)), 
entry.getValue().stream().map(ShadowAlgorithmSegment::getAlgorithmName).collect(Collectors.toList()));
     }
     
     private static Map<String, ShadowDataSourceConfiguration> 
getDataSource(final Collection<ShadowRuleSegment> rules) {
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/supporter/ShadowRuleStatementSupporter.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/supporter/ShadowRuleStatementSupporter.java
new file mode 100644
index 0000000..6d8a263
--- /dev/null
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/supporter/ShadowRuleStatementSupporter.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.shadow.distsql.handler.supporter;
+
+import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration;
+import 
org.apache.shardingsphere.shadow.api.config.table.ShadowTableConfiguration;
+import 
org.apache.shardingsphere.shadow.distsql.parser.segment.ShadowAlgorithmSegment;
+import 
org.apache.shardingsphere.shadow.distsql.parser.segment.ShadowRuleSegment;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * Shadow rule statement supporter.
+ */
+public final class ShadowRuleStatementSupporter {
+    
+    /**
+     * Get rule names from the configuration.
+     *
+     * @param configuration configuration
+     * @return rule names
+     */
+    public static List<String> getRuleNames(final ShadowRuleConfiguration 
configuration) {
+        if (null == configuration) {
+            return Collections.emptyList();
+        }
+        return new ArrayList<>(configuration.getDataSources().keySet());
+    }
+    
+    /**
+     * Get rule names from the rules.
+     *
+     * @param rules rules
+     * @return rule names
+     */
+    public static List<String> getRuleNames(final 
Collection<ShadowRuleSegment> rules) {
+        if (rules.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return 
rules.stream().map(ShadowRuleSegment::getRuleName).collect(Collectors.toList());
+    }
+    
+    /**
+     * Get table names from the configuration.
+     *
+     * @param configuration configuration
+     * @return table names
+     */
+    public static List<String> getTableNames(final ShadowRuleConfiguration 
configuration) {
+        if (null == configuration) {
+            return Collections.emptyList();
+        }
+        return new ArrayList<>(configuration.getTables().keySet());
+    }
+    
+    /**
+     * Get the table names from the rules.
+     *
+     * @param rules rules
+     * @return table names
+     */
+    public static List<String> getTableNames(final 
Collection<ShadowRuleSegment> rules) {
+        if (rules.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return rules.stream().flatMap(each -> 
each.getShadowTableRules().keySet().stream()).collect(Collectors.toList());
+    }
+    
+    /**
+     * Get the resource names from the rules.
+     *
+     * @param rules rules
+     * @return resource names
+     */
+    public static List<String> getResourceNames(final 
Collection<ShadowRuleSegment> rules) {
+        if (rules.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return rules.stream().map(each -> Arrays.asList(each.getSource(), 
each.getShadow())).flatMap(Collection::stream).filter(Objects::nonNull).collect(Collectors.toList());
+    }
+    
+    /**
+     * Get the algorithm names from the configuration.
+     *
+     * @param configuration configuration
+     * @return algorithm names
+     */
+    public static List<String> getAlgorithmNames(final ShadowRuleConfiguration 
configuration) {
+        if (null == configuration) {
+            return Collections.emptyList();
+        }
+        return new ArrayList<>(configuration.getShadowAlgorithms().keySet());
+    }
+    
+    /**
+     * Get the algorithm names from the rules.
+     *
+     * @param rules configuration
+     * @return algorithm names
+     */
+    public static List<String> getAlgorithmNames(final 
Collection<ShadowRuleSegment> rules) {
+        if (rules.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return rules.stream().flatMap(each -> 
each.getShadowTableRules().values().stream()).flatMap(Collection::stream).map(ShadowAlgorithmSegment::getAlgorithmName).collect(Collectors.toList());
+    }
+    
+    /**
+     * Get the algorithm segments from the rules.
+     *
+     * @param rules configuration
+     * @return algorithm segments
+     */
+    public static List<ShadowAlgorithmSegment> getShadowAlgorithmSegment(final 
Collection<ShadowRuleSegment> rules) {
+        return rules.stream().flatMap(each -> 
each.getShadowTableRules().values().stream()).flatMap(Collection::stream).collect(Collectors.toList());
+    }
+    
+    /**
+     * Merge configuration.
+     *
+     * @param existingConfiguration already existing configuration
+     * @param newConfiguration new shadow table configuration
+     * @return shadow table configuration
+     */
+    public static ShadowTableConfiguration mergeConfiguration(final 
ShadowTableConfiguration existingConfiguration, final ShadowTableConfiguration 
newConfiguration) {
+        
existingConfiguration.getDataSourceNames().addAll(newConfiguration.getDataSourceNames());
+        
existingConfiguration.getShadowAlgorithmNames().addAll(newConfiguration.getShadowAlgorithmNames());
+        return existingConfiguration;
+    }
+}
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/AlterShadowAlgorithmStatementUpdater.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/AlterShadowAlgorithmStatementUpdater.java
index b85e39d..6a0c50f 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/AlterShadowAlgorithmStatementUpdater.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/AlterShadowAlgorithmStatementUpdater.java
@@ -21,21 +21,17 @@ import 
org.apache.shardingsphere.infra.config.RuleConfiguration;
 import 
org.apache.shardingsphere.infra.config.algorithm.ShardingSphereAlgorithmConfiguration;
 import org.apache.shardingsphere.infra.distsql.exception.DistSQLException;
 import 
org.apache.shardingsphere.infra.distsql.exception.rule.AlgorithmInUsedException;
-import 
org.apache.shardingsphere.infra.distsql.exception.rule.InvalidAlgorithmConfigurationException;
 import 
org.apache.shardingsphere.infra.distsql.exception.rule.RequiredAlgorithmMissedException;
-import 
org.apache.shardingsphere.infra.distsql.exception.rule.RequiredRuleMissedException;
 import 
org.apache.shardingsphere.infra.distsql.update.RuleDefinitionAlterUpdater;
 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
 import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration;
+import 
org.apache.shardingsphere.shadow.distsql.handler.checker.ShadowRuleStatementChecker;
 import 
org.apache.shardingsphere.shadow.distsql.parser.segment.ShadowAlgorithmSegment;
 import 
org.apache.shardingsphere.shadow.distsql.parser.statement.AlterShadowAlgorithmStatement;
 
-import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
-import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
@@ -71,39 +67,15 @@ public final class AlterShadowAlgorithmStatementUpdater 
implements RuleDefinitio
     }
     
     private void checkConfigurationExist(final String schemaName, final 
ShadowRuleConfiguration currentRuleConfig) throws DistSQLException {
-        DistSQLException.predictionThrow(null != currentRuleConfig, new 
RequiredRuleMissedException(SHADOW, schemaName));
+        ShadowRuleStatementChecker.checkConfigurationExist(schemaName, 
currentRuleConfig);
     }
     
     private void checkAlgorithms(final String schemaName, final 
AlterShadowAlgorithmStatement sqlStatement, final ShadowRuleConfiguration 
currentRuleConfig) throws DistSQLException {
-        checkAlgorithmCompleteness(sqlStatement);
+        
ShadowRuleStatementChecker.checkAlgorithmCompleteness(sqlStatement.getAlgorithms());
         List<String> requireAlgorithmNames = 
sqlStatement.getAlgorithms().stream().map(ShadowAlgorithmSegment::getAlgorithmName).collect(Collectors.toList());
-        checkDuplicate(requireAlgorithmNames, duplicate -> new 
AlgorithmInUsedException(schemaName, duplicate));
-        Set<String> currentAlgorithms = 
currentRuleConfig.getShadowAlgorithms().keySet();
-        checkDifferent(requireAlgorithmNames, currentAlgorithms, different -> 
new RequiredAlgorithmMissedException(SHADOW, schemaName, different));
-    }
-    
-    private void checkAlgorithmCompleteness(final 
AlterShadowAlgorithmStatement sqlStatement) throws DistSQLException {
-        List<ShadowAlgorithmSegment> incompleteAlgorithms = 
sqlStatement.getAlgorithms().stream().filter(each -> 
!each.isComplete()).collect(Collectors.toList());
-        DistSQLException.predictionThrow(incompleteAlgorithms.isEmpty(), new 
InvalidAlgorithmConfigurationException(SHADOW));
-    }
-    
-    private void checkDuplicate(final List<String> require, final 
Function<Set<String>, DistSQLException> thrower) throws DistSQLException {
-        Set<String> duplicateRequire = getDuplicate(require);
-        DistSQLException.predictionThrow(duplicateRequire.isEmpty(), 
thrower.apply(duplicateRequire));
-    }
-    
-    private void checkDifferent(final Collection<String> require, final 
Collection<String> current, final Function<Set<String>, DistSQLException> 
thrower) throws DistSQLException {
-        Set<String> duplicateRequire = getDifferent(require, current);
-        DistSQLException.predictionThrow(duplicateRequire.isEmpty(), 
thrower.apply(duplicateRequire));
-    }
-    
-    private Set<String> getDuplicate(final Collection<String> requires) {
-        return requires.stream().collect(Collectors.groupingBy(each -> each, 
Collectors.counting())).entrySet().stream()
-                .filter(each -> each.getValue() > 
1).map(Map.Entry::getKey).collect(Collectors.toSet());
-    }
-    
-    private Set<String> getDifferent(final Collection<String> require, final 
Collection<String> current) {
-        return require.stream().filter(each -> 
!current.contains(each)).collect(Collectors.toSet());
+        ShadowRuleStatementChecker.checkAnyDuplicate(requireAlgorithmNames, 
duplicate -> new AlgorithmInUsedException(schemaName, duplicate));
+        ShadowRuleStatementChecker.checkAlgorithmExist(requireAlgorithmNames, 
currentRuleConfig.getShadowAlgorithms().keySet(), 
+            different -> new RequiredAlgorithmMissedException(SHADOW, 
schemaName, different));
     }
     
     @Override
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/AlterShadowRuleStatementUpdater.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/AlterShadowRuleStatementUpdater.java
index dd06d50..ec1a667 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/AlterShadowRuleStatementUpdater.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/AlterShadowRuleStatementUpdater.java
@@ -18,30 +18,27 @@
 package org.apache.shardingsphere.shadow.distsql.handler.update;
 
 import org.apache.shardingsphere.infra.config.RuleConfiguration;
+import org.apache.shardingsphere.infra.config.scope.SchemaRuleConfiguration;
 import org.apache.shardingsphere.infra.distsql.exception.DistSQLException;
-import 
org.apache.shardingsphere.infra.distsql.exception.resource.RequiredResourceMissedException;
 import 
org.apache.shardingsphere.infra.distsql.exception.rule.AlgorithmInUsedException;
 import 
org.apache.shardingsphere.infra.distsql.exception.rule.DuplicateRuleException;
 import 
org.apache.shardingsphere.infra.distsql.exception.rule.InvalidAlgorithmConfigurationException;
-import 
org.apache.shardingsphere.infra.distsql.exception.rule.RequiredRuleMissedException;
 import 
org.apache.shardingsphere.infra.distsql.update.RuleDefinitionAlterUpdater;
 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
 import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration;
+import 
org.apache.shardingsphere.shadow.api.config.datasource.ShadowDataSourceConfiguration;
+import 
org.apache.shardingsphere.shadow.api.config.table.ShadowTableConfiguration;
+import 
org.apache.shardingsphere.shadow.distsql.handler.checker.ShadowRuleStatementChecker;
 import 
org.apache.shardingsphere.shadow.distsql.handler.converter.ShadowRuleStatementConverter;
+import 
org.apache.shardingsphere.shadow.distsql.handler.supporter.ShadowRuleStatementSupporter;
 import 
org.apache.shardingsphere.shadow.distsql.parser.segment.ShadowAlgorithmSegment;
 import 
org.apache.shardingsphere.shadow.distsql.parser.segment.ShadowRuleSegment;
 import 
org.apache.shardingsphere.shadow.distsql.parser.statement.AlterShadowRuleStatement;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
+
 
 /**
  * Alter shadow rule statement updater.
@@ -50,14 +47,6 @@ public final class AlterShadowRuleStatementUpdater 
implements RuleDefinitionAlte
     
     private static final String SHADOW = "shadow";
     
-    private static final String RULE_NAME = "ruleName";
-    
-    private static final String TABLE = "table";
-    
-    private static final String RESOURCE = "resource";
-    
-    private static final String ALGORITHM = "algorithm";
-    
     @Override
     public RuleConfiguration buildToBeAlteredRuleConfiguration(final 
AlterShadowRuleStatement sqlStatement) {
         return ShadowRuleStatementConverter.convert(sqlStatement.getRules());
@@ -65,107 +54,53 @@ public final class AlterShadowRuleStatementUpdater 
implements RuleDefinitionAlte
     
     @Override
     public void updateCurrentRuleConfiguration(final ShadowRuleConfiguration 
currentRuleConfig, final ShadowRuleConfiguration toBeAlteredRuleConfig) {
-        
currentRuleConfig.getDataSources().putAll(toBeAlteredRuleConfig.getDataSources());
+        updateDataSources(currentRuleConfig, 
toBeAlteredRuleConfig.getDataSources());
+        updateTables(currentRuleConfig.getTables(), 
toBeAlteredRuleConfig.getTables());
         
currentRuleConfig.getShadowAlgorithms().putAll(toBeAlteredRuleConfig.getShadowAlgorithms());
-        currentRuleConfig.setTables(toBeAlteredRuleConfig.getTables());
-    }
-    
-    @Override
-    public void checkSQLStatement(final ShardingSphereMetaData metaData, final 
AlterShadowRuleStatement sqlStatement, final ShadowRuleConfiguration 
currentRuleConfig) throws DistSQLException {
-        String schemaName = metaData.getName();
-        checkConfigurationExist(schemaName, currentRuleConfig);
-        checkRuleNames(schemaName, sqlStatement, currentRuleConfig);
-        checkResources(schemaName, sqlStatement, metaData);
-        checkTables(schemaName, sqlStatement);
-        checkAlgorithms(schemaName, sqlStatement);
-    }
-    
-    private void checkConfigurationExist(final String schemaName, final 
ShadowRuleConfiguration currentRuleConfig) throws DistSQLException {
-        DistSQLException.predictionThrow(null != currentRuleConfig, new 
RequiredRuleMissedException(SHADOW, schemaName));
-    }
-    
-    private void checkRuleNames(final String schemaName, final 
AlterShadowRuleStatement sqlStatement, final ShadowRuleConfiguration 
currentRuleConfig) throws DistSQLException {
-        List<String> currentRuleNames = getProperties(currentRuleConfig, 
RULE_NAME);
-        List<String> requireRuleNames = getProperties(sqlStatement, RULE_NAME);
-        checkDuplicate(requireRuleNames, duplicate -> new 
DuplicateRuleException(SHADOW, schemaName, duplicate));
-        checkDifferent(requireRuleNames, currentRuleNames, different -> new 
InvalidAlgorithmConfigurationException("shadow rule name ", different));
     }
     
-    private void checkTables(final String schemaName, final 
AlterShadowRuleStatement sqlStatement) throws DistSQLException {
-        List<String> requireTables = getProperties(sqlStatement, TABLE);
-        checkDuplicate(requireTables, duplicate -> new 
DuplicateRuleException(SHADOW, schemaName, duplicate));
+    private void updateDataSources(final ShadowRuleConfiguration 
currentRuleConfig, final Map<String, ShadowDataSourceConfiguration> 
toBeAlteredDataSources) {
+        currentRuleConfig.getTables().values().forEach(tableConfig -> {
+            
tableConfig.getDataSourceNames().removeIf(toBeAlteredDataSources::containsKey);
+        });
+        currentRuleConfig.getDataSources().putAll(toBeAlteredDataSources);
     }
     
-    private void checkResources(final String schemaName, final 
AlterShadowRuleStatement sqlStatement, final ShardingSphereMetaData metaData) 
throws DistSQLException {
-        List<String> requireSourceResources = getProperties(sqlStatement, 
RESOURCE);
-        checkDuplicate(requireSourceResources, duplicate -> new 
DuplicateRuleException(SHADOW, schemaName, duplicate));
-        checkResourceExist(sqlStatement.getRules(), metaData, schemaName);
+    private void updateTables(final Map<String, ShadowTableConfiguration> 
currentTables, final Map<String, ShadowTableConfiguration> toBeAlteredTables) {
+        toBeAlteredTables.forEach((key, value) -> currentTables.merge(key, 
value, ShadowRuleStatementSupporter::mergeConfiguration));
     }
     
-    private void checkAlgorithms(final String schemaName, final 
AlterShadowRuleStatement sqlStatement) throws DistSQLException {
-        checkAlgorithmCompleteness(sqlStatement);
-        List<String> requireAlgorithmNames = getProperties(sqlStatement, 
ALGORITHM);
-        checkDuplicate(requireAlgorithmNames, duplicate -> new 
AlgorithmInUsedException(schemaName, duplicate));
-    }
-    
-    private void checkAlgorithmCompleteness(final AlterShadowRuleStatement 
sqlStatement) throws DistSQLException {
-        List<ShadowAlgorithmSegment> incompleteAlgorithms = 
getShadowAlgorithmSegment(sqlStatement).flatMap(Collection::stream).filter(each 
-> !each.isComplete()).collect(Collectors.toList());
-        DistSQLException.predictionThrow(incompleteAlgorithms.isEmpty(), new 
InvalidAlgorithmConfigurationException(SHADOW));
-    }
-    
-    private List<String> getProperties(final ShadowRuleConfiguration 
currentRuleConfig, final String propName) {
-        if (RULE_NAME.equals(propName)) {
-            return new 
ArrayList<>(currentRuleConfig.getDataSources().keySet());
-        } else if (TABLE.equals(propName)) {
-            return new ArrayList<>(currentRuleConfig.getTables().keySet());
-        } else if (RESOURCE.equals(propName)) {
-            return new 
ArrayList<>(currentRuleConfig.getSourceDataSourceNames());
-        } else if (ALGORITHM.equals(propName)) {
-            return new 
ArrayList<>(currentRuleConfig.getShadowAlgorithms().keySet());
-        }
-        return Collections.emptyList();
-    }
-    
-    private List<String> getProperties(final AlterShadowRuleStatement 
sqlStatement, final String propName) {
-        if (RULE_NAME.equals(propName)) {
-            return 
sqlStatement.getRules().stream().map(ShadowRuleSegment::getRuleName).collect(Collectors.toList());
-        } else if (TABLE.equals(propName)) {
-            return sqlStatement.getRules().stream().flatMap(each -> 
each.getShadowTableRules().keySet().stream()).collect(Collectors.toList());
-        } else if (RESOURCE.equals(propName)) {
-            return 
sqlStatement.getRules().stream().map(ShadowRuleSegment::getSource).collect(Collectors.toList());
-        } else if (ALGORITHM.equals(propName)) {
-            return 
getShadowAlgorithmSegment(sqlStatement).flatMap(Collection::stream).map(ShadowAlgorithmSegment::getAlgorithmName).collect(Collectors.toList());
-        }
-        return Collections.emptyList();
-    }
-    
-    private Stream<Collection<ShadowAlgorithmSegment>> 
getShadowAlgorithmSegment(final AlterShadowRuleStatement sqlStatement) {
-        return sqlStatement.getRules().stream().flatMap(each -> 
each.getShadowTableRules().values().stream());
-    }
-    
-    private void checkDuplicate(final List<String> require, final 
Function<Set<String>, DistSQLException> thrower) throws DistSQLException {
-        Set<String> duplicateRequire = getDuplicate(require);
-        DistSQLException.predictionThrow(duplicateRequire.isEmpty(), 
thrower.apply(duplicateRequire));
+    @Override
+    public void checkSQLStatement(final ShardingSphereMetaData metaData, final 
AlterShadowRuleStatement sqlStatement, final ShadowRuleConfiguration 
currentRuleConfig) throws DistSQLException {
+        String schemaName = metaData.getName();
+        Collection<ShadowRuleSegment> rules = sqlStatement.getRules();
+        checkConfigurationExist(schemaName, currentRuleConfig);
+        checkRuleNames(schemaName, rules, currentRuleConfig);
+        checkResources(schemaName, rules, metaData);
+        checkAlgorithms(schemaName, rules);
     }
     
-    private void checkDifferent(final List<String> require, final List<String> 
current, final Function<Set<String>, DistSQLException> thrower) throws 
DistSQLException {
-        Set<String> duplicateRequire = getDifferent(require, current);
-        DistSQLException.predictionThrow(duplicateRequire.isEmpty(), 
thrower.apply(duplicateRequire));
+    private void checkConfigurationExist(final String schemaName, final 
SchemaRuleConfiguration currentRuleConfig) throws DistSQLException {
+        ShadowRuleStatementChecker.checkConfigurationExist(schemaName, 
currentRuleConfig);
     }
     
-    private Set<String> getDuplicate(final List<String> requires) {
-        return requires.stream().collect(Collectors.groupingBy(each -> each, 
Collectors.counting())).entrySet().stream()
-                .filter(each -> each.getValue() > 
1).map(Map.Entry::getKey).collect(Collectors.toSet());
+    private void checkRuleNames(final String schemaName, final 
Collection<ShadowRuleSegment> rules, final ShadowRuleConfiguration 
currentRuleConfig) throws DistSQLException {
+        List<String> currentRuleNames = 
ShadowRuleStatementSupporter.getRuleNames(currentRuleConfig);
+        List<String> requireRuleNames = 
ShadowRuleStatementSupporter.getRuleNames(rules);
+        ShadowRuleStatementChecker.checkAnyDuplicate(requireRuleNames, 
duplicate -> new DuplicateRuleException(SHADOW, schemaName, duplicate));
+        ShadowRuleStatementChecker.checkRulesExist(requireRuleNames, 
currentRuleNames, different -> new 
InvalidAlgorithmConfigurationException("shadow rule name ", different));
     }
     
-    private Set<String> getDifferent(final List<String> require, final 
List<String> current) {
-        return require.stream().filter(each -> 
!current.contains(each)).collect(Collectors.toSet());
+    private void checkResources(final String schemaName, final 
Collection<ShadowRuleSegment> rules, final ShardingSphereMetaData metaData) 
throws DistSQLException {
+        List<String> requireResource = 
ShadowRuleStatementSupporter.getResourceNames(rules);
+        ShadowRuleStatementChecker.checkResourceExist(requireResource, 
metaData, schemaName);
     }
     
-    private void checkResourceExist(final Collection<ShadowRuleSegment> rules, 
final ShardingSphereMetaData metaData, final String schemaName) throws 
DistSQLException {
-        List<String> requireResource = rules.stream().map(each -> 
Arrays.asList(each.getSource(), 
each.getShadow())).flatMap(Collection::stream).collect(Collectors.toList());
-        Collection<String> notExistedResources = 
metaData.getResource().getNotExistedResources(requireResource);
-        DistSQLException.predictionThrow(notExistedResources.isEmpty(), new 
RequiredResourceMissedException(schemaName, notExistedResources));
+    private void checkAlgorithms(final String schemaName, final 
Collection<ShadowRuleSegment> rules) throws DistSQLException {
+        List<ShadowAlgorithmSegment> shadowAlgorithmSegment = 
ShadowRuleStatementSupporter.getShadowAlgorithmSegment(rules);
+        
ShadowRuleStatementChecker.checkAlgorithmCompleteness(shadowAlgorithmSegment);
+        List<String> requireAlgorithms = 
ShadowRuleStatementSupporter.getAlgorithmNames(rules);
+        ShadowRuleStatementChecker.checkAnyDuplicate(requireAlgorithms, 
duplicate -> new AlgorithmInUsedException(schemaName, duplicate));
     }
     
     @Override
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/CreateShadowRuleStatementUpdater.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/CreateShadowRuleStatementUpdater.java
index 791be88..d63c222 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/CreateShadowRuleStatementUpdater.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/CreateShadowRuleStatementUpdater.java
@@ -19,26 +19,21 @@ package 
org.apache.shardingsphere.shadow.distsql.handler.update;
 
 import org.apache.shardingsphere.infra.config.RuleConfiguration;
 import org.apache.shardingsphere.infra.distsql.exception.DistSQLException;
-import 
org.apache.shardingsphere.infra.distsql.exception.resource.RequiredResourceMissedException;
-import 
org.apache.shardingsphere.infra.distsql.exception.resource.ResourceInUsedException;
-import 
org.apache.shardingsphere.infra.distsql.exception.rule.AlgorithmInUsedException;
 import 
org.apache.shardingsphere.infra.distsql.exception.rule.DuplicateRuleException;
-import 
org.apache.shardingsphere.infra.distsql.exception.rule.InvalidAlgorithmConfigurationException;
 import 
org.apache.shardingsphere.infra.distsql.update.RuleDefinitionCreateUpdater;
 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
 import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration;
+import 
org.apache.shardingsphere.shadow.api.config.table.ShadowTableConfiguration;
+import 
org.apache.shardingsphere.shadow.distsql.handler.checker.ShadowRuleStatementChecker;
 import 
org.apache.shardingsphere.shadow.distsql.handler.converter.ShadowRuleStatementConverter;
+import 
org.apache.shardingsphere.shadow.distsql.handler.supporter.ShadowRuleStatementSupporter;
 import 
org.apache.shardingsphere.shadow.distsql.parser.segment.ShadowAlgorithmSegment;
 import 
org.apache.shardingsphere.shadow.distsql.parser.segment.ShadowRuleSegment;
 import 
org.apache.shardingsphere.shadow.distsql.parser.statement.CreateShadowRuleStatement;
 
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 /**
  * Create shadow rule statement updater.
@@ -57,71 +52,42 @@ public final class CreateShadowRuleStatementUpdater 
implements RuleDefinitionCre
         if (null != currentRuleConfig) {
             
currentRuleConfig.getDataSources().putAll(toBeCreatedRuleConfig.getDataSources());
             
currentRuleConfig.getShadowAlgorithms().putAll(toBeCreatedRuleConfig.getShadowAlgorithms());
-            
currentRuleConfig.getTables().putAll(toBeCreatedRuleConfig.getTables());
+            updateTables(currentRuleConfig.getTables(), 
toBeCreatedRuleConfig.getTables());
         }
     }
     
+    private void updateTables(final Map<String, ShadowTableConfiguration> 
currentTables, final Map<String, ShadowTableConfiguration> toBeCreateTables) {
+        toBeCreateTables.forEach((key, value) -> currentTables.merge(key, 
value, ShadowRuleStatementSupporter::mergeConfiguration));
+    }
+    
     @Override
     public void checkSQLStatement(final ShardingSphereMetaData metaData, final 
CreateShadowRuleStatement sqlStatement, final ShadowRuleConfiguration 
currentRuleConfig) throws DistSQLException {
         String schemaName = metaData.getName();
-        checkRuleNames(schemaName, sqlStatement, currentRuleConfig);
-        checkResources(schemaName, sqlStatement, currentRuleConfig, metaData);
-        checkTables(schemaName, sqlStatement, currentRuleConfig);
-        checkAlgorithms(schemaName, sqlStatement, currentRuleConfig);
-    }
-    
-    private void checkRuleNames(final String schemaName, final 
CreateShadowRuleStatement sqlStatement, final ShadowRuleConfiguration 
currentRuleConfig) throws DistSQLException {
-        List<String> requireRuleNames = 
sqlStatement.getRules().stream().map(ShadowRuleSegment::getRuleName).collect(Collectors.toList());
-        Set<String> duplicatedNames = 
getDuplicateInRequirement(requireRuleNames);
-        DistSQLException.predictionThrow(duplicatedNames.isEmpty(), new 
DuplicateRuleException(SHADOW, schemaName, duplicatedNames));
-        if (null != currentRuleConfig) {
-            
duplicatedNames.addAll(currentRuleConfig.getDataSources().keySet().stream().filter(requireRuleNames::contains).collect(Collectors.toList()));
-            DistSQLException.predictionThrow(duplicatedNames.isEmpty(), new 
DuplicateRuleException(SHADOW, schemaName, duplicatedNames));
-        }
-    }
-    
-    private void checkTables(final String schemaName, final 
CreateShadowRuleStatement sqlStatement, final ShadowRuleConfiguration 
currentRuleConfig) throws DistSQLException {
-        List<String> requireTables = 
sqlStatement.getRules().stream().flatMap(each -> 
each.getShadowTableRules().keySet().stream()).collect(Collectors.toList());
-        Set<String> duplicatedTables = 
getDuplicateInRequirement(requireTables);
-        DistSQLException.predictionThrow(duplicatedTables.isEmpty(), new 
DuplicateRuleException(SHADOW, schemaName, duplicatedTables));
-        if (null != currentRuleConfig) {
-            
duplicatedTables.addAll(currentRuleConfig.getTables().keySet().stream().filter(requireTables::contains).collect(Collectors.toList()));
-            DistSQLException.predictionThrow(duplicatedTables.isEmpty(), new 
DuplicateRuleException(SHADOW, schemaName, duplicatedTables));
-        }
-    }
-    
-    private void checkResources(final String schemaName, final 
CreateShadowRuleStatement sqlStatement, final ShadowRuleConfiguration 
currentRuleConfig,
-                                final ShardingSphereMetaData metaData) throws 
DistSQLException {
-        List<String> requireSourceResource = 
sqlStatement.getRules().stream().map(ShadowRuleSegment::getSource).collect(Collectors.toList());
-        Set<String> duplicatedSource = 
getDuplicateInRequirement(requireSourceResource);
-        if (null != currentRuleConfig) {
-            
duplicatedSource.addAll(currentRuleConfig.getSourceDataSourceNames().stream().filter(requireSourceResource::contains).collect(Collectors.toList()));
-        }
-        DistSQLException.predictionThrow(duplicatedSource.isEmpty(), new 
ResourceInUsedException(duplicatedSource));
-        List<String> requireResource = 
sqlStatement.getRules().stream().map(each -> Arrays.asList(each.getSource(), 
each.getShadow())).flatMap(Collection::stream).collect(Collectors.toList());
-        Collection<String> notExistedResources = 
metaData.getResource().getNotExistedResources(requireResource);
-        DistSQLException.predictionThrow(notExistedResources.isEmpty(), new 
RequiredResourceMissedException(schemaName, notExistedResources));
+        Collection<ShadowRuleSegment> rules = sqlStatement.getRules();
+        checkRuleNames(schemaName, rules, currentRuleConfig);
+        checkResources(schemaName, rules, metaData);
+        checkAlgorithms(schemaName, rules, currentRuleConfig);
     }
     
-    private void checkAlgorithms(final String schemaName, final 
CreateShadowRuleStatement sqlStatement, final ShadowRuleConfiguration 
currentRuleConfig) throws DistSQLException {
-        List<ShadowAlgorithmSegment> incompleteAlgorithms = 
getShadowAlgorithmSegment(sqlStatement).flatMap(Collection::stream).filter(each 
-> !each.isComplete()).collect(Collectors.toList());
-        DistSQLException.predictionThrow(incompleteAlgorithms.isEmpty(), new 
InvalidAlgorithmConfigurationException(SHADOW));
-        List<String> requireAlgorithmNames = 
getShadowAlgorithmSegment(sqlStatement).flatMap(Collection::stream).map(ShadowAlgorithmSegment::getAlgorithmName).collect(Collectors.toList());
-        Set<String> duplicatedAlgorithmName = 
getDuplicateInRequirement(requireAlgorithmNames);
-        DistSQLException.predictionThrow(duplicatedAlgorithmName.isEmpty(), 
new AlgorithmInUsedException(schemaName, duplicatedAlgorithmName));
-        if (null != currentRuleConfig) {
-            
duplicatedAlgorithmName.addAll(currentRuleConfig.getShadowAlgorithms().keySet().stream().filter(requireAlgorithmNames::contains).collect(Collectors.toList()));
-        }
-        DistSQLException.predictionThrow(duplicatedAlgorithmName.isEmpty(), 
new AlgorithmInUsedException(schemaName, duplicatedAlgorithmName));
+    private void checkRuleNames(final String schemaName, final 
Collection<ShadowRuleSegment> rules, final ShadowRuleConfiguration 
currentRuleConfig) throws DistSQLException {
+        List<String> requireRuleNames = 
ShadowRuleStatementSupporter.getRuleNames(rules);
+        ShadowRuleStatementChecker.checkAnyDuplicate(requireRuleNames, 
duplicate -> new DuplicateRuleException(SHADOW, schemaName, duplicate));
+        List<String> currentRuleName = 
ShadowRuleStatementSupporter.getRuleNames(currentRuleConfig);
+        ShadowRuleStatementChecker.checkAnyDuplicate(requireRuleNames, 
currentRuleName, identical -> new DuplicateRuleException(SHADOW, schemaName, 
identical));
     }
     
-    private Stream<Collection<ShadowAlgorithmSegment>> 
getShadowAlgorithmSegment(final CreateShadowRuleStatement sqlStatement) {
-        return sqlStatement.getRules().stream().flatMap(each -> 
each.getShadowTableRules().values().stream());
+    private void checkResources(final String schemaName, final 
Collection<ShadowRuleSegment> rules, final ShardingSphereMetaData metaData) 
throws DistSQLException {
+        List<String> requireResource = 
ShadowRuleStatementSupporter.getResourceNames(rules);
+        ShadowRuleStatementChecker.checkResourceExist(requireResource, 
metaData, schemaName);
     }
     
-    private Set<String> getDuplicateInRequirement(final List<String> requires) 
{
-        return requires.stream().collect(Collectors.groupingBy(each -> each, 
Collectors.counting())).entrySet().stream()
-                .filter(each -> each.getValue() > 
1).map(Map.Entry::getKey).collect(Collectors.toSet());
+    private void checkAlgorithms(final String schemaName, final 
Collection<ShadowRuleSegment> rules, final ShadowRuleConfiguration 
currentRuleConfig) throws DistSQLException {
+        List<ShadowAlgorithmSegment> requireAlgorithms = 
ShadowRuleStatementSupporter.getShadowAlgorithmSegment(rules);
+        
ShadowRuleStatementChecker.checkAlgorithmCompleteness(requireAlgorithms);
+        List<String> requireAlgorithmNames = 
ShadowRuleStatementSupporter.getAlgorithmNames(rules);
+        ShadowRuleStatementChecker.checkAnyDuplicate(requireAlgorithmNames, 
duplicate -> new DuplicateRuleException(SHADOW, schemaName, duplicate));
+        List<String> currentAlgorithmNames = 
ShadowRuleStatementSupporter.getAlgorithmNames(currentRuleConfig);
+        ShadowRuleStatementChecker.checkAnyDuplicate(requireAlgorithmNames, 
currentAlgorithmNames, duplicate -> new DuplicateRuleException(SHADOW, 
schemaName, duplicate));
     }
     
     @Override
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/DropShadowAlgorithmStatementUpdater.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/DropShadowAlgorithmStatementUpdater.java
index a3510d0..05c1455 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/DropShadowAlgorithmStatementUpdater.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/DropShadowAlgorithmStatementUpdater.java
@@ -17,17 +17,21 @@
 
 package org.apache.shardingsphere.shadow.distsql.handler.update;
 
+import org.apache.shardingsphere.infra.config.scope.SchemaRuleConfiguration;
 import org.apache.shardingsphere.infra.distsql.exception.DistSQLException;
 import 
org.apache.shardingsphere.infra.distsql.exception.rule.AlgorithmInUsedException;
 import 
org.apache.shardingsphere.infra.distsql.exception.rule.RequiredAlgorithmMissedException;
-import 
org.apache.shardingsphere.infra.distsql.exception.rule.RequiredRuleMissedException;
 import 
org.apache.shardingsphere.infra.distsql.update.RuleDefinitionDropUpdater;
 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
 import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration;
 import 
org.apache.shardingsphere.shadow.api.config.table.ShadowTableConfiguration;
+import 
org.apache.shardingsphere.shadow.distsql.handler.checker.ShadowRuleStatementChecker;
+import 
org.apache.shardingsphere.shadow.distsql.handler.supporter.ShadowRuleStatementSupporter;
 import 
org.apache.shardingsphere.shadow.distsql.parser.statement.DropShadowAlgorithmStatement;
 
 import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -46,51 +50,41 @@ public final class DropShadowAlgorithmStatementUpdater 
implements RuleDefinition
         checkAlgorithm(schemaName, sqlStatement, currentRuleConfig);
     }
     
-    private void checkAlgorithm(final String schemaName, final 
DropShadowAlgorithmStatement sqlStatement, final ShadowRuleConfiguration 
currentRuleConfig) throws DistSQLException {
-        Collection<String> currentAlgorithms = 
getCurrentAlgorithms(currentRuleConfig);
-        Collection<String> requireAlgorithms = 
sqlStatement.getAlgorithmNames();
-        checkDifferent(requireAlgorithms, currentAlgorithms, different -> new 
RequiredAlgorithmMissedException(SHADOW, schemaName, different));
-        checkIdentical(requireAlgorithms, 
getAlgorithmInUse(currentRuleConfig), identical -> new 
AlgorithmInUsedException(schemaName, identical));
-    }
-    
-    private Set<String> getAlgorithmInUse(final ShadowRuleConfiguration 
currentRuleConfig) {
-        return 
currentRuleConfig.getTables().values().stream().map(ShadowTableConfiguration::getShadowAlgorithmNames).flatMap(Collection::stream).collect(Collectors.toSet());
-    }
-    
-    private void checkConfigurationExist(final String schemaName, final 
ShadowRuleConfiguration currentRuleConfig) throws DistSQLException {
-        DistSQLException.predictionThrow(currentRuleConfig != null, new 
RequiredRuleMissedException(SHADOW, schemaName));
-    }
-    
-    private void checkIdentical(final Collection<String> require, final 
Collection<String> current, final Function<Set<String>, DistSQLException> 
thrower) throws DistSQLException {
-        Set<String> identical = getIdentical(require, current);
-        DistSQLException.predictionThrow(identical.isEmpty(), 
thrower.apply(identical));
-    }
-    
-    private void checkDifferent(final Collection<String> require, final 
Collection<String> current, final Function<Set<String>, DistSQLException> 
thrower) throws DistSQLException {
-        Set<String> duplicateRequire = getDifferent(require, current);
-        DistSQLException.predictionThrow(duplicateRequire.isEmpty(), 
thrower.apply(duplicateRequire));
+    private void checkConfigurationExist(final String schemaName, final 
SchemaRuleConfiguration currentRuleConfig) throws DistSQLException {
+        ShadowRuleStatementChecker.checkConfigurationExist(schemaName, 
currentRuleConfig);
     }
     
-    private Set<String> getDifferent(final Collection<String> require, final 
Collection<String> current) {
-        return require.stream().filter(each -> 
!current.contains(each)).collect(Collectors.toSet());
+    private void checkAlgorithm(final String schemaName, final 
DropShadowAlgorithmStatement sqlStatement, final ShadowRuleConfiguration 
currentRuleConfig) throws DistSQLException {
+        Collection<String> currentAlgorithms = 
ShadowRuleStatementSupporter.getAlgorithmNames(currentRuleConfig);
+        Collection<String> requireAlgorithms = 
sqlStatement.getAlgorithmNames();
+        ShadowRuleStatementChecker.checkAlgorithmExist(requireAlgorithms, 
currentAlgorithms, different -> new RequiredAlgorithmMissedException(SHADOW, 
schemaName, different));
+        checkAlgorithmInUsed(requireAlgorithms, 
getAlgorithmInUse(currentRuleConfig), identical -> new 
AlgorithmInUsedException(schemaName, identical));
     }
     
-    private Set<String> getIdentical(final Collection<String> require, final 
Collection<String> current) {
-        return 
require.stream().filter(current::contains).collect(Collectors.toSet());
+    private void checkAlgorithmInUsed(final Collection<String> 
requireAlgorithms, final Collection<String> currentAlgorithms, 
+                                      final Function<Set<String>, 
DistSQLException> thrower) throws DistSQLException {
+        ShadowRuleStatementChecker.checkAnyDuplicate(requireAlgorithms, 
currentAlgorithms, thrower);
     }
     
-    private Collection<String> getCurrentAlgorithms(final 
ShadowRuleConfiguration configuration) {
-        return configuration.getShadowAlgorithms().keySet();
+    private Set<String> getAlgorithmInUse(final ShadowRuleConfiguration 
currentRuleConfig) {
+        return currentRuleConfig.getTables().values().stream().filter(each -> 
!each.getDataSourceNames().isEmpty()).map(ShadowTableConfiguration::getShadowAlgorithmNames)
+                .flatMap(Collection::stream).collect(Collectors.toSet());
     }
     
     @Override
     public boolean updateCurrentRuleConfiguration(final 
DropShadowAlgorithmStatement sqlStatement, final ShadowRuleConfiguration 
currentRuleConfig) {
-        sqlStatement.getAlgorithmNames().forEach(each -> {
-            
getCurrentAlgorithms(currentRuleConfig).removeIf(each::equalsIgnoreCase);
-        });
+        Collection<String> algorithmNames = sqlStatement.getAlgorithmNames();
+        algorithmNames.forEach(each -> 
currentRuleConfig.getShadowAlgorithms().remove(each));
+        currentRuleConfig.getTables().forEach((key, value) -> 
value.getShadowAlgorithmNames().removeIf(algorithmNames::contains));
+        getEmptyTableRules(currentRuleConfig.getTables()).forEach(each -> 
currentRuleConfig.getTables().remove(each));
         return false;
     }
     
+    private Set<String> getEmptyTableRules(final Map<String, 
ShadowTableConfiguration> tables) {
+        return tables.entrySet().stream().filter(entry -> 
entry.getValue().getShadowAlgorithmNames().isEmpty() && 
entry.getValue().getDataSourceNames().isEmpty())
+                .map(Entry::getKey).collect(Collectors.toSet());
+    }
+    
     @Override
     public Class<ShadowRuleConfiguration> getRuleConfigurationClass() {
         return ShadowRuleConfiguration.class;
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/DropShadowRuleStatementUpdater.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/DropShadowRuleStatementUpdater.java
index e490076..7320223 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/DropShadowRuleStatementUpdater.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/main/java/org/apache/shardingsphere/shadow/distsql/handler/update/DropShadowRuleStatementUpdater.java
@@ -22,12 +22,11 @@ import 
org.apache.shardingsphere.infra.distsql.exception.rule.RequiredRuleMissed
 import 
org.apache.shardingsphere.infra.distsql.update.RuleDefinitionDropUpdater;
 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
 import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration;
+import 
org.apache.shardingsphere.shadow.distsql.handler.checker.ShadowRuleStatementChecker;
 import 
org.apache.shardingsphere.shadow.distsql.parser.statement.DropShadowRuleStatement;
 
 import java.util.Collection;
-import java.util.List;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 /**
  * Drop shadow rule statement updater.
@@ -44,19 +43,19 @@ public final class DropShadowRuleStatementUpdater 
implements RuleDefinitionDropU
     }
     
     private void checkConfigurationExist(final String schemaName, final 
ShadowRuleConfiguration currentRuleConfig) throws DistSQLException {
-        DistSQLException.predictionThrow(null != currentRuleConfig, new 
RequiredRuleMissedException(SHADOW, schemaName));
+        ShadowRuleStatementChecker.checkConfigurationExist(schemaName, 
currentRuleConfig);
     }
     
     private void checkRuleNames(final String schemaName, final 
DropShadowRuleStatement sqlStatement, final ShadowRuleConfiguration 
currentRuleConfig) throws DistSQLException {
         Set<String> currentRuleNames = 
currentRuleConfig.getDataSources().keySet();
-        List<String> notExistRuleNames = 
sqlStatement.getRuleNames().stream().filter(each -> 
!currentRuleNames.contains(each)).collect(Collectors.toList());
-        DistSQLException.predictionThrow(notExistRuleNames.isEmpty(), new 
RequiredRuleMissedException(SHADOW, schemaName, notExistRuleNames));
+        ShadowRuleStatementChecker.checkRulesExist(currentRuleNames, 
sqlStatement.getRuleNames(), different -> new 
RequiredRuleMissedException(SHADOW, schemaName, different));
     }
     
     @Override
     public boolean updateCurrentRuleConfiguration(final 
DropShadowRuleStatement sqlStatement, final ShadowRuleConfiguration 
currentRuleConfig) {
         Collection<String> ruleNames = sqlStatement.getRuleNames();
         ruleNames.forEach(each -> 
currentRuleConfig.getDataSources().remove(each));
+        currentRuleConfig.getTables().forEach((key, value) -> 
value.getDataSourceNames().removeIf(ruleNames::contains));
         return false;
     }
     
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/test/java/org/apache/shardingsphere/shadow/distsql/update/AlterShadowAlgorithmStatementUpdaterTest.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/test/java/org/apache/shardingsphere/shadow/distsql/update/AlterShadowAlgorithmStatementUpdaterTest.java
index 9c70701..3c10b7a 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/test/java/org/apache/shardingsphere/shadow/distsql/update/AlterShadowAlgorithmStatementUpdaterTest.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/test/java/org/apache/shardingsphere/shadow/distsql/update/AlterShadowAlgorithmStatementUpdaterTest.java
@@ -54,8 +54,8 @@ public final class AlterShadowAlgorithmStatementUpdaterTest {
     public void assertExecuteDuplicateAlgorithm() throws DistSQLException {
         Properties prop = new Properties();
         prop.setProperty("type", "value");
-        AlterShadowAlgorithmStatement sqlStatement = createSQLStatement(new 
ShadowAlgorithmSegment("simple-note-algorithm", new 
AlgorithmSegment("simple-note", prop)),
-                new ShadowAlgorithmSegment("simple-note-algorithm", new 
AlgorithmSegment("simple-note", prop)));
+        AlterShadowAlgorithmStatement sqlStatement = createSQLStatement(new 
ShadowAlgorithmSegment("simpleNoteAlgorithm", new 
AlgorithmSegment("SIMPLE_NOTE", prop)),
+                new ShadowAlgorithmSegment("simpleNoteAlgorithm", new 
AlgorithmSegment("SIMPLE_NOTE", prop)));
         updater.checkSQLStatement(shardingSphereMetaData, sqlStatement, 
currentConfiguration);
     }
     
@@ -63,7 +63,7 @@ public final class AlterShadowAlgorithmStatementUpdaterTest {
     public void assertExecuteAlgorithmWithoutConfiguration() throws 
DistSQLException {
         Properties prop = new Properties();
         prop.setProperty("type", "value");
-        AlterShadowAlgorithmStatement sqlStatement = createSQLStatement(new 
ShadowAlgorithmSegment("simple-note-algorithm", new 
AlgorithmSegment("simple-note", prop)));
+        AlterShadowAlgorithmStatement sqlStatement = createSQLStatement(new 
ShadowAlgorithmSegment("simpleNoteAlgorithm", new 
AlgorithmSegment("SIMPLE_NOTE", prop)));
         updater.checkSQLStatement(shardingSphereMetaData, sqlStatement, null);
     }
     
@@ -72,7 +72,7 @@ public final class AlterShadowAlgorithmStatementUpdaterTest {
         Properties prop = new Properties();
         prop.setProperty("type", "value");
         
when(currentConfiguration.getShadowAlgorithms()).thenReturn(Collections.singletonMap("simpleNoteAlgorithm",
 new ShardingSphereAlgorithmConfiguration("type", prop)));
-        AlterShadowAlgorithmStatement sqlStatement = createSQLStatement(new 
ShadowAlgorithmSegment("simple-note-algorithm", new 
AlgorithmSegment("simple-note", prop)));
+        AlterShadowAlgorithmStatement sqlStatement = createSQLStatement(new 
ShadowAlgorithmSegment("simpleNoteAlgorithm1", new 
AlgorithmSegment("SIMPLE_NOTE", prop)));
         updater.checkSQLStatement(shardingSphereMetaData, sqlStatement, 
currentConfiguration);
     }
     
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/test/java/org/apache/shardingsphere/shadow/distsql/update/AlterShadowRuleStatementUpdaterTest.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/test/java/org/apache/shardingsphere/shadow/distsql/update/AlterShadowRuleStatementUpdaterTest.java
index b286609..2000e5f 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/test/java/org/apache/shardingsphere/shadow/distsql/update/AlterShadowRuleStatementUpdaterTest.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/test/java/org/apache/shardingsphere/shadow/distsql/update/AlterShadowRuleStatementUpdaterTest.java
@@ -89,28 +89,14 @@ public final class AlterShadowRuleStatementUpdaterTest {
         updater.checkSQLStatement(shardingSphereMetaData, 
createSQLStatement(ruleSegment), currentConfiguration);
     }
     
-    @Test(expected = DuplicateRuleException.class)
-    public void assertExecuteWithDuplicateResource() throws DistSQLException {
-        AlterShadowRuleStatement sqlStatement = createSQLStatement(new 
ShadowRuleSegment("initRuleName1", "ds", null, null),
-                new ShadowRuleSegment("initRuleName2", "ds", null, null));
-        updater.checkSQLStatement(shardingSphereMetaData, sqlStatement, 
currentConfiguration);
-    }
-    
     @Test(expected = RequiredResourceMissedException.class)
-    public void assertExecuteWithDuplicateResourceInMetaData() throws 
DistSQLException {
+    public void assertExecuteWithNotExistResource() throws DistSQLException {
         List<String> dataSources = Arrays.asList("ds", "ds0");
         when(resource.getNotExistedResources(any())).thenReturn(dataSources);
         AlterShadowRuleStatement sqlStatement = createSQLStatement(new 
ShadowRuleSegment("initRuleName1", "ds3", null, null));
         updater.checkSQLStatement(shardingSphereMetaData, sqlStatement, 
currentConfiguration);
     }
     
-    @Test(expected = DuplicateRuleException.class)
-    public void assertExecuteDuplicateTable() throws DistSQLException {
-        AlterShadowRuleStatement sqlStatement = createSQLStatement(new 
ShadowRuleSegment("initRuleName1", "ds", null, 
Collections.singletonMap("t_order", Collections.emptyList())),
-                new ShadowRuleSegment("initRuleName2", "ds1", null, 
Collections.singletonMap("t_order", Collections.emptyList())));
-        updater.checkSQLStatement(shardingSphereMetaData, sqlStatement, 
currentConfiguration);
-    }
-    
     @Test(expected = AlgorithmInUsedException.class)
     public void assertExecuteDuplicateAlgorithm() throws DistSQLException {
         Properties prop = new Properties();
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/test/java/org/apache/shardingsphere/shadow/distsql/update/CreateShadowRuleStatementUpdaterTest.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/test/java/org/apache/shardingsphere/shadow/distsql/update/CreateShadowRuleStatementUpdaterTest.java
index 19d5342..0c60943 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/test/java/org/apache/shardingsphere/shadow/distsql/update/CreateShadowRuleStatementUpdaterTest.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-handler/src/test/java/org/apache/shardingsphere/shadow/distsql/update/CreateShadowRuleStatementUpdaterTest.java
@@ -21,12 +21,11 @@ import 
org.apache.shardingsphere.distsql.parser.segment.AlgorithmSegment;
 import 
org.apache.shardingsphere.infra.config.algorithm.ShardingSphereAlgorithmConfiguration;
 import org.apache.shardingsphere.infra.distsql.exception.DistSQLException;
 import 
org.apache.shardingsphere.infra.distsql.exception.resource.RequiredResourceMissedException;
-import 
org.apache.shardingsphere.infra.distsql.exception.resource.ResourceInUsedException;
-import 
org.apache.shardingsphere.infra.distsql.exception.rule.AlgorithmInUsedException;
 import 
org.apache.shardingsphere.infra.distsql.exception.rule.DuplicateRuleException;
 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
 import 
org.apache.shardingsphere.infra.metadata.resource.ShardingSphereResource;
 import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration;
+import 
org.apache.shardingsphere.shadow.api.config.datasource.ShadowDataSourceConfiguration;
 import 
org.apache.shardingsphere.shadow.distsql.handler.update.CreateShadowRuleStatementUpdater;
 import 
org.apache.shardingsphere.shadow.distsql.parser.segment.ShadowAlgorithmSegment;
 import 
org.apache.shardingsphere.shadow.distsql.parser.segment.ShadowRuleSegment;
@@ -62,7 +61,7 @@ public final class CreateShadowRuleStatementUpdaterTest {
     @Before
     public void before() {
         when(shardingSphereMetaData.getResource()).thenReturn(resource);
-        
when(currentConfiguration.getDataSources()).thenReturn(Collections.singletonMap("initRuleName",
 null));
+        
when(currentConfiguration.getDataSources()).thenReturn(Collections.singletonMap("initRuleName",
 new ShadowDataSourceConfiguration("initDs0", "initDs0Shadow")));
     }
     
     @Test(expected = DuplicateRuleException.class)
@@ -78,36 +77,15 @@ public final class CreateShadowRuleStatementUpdaterTest {
         updater.checkSQLStatement(shardingSphereMetaData, 
createSQLStatement(ruleSegment), currentConfiguration);
     }
     
-    @Test(expected = ResourceInUsedException.class)
-    public void assertExecuteWithDuplicateResource() throws DistSQLException {
-        CreateShadowRuleStatement sqlStatement = createSQLStatement(new 
ShadowRuleSegment("ruleName", "ds", null, null),
-                new ShadowRuleSegment("ruleName1", "ds", null, null));
-        updater.checkSQLStatement(shardingSphereMetaData, sqlStatement, 
currentConfiguration);
-    }
-    
     @Test(expected = RequiredResourceMissedException.class)
-    public void assertExecuteWithDuplicateResourceInMetaData() throws 
DistSQLException {
+    public void assertExecuteWithNotExistResource() throws DistSQLException {
         List<String> dataSources = Arrays.asList("ds0", "ds1");
         when(resource.getNotExistedResources(any())).thenReturn(dataSources);
-        CreateShadowRuleStatement sqlStatement = createSQLStatement(new 
ShadowRuleSegment("ruleName", "ds3", null, null));
-        updater.checkSQLStatement(shardingSphereMetaData, sqlStatement, 
currentConfiguration);
-    }
-    
-    @Test(expected = DuplicateRuleException.class)
-    public void assertExecuteDuplicateTable() throws DistSQLException {
-        CreateShadowRuleStatement sqlStatement = createSQLStatement(new 
ShadowRuleSegment("ruleName", "ds", null, Collections.singletonMap("t_order", 
Collections.emptyList())),
-                new ShadowRuleSegment("ruleName1", "ds1", null, 
Collections.singletonMap("t_order", Collections.emptyList())));
+        CreateShadowRuleStatement sqlStatement = createSQLStatement(new 
ShadowRuleSegment("ruleName", "ds1", null, null));
         updater.checkSQLStatement(shardingSphereMetaData, sqlStatement, 
currentConfiguration);
     }
     
     @Test(expected = DuplicateRuleException.class)
-    public void assertExecuteDuplicateTableInMetaData() throws 
DistSQLException {
-        
when(currentConfiguration.getTables()).thenReturn(Collections.singletonMap("t_order",
 null));
-        CreateShadowRuleStatement sqlStatement = createSQLStatement(new 
ShadowRuleSegment("ruleName", "ds", null, Collections.singletonMap("t_order", 
Collections.emptyList())));
-        updater.checkSQLStatement(shardingSphereMetaData, sqlStatement, 
currentConfiguration);
-    }
-    
-    @Test(expected = AlgorithmInUsedException.class)
     public void assertExecuteDuplicateAlgorithm() throws DistSQLException {
         Properties prop = new Properties();
         prop.setProperty("type", "value");
@@ -117,7 +95,7 @@ public final class CreateShadowRuleStatementUpdaterTest {
         updater.checkSQLStatement(shardingSphereMetaData, sqlStatement, 
currentConfiguration);
     }
     
-    @Test(expected = AlgorithmInUsedException.class)
+    @Test(expected = DuplicateRuleException.class)
     public void assertExecuteDuplicateAlgorithmWithoutConfiguration() throws 
DistSQLException {
         Properties prop = new Properties();
         prop.setProperty("type", "value");
@@ -127,7 +105,7 @@ public final class CreateShadowRuleStatementUpdaterTest {
         updater.checkSQLStatement(shardingSphereMetaData, sqlStatement, null);
     }
     
-    @Test(expected = AlgorithmInUsedException.class)
+    @Test(expected = DuplicateRuleException.class)
     public void assertExecuteDuplicateAlgorithmInMetaData() throws 
DistSQLException {
         Properties prop = new Properties();
         prop.setProperty("type", "value");
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-parser/src/main/java/org/apache/shardingsphere/shadow/distsql/parser/core/ShadowDistSQLStatementVisitor.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-parser/src/main/java/org/apache/shardingsphere/shadow/distsql/parser/core/ShadowDistSQLStatementVisitor.java
index 14ff0f8..7e62a19 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-parser/src/main/java/org/apache/shardingsphere/shadow/distsql/parser/core/ShadowDistSQLStatementVisitor.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-distsql/shardingsphere-shadow-distsql-parser/src/main/java/org/apache/shardingsphere/shadow/distsql/parser/core/ShadowDistSQLStatementVisitor.java
@@ -70,7 +70,7 @@ public final class ShadowDistSQLStatementVisitor extends 
ShadowDistSQLStatementB
     @Override
     public ASTNode visitShadowRuleDefinition(final ShadowRuleDefinitionContext 
ctx) {
         Map<String, Collection<ShadowAlgorithmSegment>> shadowAlgorithms = 
ctx.shadowTableRule().stream()
-                .collect(Collectors.toMap(each -> getText(each.tableName()), 
each -> visitShadowAlgorithms(each.shadowAlgorithmDefinition())));
+                .collect(Collectors.toMap(each -> getText(each.tableName()), 
each -> visitShadowAlgorithms(each.shadowAlgorithmDefinition()), (oldValue, 
newValue) -> newValue));
         return new ShadowRuleSegment(getText(ctx.ruleName()), 
getText(ctx.source()), getText(ctx.shadow()), shadowAlgorithms);
     }
     
@@ -81,9 +81,10 @@ public final class ShadowDistSQLStatementVisitor extends 
ShadowDistSQLStatementB
     
     @Override
     public ASTNode visitShadowAlgorithmDefinition(final 
ShadowAlgorithmDefinitionContext ctx) {
-        AlgorithmSegment algorithmSegment = new 
AlgorithmSegment(getText(ctx.shadowAlgorithmType()), 
getAlgorithmProperties(ctx.algorithmProperties()));
-        String algorithmName = null != ctx.algorithmName() ? 
getText(ctx.algorithmName()) : 
createAlgorithmName(getText(((ShadowTableRuleContext) 
ctx.getParent()).tableName()), algorithmSegment);
-        return new ShadowAlgorithmSegment(algorithmName, algorithmSegment);
+        AlgorithmSegment segment = new 
AlgorithmSegment(getText(ctx.shadowAlgorithmType()), 
getAlgorithmProperties(ctx.algorithmProperties()));
+        String algorithmName = null != ctx.algorithmName() ? 
getText(ctx.algorithmName()) 
+                : createAlgorithmName(getText(((ShadowRuleDefinitionContext) 
ctx.getParent().getParent()).ruleName()), getText(((ShadowTableRuleContext) 
ctx.getParent()).tableName()), segment);
+        return new ShadowAlgorithmSegment(algorithmName, segment);
     }
     
     private Properties getAlgorithmProperties(final AlgorithmPropertiesContext 
ctx) {
@@ -127,6 +128,9 @@ public final class ShadowDistSQLStatementVisitor extends 
ShadowDistSQLStatementB
     }
     
     private static String getText(final ParserRuleContext ctx) {
+        if (null == ctx || ctx.isEmpty()) {
+            return null;
+        }
         return new IdentifierValue(ctx.getText()).getValue();
     }
     
@@ -134,8 +138,8 @@ public final class ShadowDistSQLStatementVisitor extends 
ShadowDistSQLStatementB
         return ctxs.stream().map(this::visit).map(each -> 
(ShadowAlgorithmSegment) each).collect(Collectors.toList());
     }
     
-    private String createAlgorithmName(final String tableName, final 
AlgorithmSegment algorithmSegment) {
-        return (tableName + "_" + algorithmSegment.getName()).toLowerCase();
+    private String createAlgorithmName(final String ruleName, final String 
tableName, final AlgorithmSegment algorithmSegment) {
+        return String.format("%s_%s_%s", ruleName, tableName, 
algorithmSegment.getName()).toLowerCase();
     }
     
     @Override
diff --git 
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/alter.xml
 
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/alter.xml
index 7be7ed4..ae8ea07 100644
--- 
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/alter.xml
+++ 
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/alter.xml
@@ -170,7 +170,7 @@
     <alter-shadow-rule sql-case-id="alter-shadow-rule">
         <rule name="rule" rule-name="shadow_rule" source="demo_ds" 
shadow="demo_ds_shadow">
             <table-rule  table-name="t_order">
-                <shadow-algorithm algorithm-id="t_order_column_regex_match">
+                <shadow-algorithm 
algorithm-id="shadow_rule_t_order_column_regex_match">
                     <algorithm algorithm-name="COLUMN_REGEX_MATCH">
                         <properties>
                             <property key="operation" value="insert"/>
diff --git 
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/create.xml
 
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/create.xml
index 494c633..9ff65a7 100644
--- 
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/create.xml
+++ 
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/create.xml
@@ -172,7 +172,7 @@
     <create-shadow-rule sql-case-id="create-shadow-rule">
         <rule name="rule" rule-name="shadow_rule" source="demo_ds" 
shadow="demo_ds_shadow">
             <table-rule  table-name="t_order">
-                <shadow-algorithm algorithm-id="t_order_column_regex_match">
+                <shadow-algorithm 
algorithm-id="shadow_rule_t_order_column_regex_match">
                     <algorithm algorithm-name="COLUMN_REGEX_MATCH">
                         <properties>
                             <property key="operation" value="insert"/>

Reply via email to