You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by ji...@apache.org on 2023/04/13 05:56:21 UTC

[shardingsphere] branch master updated: Add check for CREATE/ALTER SHARDING TABLE RULE with NoneShardingStrategy (#25145)

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 507b2d427cb Add check for CREATE/ALTER SHARDING TABLE RULE with NoneShardingStrategy (#25145)
507b2d427cb is described below

commit 507b2d427cb423991c24a41749364b1b7606cd0d
Author: ChenJiaHao <Pa...@163.com>
AuthorDate: Thu Apr 13 13:56:08 2023 +0800

    Add check for CREATE/ALTER SHARDING TABLE RULE with NoneShardingStrategy (#25145)
    
    * Add check for CREATE/ALTER SHARDING TABLE RULE with NoneShardingStrategy
    
    * Fix UT
    
    * Fix code style
    
    * Fix code style
---
 ...alidShardingStrategyConfigurationException.java |  33 ++
 .../checker/ShardingTableRuleStatementChecker.java | 405 +++++++++++----------
 .../checker/ShardingRuleStatementCheckerTest.java  |  21 +-
 ...reateShardingTableRuleStatementUpdaterTest.java |  45 +++
 4 files changed, 317 insertions(+), 187 deletions(-)

diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/exception/strategy/InvalidShardingStrategyConfigurationException.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/exception/strategy/InvalidShardingStrategyConfigurationException.java
new file mode 100644
index 00000000000..033565a3d88
--- /dev/null
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/exception/strategy/InvalidShardingStrategyConfigurationException.java
@@ -0,0 +1,33 @@
+/*
+ * 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.sharding.exception.strategy;
+
+import org.apache.shardingsphere.infra.util.exception.external.sql.sqlstate.XOpenSQLState;
+import org.apache.shardingsphere.sharding.exception.ShardingSQLException;
+
+/**
+ * Invalid sharding strategy configuration exception.
+ */
+public final class InvalidShardingStrategyConfigurationException extends ShardingSQLException {
+    
+    private static final long serialVersionUID = -5874317771225005670L;
+    
+    public InvalidShardingStrategyConfigurationException(final String strategyLevel, final String strategyType, final String message) {
+        super(XOpenSQLState.GENERAL_ERROR, 99, String.format("Invalid %s strategy `%s`, %s.", strategyLevel, strategyType, message));
+    }
+}
diff --git a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/checker/ShardingTableRuleStatementChecker.java b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/checker/ShardingTableRuleStatementChecker.java
index 0e5586a9055..cc19ceaaaf5 100644
--- a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/checker/ShardingTableRuleStatementChecker.java
+++ b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/checker/ShardingTableRuleStatementChecker.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.sharding.distsql.handler.checker;
 
 import com.google.common.base.Splitter;
 import org.apache.shardingsphere.distsql.handler.exception.algorithm.InvalidAlgorithmConfigurationException;
+import org.apache.shardingsphere.sharding.exception.strategy.InvalidShardingStrategyConfigurationException;
 import org.apache.shardingsphere.distsql.handler.exception.algorithm.MissingRequiredAlgorithmException;
 import org.apache.shardingsphere.distsql.handler.exception.rule.DuplicateRuleException;
 import org.apache.shardingsphere.distsql.handler.exception.rule.InvalidRuleConfigurationException;
@@ -117,11 +118,27 @@ public final class ShardingTableRuleStatementChecker {
     public static boolean isValidBindingTableGroups(final Collection<ShardingTableReferenceRuleConfiguration> bindingTableGroups, final ShardingRuleConfiguration currentRuleConfig) {
         ShardingRuleConfiguration toBeCheckedRuleConfig = createToBeCheckedShardingRuleConfiguration(currentRuleConfig);
         toBeCheckedRuleConfig.setBindingTableGroups(bindingTableGroups);
-        Collection<String> dataSourceNames = getRequiredDataSource(toBeCheckedRuleConfig);
-        dataSourceNames.addAll(getRequiredDataSource(currentRuleConfig));
+        Collection<String> dataSourceNames = getRequiredDataSources(toBeCheckedRuleConfig);
+        dataSourceNames.addAll(getRequiredDataSources(currentRuleConfig));
         return check(toBeCheckedRuleConfig, dataSourceNames);
     }
     
+    private static ShardingRuleConfiguration createToBeCheckedShardingRuleConfiguration(final ShardingRuleConfiguration currentRuleConfig) {
+        ShardingRuleConfiguration result = new ShardingRuleConfiguration();
+        result.setTables(new LinkedList<>(currentRuleConfig.getTables()));
+        result.setAutoTables(new LinkedList<>(currentRuleConfig.getAutoTables()));
+        result.setBindingTableGroups(new LinkedList<>(currentRuleConfig.getBindingTableGroups()));
+        result.setBroadcastTables(new LinkedList<>(currentRuleConfig.getBroadcastTables()));
+        result.setDefaultTableShardingStrategy(currentRuleConfig.getDefaultTableShardingStrategy());
+        result.setDefaultDatabaseShardingStrategy(currentRuleConfig.getDefaultDatabaseShardingStrategy());
+        result.setDefaultKeyGenerateStrategy(currentRuleConfig.getDefaultKeyGenerateStrategy());
+        result.setDefaultShardingColumn(currentRuleConfig.getDefaultShardingColumn());
+        result.setShardingAlgorithms(new LinkedHashMap<>(currentRuleConfig.getShardingAlgorithms()));
+        result.setKeyGenerators(new LinkedHashMap<>(currentRuleConfig.getKeyGenerators()));
+        result.setAuditors(new LinkedHashMap<>(currentRuleConfig.getAuditors()));
+        return result;
+    }
+    
     private static void check(final ShardingSphereDatabase database, final Collection<AbstractTableRuleSegment> rules, final boolean ifNotExists, final ShardingRuleConfiguration currentRuleConfig,
                               final boolean isCreated) {
         String databaseName = database.getName();
@@ -155,34 +172,8 @@ public final class ShardingTableRuleStatementChecker {
                 defaultDatabaseShardingStrategyConfig, defaultTableShardingStrategyConfig, checkedConfig.getDefaultShardingColumn()));
     }
     
-    private static void checkDataSources(final String databaseName, final Collection<AbstractTableRuleSegment> rules, final ShardingSphereDatabase database) {
-        Collection<String> requiredDataSource = getRequiredDataSources(rules);
-        Collection<String> notExistedDataSources = database.getResourceMetaData().getNotExistedDataSources(requiredDataSource);
-        Collection<String> logicDataSources = getLogicDataSources(database);
-        notExistedDataSources.removeIf(logicDataSources::contains);
-        ShardingSpherePreconditions.checkState(notExistedDataSources.isEmpty(), () -> new MissingRequiredStorageUnitsException(databaseName, notExistedDataSources));
-    }
-    
-    private static Collection<String> getLogicDataSources(final ShardingSphereDatabase database) {
-        return database.getRuleMetaData().findRules(DataSourceContainedRule.class).stream()
-                .map(each -> each.getDataSourceMapper().keySet()).flatMap(Collection::stream).collect(Collectors.toCollection(LinkedHashSet::new));
-    }
-    
-    private static Collection<String> getRequiredDataSources(final Collection<AbstractTableRuleSegment> rules) {
-        return rules.stream().map(AbstractTableRuleSegment::getDataSourceNodes).flatMap(Collection::stream)
-                .map(ShardingTableRuleStatementChecker::parseDateSource).map(ShardingTableRuleStatementChecker::getDataSourceNames).flatMap(Collection::stream).collect(Collectors.toList());
-    }
-    
-    private static Collection<String> parseDateSource(final String dateSource) {
-        return new InlineExpressionParser(dateSource).splitAndEvaluate();
-    }
-    
-    private static Collection<String> getDataSourceNames(final Collection<String> actualDataNodes) {
-        Collection<String> result = new HashSet<>();
-        for (String each : actualDataNodes) {
-            result.add(isValidDataNode(each) ? new DataNode(each).getDataSourceName() : each);
-        }
-        return result;
+    private static Map<String, List<AbstractTableRuleSegment>> groupingByClassType(final Collection<AbstractTableRuleSegment> rules) {
+        return rules.stream().collect(Collectors.groupingBy(each -> each.getClass().getSimpleName()));
     }
     
     private static Collection<String> getDataSourceNames(final Collection<ShardingTableRuleConfiguration> tableRuleConfigs,
@@ -203,10 +194,154 @@ public final class ShardingTableRuleStatementChecker {
         return new InlineExpressionParser(shardingTableRuleConfig.getActualDataNodes()).splitAndEvaluate().stream().map(each -> new DataNode(each).getDataSourceName()).collect(Collectors.toList());
     }
     
+    private static Collection<String> getDataSourceNames(final Collection<String> actualDataNodes) {
+        Collection<String> result = new HashSet<>();
+        for (String each : actualDataNodes) {
+            result.add(isValidDataNode(each) ? new DataNode(each).getDataSourceName() : each);
+        }
+        return result;
+    }
+    
     private static boolean isValidDataNode(final String dataNodeStr) {
         return dataNodeStr.contains(DELIMITER) && 2 == Splitter.on(DELIMITER).omitEmptyStrings().splitToList(dataNodeStr).size();
     }
     
+    private static Map<String, TableRule> createTableRules(final Collection<ShardingTableRuleConfiguration> tableRuleConfigs, final KeyGenerateStrategyConfiguration defaultKeyGenerateStrategyConfig,
+                                                           final Collection<String> dataSourceNames) {
+        return tableRuleConfigs.stream().map(each -> new TableRule(each, dataSourceNames, getDefaultGenerateKeyColumn(defaultKeyGenerateStrategyConfig)))
+                .collect(Collectors.toMap(each -> each.getLogicTable().toLowerCase(), Function.identity(), (oldValue, currentValue) -> oldValue, LinkedHashMap::new));
+    }
+    
+    private static String getDefaultGenerateKeyColumn(final KeyGenerateStrategyConfiguration defaultKeyGenerateStrategyConfig) {
+        return Optional.ofNullable(defaultKeyGenerateStrategyConfig).map(KeyGenerateStrategyConfiguration::getColumn).orElse(null);
+    }
+    
+    private static Map<String, TableRule> createAutoTableRules(final Collection<ShardingAutoTableRuleConfiguration> autoTableRuleConfigs, final Map<String, ShardingAlgorithm> shardingAlgorithms,
+                                                               final KeyGenerateStrategyConfiguration defaultKeyGenerateStrategyConfig, final Collection<String> dataSourceNames) {
+        return autoTableRuleConfigs.stream().map(each -> createAutoTableRule(defaultKeyGenerateStrategyConfig, each, shardingAlgorithms, dataSourceNames))
+                .collect(Collectors.toMap(each -> each.getLogicTable().toLowerCase(), Function.identity(), (oldValue, currentValue) -> oldValue, LinkedHashMap::new));
+    }
+    
+    private static TableRule createAutoTableRule(final KeyGenerateStrategyConfiguration defaultKeyGenerateStrategyConfig, final ShardingAutoTableRuleConfiguration autoTableRuleConfig,
+                                                 final Map<String, ShardingAlgorithm> shardingAlgorithms, final Collection<String> dataSourceNames) {
+        ShardingAlgorithm shardingAlgorithm = shardingAlgorithms.get(autoTableRuleConfig.getShardingStrategy().getShardingAlgorithmName());
+        ShardingSpherePreconditions.checkState(shardingAlgorithm instanceof ShardingAutoTableAlgorithm,
+                () -> new ShardingAlgorithmClassImplementationException(autoTableRuleConfig.getShardingStrategy().getShardingAlgorithmName(), ShardingAutoTableAlgorithm.class));
+        return new TableRule(autoTableRuleConfig, dataSourceNames, (ShardingAutoTableAlgorithm) shardingAlgorithm, getDefaultGenerateKeyColumn(defaultKeyGenerateStrategyConfig));
+    }
+    
+    private static Collection<String> createBroadcastTables(final Collection<String> broadcastTables) {
+        Collection<String> result = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+        result.addAll(broadcastTables);
+        return result;
+    }
+    
+    private static boolean isValidBindingTableConfiguration(final Map<String, TableRule> tableRules, final BindingTableCheckedConfiguration checkedConfig) {
+        for (ShardingTableReferenceRuleConfiguration each : checkedConfig.getBindingTableGroups()) {
+            Collection<String> bindingTables = Splitter.on(",").trimResults().splitToList(each.getReference().toLowerCase());
+            if (bindingTables.size() <= 1) {
+                return false;
+            }
+            Iterator<String> iterator = bindingTables.iterator();
+            TableRule sampleTableRule = getTableRule(iterator.next(), checkedConfig.getDataSourceNames(), tableRules, checkedConfig.getBroadcastTables());
+            while (iterator.hasNext()) {
+                TableRule tableRule = getTableRule(iterator.next(), checkedConfig.getDataSourceNames(), tableRules, checkedConfig.getBroadcastTables());
+                if (!isValidActualDataSourceName(sampleTableRule, tableRule) || !isValidActualTableName(sampleTableRule, tableRule)) {
+                    return false;
+                }
+                if (isInvalidShardingAlgorithm(sampleTableRule, tableRule, true, checkedConfig) || isInvalidShardingAlgorithm(sampleTableRule, tableRule, false, checkedConfig)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+    
+    private static TableRule getTableRule(final String logicTableName, final Collection<String> dataSourceNames, final Map<String, TableRule> tableRules, final Collection<String> broadcastTables) {
+        TableRule result = tableRules.get(logicTableName);
+        if (null != result) {
+            return result;
+        }
+        if (broadcastTables.contains(logicTableName)) {
+            return new TableRule(dataSourceNames, logicTableName);
+        }
+        throw new ShardingTableRuleNotFoundException(Collections.singleton(logicTableName));
+    }
+    
+    private static boolean isValidActualDataSourceName(final TableRule sampleTableRule, final TableRule tableRule) {
+        return sampleTableRule.getActualDataSourceNames().equals(tableRule.getActualDataSourceNames());
+    }
+    
+    private static boolean isValidActualTableName(final TableRule sampleTableRule, final TableRule tableRule) {
+        for (String each : sampleTableRule.getActualDataSourceNames()) {
+            Collection<String> sampleActualTableNames =
+                    sampleTableRule.getActualTableNames(each).stream().map(actualTableName -> actualTableName.replace(sampleTableRule.getTableDataNode().getPrefix(), "")).collect(Collectors.toSet());
+            Collection<String> actualTableNames =
+                    tableRule.getActualTableNames(each).stream().map(optional -> optional.replace(tableRule.getTableDataNode().getPrefix(), "")).collect(Collectors.toSet());
+            if (!sampleActualTableNames.equals(actualTableNames)) {
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    private static boolean isInvalidShardingAlgorithm(final TableRule sampleTableRule, final TableRule tableRule, final boolean databaseAlgorithm,
+                                                      final BindingTableCheckedConfiguration checkedConfig) {
+        return !getAlgorithmExpression(sampleTableRule, databaseAlgorithm, checkedConfig).equals(getAlgorithmExpression(tableRule, databaseAlgorithm, checkedConfig));
+    }
+    
+    private static Optional<String> getAlgorithmExpression(final TableRule tableRule, final boolean databaseAlgorithm, final BindingTableCheckedConfiguration checkedConfig) {
+        ShardingStrategyConfiguration shardingStrategyConfig = databaseAlgorithm
+                ? null == tableRule.getDatabaseShardingStrategyConfig() ? checkedConfig.getDefaultDatabaseShardingStrategyConfig() : tableRule.getDatabaseShardingStrategyConfig()
+                : null == tableRule.getTableShardingStrategyConfig() ? checkedConfig.getDefaultTableShardingStrategyConfig() : tableRule.getTableShardingStrategyConfig();
+        ShardingAlgorithm shardingAlgorithm = checkedConfig.getShardingAlgorithms().get(shardingStrategyConfig.getShardingAlgorithmName());
+        String dataNodePrefix = databaseAlgorithm ? tableRule.getDataSourceDataNode().getPrefix() : tableRule.getTableDataNode().getPrefix();
+        String shardingColumn = getShardingColumn(shardingStrategyConfig, checkedConfig.getDefaultShardingColumn());
+        return null == shardingAlgorithm ? Optional.empty() : shardingAlgorithm.getAlgorithmStructure(dataNodePrefix, shardingColumn);
+    }
+    
+    private static String getShardingColumn(final ShardingStrategyConfiguration shardingStrategyConfig, final String defaultShardingColumn) {
+        String shardingColumn = defaultShardingColumn;
+        if (shardingStrategyConfig instanceof ComplexShardingStrategyConfiguration) {
+            shardingColumn = ((ComplexShardingStrategyConfiguration) shardingStrategyConfig).getShardingColumns();
+        }
+        if (shardingStrategyConfig instanceof StandardShardingStrategyConfiguration) {
+            shardingColumn = ((StandardShardingStrategyConfiguration) shardingStrategyConfig).getShardingColumn();
+        }
+        return null == shardingColumn ? "" : shardingColumn;
+    }
+    
+    private static void checkDataSources(final String databaseName, final Collection<AbstractTableRuleSegment> rules, final ShardingSphereDatabase database) {
+        Collection<String> requiredDataSource = getRequiredDataSources(rules);
+        Collection<String> notExistedDataSources = database.getResourceMetaData().getNotExistedDataSources(requiredDataSource);
+        Collection<String> logicDataSources = getLogicDataSources(database);
+        notExistedDataSources.removeIf(logicDataSources::contains);
+        ShardingSpherePreconditions.checkState(notExistedDataSources.isEmpty(), () -> new MissingRequiredStorageUnitsException(databaseName, notExistedDataSources));
+    }
+    
+    private static Collection<String> getRequiredDataSources(final ShardingRuleConfiguration config) {
+        Collection<String> result = new LinkedHashSet<>();
+        result.addAll(config.getAutoTables().stream().map(ShardingAutoTableRuleConfiguration::getActualDataSources)
+                .map(each -> Splitter.on(",").trimResults().splitToList(each)).flatMap(Collection::stream).collect(Collectors.toSet()));
+        result.addAll(config.getTables().stream().map(each -> new InlineExpressionParser(each.getActualDataNodes()).splitAndEvaluate())
+                .flatMap(Collection::stream).distinct().map(each -> new DataNode(each).getDataSourceName()).collect(Collectors.toSet()));
+        return result;
+    }
+    
+    private static <T extends AbstractTableRuleSegment> Collection<String> getRequiredDataSources(final Collection<T> rules) {
+        return rules.stream().map(AbstractTableRuleSegment::getDataSourceNodes).flatMap(Collection::stream)
+                .map(ShardingTableRuleStatementChecker::parseDateSource).map(ShardingTableRuleStatementChecker::getDataSourceNames).flatMap(Collection::stream).collect(Collectors.toList());
+    }
+    
+    private static Collection<String> parseDateSource(final String dateSource) {
+        return new InlineExpressionParser(dateSource).splitAndEvaluate();
+    }
+    
+    private static Collection<String> getLogicDataSources(final ShardingSphereDatabase database) {
+        return database.getRuleMetaData().findRules(DataSourceContainedRule.class).stream()
+                .map(each -> each.getDataSourceMapper().keySet()).flatMap(Collection::stream).collect(Collectors.toCollection(LinkedHashSet::new));
+    }
+    
     private static void checkTables(final String databaseName, final Collection<AbstractTableRuleSegment> rules, final ShardingRuleConfiguration currentRuleConfig, final boolean isCreate,
                                     final boolean ifNotExists) {
         Collection<String> requiredTables = rules.stream().map(AbstractTableRuleSegment::getLogicTable).collect(Collectors.toList());
@@ -302,38 +437,67 @@ public final class ShardingTableRuleStatementChecker {
     private static void checkStrategy(final String databaseName, final Collection<TableRuleSegment> rules) {
         for (TableRuleSegment each : rules) {
             Optional<ShardingStrategySegment> databaseStrategySegment = Optional.ofNullable(each.getDatabaseStrategySegment());
-            if (databaseStrategySegment.isPresent() && !databaseStrategySegment.get().getType().equalsIgnoreCase("none")) {
-                AlgorithmSegment databaseShardingAlgorithm = databaseStrategySegment.get().getShardingAlgorithm();
-                if (null != databaseShardingAlgorithm) {
-                    ShardingAlgorithm shardingAlgorithm = TypedSPILoader.getService(ShardingAlgorithm.class, databaseShardingAlgorithm.getName(), databaseShardingAlgorithm.getProps());
-                    ShardingSpherePreconditions.checkState(!(shardingAlgorithm instanceof ShardingAutoTableAlgorithm),
-                            () -> new InvalidAlgorithmConfigurationException("sharding", shardingAlgorithm.getType(),
-                                    String.format("auto sharding algorithm cannot be used to create a table in Table mode `%s`", each.getLogicTable())));
+            if (databaseStrategySegment.isPresent()) {
+                if (databaseStrategySegment.get().getType().equalsIgnoreCase("none")) {
+                    Collection<String> requiredDataSources = getRequiredDataSources(rules);
+                    ShardingSpherePreconditions.checkState(1 == requiredDataSources.size(),
+                            () -> new InvalidShardingStrategyConfigurationException("database", databaseStrategySegment.get().getType(), "strategy does not match data nodes"));
+                } else {
+                    AlgorithmSegment databaseShardingAlgorithm = databaseStrategySegment.get().getShardingAlgorithm();
+                    checkDatabaseShardingAlgorithm(databaseName, each, databaseShardingAlgorithm);
                 }
-                ShardingSpherePreconditions.checkState(!isInvalidStrategy(each.getDatabaseStrategySegment()),
-                        () -> new InvalidAlgorithmConfigurationException(databaseName, null == databaseShardingAlgorithm ? null : databaseShardingAlgorithm.getName()));
             }
             Optional<ShardingStrategySegment> tableStrategySegment = Optional.ofNullable(each.getTableStrategySegment());
-            if (tableStrategySegment.isPresent() && !tableStrategySegment.get().getType().equalsIgnoreCase("none")) {
-                AlgorithmSegment tableShardingAlgorithm = tableStrategySegment.get().getShardingAlgorithm();
-                if (null != tableShardingAlgorithm) {
-                    ShardingAlgorithm shardingAlgorithm = TypedSPILoader.getService(ShardingAlgorithm.class, tableShardingAlgorithm.getName(), tableShardingAlgorithm.getProps());
-                    ShardingSpherePreconditions.checkState(!(shardingAlgorithm instanceof ShardingAutoTableAlgorithm),
-                            () -> new InvalidAlgorithmConfigurationException("sharding", shardingAlgorithm.getType(),
-                                    String.format("auto sharding algorithm cannot be used to create a table in Table mode `%s`", each.getLogicTable())));
+            if (tableStrategySegment.isPresent()) {
+                if (tableStrategySegment.get().getType().equalsIgnoreCase("none")) {
+                    Collection<String> requiredTables = getRequiredTables(rules);
+                    ShardingSpherePreconditions.checkState(1 == requiredTables.size(),
+                            () -> new InvalidShardingStrategyConfigurationException("table", tableStrategySegment.get().getType(), "strategy does not match data nodes"));
+                } else {
+                    AlgorithmSegment tableShardingAlgorithm = tableStrategySegment.get().getShardingAlgorithm();
+                    checkTableShardingAlgorithm(databaseName, each, tableShardingAlgorithm);
                 }
-                ShardingSpherePreconditions.checkState(!isInvalidStrategy(each.getTableStrategySegment()),
-                        () -> new InvalidAlgorithmConfigurationException(databaseName, null == tableShardingAlgorithm ? null : tableShardingAlgorithm.getName()));
             }
         }
     }
     
-    private static boolean isInvalidStrategy(final ShardingStrategySegment shardingStrategySegment) {
-        return !ShardingStrategyType.getValueOf(shardingStrategySegment.getType()).isValid(shardingStrategySegment.getShardingColumn()) || null == shardingStrategySegment.getShardingAlgorithm();
+    private static void checkDatabaseShardingAlgorithm(final String databaseName, final TableRuleSegment each, final AlgorithmSegment databaseShardingAlgorithm) {
+        if (null != databaseShardingAlgorithm) {
+            ShardingAlgorithm shardingAlgorithm = TypedSPILoader.getService(ShardingAlgorithm.class, databaseShardingAlgorithm.getName(), databaseShardingAlgorithm.getProps());
+            ShardingSpherePreconditions.checkState(!(shardingAlgorithm instanceof ShardingAutoTableAlgorithm),
+                    () -> new InvalidAlgorithmConfigurationException("sharding", shardingAlgorithm.getType(),
+                            String.format("auto sharding algorithm cannot be used to create a table in Table mode `%s`", each.getLogicTable())));
+        }
+        ShardingSpherePreconditions.checkState(isValidStrategy(each.getDatabaseStrategySegment()),
+                () -> new InvalidAlgorithmConfigurationException(databaseName, null == databaseShardingAlgorithm ? null : databaseShardingAlgorithm.getName()));
     }
     
-    private static Map<String, List<AbstractTableRuleSegment>> groupingByClassType(final Collection<AbstractTableRuleSegment> rules) {
-        return rules.stream().collect(Collectors.groupingBy(each -> each.getClass().getSimpleName()));
+    private static void checkTableShardingAlgorithm(final String databaseName, final TableRuleSegment each, final AlgorithmSegment tableShardingAlgorithm) {
+        if (null != tableShardingAlgorithm) {
+            ShardingAlgorithm shardingAlgorithm = TypedSPILoader.getService(ShardingAlgorithm.class, tableShardingAlgorithm.getName(), tableShardingAlgorithm.getProps());
+            ShardingSpherePreconditions.checkState(!(shardingAlgorithm instanceof ShardingAutoTableAlgorithm),
+                    () -> new InvalidAlgorithmConfigurationException("sharding", shardingAlgorithm.getType(),
+                            String.format("auto sharding algorithm cannot be used to create a table in Table mode `%s`", each.getLogicTable())));
+        }
+        ShardingSpherePreconditions.checkState(isValidStrategy(each.getTableStrategySegment()),
+                () -> new InvalidAlgorithmConfigurationException(databaseName, null == tableShardingAlgorithm ? null : tableShardingAlgorithm.getName()));
+    }
+    
+    private static boolean isValidStrategy(final ShardingStrategySegment shardingStrategySegment) {
+        return ShardingStrategyType.getValueOf(shardingStrategySegment.getType()).isValid(shardingStrategySegment.getShardingColumn()) && null != shardingStrategySegment.getShardingAlgorithm();
+    }
+    
+    private static <T extends AbstractTableRuleSegment> Collection<String> getRequiredTables(final Collection<T> rules) {
+        return rules.stream().map(AbstractTableRuleSegment::getDataSourceNodes).flatMap(Collection::stream)
+                .map(ShardingTableRuleStatementChecker::parseDateSource).map(ShardingTableRuleStatementChecker::getTableNames).flatMap(Collection::stream).collect(Collectors.toList());
+    }
+    
+    private static Collection<String> getTableNames(final Collection<String> actualDataNodes) {
+        Collection<String> result = new HashSet<>();
+        for (String each : actualDataNodes) {
+            result.add(isValidDataNode(each) ? new DataNode(each).getTableName() : each);
+        }
+        return result;
     }
     
     private static void checkBindingTableRules(final Collection<AbstractTableRuleSegment> rules, final ShardingRuleConfiguration currentRuleConfig) {
@@ -353,141 +517,18 @@ public final class ShardingTableRuleStatementChecker {
         ShardingRuleConfiguration toBeCheckedRuleConfig = createToBeCheckedShardingRuleConfiguration(currentRuleConfig);
         removeRuleConfiguration(toBeCheckedRuleConfig, toBeAlteredRuleConfig);
         addRuleConfiguration(toBeCheckedRuleConfig, toBeAlteredRuleConfig);
-        Collection<String> dataSourceNames = getRequiredDataSource(toBeCheckedRuleConfig);
-        dataSourceNames.addAll(getRequiredDataSource(toBeAlteredRuleConfig));
+        Collection<String> dataSourceNames = getRequiredDataSources(toBeCheckedRuleConfig);
+        dataSourceNames.addAll(getRequiredDataSources(toBeAlteredRuleConfig));
         ShardingSpherePreconditions.checkState(check(toBeCheckedRuleConfig, dataSourceNames),
                 () -> new InvalidRuleConfigurationException("sharding table", toBeAlteredLogicTableNames, Collections.singleton("invalid binding table configuration.")));
     }
     
-    private static ShardingRuleConfiguration createToBeCheckedShardingRuleConfiguration(final ShardingRuleConfiguration currentRuleConfig) {
-        ShardingRuleConfiguration result = new ShardingRuleConfiguration();
-        result.setTables(new LinkedList<>(currentRuleConfig.getTables()));
-        result.setAutoTables(new LinkedList<>(currentRuleConfig.getAutoTables()));
-        result.setBindingTableGroups(new LinkedList<>(currentRuleConfig.getBindingTableGroups()));
-        result.setBroadcastTables(new LinkedList<>(currentRuleConfig.getBroadcastTables()));
-        result.setDefaultTableShardingStrategy(currentRuleConfig.getDefaultTableShardingStrategy());
-        result.setDefaultDatabaseShardingStrategy(currentRuleConfig.getDefaultDatabaseShardingStrategy());
-        result.setDefaultKeyGenerateStrategy(currentRuleConfig.getDefaultKeyGenerateStrategy());
-        result.setDefaultShardingColumn(currentRuleConfig.getDefaultShardingColumn());
-        result.setShardingAlgorithms(new LinkedHashMap<>(currentRuleConfig.getShardingAlgorithms()));
-        result.setKeyGenerators(new LinkedHashMap<>(currentRuleConfig.getKeyGenerators()));
-        result.setAuditors(new LinkedHashMap<>(currentRuleConfig.getAuditors()));
-        return result;
-    }
-    
-    private static Collection<String> getRequiredDataSource(final ShardingRuleConfiguration config) {
+    private static Collection<String> getCurrentBindingTables(final ShardingRuleConfiguration currentRuleConfig) {
         Collection<String> result = new LinkedHashSet<>();
-        result.addAll(config.getAutoTables().stream().map(ShardingAutoTableRuleConfiguration::getActualDataSources)
-                .map(each -> Splitter.on(",").trimResults().splitToList(each)).flatMap(Collection::stream).collect(Collectors.toSet()));
-        result.addAll(config.getTables().stream().map(each -> new InlineExpressionParser(each.getActualDataNodes()).splitAndEvaluate())
-                .flatMap(Collection::stream).distinct().map(each -> new DataNode(each).getDataSourceName()).collect(Collectors.toSet()));
-        return result;
-    }
-    
-    private static boolean isValidBindingTableConfiguration(final Map<String, TableRule> tableRules, final BindingTableCheckedConfiguration checkedConfig) {
-        for (ShardingTableReferenceRuleConfiguration each : checkedConfig.getBindingTableGroups()) {
-            Collection<String> bindingTables = Splitter.on(",").trimResults().splitToList(each.getReference().toLowerCase());
-            if (bindingTables.size() <= 1) {
-                return false;
-            }
-            Iterator<String> iterator = bindingTables.iterator();
-            TableRule sampleTableRule = getTableRule(iterator.next(), checkedConfig.getDataSourceNames(), tableRules, checkedConfig.getBroadcastTables());
-            while (iterator.hasNext()) {
-                TableRule tableRule = getTableRule(iterator.next(), checkedConfig.getDataSourceNames(), tableRules, checkedConfig.getBroadcastTables());
-                if (!isValidActualDataSourceName(sampleTableRule, tableRule) || !isValidActualTableName(sampleTableRule, tableRule)) {
-                    return false;
-                }
-                if (!isValidShardingAlgorithm(sampleTableRule, tableRule, true, checkedConfig) || !isValidShardingAlgorithm(sampleTableRule, tableRule, false, checkedConfig)) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-    
-    private static boolean isValidActualDataSourceName(final TableRule sampleTableRule, final TableRule tableRule) {
-        return sampleTableRule.getActualDataSourceNames().equals(tableRule.getActualDataSourceNames());
-    }
-    
-    private static boolean isValidActualTableName(final TableRule sampleTableRule, final TableRule tableRule) {
-        for (String each : sampleTableRule.getActualDataSourceNames()) {
-            Collection<String> sampleActualTableNames =
-                    sampleTableRule.getActualTableNames(each).stream().map(actualTableName -> actualTableName.replace(sampleTableRule.getTableDataNode().getPrefix(), "")).collect(Collectors.toSet());
-            Collection<String> actualTableNames =
-                    tableRule.getActualTableNames(each).stream().map(optional -> optional.replace(tableRule.getTableDataNode().getPrefix(), "")).collect(Collectors.toSet());
-            if (!sampleActualTableNames.equals(actualTableNames)) {
-                return false;
-            }
-        }
-        return true;
-    }
-    
-    private static boolean isValidShardingAlgorithm(final TableRule sampleTableRule, final TableRule tableRule, final boolean databaseAlgorithm, final BindingTableCheckedConfiguration checkedConfig) {
-        return getAlgorithmExpression(sampleTableRule, databaseAlgorithm, checkedConfig).equals(getAlgorithmExpression(tableRule, databaseAlgorithm, checkedConfig));
-    }
-    
-    private static Optional<String> getAlgorithmExpression(final TableRule tableRule, final boolean databaseAlgorithm, final BindingTableCheckedConfiguration checkedConfig) {
-        ShardingStrategyConfiguration shardingStrategyConfig = databaseAlgorithm
-                ? null == tableRule.getDatabaseShardingStrategyConfig() ? checkedConfig.getDefaultDatabaseShardingStrategyConfig() : tableRule.getDatabaseShardingStrategyConfig()
-                : null == tableRule.getTableShardingStrategyConfig() ? checkedConfig.getDefaultTableShardingStrategyConfig() : tableRule.getTableShardingStrategyConfig();
-        ShardingAlgorithm shardingAlgorithm = checkedConfig.getShardingAlgorithms().get(shardingStrategyConfig.getShardingAlgorithmName());
-        String dataNodePrefix = databaseAlgorithm ? tableRule.getDataSourceDataNode().getPrefix() : tableRule.getTableDataNode().getPrefix();
-        String shardingColumn = getShardingColumn(shardingStrategyConfig, checkedConfig.getDefaultShardingColumn());
-        return null == shardingAlgorithm ? Optional.empty() : shardingAlgorithm.getAlgorithmStructure(dataNodePrefix, shardingColumn);
-    }
-    
-    private static String getShardingColumn(final ShardingStrategyConfiguration shardingStrategyConfig, final String defaultShardingColumn) {
-        String shardingColumn = defaultShardingColumn;
-        if (shardingStrategyConfig instanceof ComplexShardingStrategyConfiguration) {
-            shardingColumn = ((ComplexShardingStrategyConfiguration) shardingStrategyConfig).getShardingColumns();
-        }
-        if (shardingStrategyConfig instanceof StandardShardingStrategyConfiguration) {
-            shardingColumn = ((StandardShardingStrategyConfiguration) shardingStrategyConfig).getShardingColumn();
-        }
-        return null == shardingColumn ? "" : shardingColumn;
-    }
-    
-    private static TableRule getTableRule(final String logicTableName, final Collection<String> dataSourceNames, final Map<String, TableRule> tableRules, final Collection<String> broadcastTables) {
-        TableRule result = tableRules.get(logicTableName);
-        if (null != result) {
-            return result;
-        }
-        if (broadcastTables.contains(logicTableName)) {
-            return new TableRule(dataSourceNames, logicTableName);
-        }
-        throw new ShardingTableRuleNotFoundException(Collections.singleton(logicTableName));
-    }
-    
-    private static Collection<String> createBroadcastTables(final Collection<String> broadcastTables) {
-        Collection<String> result = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
-        result.addAll(broadcastTables);
+        currentRuleConfig.getBindingTableGroups().forEach(each -> result.addAll(Splitter.on(",").trimResults().splitToList(each.getReference())));
         return result;
     }
     
-    private static Map<String, TableRule> createAutoTableRules(final Collection<ShardingAutoTableRuleConfiguration> autoTableRuleConfigs, final Map<String, ShardingAlgorithm> shardingAlgorithms,
-                                                               final KeyGenerateStrategyConfiguration defaultKeyGenerateStrategyConfig, final Collection<String> dataSourceNames) {
-        return autoTableRuleConfigs.stream().map(each -> createAutoTableRule(defaultKeyGenerateStrategyConfig, each, shardingAlgorithms, dataSourceNames))
-                .collect(Collectors.toMap(each -> each.getLogicTable().toLowerCase(), Function.identity(), (oldValue, currentValue) -> oldValue, LinkedHashMap::new));
-    }
-    
-    private static TableRule createAutoTableRule(final KeyGenerateStrategyConfiguration defaultKeyGenerateStrategyConfig, final ShardingAutoTableRuleConfiguration autoTableRuleConfig,
-                                                 final Map<String, ShardingAlgorithm> shardingAlgorithms, final Collection<String> dataSourceNames) {
-        ShardingAlgorithm shardingAlgorithm = shardingAlgorithms.get(autoTableRuleConfig.getShardingStrategy().getShardingAlgorithmName());
-        ShardingSpherePreconditions.checkState(shardingAlgorithm instanceof ShardingAutoTableAlgorithm,
-                () -> new ShardingAlgorithmClassImplementationException(autoTableRuleConfig.getShardingStrategy().getShardingAlgorithmName(), ShardingAutoTableAlgorithm.class));
-        return new TableRule(autoTableRuleConfig, dataSourceNames, (ShardingAutoTableAlgorithm) shardingAlgorithm, getDefaultGenerateKeyColumn(defaultKeyGenerateStrategyConfig));
-    }
-    
-    private static Map<String, TableRule> createTableRules(final Collection<ShardingTableRuleConfiguration> tableRuleConfigs, final KeyGenerateStrategyConfiguration defaultKeyGenerateStrategyConfig,
-                                                           final Collection<String> dataSourceNames) {
-        return tableRuleConfigs.stream().map(each -> new TableRule(each, dataSourceNames, getDefaultGenerateKeyColumn(defaultKeyGenerateStrategyConfig)))
-                .collect(Collectors.toMap(each -> each.getLogicTable().toLowerCase(), Function.identity(), (oldValue, currentValue) -> oldValue, LinkedHashMap::new));
-    }
-    
-    private static String getDefaultGenerateKeyColumn(final KeyGenerateStrategyConfiguration defaultKeyGenerateStrategyConfig) {
-        return Optional.ofNullable(defaultKeyGenerateStrategyConfig).map(KeyGenerateStrategyConfiguration::getColumn).orElse(null);
-    }
-    
     private static void removeRuleConfiguration(final ShardingRuleConfiguration currentRuleConfig, final ShardingRuleConfiguration toBeAlteredRuleConfig) {
         Collection<String> toBeAlteredLogicTableNames = getAlteredLogicalTableNames(toBeAlteredRuleConfig);
         toBeAlteredLogicTableNames.forEach(each -> {
@@ -508,10 +549,4 @@ public final class ShardingTableRuleStatementChecker {
         result.addAll(toBeAlteredRuleConfig.getAutoTables().stream().map(ShardingAutoTableRuleConfiguration::getLogicTable).collect(Collectors.toList()));
         return result;
     }
-    
-    private static Collection<String> getCurrentBindingTables(final ShardingRuleConfiguration currentRuleConfig) {
-        Collection<String> result = new LinkedHashSet<>();
-        currentRuleConfig.getBindingTableGroups().forEach(each -> result.addAll(Splitter.on(",").trimResults().splitToList(each.getReference())));
-        return result;
-    }
 }
diff --git a/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/checker/ShardingRuleStatementCheckerTest.java b/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/checker/ShardingRuleStatementCheckerTest.java
index c2721efd586..f9c922607f9 100644
--- a/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/checker/ShardingRuleStatementCheckerTest.java
+++ b/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/checker/ShardingRuleStatementCheckerTest.java
@@ -18,6 +18,7 @@
 package org.apache.shardingsphere.sharding.distsql.checker;
 
 import org.apache.shardingsphere.distsql.handler.exception.algorithm.InvalidAlgorithmConfigurationException;
+import org.apache.shardingsphere.sharding.exception.strategy.InvalidShardingStrategyConfigurationException;
 import org.apache.shardingsphere.distsql.handler.exception.rule.DuplicateRuleException;
 import org.apache.shardingsphere.distsql.handler.exception.rule.MissingRequiredRuleException;
 import org.apache.shardingsphere.distsql.handler.exception.storageunit.MissingRequiredStorageUnitsException;
@@ -269,7 +270,14 @@ class ShardingRuleStatementCheckerTest {
     }
     
     @Test
-    void assertCheckerTableRuleWithNoneStrategyTypeSuccess() {
+    void assertCheckTableRuleWithNoneStrategyTypeThrows() {
+        Collection<AbstractTableRuleSegment> rules = new LinkedList<>();
+        rules.add(createWrongTableRuleWithNoneTypeStrategy());
+        assertThrows(InvalidShardingStrategyConfigurationException.class, () -> ShardingTableRuleStatementChecker.checkCreation(database, rules, false, shardingRuleConfig));
+    }
+    
+    @Test
+    void assertCheckTableRuleWithNoneStrategyTypeSuccess() {
         Collection<AbstractTableRuleSegment> rules = new LinkedList<>();
         rules.add(createCompleteTableRuleWithNoneTypeStrategy());
         ShardingTableRuleStatementChecker.checkCreation(database, rules, false, shardingRuleConfig);
@@ -314,12 +322,21 @@ class ShardingRuleStatementCheckerTest {
         return result;
     }
     
-    private TableRuleSegment createCompleteTableRuleWithNoneTypeStrategy() {
+    private TableRuleSegment createWrongTableRuleWithNoneTypeStrategy() {
         Properties props = new Properties();
         KeyGenerateStrategySegment keyGenerator = new KeyGenerateStrategySegment("product_id", new AlgorithmSegment("DISTSQL.FIXTURE", props));
         TableRuleSegment result = new TableRuleSegment("t_product_1", Collections.singletonList("ds_${0..1}.t_order${0..1}"), keyGenerator, null);
+        result.setDatabaseStrategySegment(new ShardingStrategySegment("none", null, null));
         result.setTableStrategySegment(new ShardingStrategySegment("none", null, null));
+        return result;
+    }
+    
+    private TableRuleSegment createCompleteTableRuleWithNoneTypeStrategy() {
+        Properties props = PropertiesBuilder.build(new Property("algorithm-expression", "t_order_${order_id % 2}"));
+        KeyGenerateStrategySegment keyGenerator = new KeyGenerateStrategySegment("product_id", new AlgorithmSegment("DISTSQL.FIXTURE", props));
+        TableRuleSegment result = new TableRuleSegment("t_product_1", Collections.singletonList("ds_0.t_order${0..1}"), keyGenerator, null);
         result.setDatabaseStrategySegment(new ShardingStrategySegment("none", null, null));
+        result.setTableStrategySegment(new ShardingStrategySegment("standard", "order_id", new AlgorithmSegment("inline", props)));
         return result;
     }
 }
diff --git a/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/update/CreateShardingTableRuleStatementUpdaterTest.java b/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/update/CreateShardingTableRuleStatementUpdaterTest.java
index 7a1bd79c1c1..683de397c93 100644
--- a/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/update/CreateShardingTableRuleStatementUpdaterTest.java
+++ b/features/sharding/distsql/handler/src/test/java/org/apache/shardingsphere/sharding/distsql/update/CreateShardingTableRuleStatementUpdaterTest.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.sharding.distsql.update;
 import lombok.SneakyThrows;
 import org.antlr.v4.runtime.tree.ParseTreeVisitor;
 import org.apache.shardingsphere.distsql.handler.exception.DistSQLException;
+import org.apache.shardingsphere.sharding.exception.strategy.InvalidShardingStrategyConfigurationException;
 import org.apache.shardingsphere.distsql.parser.engine.spi.FeaturedDistSQLStatementParserFacade;
 import org.apache.shardingsphere.distsql.parser.segment.AlgorithmSegment;
 import org.apache.shardingsphere.distsql.parser.statement.DistSQLStatement;
@@ -154,6 +155,50 @@ class CreateShardingTableRuleStatementUpdaterTest {
         assertThrows(DistSQLException.class, () -> updater.checkSQLStatement(database, distSQLStatement, null));
     }
     
+    @Test
+    void assertCheckCreateShardingStatementWithNoneDatabaseStrategy() {
+        String sql = "CREATE SHARDING TABLE RULE t_order("
+                + "DATANODES('ds_0.t_order_${0..1}'),"
+                + "DATABASE_STRATEGY(TYPE='NONE'),"
+                + "TABLE_STRATEGY(TYPE='standard',SHARDING_COLUMN=order_id,SHARDING_ALGORITHM(TYPE(NAME='inline',PROPERTIES('algorithm-expression'='t_order_${order_id % 2}'))))"
+                + ");";
+        CreateShardingTableRuleStatement distSQLStatement = (CreateShardingTableRuleStatement) getDistSQLStatement(sql);
+        updater.checkSQLStatement(database, distSQLStatement, null);
+    }
+    
+    @Test
+    void assertCheckCreateShardingStatementWithNoneDatabaseStrategyThrows() {
+        String sql = "CREATE SHARDING TABLE RULE t_order("
+                + "DATANODES('ds_${0..1}.t_order_${0..1}'),"
+                + "DATABASE_STRATEGY(TYPE='NONE'),"
+                + "TABLE_STRATEGY(TYPE='standard',SHARDING_COLUMN=order_id,SHARDING_ALGORITHM(TYPE(NAME='inline',PROPERTIES('algorithm-expression'='t_order_${order_id % 2}'))))"
+                + ");";
+        CreateShardingTableRuleStatement distSQLStatement = (CreateShardingTableRuleStatement) getDistSQLStatement(sql);
+        assertThrows(InvalidShardingStrategyConfigurationException.class, () -> updater.checkSQLStatement(database, distSQLStatement, null));
+    }
+    
+    @Test
+    void assertCheckCreateShardingStatementWithNoneTableStrategy() {
+        String sql = "CREATE SHARDING TABLE RULE t_order("
+                + "DATANODES('ds_${0..1}.t_order_0'),"
+                + "DATABASE_STRATEGY(TYPE='standard',SHARDING_COLUMN=user_id,SHARDING_ALGORITHM(TYPE(NAME='inline',PROPERTIES('algorithm-expression'='ds_${user_id % 2}')))),"
+                + "TABLE_STRATEGY(TYPE='NONE')"
+                + ");";
+        CreateShardingTableRuleStatement distSQLStatement = (CreateShardingTableRuleStatement) getDistSQLStatement(sql);
+        updater.checkSQLStatement(database, distSQLStatement, null);
+    }
+    
+    @Test
+    void assertCheckCreateShardingStatementWithNoneTableStrategyThrows() {
+        String sql = "CREATE SHARDING TABLE RULE t_order("
+                + "DATANODES('ds_${0..1}.t_order_${0..1}'),"
+                + "DATABASE_STRATEGY(TYPE='standard',SHARDING_COLUMN=user_id,SHARDING_ALGORITHM(TYPE(NAME='inline',PROPERTIES('algorithm-expression'='ds_${user_id % 2}')))),"
+                + "TABLE_STRATEGY(TYPE='NONE')"
+                + ");";
+        CreateShardingTableRuleStatement distSQLStatement = (CreateShardingTableRuleStatement) getDistSQLStatement(sql);
+        assertThrows(InvalidShardingStrategyConfigurationException.class, () -> updater.checkSQLStatement(database, distSQLStatement, null));
+    }
+    
     @Test
     void assertUpdateWithIfNotExistsStatement() {
         Collection<AbstractTableRuleSegment> segments = new LinkedList<>();