You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2022/10/12 00:29:16 UTC

[shardingsphere] branch master updated: Support sharding SQL hint. (#21346)

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

duanzhengqiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 72c189ece6b Support sharding SQL hint. (#21346)
72c189ece6b is described below

commit 72c189ece6bce1477171bbd10ca899d6c31c495f
Author: Zonglei Dong <do...@apache.org>
AuthorDate: Wed Oct 12 08:29:07 2022 +0800

    Support sharding SQL hint. (#21346)
    
    * Support sharding SQL hint.
    
    * Support sharding SQL hint.
    
    * Fixes checkstyle problem.
    
    * Support sharding SQL hint.
    
    * Fixes SQL hint sharding value to Comparable.
    
    * Fixes SQL hint sharding value to Comparable.
    
    * Fixes checkstyle.
    
    * Optimize code.
---
 .../engine/type/ShardingRouteEngineFactory.java    |  6 +--
 .../type/complex/ShardingComplexRoutingEngine.java |  5 ++-
 .../standard/ShardingStandardRoutingEngine.java    | 48 ++++++++++++++++++++
 .../dml/impl/ShardingInsertStatementValidator.java |  3 +-
 .../dml/impl/ShardingUpdateStatementValidator.java |  2 +-
 .../complex/ShardingComplexRoutingEngineTest.java  |  7 +--
 .../ShardingStandardRoutingEngineTest.java         | 24 +++++-----
 .../statement/CommonSQLStatementContext.java       | 50 +++++++++++++++++++++
 .../infra/hint/SQLHintExtractor.java               | 51 ++++++++++++++--------
 .../infra/hint/SQLHintPropertiesKey.java           |  4 +-
 .../shardingsphere/infra/hint/SQLHintUtils.java    | 11 ++++-
 .../infra/hint/SQLHintExtractorTest.java           | 29 +++++++++---
 12 files changed, 193 insertions(+), 47 deletions(-)

diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/ShardingRouteEngineFactory.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/ShardingRouteEngineFactory.java
index 33ef4abf227..bd772095445 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/ShardingRouteEngineFactory.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/ShardingRouteEngineFactory.java
@@ -147,7 +147,7 @@ public final class ShardingRouteEngineFactory {
         Collection<String> logicTableNames = shardingRule.getShardingLogicTableNames(tableNames);
         boolean allBindingTables = logicTableNames.size() > 1 && shardingRule.isAllBindingTables(database, sqlStatementContext, logicTableNames);
         if (isShardingStandardQuery(shardingRule, logicTableNames, allBindingTables)) {
-            return new ShardingStandardRoutingEngine(getLogicTableName(shardingConditions, logicTableNames), shardingConditions, props);
+            return new ShardingStandardRoutingEngine(getLogicTableName(shardingConditions, logicTableNames), shardingConditions, sqlStatementContext, props);
         }
         return new ShardingIgnoreRoutingEngine();
     }
@@ -227,10 +227,10 @@ public final class ShardingRouteEngineFactory {
                                                                          final ConfigurationProperties props, final Collection<String> tableNames) {
         boolean allBindingTables = tableNames.size() > 1 && shardingRule.isAllBindingTables(database, sqlStatementContext, tableNames);
         if (isShardingStandardQuery(shardingRule, tableNames, allBindingTables)) {
-            return new ShardingStandardRoutingEngine(getLogicTableName(shardingConditions, tableNames), shardingConditions, props);
+            return new ShardingStandardRoutingEngine(getLogicTableName(shardingConditions, tableNames), shardingConditions, sqlStatementContext, props);
         }
         // TODO config for cartesian set
-        return new ShardingComplexRoutingEngine(shardingConditions, props, tableNames);
+        return new ShardingComplexRoutingEngine(shardingConditions, sqlStatementContext, props, tableNames);
     }
     
     private static String getLogicTableName(final ShardingConditions shardingConditions, final Collection<String> tableNames) {
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/complex/ShardingComplexRoutingEngine.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/complex/ShardingComplexRoutingEngine.java
index a4adf1a13bb..bb4be8a81ff 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/complex/ShardingComplexRoutingEngine.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/complex/ShardingComplexRoutingEngine.java
@@ -18,6 +18,7 @@
 package org.apache.shardingsphere.sharding.route.engine.type.complex;
 
 import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
 import org.apache.shardingsphere.infra.route.context.RouteContext;
 import org.apache.shardingsphere.sharding.exception.metadata.ShardingRuleNotFoundException;
@@ -40,6 +41,8 @@ public final class ShardingComplexRoutingEngine implements ShardingRouteEngine {
     
     private final ShardingConditions shardingConditions;
     
+    private final SQLStatementContext<?> sqlStatementContext;
+    
     private final ConfigurationProperties props;
     
     private final Collection<String> logicTables;
@@ -53,7 +56,7 @@ public final class ShardingComplexRoutingEngine implements ShardingRouteEngine {
             Optional<TableRule> tableRule = shardingRule.findTableRule(each);
             if (tableRule.isPresent()) {
                 if (!bindingTableNames.contains(each)) {
-                    routeContexts.add(new ShardingStandardRoutingEngine(tableRule.get().getLogicTable(), shardingConditions, props).route(shardingRule));
+                    routeContexts.add(new ShardingStandardRoutingEngine(tableRule.get().getLogicTable(), shardingConditions, sqlStatementContext, props).route(shardingRule));
                 }
                 shardingRule.findBindingTableRule(each).ifPresent(optional -> bindingTableNames.addAll(optional.getTableRules().keySet()));
             }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/standard/ShardingStandardRoutingEngine.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/standard/ShardingStandardRoutingEngine.java
index d4c31edb509..4f4cc4f37e1 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/standard/ShardingStandardRoutingEngine.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/standard/ShardingStandardRoutingEngine.java
@@ -19,6 +19,8 @@ package org.apache.shardingsphere.sharding.route.engine.type.standard;
 
 import com.google.common.base.Preconditions;
 import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.infra.binder.statement.CommonSQLStatementContext;
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
 import org.apache.shardingsphere.infra.datanode.DataNode;
 import org.apache.shardingsphere.infra.hint.HintManager;
@@ -59,6 +61,8 @@ public final class ShardingStandardRoutingEngine implements ShardingRouteEngine
     
     private final ShardingConditions shardingConditions;
     
+    private final SQLStatementContext<?> sqlStatementContext;
+    
     private final ConfigurationProperties properties;
     
     private final Collection<Collection<DataNode>> originalDataNodes = new LinkedList<>();
@@ -94,6 +98,18 @@ public final class ShardingStandardRoutingEngine implements ShardingRouteEngine
                 && shardingRule.getTableShardingStrategyConfiguration(tableRule) instanceof HintShardingStrategyConfiguration;
     }
     
+    private boolean isRoutingBySQLHint() {
+        if (sqlStatementContext instanceof CommonSQLStatementContext) {
+            Collection<String> tableNames = sqlStatementContext.getTablesContext().getTableNames();
+            for (String each : tableNames) {
+                if (((CommonSQLStatementContext<?>) sqlStatementContext).containsHintShardingValue(each)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+    
     private Collection<DataNode> routeByHint(final TableRule tableRule, final ShardingStrategy databaseShardingStrategy, final ShardingStrategy tableShardingStrategy) {
         return route0(tableRule, databaseShardingStrategy, getDatabaseShardingValuesFromHint(), tableShardingStrategy, getTableShardingValuesFromHint());
     }
@@ -167,13 +183,45 @@ public final class ShardingStandardRoutingEngine implements ShardingRouteEngine
     }
     
     private List<ShardingConditionValue> getDatabaseShardingValuesFromHint() {
+        if (isRoutingBySQLHint()) {
+            return getDatabaseShardingValuesFromSQLHint();
+        }
         return getShardingConditions(HintManager.isDatabaseShardingOnly() ? HintManager.getDatabaseShardingValues() : HintManager.getDatabaseShardingValues(logicTableName));
     }
     
+    private List<ShardingConditionValue> getDatabaseShardingValuesFromSQLHint() {
+        Collection<Comparable<?>> shardingValues = new LinkedList<>();
+        if (sqlStatementContext instanceof CommonSQLStatementContext) {
+            Collection<String> tableNames = sqlStatementContext.getTablesContext().getTableNames();
+            for (String each : tableNames) {
+                if (each.equals(logicTableName) && ((CommonSQLStatementContext<?>) sqlStatementContext).containsHintShardingDatabaseValue(each)) {
+                    shardingValues.add(((CommonSQLStatementContext<?>) sqlStatementContext).getHintShardingDatabaseValue(each));
+                }
+            }
+        }
+        return getShardingConditions(shardingValues);
+    }
+    
     private List<ShardingConditionValue> getTableShardingValuesFromHint() {
+        if (isRoutingBySQLHint()) {
+            return getTableShardingValuesFromSQLHint();
+        }
         return getShardingConditions(HintManager.getTableShardingValues(logicTableName));
     }
     
+    private List<ShardingConditionValue> getTableShardingValuesFromSQLHint() {
+        Collection<Comparable<?>> shardingValues = new LinkedList<>();
+        if (sqlStatementContext instanceof CommonSQLStatementContext) {
+            Collection<String> tableNames = sqlStatementContext.getTablesContext().getTableNames();
+            for (String each : tableNames) {
+                if (each.equals(logicTableName) && ((CommonSQLStatementContext<?>) sqlStatementContext).containsHintShardingTableValue(each)) {
+                    shardingValues.add(((CommonSQLStatementContext<?>) sqlStatementContext).getHintShardingTableValue(each));
+                }
+            }
+        }
+        return getShardingConditions(shardingValues);
+    }
+    
     private List<ShardingConditionValue> getShardingConditions(final Collection<Comparable<?>> shardingValue) {
         return shardingValue.isEmpty() ? Collections.emptyList() : Collections.singletonList(new ListShardingConditionValue<>("", logicTableName, shardingValue));
     }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingInsertStatementValidator.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingInsertStatementValidator.java
index 2c325b30bff..9cf68815074 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingInsertStatementValidator.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingInsertStatementValidator.java
@@ -95,7 +95,8 @@ public final class ShardingInsertStatementValidator extends ShardingDMLStatement
         Collection<AssignmentSegment> assignments = InsertStatementHandler.getOnDuplicateKeyColumnsSegment(sqlStatementContext.getSqlStatement())
                 .map(OnDuplicateKeyColumnsSegment::getColumns).orElse(Collections.emptyList());
         Optional<ShardingConditions> onDuplicateKeyShardingConditions = createShardingConditions(sqlStatementContext, shardingRule, assignments, parameters);
-        Optional<RouteContext> onDuplicateKeyRouteContext = onDuplicateKeyShardingConditions.map(optional -> new ShardingStandardRoutingEngine(tableName, optional, props).route(shardingRule));
+        Optional<RouteContext> onDuplicateKeyRouteContext = onDuplicateKeyShardingConditions.map(optional -> new ShardingStandardRoutingEngine(tableName, optional,
+                sqlStatementContext, props).route(shardingRule));
         if (onDuplicateKeyRouteContext.isPresent() && !isSameRouteContext(routeContext, onDuplicateKeyRouteContext.get())) {
             throw new UnsupportedUpdatingShardingValueException(tableName);
         }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingUpdateStatementValidator.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingUpdateStatementValidator.java
index a2c83b64a40..834d8f60a82 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingUpdateStatementValidator.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/validator/dml/impl/ShardingUpdateStatementValidator.java
@@ -50,7 +50,7 @@ public final class ShardingUpdateStatementValidator extends ShardingDMLStatement
         String tableName = sqlStatementContext.getTablesContext().getTableNames().iterator().next();
         Optional<ShardingConditions> shardingConditions = createShardingConditions(sqlStatementContext, shardingRule,
                 sqlStatementContext.getSqlStatement().getSetAssignment().getAssignments(), parameters);
-        Optional<RouteContext> setAssignmentRouteContext = shardingConditions.map(optional -> new ShardingStandardRoutingEngine(tableName, optional, props).route(shardingRule));
+        Optional<RouteContext> setAssignmentRouteContext = shardingConditions.map(optional -> new ShardingStandardRoutingEngine(tableName, optional, sqlStatementContext, props).route(shardingRule));
         if (setAssignmentRouteContext.isPresent() && !isSameRouteContext(routeContext, setAssignmentRouteContext.get())) {
             throw new UnsupportedUpdatingShardingValueException(tableName);
         }
diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/complex/ShardingComplexRoutingEngineTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/complex/ShardingComplexRoutingEngineTest.java
index 1b8431d5e99..4e4b9b4d3e3 100644
--- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/complex/ShardingComplexRoutingEngineTest.java
+++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/complex/ShardingComplexRoutingEngineTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.sharding.route.engine.type.complex;
 
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
 import org.apache.shardingsphere.infra.route.context.RouteContext;
 import org.apache.shardingsphere.infra.route.context.RouteUnit;
@@ -40,7 +41,7 @@ public final class ShardingComplexRoutingEngineTest extends AbstractRoutingEngin
     @Test
     public void assertRoutingForBindingTables() {
         ShardingComplexRoutingEngine complexRoutingEngine = new ShardingComplexRoutingEngine(
-                createShardingConditions("t_order"), new ConfigurationProperties(new Properties()), Arrays.asList("t_order", "t_order_item"));
+                createShardingConditions("t_order"), mock(SQLStatementContext.class), new ConfigurationProperties(new Properties()), Arrays.asList("t_order", "t_order_item"));
         RouteContext routeContext = complexRoutingEngine.route(createBindingShardingRule());
         List<RouteUnit> routeUnits = new ArrayList<>(routeContext.getRouteUnits());
         assertThat(routeContext.getRouteUnits().size(), is(1));
@@ -53,7 +54,7 @@ public final class ShardingComplexRoutingEngineTest extends AbstractRoutingEngin
     @Test
     public void assertRoutingForShardingTableJoinBroadcastTable() {
         ShardingComplexRoutingEngine complexRoutingEngine = new ShardingComplexRoutingEngine(
-                createShardingConditions("t_order"), new ConfigurationProperties(new Properties()), Arrays.asList("t_order", "t_config"));
+                createShardingConditions("t_order"), mock(SQLStatementContext.class), new ConfigurationProperties(new Properties()), Arrays.asList("t_order", "t_config"));
         RouteContext routeContext = complexRoutingEngine.route(createBroadcastShardingRule());
         List<RouteUnit> routeUnits = new ArrayList<>(routeContext.getRouteUnits());
         assertThat(routeContext.getRouteUnits().size(), is(1));
@@ -66,7 +67,7 @@ public final class ShardingComplexRoutingEngineTest extends AbstractRoutingEngin
     @Test(expected = ShardingRuleNotFoundException.class)
     public void assertRoutingForNonLogicTable() {
         ShardingComplexRoutingEngine complexRoutingEngine = new ShardingComplexRoutingEngine(
-                createShardingConditions("t_order"), new ConfigurationProperties(new Properties()), Collections.emptyList());
+                createShardingConditions("t_order"), mock(SQLStatementContext.class), new ConfigurationProperties(new Properties()), Collections.emptyList());
         complexRoutingEngine.route(mock(ShardingRule.class));
     }
 }
diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/standard/ShardingStandardRoutingEngineTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/standard/ShardingStandardRoutingEngineTest.java
index 8b5822e63d5..c5846922a59 100644
--- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/standard/ShardingStandardRoutingEngineTest.java
+++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/standard/ShardingStandardRoutingEngineTest.java
@@ -48,7 +48,7 @@ public final class ShardingStandardRoutingEngineTest extends AbstractRoutingEngi
     @Test
     public void assertRouteByNonConditions() {
         ShardingStandardRoutingEngine standardRoutingEngine = createShardingStandardRoutingEngine("t_order",
-                new ShardingConditions(Collections.emptyList(), mock(SQLStatementContext.class), mock(ShardingRule.class)));
+                new ShardingConditions(Collections.emptyList(), mock(SQLStatementContext.class), mock(ShardingRule.class)), mock(SQLStatementContext.class));
         RouteContext routeContext = standardRoutingEngine.route(createBasedShardingRule());
         List<RouteUnit> routeUnits = new ArrayList<>(routeContext.getRouteUnits());
         assertThat(routeContext.getRouteUnits().size(), is(4));
@@ -72,7 +72,7 @@ public final class ShardingStandardRoutingEngineTest extends AbstractRoutingEngi
     
     @Test
     public void assertRouteByShardingConditions() {
-        ShardingStandardRoutingEngine standardRoutingEngine = createShardingStandardRoutingEngine("t_order", createShardingConditions("t_order"));
+        ShardingStandardRoutingEngine standardRoutingEngine = createShardingStandardRoutingEngine("t_order", createShardingConditions("t_order"), mock(SQLStatementContext.class));
         RouteContext routeContext = standardRoutingEngine.route(createBasedShardingRule());
         List<RouteUnit> routeUnits = new ArrayList<>(routeContext.getRouteUnits());
         assertThat(routeContext.getRouteUnits().size(), is(1));
@@ -84,14 +84,14 @@ public final class ShardingStandardRoutingEngineTest extends AbstractRoutingEngi
     
     @Test(expected = ShardingRouteAlgorithmException.class)
     public void assertRouteByErrorShardingTableStrategy() {
-        ShardingStandardRoutingEngine standardRoutingEngine = createShardingStandardRoutingEngine("t_order", createErrorShardingConditions("t_order"));
+        ShardingStandardRoutingEngine standardRoutingEngine = createShardingStandardRoutingEngine("t_order", createErrorShardingConditions("t_order"), mock(SQLStatementContext.class));
         standardRoutingEngine.route(createErrorShardingRule());
     }
     
     @Test
     public void assertRouteByHint() {
         ShardingStandardRoutingEngine standardRoutingEngine = createShardingStandardRoutingEngine("t_hint_test",
-                new ShardingConditions(Collections.emptyList(), mock(SQLStatementContext.class), mock(ShardingRule.class)));
+                new ShardingConditions(Collections.emptyList(), mock(SQLStatementContext.class), mock(ShardingRule.class)), mock(SQLStatementContext.class));
         HintManager hintManager = HintManager.getInstance();
         hintManager.addDatabaseShardingValue("t_hint_test", 1);
         hintManager.addTableShardingValue("t_hint_test", 1);
@@ -106,7 +106,7 @@ public final class ShardingStandardRoutingEngineTest extends AbstractRoutingEngi
     
     @Test
     public void assertRouteByMixedWithHintDataSource() {
-        ShardingStandardRoutingEngine standardRoutingEngine = createShardingStandardRoutingEngine("t_hint_ds_test", createShardingConditions("t_hint_ds_test"));
+        ShardingStandardRoutingEngine standardRoutingEngine = createShardingStandardRoutingEngine("t_hint_ds_test", createShardingConditions("t_hint_ds_test"), mock(SQLStatementContext.class));
         HintManager hintManager = HintManager.getInstance();
         hintManager.addDatabaseShardingValue("t_hint_ds_test", 1);
         RouteContext routeContext = standardRoutingEngine.route(createMixedShardingRule());
@@ -121,7 +121,7 @@ public final class ShardingStandardRoutingEngineTest extends AbstractRoutingEngi
     @Test
     public void assertRouteByMixedWithHintDataSourceOnly() {
         ShardingStandardRoutingEngine standardRoutingEngine = createShardingStandardRoutingEngine("t_hint_ds_test",
-                new ShardingConditions(Collections.emptyList(), mock(SQLStatementContext.class), mock(ShardingRule.class)));
+                new ShardingConditions(Collections.emptyList(), mock(SQLStatementContext.class), mock(ShardingRule.class)), mock(SQLStatementContext.class));
         HintManager hintManager = HintManager.getInstance();
         hintManager.addDatabaseShardingValue("t_hint_ds_test", 1);
         RouteContext routeContext = standardRoutingEngine.route(createMixedShardingRule());
@@ -139,7 +139,7 @@ public final class ShardingStandardRoutingEngineTest extends AbstractRoutingEngi
     
     @Test
     public void assertRouteByMixedWithHintTable() {
-        ShardingStandardRoutingEngine standardRoutingEngine = createShardingStandardRoutingEngine("t_hint_table_test", createShardingConditions("t_hint_table_test"));
+        ShardingStandardRoutingEngine standardRoutingEngine = createShardingStandardRoutingEngine("t_hint_table_test", createShardingConditions("t_hint_table_test"), mock(SQLStatementContext.class));
         HintManager hintManager = HintManager.getInstance();
         hintManager.addTableShardingValue("t_hint_table_test", 1);
         RouteContext routeContext = standardRoutingEngine.route(createMixedShardingRule());
@@ -154,7 +154,7 @@ public final class ShardingStandardRoutingEngineTest extends AbstractRoutingEngi
     @Test
     public void assertRouteByMixedWithHintTableOnly() {
         ShardingStandardRoutingEngine standardRoutingEngine = createShardingStandardRoutingEngine("t_hint_table_test",
-                new ShardingConditions(Collections.emptyList(), mock(SQLStatementContext.class), mock(ShardingRule.class)));
+                new ShardingConditions(Collections.emptyList(), mock(SQLStatementContext.class), mock(ShardingRule.class)), mock(SQLStatementContext.class));
         HintManager hintManager = HintManager.getInstance();
         hintManager.addTableShardingValue("t_hint_table_test", 1);
         RouteContext routeContext = standardRoutingEngine.route(createMixedShardingRule());
@@ -172,7 +172,8 @@ public final class ShardingStandardRoutingEngineTest extends AbstractRoutingEngi
     
     @Test
     public void assertRouteByIntervalTableShardingStrategyOnly() {
-        ShardingStandardRoutingEngine standardRoutingEngine = createShardingStandardRoutingEngine("t_interval_test", createIntervalShardingConditions("t_interval_test"));
+        ShardingStandardRoutingEngine standardRoutingEngine = createShardingStandardRoutingEngine("t_interval_test",
+                createIntervalShardingConditions("t_interval_test"), mock(SQLStatementContext.class));
         RouteContext routeContext = standardRoutingEngine.route(createIntervalTableShardingRule());
         List<RouteUnit> routeUnits = new ArrayList<>(routeContext.getRouteUnits());
         assertThat(routeContext.getRouteUnits().size(), is(1));
@@ -182,7 +183,8 @@ public final class ShardingStandardRoutingEngineTest extends AbstractRoutingEngi
         assertThat(routeUnits.get(0).getTableMappers().iterator().next().getLogicName(), is("t_interval_test"));
     }
     
-    private ShardingStandardRoutingEngine createShardingStandardRoutingEngine(final String logicTableName, final ShardingConditions shardingConditions) {
-        return new ShardingStandardRoutingEngine(logicTableName, shardingConditions, new ConfigurationProperties(new Properties()));
+    private ShardingStandardRoutingEngine createShardingStandardRoutingEngine(final String logicTableName, final ShardingConditions shardingConditions,
+                                                                              final SQLStatementContext<?> sqlStatementContext) {
+        return new ShardingStandardRoutingEngine(logicTableName, shardingConditions, sqlStatementContext, new ConfigurationProperties(new Properties()));
     }
 }
diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/CommonSQLStatementContext.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/CommonSQLStatementContext.java
index bf69e0b76a0..363989bb330 100644
--- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/CommonSQLStatementContext.java
+++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/CommonSQLStatementContext.java
@@ -86,4 +86,54 @@ public class CommonSQLStatementContext<T extends SQLStatement> implements SQLSta
     public boolean isHintWriteRouteOnly() {
         return sqlHintExtractor.isHintWriteRouteOnly();
     }
+    
+    /**
+     * Get hint sharding database value.
+     *
+     * @param tableName table name
+     * @return sharding database value
+     */
+    public Comparable<?> getHintShardingDatabaseValue(final String tableName) {
+        return sqlHintExtractor.getHintShardingDatabaseValue(tableName);
+    }
+    
+    /**
+     * Get hint sharding table value.
+     *
+     * @param tableName table name
+     * @return sharding table value
+     */
+    public Comparable<?> getHintShardingTableValue(final String tableName) {
+        return sqlHintExtractor.getHintShardingTableValue(tableName);
+    }
+    
+    /**
+     * Judge contains hint sharding databases value or not.
+     *
+     * @param tableName table name
+     * @return contains hint sharding databases value or not
+     */
+    public boolean containsHintShardingDatabaseValue(final String tableName) {
+        return sqlHintExtractor.containsHintShardingDatabaseValue(tableName);
+    }
+    
+    /**
+     * Judge contains hint sharding table value or not.
+     *
+     * @param tableName table name
+     * @return Contains hint sharding table value or not
+     */
+    public boolean containsHintShardingTableValue(final String tableName) {
+        return sqlHintExtractor.containsHintShardingTableValue(tableName);
+    }
+    
+    /**
+     * Judge contains hint sharding value or not.
+     *
+     * @param tableName table name
+     * @return Contains hint sharding value or not
+     */
+    public boolean containsHintShardingValue(final String tableName) {
+        return containsHintShardingDatabaseValue(tableName) || containsHintShardingTableValue(tableName);
+    }
 }
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintExtractor.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintExtractor.java
index 82643dbe64b..7db4fc4328a 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintExtractor.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintExtractor.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.infra.hint;
 
+import com.google.common.base.Joiner;
 import lombok.Getter;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.CommentSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.AbstractSQLStatement;
@@ -76,35 +77,34 @@ public final class SQLHintExtractor {
         return SQLHintUtils.getSplitterSQLHintValue(sqlHintProperties.getValue(SQLHintPropertiesKey.DISABLE_AUDIT_NAMES_KEY));
     }
     
-    /**
-     * Get hint sharding database value.
-     *
-     * @return sharding database value
-     */
-    public int getHintShardingDatabaseValue() {
-        return sqlHintProperties.getValue(SQLHintPropertiesKey.SHARDING_DATABASE_VALUE_KEY);
-    }
-    
     /**
      * Get hint sharding database value.
      *
      * @param tableName table name
      * @return sharding database value
      */
-    public int getHintShardingDatabaseValue(final String tableName) {
+    public Comparable<?> getHintShardingDatabaseValue(final String tableName) {
         String key = String.join(".", tableName.toUpperCase(), SQLHintPropertiesKey.SHARDING_DATABASE_VALUE_KEY.getKey());
+        Object result = sqlHintProperties.getProps().containsKey(key)
+                ? sqlHintProperties.getProps().get(key)
+                : sqlHintProperties.getProps().get(SQLHintPropertiesKey.SHARDING_DATABASE_VALUE_KEY.getKey());
+        if (result instanceof Comparable) {
+            return (Comparable<?>) result;
+        }
         return sqlHintProperties.getProps().containsKey(key)
-                ? Integer.parseInt(sqlHintProperties.getProps().getProperty(key))
+                ? sqlHintProperties.getProps().getProperty(key)
                 : sqlHintProperties.getValue(SQLHintPropertiesKey.SHARDING_DATABASE_VALUE_KEY);
     }
     
     /**
-     * Get hint sharding table value.
+     * Judge contains hint sharding databases value or not.
      *
-     * @return sharding table value
+     * @param tableName table name
+     * @return contains hint sharding databases value or not
      */
-    public int getHintShardingTableValue() {
-        return sqlHintProperties.getValue(SQLHintPropertiesKey.SHARDING_TABLE_VALUE_KEY);
+    public boolean containsHintShardingDatabaseValue(final String tableName) {
+        String key = Joiner.on(".").join(tableName.toUpperCase(), SQLHintPropertiesKey.SHARDING_DATABASE_VALUE_KEY.getKey());
+        return sqlHintProperties.getProps().containsKey(key) || sqlHintProperties.getProps().containsKey(SQLHintPropertiesKey.SHARDING_DATABASE_VALUE_KEY.getKey());
     }
     
     /**
@@ -113,10 +113,27 @@ public final class SQLHintExtractor {
      * @param tableName table name
      * @return sharding table value
      */
-    public int getHintShardingTableValue(final String tableName) {
+    public Comparable<?> getHintShardingTableValue(final String tableName) {
         String key = String.join(".", tableName.toUpperCase(), SQLHintPropertiesKey.SHARDING_TABLE_VALUE_KEY.getKey());
+        Object result = sqlHintProperties.getProps().containsKey(key)
+                ? sqlHintProperties.getProps().get(key)
+                : sqlHintProperties.getProps().get(SQLHintPropertiesKey.SHARDING_TABLE_VALUE_KEY.getKey());
+        if (result instanceof Comparable) {
+            return (Comparable<?>) result;
+        }
         return sqlHintProperties.getProps().containsKey(key)
-                ? Integer.parseInt(sqlHintProperties.getProps().getProperty(key))
+                ? sqlHintProperties.getProps().getProperty(key)
                 : sqlHintProperties.getValue(SQLHintPropertiesKey.SHARDING_TABLE_VALUE_KEY);
     }
+    
+    /**
+     * Judge contains hint sharding table value or not.
+     *
+     * @param tableName table name
+     * @return Contains hint sharding table value or not
+     */
+    public boolean containsHintShardingTableValue(final String tableName) {
+        String key = Joiner.on(".").join(tableName.toUpperCase(), SQLHintPropertiesKey.SHARDING_TABLE_VALUE_KEY.getKey());
+        return sqlHintProperties.getProps().containsKey(key) || sqlHintProperties.getProps().containsKey(SQLHintPropertiesKey.SHARDING_TABLE_VALUE_KEY.getKey());
+    }
 }
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintPropertiesKey.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintPropertiesKey.java
index 2d491ad0ef8..a159df85ecc 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintPropertiesKey.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintPropertiesKey.java
@@ -51,12 +51,12 @@ public enum SQLHintPropertiesKey implements TypedPropertyKey {
     /**
      * Hint sharding database value.
      */
-    SHARDING_DATABASE_VALUE_KEY("SHARDING_DATABASE_VALUE", "0", int.class),
+    SHARDING_DATABASE_VALUE_KEY("SHARDING_DATABASE_VALUE", "", Comparable.class),
     
     /**
      * Hint sharding table value.
      */
-    SHARDING_TABLE_VALUE_KEY("SHARDING_TABLE_VALUE", "0", int.class);
+    SHARDING_TABLE_VALUE_KEY("SHARDING_TABLE_VALUE", "", Comparable.class);
     
     private final String key;
     
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintUtils.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintUtils.java
index 593d01bc30a..75029d5b318 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintUtils.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/hint/SQLHintUtils.java
@@ -21,6 +21,7 @@ import com.google.common.base.Splitter;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 
+import java.math.BigInteger;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
@@ -63,12 +64,20 @@ public final class SQLHintUtils {
         for (String each : sqlHints) {
             List<String> hintValues = Splitter.on(SQL_HINT_VALUE_SPLIT).trimResults().splitToList(each);
             if (SQL_HINT_VALUE_SIZE == hintValues.size()) {
-                result.put(hintValues.get(0).toUpperCase(), hintValues.get(1));
+                result.put(hintValues.get(0).toUpperCase(), convert(hintValues.get(1)));
             }
         }
         return result;
     }
     
+    private static Object convert(final String value) {
+        try {
+            return new BigInteger(value);
+        } catch (final NumberFormatException e) {
+            return value;
+        }
+    }
+    
     /**
      * Get splitter SQL hint Value.
      *
diff --git a/infra/common/src/test/java/org/apache/shardingsphere/infra/hint/SQLHintExtractorTest.java b/infra/common/src/test/java/org/apache/shardingsphere/infra/hint/SQLHintExtractorTest.java
index e50bd2ceb56..816495ba12e 100644
--- a/infra/common/src/test/java/org/apache/shardingsphere/infra/hint/SQLHintExtractorTest.java
+++ b/infra/common/src/test/java/org/apache/shardingsphere/infra/hint/SQLHintExtractorTest.java
@@ -21,15 +21,16 @@ import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.CommentSe
 import org.apache.shardingsphere.sql.parser.sql.common.statement.AbstractSQLStatement;
 import org.junit.Test;
 
+import java.math.BigInteger;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 
+import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
-import static org.hamcrest.CoreMatchers.is;
 
 public final class SQLHintExtractorTest {
     
@@ -59,28 +60,42 @@ public final class SQLHintExtractorTest {
     @Test
     public void assertSQLHintShardingDatabaseValue() {
         AbstractSQLStatement statement = mock(AbstractSQLStatement.class);
-        when(statement.getCommentSegments()).thenReturn(Collections.singletonList(new CommentSegment("/* SHARDINGSPHERE_HINT: SHARDING_DATABASE_VALUE=100 */", 0, 0)));
-        assertThat(new SQLHintExtractor(statement).getHintShardingDatabaseValue(), is(100));
+        when(statement.getCommentSegments()).thenReturn(Collections.singletonList(new CommentSegment("/* SHARDINGSPHERE_HINT: SHARDING_DATABASE_VALUE=10 */", 0, 0)));
+        assertThat(new SQLHintExtractor(statement).getHintShardingDatabaseValue("t_order"), is(new BigInteger("10")));
     }
     
     @Test
     public void assertSQLHintShardingDatabaseValueWithTableName() {
         AbstractSQLStatement statement = mock(AbstractSQLStatement.class);
         when(statement.getCommentSegments()).thenReturn(Collections.singletonList(new CommentSegment("/* SHARDINGSPHERE_HINT: t_order.SHARDING_DATABASE_VALUE=10 */", 0, 0)));
-        assertThat(new SQLHintExtractor(statement).getHintShardingDatabaseValue("t_order"), is(10));
+        assertThat(new SQLHintExtractor(statement).getHintShardingDatabaseValue("t_order"), is(new BigInteger("10")));
+    }
+    
+    @Test
+    public void assertSQLHintShardingDatabaseValueWithStringHintValue() {
+        AbstractSQLStatement statement = mock(AbstractSQLStatement.class);
+        when(statement.getCommentSegments()).thenReturn(Collections.singletonList(new CommentSegment("/* SHARDINGSPHERE_HINT: t_order.SHARDING_DATABASE_VALUE=a */", 0, 0)));
+        assertThat(new SQLHintExtractor(statement).getHintShardingDatabaseValue("t_order"), is("a"));
     }
     
     @Test
     public void assertSQLHintShardingTableValue() {
         AbstractSQLStatement statement = mock(AbstractSQLStatement.class);
-        when(statement.getCommentSegments()).thenReturn(Collections.singletonList(new CommentSegment("/* SHARDINGSPHERE_HINT: SHARDING_TABLE_VALUE=100 */", 0, 0)));
-        assertThat(new SQLHintExtractor(statement).getHintShardingTableValue(), is(100));
+        when(statement.getCommentSegments()).thenReturn(Collections.singletonList(new CommentSegment("/* SHARDINGSPHERE_HINT: SHARDING_TABLE_VALUE=10 */", 0, 0)));
+        assertThat(new SQLHintExtractor(statement).getHintShardingTableValue("t_order"), is(new BigInteger("10")));
     }
     
     @Test
     public void assertSQLHintShardingTableValueWithTableName() {
         AbstractSQLStatement statement = mock(AbstractSQLStatement.class);
         when(statement.getCommentSegments()).thenReturn(Collections.singletonList(new CommentSegment("/* SHARDINGSPHERE_HINT: t_order.SHARDING_TABLE_VALUE=10 */", 0, 0)));
-        assertThat(new SQLHintExtractor(statement).getHintShardingTableValue("t_order"), is(10));
+        assertThat(new SQLHintExtractor(statement).getHintShardingTableValue("t_order"), is(new BigInteger("10")));
+    }
+    
+    @Test
+    public void assertSQLHintShardingTableValueWithStringHintValue() {
+        AbstractSQLStatement statement = mock(AbstractSQLStatement.class);
+        when(statement.getCommentSegments()).thenReturn(Collections.singletonList(new CommentSegment("/* SHARDINGSPHERE_HINT: t_order.SHARDING_TABLE_VALUE=a */", 0, 0)));
+        assertThat(new SQLHintExtractor(statement).getHintShardingTableValue("t_order"), is("a"));
     }
 }