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

chengzhang 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 cf0b19a0b51 Remove TablesContext#findTableNames method and implement 
select order by, group by bind logic (#34123)
cf0b19a0b51 is described below

commit cf0b19a0b511f91135725f3abcc60a57dfebd9ad
Author: Zhengqiang Duan <duanzhengqi...@apache.org>
AuthorDate: Tue Dec 24 16:14:18 2024 +0800

    Remove TablesContext#findTableNames method and implement select order by, 
group by bind logic (#34123)
    
    * Remove TablesContext#findTableNames method and use sql bind info to 
replace
    
    * fix unit test
    
    * optimize select statement binder
    
    * update release note
---
 RELEASE-NOTES.md                                   |   1 +
 .../EncryptOrderByItemSupportedChecker.java        |  10 +-
 .../EncryptPredicateColumnSupportedChecker.java    |   9 +-
 .../rewrite/condition/EncryptConditionEngine.java  |  28 ++---
 .../context/EncryptSQLRewriteContextDecorator.java |   5 +-
 .../select/EncryptGroupByItemTokenGenerator.java   |  20 +---
 .../EncryptOrderByItemSupportedCheckerTest.java    |   4 +
 ...EncryptPredicateColumnSupportedCheckerTest.java |   2 -
 ...cryptPredicateRightValueTokenGeneratorTest.java |   2 +-
 .../EncryptGroupByItemTokenGeneratorTest.java      |   6 +-
 .../engine/WhereClauseShardingConditionEngine.java |  27 ++---
 .../shardingsphere/sharding/rule/ShardingRule.java |  17 ++-
 .../WhereClauseShardingConditionEngineTest.java    |   5 -
 .../sharding/rule/ShardingRuleTest.java            |  13 ++-
 .../context/segment/table/TablesContext.java       | 127 ---------------------
 .../expression/ExpressionSegmentBinder.java        |   5 +
 .../type/BetweenExpressionSegmentBinder.java}      |  27 +++--
 .../engine/segment/order/GroupBySegmentBinder.java |  71 ++++++++++++
 .../engine/segment/order/OrderBySegmentBinder.java |  71 ++++++++++++
 .../item/ColumnOrderByItemSegmentBinder.java}      |  27 ++---
 .../item/ExpressionOrderByItemSegmentBinder.java}  |  25 ++--
 .../item/OrderByItemSegmentBinder.java}            |  33 +++---
 .../HavingSegmentBinder.java}                      |  22 ++--
 .../{where => predicate}/WhereSegmentBinder.java   |   2 +-
 .../statement/dml/DeleteStatementBinder.java       |   2 +-
 .../statement/dml/SelectStatementBinder.java       |  28 ++++-
 .../statement/dml/UpdateStatementBinder.java       |   2 +-
 .../context/segment/table/TablesContextTest.java   |  70 ------------
 .../WhereSegmentBinderTest.java                    |   2 +-
 29 files changed, 304 insertions(+), 359 deletions(-)

diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index b1f96d7cd95..318dd2e0892 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -37,6 +37,7 @@
 1. SQL Binder: Add sql bind logic for create table statement - 
[#34074](https://github.com/apache/shardingsphere/pull/34074)
 1. SQL Binder: Support create index statement sql bind - 
[#34112](https://github.com/apache/shardingsphere/pull/34112)
 1. SQL Parser: Support MySQL update with statement parse - 
[#34126](https://github.com/apache/shardingsphere/pull/34126)
+1. SQL Binder: Remove TablesContext#findTableNames method and implement select 
order by, group by bind logic - 
[#34123](https://github.com/apache/shardingsphere/pull/34123)
 
 ### Bug Fixes
 
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/checker/sql/orderby/EncryptOrderByItemSupportedChecker.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/checker/sql/orderby/EncryptOrderByItemSupportedChecker.java
index f12994d2ea1..45ec1217aa6 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/checker/sql/orderby/EncryptOrderByItemSupportedChecker.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/checker/sql/orderby/EncryptOrderByItemSupportedChecker.java
@@ -32,9 +32,7 @@ import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.Co
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ColumnOrderByItemSegment;
 
 import java.util.Collection;
-import java.util.Collections;
 import java.util.LinkedList;
-import java.util.Map;
 import java.util.Optional;
 
 /**
@@ -64,7 +62,7 @@ public final class EncryptOrderByItemSupportedChecker 
implements SupportedSQLChe
     public void check(final EncryptRule rule, final ShardingSphereDatabase 
database, final ShardingSphereSchema currentSchema, final 
SelectStatementContext sqlStatementContext) {
         for (OrderByItem each : getOrderByItems(sqlStatementContext)) {
             if (each.getSegment() instanceof ColumnOrderByItemSegment) {
-                checkColumnOrderByItem(rule, currentSchema, 
sqlStatementContext, ((ColumnOrderByItemSegment) 
each.getSegment()).getColumn());
+                checkColumnOrderByItem(rule, ((ColumnOrderByItemSegment) 
each.getSegment()).getColumn());
             }
         }
     }
@@ -80,10 +78,8 @@ public final class EncryptOrderByItemSupportedChecker 
implements SupportedSQLChe
         return result;
     }
     
-    private void checkColumnOrderByItem(final EncryptRule rule, final 
ShardingSphereSchema schema, final SelectStatementContext sqlStatementContext, 
final ColumnSegment columnSegment) {
-        Map<String, String> columnTableNames = 
sqlStatementContext.getTablesContext().findTableNames(Collections.singleton(columnSegment),
 schema);
-        String tableName = 
columnTableNames.getOrDefault(columnSegment.getExpression(), "");
-        Optional<EncryptTable> encryptTable = rule.findEncryptTable(tableName);
+    private void checkColumnOrderByItem(final EncryptRule rule, final 
ColumnSegment columnSegment) {
+        Optional<EncryptTable> encryptTable = 
rule.findEncryptTable(columnSegment.getColumnBoundInfo().getOriginalTable().getValue());
         String columnName = columnSegment.getIdentifier().getValue();
         ShardingSpherePreconditions.checkState(!encryptTable.isPresent() || 
!encryptTable.get().isEncryptColumn(columnName), () -> new 
UnsupportedEncryptSQLException("ORDER BY"));
     }
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/checker/sql/predicate/EncryptPredicateColumnSupportedChecker.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/checker/sql/predicate/EncryptPredicateColumnSupportedChecker.java
index 9938819dc23..129e69441bb 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/checker/sql/predicate/EncryptPredicateColumnSupportedChecker.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/checker/sql/predicate/EncryptPredicateColumnSupportedChecker.java
@@ -25,7 +25,6 @@ import 
org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation;
 import 
org.apache.shardingsphere.infra.binder.context.extractor.SQLStatementContextExtractor;
 import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
 import 
org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext;
-import org.apache.shardingsphere.infra.binder.context.type.TableAvailable;
 import org.apache.shardingsphere.infra.binder.context.type.WhereAvailable;
 import org.apache.shardingsphere.infra.checker.SupportedSQLChecker;
 import 
org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
@@ -40,7 +39,6 @@ import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
 
 import java.util.Collection;
-import java.util.Map;
 import java.util.Optional;
 
 /**
@@ -60,13 +58,12 @@ public final class EncryptPredicateColumnSupportedChecker 
implements SupportedSQ
         Collection<BinaryOperationExpression> joinConditions = 
SQLStatementContextExtractor.getJoinConditions((WhereAvailable) 
sqlStatementContext, allSubqueryContexts);
         
ShardingSpherePreconditions.checkState(JoinConditionsEncryptorComparator.isSame(joinConditions,
 rule),
                 () -> new UnsupportedSQLOperationException("Can not use 
different encryptor in join condition"));
-        check(rule, currentSchema, (WhereAvailable) sqlStatementContext);
+        check(rule, (WhereAvailable) sqlStatementContext);
     }
     
-    private void check(final EncryptRule rule, final ShardingSphereSchema 
schema, final WhereAvailable sqlStatementContext) {
-        Map<String, String> columnExpressionTableNames = ((TableAvailable) 
sqlStatementContext).getTablesContext().findTableNames(sqlStatementContext.getColumnSegments(),
 schema);
+    private void check(final EncryptRule rule, final WhereAvailable 
sqlStatementContext) {
         for (ColumnSegment each : sqlStatementContext.getColumnSegments()) {
-            Optional<EncryptTable> encryptTable = 
rule.findEncryptTable(columnExpressionTableNames.getOrDefault(each.getExpression(),
 ""));
+            Optional<EncryptTable> encryptTable = 
rule.findEncryptTable(each.getColumnBoundInfo().getOriginalTable().getValue());
             String columnName = each.getIdentifier().getValue();
             if (encryptTable.isPresent() && 
encryptTable.get().isEncryptColumn(columnName) && 
includesLike(sqlStatementContext.getWhereSegments(), each)) {
                 String tableName = encryptTable.get().getTable();
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/condition/EncryptConditionEngine.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/condition/EncryptConditionEngine.java
index ecee22e14e1..2c66ec5d512 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/condition/EncryptConditionEngine.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/condition/EncryptConditionEngine.java
@@ -24,12 +24,8 @@ import 
org.apache.shardingsphere.encrypt.rewrite.condition.impl.EncryptInConditi
 import org.apache.shardingsphere.encrypt.rule.EncryptRule;
 import org.apache.shardingsphere.encrypt.rule.table.EncryptTable;
 import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation;
-import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
-import org.apache.shardingsphere.infra.binder.context.type.TableAvailable;
-import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
 import 
org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
-import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
 import 
org.apache.shardingsphere.sql.parser.statement.core.extractor.ColumnExtractor;
 import 
org.apache.shardingsphere.sql.parser.statement.core.extractor.ExpressionExtractor;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
@@ -43,13 +39,11 @@ import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simp
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubqueryExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.AndPredicate;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.ColumnSegmentBoundInfo;
 
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.TreeSet;
@@ -89,44 +83,36 @@ public final class EncryptConditionEngine {
      * Create encrypt conditions.
      *
      * @param whereSegments where segments
-     * @param columnSegments column segments
-     * @param sqlStatementContext SQL statement context
-     * @param databaseName database name
      * @return encrypt conditions
      */
-    public Collection<EncryptCondition> createEncryptConditions(final 
Collection<WhereSegment> whereSegments, final Collection<ColumnSegment> 
columnSegments,
-                                                                final 
SQLStatementContext sqlStatementContext, final String databaseName) {
+    public Collection<EncryptCondition> createEncryptConditions(final 
Collection<WhereSegment> whereSegments) {
         Collection<EncryptCondition> result = new LinkedList<>();
-        String defaultSchema = new 
DatabaseTypeRegistry(sqlStatementContext.getDatabaseType()).getDefaultSchemaName(databaseName);
-        ShardingSphereSchema schema = ((TableAvailable) 
sqlStatementContext).getTablesContext().getSchemaName().map(database::getSchema).orElseGet(()
 -> database.getSchema(defaultSchema));
-        Map<String, String> expressionTableNames = ((TableAvailable) 
sqlStatementContext).getTablesContext().findTableNames(columnSegments, schema);
         for (WhereSegment each : whereSegments) {
             Collection<AndPredicate> andPredicates = 
ExpressionExtractor.extractAndPredicates(each.getExpr());
             for (AndPredicate predicate : andPredicates) {
-                addEncryptConditions(result, predicate.getPredicates(), 
expressionTableNames);
+                addEncryptConditions(result, predicate.getPredicates());
             }
         }
         return result;
     }
     
-    private void addEncryptConditions(final Collection<EncryptCondition> 
encryptConditions, final Collection<ExpressionSegment> predicates, final 
Map<String, String> expressionTableNames) {
+    private void addEncryptConditions(final Collection<EncryptCondition> 
encryptConditions, final Collection<ExpressionSegment> predicates) {
         Collection<Integer> stopIndexes = new HashSet<>(predicates.size(), 1F);
         for (ExpressionSegment each : predicates) {
             if (stopIndexes.add(each.getStopIndex())) {
-                addEncryptConditions(encryptConditions, each, 
expressionTableNames);
+                addEncryptConditions(encryptConditions, each);
             }
         }
     }
     
-    private void addEncryptConditions(final Collection<EncryptCondition> 
encryptConditions, final ExpressionSegment expression, final Map<String, 
String> expressionTableNames) {
+    private void addEncryptConditions(final Collection<EncryptCondition> 
encryptConditions, final ExpressionSegment expression) {
         if (!findNotContainsNullLiteralsExpression(expression).isPresent()) {
             return;
         }
         for (ColumnSegment each : ColumnExtractor.extract(expression)) {
-            ColumnSegmentBoundInfo columnBoundInfo = each.getColumnBoundInfo();
-            String tableName = 
columnBoundInfo.getOriginalTable().getValue().isEmpty() ? 
expressionTableNames.getOrDefault(each.getExpression(), "") : 
columnBoundInfo.getOriginalTable().getValue();
+            String tableName = 
each.getColumnBoundInfo().getOriginalTable().getValue();
             Optional<EncryptTable> encryptTable = 
rule.findEncryptTable(tableName);
-            if (encryptTable.isPresent() && 
encryptTable.get().isEncryptColumn(each.getIdentifier().getValue())) {
+            if (encryptTable.isPresent() && 
encryptTable.get().isEncryptColumn(each.getColumnBoundInfo().getOriginalColumn().getValue()))
 {
                 createEncryptCondition(expression, 
tableName).ifPresent(encryptConditions::add);
             }
         }
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/context/EncryptSQLRewriteContextDecorator.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/context/EncryptSQLRewriteContextDecorator.java
index 045a014ba00..7f7fab2ad91 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/context/EncryptSQLRewriteContextDecorator.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/context/EncryptSQLRewriteContextDecorator.java
@@ -37,7 +37,6 @@ import 
org.apache.shardingsphere.infra.rewrite.parameter.rewriter.ParameterRewri
 import 
org.apache.shardingsphere.infra.rewrite.parameter.rewriter.ParameterRewritersBuilder;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.common.generator.builder.SQLTokenGeneratorBuilder;
 import org.apache.shardingsphere.infra.route.context.RouteContext;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
 
 import java.util.Collection;
@@ -93,9 +92,7 @@ public final class EncryptSQLRewriteContextDecorator 
implements SQLRewriteContex
         }
         Collection<SelectStatementContext> allSubqueryContexts = 
SQLStatementContextExtractor.getAllSubqueryContexts(sqlStatementContext);
         Collection<WhereSegment> whereSegments = 
SQLStatementContextExtractor.getWhereSegments((WhereAvailable) 
sqlStatementContext, allSubqueryContexts);
-        Collection<ColumnSegment> columnSegments = 
SQLStatementContextExtractor.getColumnSegments((WhereAvailable) 
sqlStatementContext, allSubqueryContexts);
-        return new EncryptConditionEngine(rule, 
sqlRewriteContext.getDatabase()).createEncryptConditions(whereSegments, 
columnSegments, sqlStatementContext,
-                sqlRewriteContext.getDatabase().getName());
+        return new EncryptConditionEngine(rule, 
sqlRewriteContext.getDatabase()).createEncryptConditions(whereSegments);
     }
     
     private void rewriteParameters(final SQLRewriteContext sqlRewriteContext, 
final Collection<ParameterRewriter> parameterRewriters) {
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/select/EncryptGroupByItemTokenGenerator.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/select/EncryptGroupByItemTokenGenerator.java
index 2abad5c7304..cfc5d86a689 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/select/EncryptGroupByItemTokenGenerator.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/select/EncryptGroupByItemTokenGenerator.java
@@ -30,9 +30,7 @@ import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementCont
 import 
org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext;
 import 
org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter;
 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
-import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.common.generator.CollectionSQLTokenGenerator;
-import 
org.apache.shardingsphere.infra.rewrite.sql.token.common.generator.aware.SchemaMetaDataAware;
 import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.SQLToken;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.generic.SubstitutableColumnNameToken;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
@@ -42,7 +40,6 @@ import 
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.Iden
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
-import java.util.Map;
 import java.util.Optional;
 
 /**
@@ -51,14 +48,10 @@ import java.util.Optional;
 @HighFrequencyInvocation
 @RequiredArgsConstructor
 @Setter
-public final class EncryptGroupByItemTokenGenerator implements 
CollectionSQLTokenGenerator<SelectStatementContext>, SchemaMetaDataAware {
+public final class EncryptGroupByItemTokenGenerator implements 
CollectionSQLTokenGenerator<SelectStatementContext> {
     
     private final EncryptRule rule;
     
-    private Map<String, ShardingSphereSchema> schemas;
-    
-    private ShardingSphereSchema defaultSchema;
-    
     @Override
     public boolean isGenerateSQLToken(final SQLStatementContext 
sqlStatementContext) {
         return sqlStatementContext instanceof SelectStatementContext && 
containsGroupByItem((SelectStatementContext) sqlStatementContext);
@@ -79,21 +72,18 @@ public final class EncryptGroupByItemTokenGenerator 
implements CollectionSQLToke
     @Override
     public Collection<SQLToken> generateSQLTokens(final SelectStatementContext 
sqlStatementContext) {
         Collection<SQLToken> result = new LinkedList<>();
-        ShardingSphereSchema schema = 
sqlStatementContext.getTablesContext().getSchemaName().map(schemas::get).orElseGet(()
 -> defaultSchema);
         for (OrderByItem each : getGroupByItems(sqlStatementContext)) {
             if (each.getSegment() instanceof ColumnOrderByItemSegment) {
                 ColumnSegment columnSegment = ((ColumnOrderByItemSegment) 
each.getSegment()).getColumn();
-                Map<String, String> columnTableNames = 
sqlStatementContext.getTablesContext().findTableNames(Collections.singleton(columnSegment),
 schema);
-                generateSQLToken(columnSegment, columnTableNames, 
sqlStatementContext.getDatabaseType()).ifPresent(result::add);
+                generateSQLToken(columnSegment, 
sqlStatementContext.getDatabaseType()).ifPresent(result::add);
             }
         }
         return result;
     }
     
-    private Optional<SubstitutableColumnNameToken> generateSQLToken(final 
ColumnSegment columnSegment, final Map<String, String> columnTableNames, final 
DatabaseType databaseType) {
-        String tableName = 
columnTableNames.getOrDefault(columnSegment.getExpression(), "");
-        Optional<EncryptTable> encryptTable = rule.findEncryptTable(tableName);
-        String columnName = columnSegment.getIdentifier().getValue();
+    private Optional<SubstitutableColumnNameToken> generateSQLToken(final 
ColumnSegment columnSegment, final DatabaseType databaseType) {
+        Optional<EncryptTable> encryptTable = 
rule.findEncryptTable(columnSegment.getColumnBoundInfo().getOriginalTable().getValue());
+        String columnName = 
columnSegment.getColumnBoundInfo().getOriginalColumn().getValue();
         if (!encryptTable.isPresent() || 
!encryptTable.get().isEncryptColumn(columnName)) {
             return Optional.empty();
         }
diff --git 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/sql/orderby/EncryptOrderByItemSupportedCheckerTest.java
 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/sql/orderby/EncryptOrderByItemSupportedCheckerTest.java
index bd54b59414a..edaaffc99ea 100644
--- 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/sql/orderby/EncryptOrderByItemSupportedCheckerTest.java
+++ 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/sql/orderby/EncryptOrderByItemSupportedCheckerTest.java
@@ -33,6 +33,8 @@ import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.Co
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ColumnOrderByItemSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.AliasSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.ColumnSegmentBoundInfo;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.TableSegmentBoundInfo;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
@@ -116,6 +118,8 @@ class EncryptOrderByItemSupportedCheckerTest {
         simpleTableSegment.setAlias(new AliasSegment(0, 0, new 
IdentifierValue("a")));
         ColumnSegment columnSegment = new ColumnSegment(0, 0, new 
IdentifierValue("foo_col"));
         columnSegment.setOwner(new OwnerSegment(0, 0, new 
IdentifierValue("a")));
+        columnSegment.setColumnBoundInfo(
+                new ColumnSegmentBoundInfo(new TableSegmentBoundInfo(new 
IdentifierValue("foo_db"), new IdentifierValue("foo_db")), new 
IdentifierValue(tableName), new IdentifierValue("foo_col")));
         SelectStatementContext result = mock(SelectStatementContext.class, 
RETURNS_DEEP_STUBS);
         when(result.getDatabaseType()).thenReturn(databaseType);
         ColumnOrderByItemSegment columnOrderByItemSegment = new 
ColumnOrderByItemSegment(columnSegment, OrderDirection.ASC, 
NullsOrderType.FIRST);
diff --git 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/sql/predicate/EncryptPredicateColumnSupportedCheckerTest.java
 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/sql/predicate/EncryptPredicateColumnSupportedCheckerTest.java
index 1c2ef0ba5af..b82a0c37a5e 100644
--- 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/sql/predicate/EncryptPredicateColumnSupportedCheckerTest.java
+++ 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/sql/predicate/EncryptPredicateColumnSupportedCheckerTest.java
@@ -88,7 +88,6 @@ class EncryptPredicateColumnSupportedCheckerTest {
         columnSegment.setColumnBoundInfo(new ColumnSegmentBoundInfo(new 
TableSegmentBoundInfo(new IdentifierValue("foo_db"), new 
IdentifierValue("foo_schema")), new IdentifierValue("t_user"),
                 new IdentifierValue("user_name")));
         SelectStatementContext result = mock(SelectStatementContext.class, 
RETURNS_DEEP_STUBS);
-        
when(result.getTablesContext().findTableNames(Collections.singleton(columnSegment),
 null)).thenReturn(Collections.singletonMap("user_name", "t_user"));
         
when(result.getColumnSegments()).thenReturn(Collections.singleton(columnSegment));
         when(result.getWhereSegments()).thenReturn(Collections.singleton(new 
WhereSegment(0, 0, new BinaryOperationExpression(0, 0, columnSegment, 
columnSegment, "LIKE", ""))));
         when(result.getSubqueryContexts()).thenReturn(Collections.emptyMap());
@@ -106,7 +105,6 @@ class EncryptPredicateColumnSupportedCheckerTest {
         columnSegment.setColumnBoundInfo(new ColumnSegmentBoundInfo(new 
TableSegmentBoundInfo(new IdentifierValue("foo_db"), new 
IdentifierValue("foo_schema")), new IdentifierValue("t_user"),
                 new IdentifierValue("user_name")));
         SelectStatementContext result = mock(SelectStatementContext.class, 
RETURNS_DEEP_STUBS);
-        
when(result.getTablesContext().findTableNames(Collections.singleton(columnSegment),
 null)).thenReturn(Collections.singletonMap("user_name", "t_user"));
         
when(result.getColumnSegments()).thenReturn(Collections.singleton(columnSegment));
         when(result.getWhereSegments()).thenReturn(Collections.singleton(new 
WhereSegment(0, 0, new BinaryOperationExpression(0, 0, columnSegment, 
columnSegment, "=", ""))));
         when(result.getSubqueryContexts()).thenReturn(Collections.emptyMap());
diff --git 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/predicate/EncryptPredicateRightValueTokenGeneratorTest.java
 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/predicate/EncryptPredicateRightValueTokenGeneratorTest.java
index d37fea852b7..002e641a26f 100644
--- 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/predicate/EncryptPredicateRightValueTokenGeneratorTest.java
+++ 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/predicate/EncryptPredicateRightValueTokenGeneratorTest.java
@@ -63,6 +63,6 @@ class EncryptPredicateRightValueTokenGeneratorTest {
     private Collection<EncryptCondition> getEncryptConditions(final 
UpdateStatementContext updateStatementContext) {
         ShardingSphereDatabase database = new ShardingSphereDatabase("foo_db", 
mock(), mock(), mock(), Collections.singleton(new 
ShardingSphereSchema("foo_db")));
         return new 
EncryptConditionEngine(EncryptGeneratorFixtureBuilder.createEncryptRule(), 
database)
-                
.createEncryptConditions(updateStatementContext.getWhereSegments(), 
updateStatementContext.getColumnSegments(), updateStatementContext, "foo_db");
+                
.createEncryptConditions(updateStatementContext.getWhereSegments());
     }
 }
diff --git 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/select/EncryptGroupByItemTokenGeneratorTest.java
 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/select/EncryptGroupByItemTokenGeneratorTest.java
index add57075398..ab0011e86f5 100644
--- 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/select/EncryptGroupByItemTokenGeneratorTest.java
+++ 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/select/EncryptGroupByItemTokenGeneratorTest.java
@@ -25,13 +25,14 @@ import 
org.apache.shardingsphere.infra.binder.context.segment.table.TablesContex
 import 
org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext;
 import 
org.apache.shardingsphere.infra.database.core.metadata.database.enums.NullsOrderType;
 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
-import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import 
org.apache.shardingsphere.sql.parser.statement.core.enums.OrderDirection;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ColumnOrderByItemSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.AliasSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.ColumnSegmentBoundInfo;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.TableSegmentBoundInfo;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
@@ -56,7 +57,6 @@ class EncryptGroupByItemTokenGeneratorTest {
     @BeforeEach
     void setup() {
         generator = new EncryptGroupByItemTokenGenerator(mockEncryptRule());
-        generator.setSchemas(Collections.singletonMap("test", 
mock(ShardingSphereSchema.class)));
     }
     
     private EncryptRule mockEncryptRule() {
@@ -79,6 +79,8 @@ class EncryptGroupByItemTokenGeneratorTest {
         SimpleTableSegment simpleTableSegment = new SimpleTableSegment(new 
TableNameSegment(0, 0, new IdentifierValue("t_encrypt")));
         simpleTableSegment.setAlias(new AliasSegment(0, 0, new 
IdentifierValue("a")));
         ColumnSegment columnSegment = new ColumnSegment(0, 0, new 
IdentifierValue("certificate_number"));
+        columnSegment.setColumnBoundInfo(new ColumnSegmentBoundInfo(new 
TableSegmentBoundInfo(new IdentifierValue("foo_db"), new 
IdentifierValue("foo_db")), new IdentifierValue("t_encrypt"),
+                new IdentifierValue("certificate_number")));
         columnSegment.setOwner(new OwnerSegment(0, 0, new 
IdentifierValue("a")));
         SelectStatementContext result = mock(SelectStatementContext.class, 
RETURNS_DEEP_STUBS);
         when(result.getDatabaseType()).thenReturn(databaseType);
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/WhereClauseShardingConditionEngine.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/WhereClauseShardingConditionEngine.java
index 752f68dbff1..8a9eb3f0aec 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/WhereClauseShardingConditionEngine.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/WhereClauseShardingConditionEngine.java
@@ -36,12 +36,12 @@ import 
org.apache.shardingsphere.sharding.route.engine.condition.value.ListShard
 import 
org.apache.shardingsphere.sharding.route.engine.condition.value.RangeShardingConditionValue;
 import 
org.apache.shardingsphere.sharding.route.engine.condition.value.ShardingConditionValue;
 import org.apache.shardingsphere.sharding.rule.ShardingRule;
+import 
org.apache.shardingsphere.sql.parser.statement.core.extractor.ColumnExtractor;
+import 
org.apache.shardingsphere.sql.parser.statement.core.extractor.ExpressionExtractor;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.AndPredicate;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
-import 
org.apache.shardingsphere.sql.parser.statement.core.extractor.ColumnExtractor;
-import 
org.apache.shardingsphere.sql.parser.statement.core.extractor.ExpressionExtractor;
 import 
org.apache.shardingsphere.sql.parser.statement.core.util.SafeNumberOperationUtils;
 import org.apache.shardingsphere.timeservice.core.rule.TimestampServiceRule;
 
@@ -80,23 +80,18 @@ public final class WhereClauseShardingConditionEngine {
         if (!(sqlStatementContext instanceof WhereAvailable)) {
             return Collections.emptyList();
         }
-        Collection<ColumnSegment> columnSegments = ((WhereAvailable) 
sqlStatementContext).getColumnSegments();
-        ShardingSphereSchema schema = getSchema(sqlStatementContext, database);
-        Map<String, String> columnExpressionTableNames = sqlStatementContext 
instanceof TableAvailable
-                ? ((TableAvailable) 
sqlStatementContext).getTablesContext().findTableNames(columnSegments, schema)
-                : Collections.emptyMap();
         List<ShardingCondition> result = new ArrayList<>();
         for (WhereSegment each : 
SQLStatementContextExtractor.getAllWhereSegments(sqlStatementContext)) {
-            result.addAll(createShardingConditions(each.getExpr(), params, 
columnExpressionTableNames));
+            result.addAll(createShardingConditions(each.getExpr(), params));
         }
         return result;
     }
     
-    private Collection<ShardingCondition> createShardingConditions(final 
ExpressionSegment expression, final List<Object> params, final Map<String, 
String> columnExpressionTableNames) {
+    private Collection<ShardingCondition> createShardingConditions(final 
ExpressionSegment expression, final List<Object> params) {
         Collection<AndPredicate> andPredicates = 
ExpressionExtractor.extractAndPredicates(expression);
         Collection<ShardingCondition> result = new LinkedList<>();
         for (AndPredicate each : andPredicates) {
-            Map<Column, Collection<ShardingConditionValue>> 
shardingConditionValues = createShardingConditionValueMap(each.getPredicates(), 
params, columnExpressionTableNames);
+            Map<Column, Collection<ShardingConditionValue>> 
shardingConditionValues = createShardingConditionValueMap(each.getPredicates(), 
params);
             if (shardingConditionValues.isEmpty()) {
                 return Collections.emptyList();
             }
@@ -115,18 +110,16 @@ public final class WhereClauseShardingConditionEngine {
                 : database.getSchema(defaultSchemaName);
     }
     
-    private Map<Column, Collection<ShardingConditionValue>> 
createShardingConditionValueMap(final Collection<ExpressionSegment> predicates,
-                                                                               
             final List<Object> params, final Map<String, String> 
columnTableNames) {
+    private Map<Column, Collection<ShardingConditionValue>> 
createShardingConditionValueMap(final Collection<ExpressionSegment> predicates, 
final List<Object> params) {
         Map<Column, Collection<ShardingConditionValue>> result = new 
HashMap<>(predicates.size(), 1F);
         for (ExpressionSegment each : predicates) {
             for (ColumnSegment columnSegment : ColumnExtractor.extract(each)) {
-                Optional<String> tableName = 
Optional.ofNullable(Optional.ofNullable(columnTableNames.get(columnSegment.getExpression()))
-                        
.orElse(columnSegment.getColumnBoundInfo().getOriginalTable().getValue()));
-                Optional<String> shardingColumn = tableName.flatMap(optional 
-> 
shardingRule.findShardingColumn(columnSegment.getColumnBoundInfo().getOriginalColumn().getValue(),
 optional));
-                if (!tableName.isPresent() || !shardingColumn.isPresent()) {
+                String tableName = 
columnSegment.getColumnBoundInfo().getOriginalTable().getValue();
+                Optional<String> shardingColumn = 
shardingRule.findShardingColumn(columnSegment.getColumnBoundInfo().getOriginalColumn().getValue(),
 tableName);
+                if (!shardingColumn.isPresent()) {
                     continue;
                 }
-                Column column = new Column(shardingColumn.get(), 
tableName.get());
+                Column column = new Column(shardingColumn.get(), tableName);
                 Optional<ShardingConditionValue> shardingConditionValue = 
ConditionValueGeneratorFactory.generate(each, column, params, 
timestampServiceRule);
                 if (!shardingConditionValue.isPresent()) {
                     continue;
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java
index 758d45b663c..6c3e63386ea 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java
@@ -68,7 +68,6 @@ import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
 
 import javax.sql.DataSource;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
@@ -586,8 +585,8 @@ public final class ShardingRule implements DatabaseRule {
                 return false;
             }
             for (AndPredicate andPredicate : andPredicates) {
-                
databaseJoinConditionTables.addAll(getJoinConditionTables(schema, select, 
andPredicate.getPredicates(), true));
-                tableJoinConditionTables.addAll(getJoinConditionTables(schema, 
select, andPredicate.getPredicates(), false));
+                
databaseJoinConditionTables.addAll(getJoinConditionTables(andPredicate.getPredicates(),
 true));
+                
tableJoinConditionTables.addAll(getJoinConditionTables(andPredicate.getPredicates(),
 false));
             }
         }
         ShardingTable shardingTable = 
getShardingTable(tableNames.iterator().next());
@@ -598,8 +597,7 @@ public final class ShardingRule implements DatabaseRule {
         return containsDatabaseShardingColumns && containsTableShardingColumns;
     }
     
-    private Collection<String> getJoinConditionTables(final 
ShardingSphereSchema schema, final SelectStatementContext select,
-                                                      final 
Collection<ExpressionSegment> predicates, final boolean 
isDatabaseJoinCondition) {
+    private Collection<String> getJoinConditionTables(final 
Collection<ExpressionSegment> predicates, final boolean 
isDatabaseJoinCondition) {
         Collection<String> result = new LinkedList<>();
         for (ExpressionSegment each : predicates) {
             if (!isJoinConditionExpression(each)) {
@@ -607,9 +605,8 @@ public final class ShardingRule implements DatabaseRule {
             }
             ColumnSegment leftColumn = (ColumnSegment) 
((BinaryOperationExpression) each).getLeft();
             ColumnSegment rightColumn = (ColumnSegment) 
((BinaryOperationExpression) each).getRight();
-            Map<String, String> columnExpressionTableNames = 
select.getTablesContext().findTableNames(Arrays.asList(leftColumn, 
rightColumn), schema);
-            Optional<ShardingTable> leftShardingTable = 
findShardingTable(columnExpressionTableNames.get(leftColumn.getExpression()));
-            Optional<ShardingTable> rightShardingTable = 
findShardingTable(columnExpressionTableNames.get(rightColumn.getExpression()));
+            Optional<ShardingTable> leftShardingTable = 
findShardingTable(leftColumn.getColumnBoundInfo().getOriginalTable().getValue());
+            Optional<ShardingTable> rightShardingTable = 
findShardingTable(rightColumn.getColumnBoundInfo().getOriginalTable().getValue());
             if (!leftShardingTable.isPresent() || 
!rightShardingTable.isPresent()) {
                 continue;
             }
@@ -621,8 +618,8 @@ public final class ShardingRule implements DatabaseRule {
                     : 
getTableShardingStrategyConfiguration(rightShardingTable.get());
             if (findShardingColumn(leftConfig, 
leftColumn.getIdentifier().getValue()).isPresent()
                     && findShardingColumn(rightConfig, 
rightColumn.getIdentifier().getValue()).isPresent()) {
-                
result.add(columnExpressionTableNames.get(leftColumn.getExpression()));
-                
result.add(columnExpressionTableNames.get(rightColumn.getExpression()));
+                
result.add(leftColumn.getColumnBoundInfo().getOriginalTable().getValue());
+                
result.add(rightColumn.getColumnBoundInfo().getOriginalTable().getValue());
             }
         }
         return result;
diff --git 
a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/WhereClauseShardingConditionEngineTest.java
 
b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/WhereClauseShardingConditionEngineTest.java
index 307d85fc262..d85bba0435e 100644
--- 
a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/WhereClauseShardingConditionEngineTest.java
+++ 
b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/WhereClauseShardingConditionEngineTest.java
@@ -17,7 +17,6 @@
 
 package org.apache.shardingsphere.sharding.route.engine.condition.engine;
 
-import org.apache.groovy.util.Maps;
 import 
org.apache.shardingsphere.infra.binder.context.segment.table.TablesContext;
 import 
org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
@@ -52,7 +51,6 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyCollection;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -78,9 +76,6 @@ class WhereClauseShardingConditionEngineTest {
         shardingConditionEngine = new 
WhereClauseShardingConditionEngine(ShardingSphereDatabase.create("test_db",
                 TypedSPILoader.getService(DatabaseType.class, "FIXTURE"), new 
ConfigurationProperties(new Properties())), shardingRule, 
mock(TimestampServiceRule.class));
         
when(sqlStatementContext.getWhereSegments()).thenReturn(Collections.singleton(whereSegment));
-        when(sqlStatementContext.getTablesContext()).thenReturn(tablesContext);
-        
when(sqlStatementContext.getDatabaseType()).thenReturn(TypedSPILoader.getService(DatabaseType.class,
 "FIXTURE"));
-        when(tablesContext.findTableNames(anyCollection(), 
any())).thenReturn(Maps.of("foo_sharding_col", "table_1"));
     }
     
     @Test
diff --git 
a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rule/ShardingRuleTest.java
 
b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rule/ShardingRuleTest.java
index 4d2c328ee12..9caefec97bf 100644
--- 
a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rule/ShardingRuleTest.java
+++ 
b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rule/ShardingRuleTest.java
@@ -53,6 +53,8 @@ import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.Bina
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.ColumnSegmentBoundInfo;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.TableSegmentBoundInfo;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.JoinTableSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
@@ -653,7 +655,6 @@ class ShardingRuleTest {
         when(sqlStatementContext.getDatabaseType()).thenReturn(databaseType);
         
when(sqlStatementContext.getTablesContext().getSchemaName()).thenReturn(Optional.empty());
         ShardingSphereSchema schema = mock(ShardingSphereSchema.class);
-        
when(sqlStatementContext.getTablesContext().findTableNames(Arrays.asList(leftDatabaseJoin,
 rightDatabaseJoin), schema)).thenReturn(createColumnTableNameMap());
         ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, 
RETURNS_DEEP_STUBS);
         when(database.getName()).thenReturn("foo_db");
         when(database.getSchema("foo_db")).thenReturn(schema);
@@ -686,10 +687,18 @@ class ShardingRuleTest {
     @Test
     void assertIsAllBindingTableWithJoinQueryWithDatabaseTableJoinCondition() {
         ColumnSegment leftDatabaseJoin = createColumnSegment("user_id", 
"logic_Table");
+        leftDatabaseJoin.setColumnBoundInfo(new ColumnSegmentBoundInfo(new 
TableSegmentBoundInfo(new IdentifierValue("foo_db"), new 
IdentifierValue("foo_db")), new IdentifierValue("logic_Table"),
+                new IdentifierValue("user_id")));
         ColumnSegment rightDatabaseJoin = createColumnSegment("user_id", 
"sub_Logic_Table");
+        rightDatabaseJoin.setColumnBoundInfo(new ColumnSegmentBoundInfo(new 
TableSegmentBoundInfo(new IdentifierValue("foo_db"), new 
IdentifierValue("foo_db")), new IdentifierValue("sub_Logic_Table"),
+                new IdentifierValue("user_id")));
         BinaryOperationExpression databaseJoin = 
createBinaryOperationExpression(leftDatabaseJoin, rightDatabaseJoin, EQUAL);
         ColumnSegment leftTableJoin = createColumnSegment("order_id", 
"logic_Table");
+        leftTableJoin.setColumnBoundInfo(new ColumnSegmentBoundInfo(new 
TableSegmentBoundInfo(new IdentifierValue("foo_db"), new 
IdentifierValue("foo_db")), new IdentifierValue("logic_Table"),
+                new IdentifierValue("order_id")));
         ColumnSegment rightTableJoin = createColumnSegment("order_id", 
"sub_Logic_Table");
+        rightTableJoin.setColumnBoundInfo(new ColumnSegmentBoundInfo(new 
TableSegmentBoundInfo(new IdentifierValue("foo_db"), new 
IdentifierValue("foo_db")), new IdentifierValue("sub_Logic_Table"),
+                new IdentifierValue("order_id")));
         BinaryOperationExpression tableJoin = 
createBinaryOperationExpression(leftTableJoin, rightTableJoin, EQUAL);
         JoinTableSegment joinTable = mock(JoinTableSegment.class);
         BinaryOperationExpression condition = 
createBinaryOperationExpression(databaseJoin, tableJoin, AND);
@@ -703,8 +712,6 @@ class ShardingRuleTest {
         
when(sqlStatementContext.getTablesContext().getSchemaName()).thenReturn(Optional.empty());
         
when(sqlStatementContext.getWhereSegments()).thenReturn(Collections.singleton(new
 WhereSegment(0, 0, condition)));
         ShardingSphereSchema schema = mock(ShardingSphereSchema.class);
-        
when(sqlStatementContext.getTablesContext().findTableNames(Arrays.asList(leftDatabaseJoin,
 rightDatabaseJoin), schema)).thenReturn(createColumnTableNameMap());
-        
when(sqlStatementContext.getTablesContext().findTableNames(Arrays.asList(leftTableJoin,
 rightTableJoin), schema)).thenReturn(createColumnTableNameMap());
         ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, 
RETURNS_DEEP_STUBS);
         when(database.getName()).thenReturn("foo_db");
         when(database.getSchema("foo_db")).thenReturn(schema);
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/table/TablesContext.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/table/TablesContext.java
index 50fb33851a6..b274f0d8eaa 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/table/TablesContext.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/table/TablesContext.java
@@ -17,19 +17,14 @@
 
 package org.apache.shardingsphere.infra.binder.context.segment.table;
 
-import com.cedarsoftware.util.CaseInsensitiveMap;
 import com.cedarsoftware.util.CaseInsensitiveSet;
 import com.google.common.base.Preconditions;
 import lombok.AccessLevel;
 import lombok.Getter;
 import lombok.ToString;
-import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.subquery.SubqueryTableContext;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.subquery.engine.SubqueryTableContextEngine;
 import 
org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext;
-import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
-import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SubqueryTableSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
@@ -38,11 +33,9 @@ import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.Map;
 import java.util.Optional;
-import java.util.TreeSet;
 
 /**
  * Tables context.
@@ -111,126 +104,6 @@ public final class TablesContext {
         return result;
     }
     
-    /**
-     * Find expression table name map.
-     *
-     * @param columns column segments
-     * @param schema schema
-     * @return expression table name map
-     */
-    @HighFrequencyInvocation
-    public Map<String, String> findTableNames(final Collection<ColumnSegment> 
columns, final ShardingSphereSchema schema) {
-        if (1 == simpleTables.size()) {
-            return findTableNameFromSingleTable(columns);
-        }
-        Map<String, String> result = new CaseInsensitiveMap<>();
-        Map<String, Collection<String>> ownerColumnNames = 
getOwnerColumnNames(columns);
-        result.putAll(findTableNameFromSQL(ownerColumnNames));
-        Collection<String> noOwnerColumnNames = getNoOwnerColumnNames(columns);
-        result.putAll(findTableNameFromMetaData(noOwnerColumnNames, schema));
-        result.putAll(findTableNameFromSubquery(columns, result));
-        return result;
-    }
-    
-    @HighFrequencyInvocation
-    private Map<String, String> findTableNameFromSingleTable(final 
Collection<ColumnSegment> columns) {
-        String tableName = 
simpleTables.iterator().next().getTableName().getIdentifier().getValue();
-        Map<String, String> result = new CaseInsensitiveMap<>();
-        for (ColumnSegment each : columns) {
-            result.putIfAbsent(each.getExpression(), tableName);
-        }
-        return result;
-    }
-    
-    @HighFrequencyInvocation
-    private Map<String, Collection<String>> getOwnerColumnNames(final 
Collection<ColumnSegment> columns) {
-        Map<String, Collection<String>> result = new CaseInsensitiveMap<>();
-        for (ColumnSegment each : columns) {
-            if (!each.getOwner().isPresent()) {
-                continue;
-            }
-            
result.computeIfAbsent(each.getOwner().get().getIdentifier().getValue(), unused 
-> new LinkedList<>()).add(each.getExpression());
-        }
-        return result;
-    }
-    
-    @HighFrequencyInvocation
-    private Map<String, String> findTableNameFromSQL(final Map<String, 
Collection<String>> ownerColumnNames) {
-        if (ownerColumnNames.isEmpty()) {
-            return Collections.emptyMap();
-        }
-        Map<String, String> result = new LinkedHashMap<>(simpleTables.size(), 
1F);
-        for (SimpleTableSegment each : simpleTables) {
-            String tableName = each.getTableName().getIdentifier().getValue();
-            if (ownerColumnNames.containsKey(tableName)) {
-                ownerColumnNames.get(tableName).forEach(column -> 
result.put(column, tableName));
-            }
-            Optional<String> alias = each.getAliasName();
-            if (alias.isPresent() && 
ownerColumnNames.containsKey(alias.get())) {
-                ownerColumnNames.get(alias.get()).forEach(column -> 
result.put(column, tableName));
-            }
-        }
-        return result;
-    }
-    
-    @HighFrequencyInvocation
-    private Map<String, String> findTableNameFromMetaData(final 
Collection<String> noOwnerColumnNames, final ShardingSphereSchema schema) {
-        if (noOwnerColumnNames.isEmpty()) {
-            return Collections.emptyMap();
-        }
-        Map<String, String> result = new 
LinkedHashMap<>(noOwnerColumnNames.size(), 1F);
-        for (SimpleTableSegment each : simpleTables) {
-            String tableName = each.getTableName().getIdentifier().getValue();
-            if (schema.containsTable(tableName)) {
-                filterColumnNames(noOwnerColumnNames, 
schema.getTable(tableName)).forEach(columnName -> result.put(columnName, 
tableName));
-            }
-        }
-        return result;
-    }
-    
-    @HighFrequencyInvocation
-    private Collection<String> filterColumnNames(final Collection<String> 
noOwnerColumnNames, final ShardingSphereTable table) {
-        Collection<String> result = new LinkedList<>();
-        for (String each : noOwnerColumnNames) {
-            if (table.containsColumn(each)) {
-                result.add(each);
-            }
-        }
-        return result;
-    }
-    
-    @HighFrequencyInvocation
-    private Collection<String> getNoOwnerColumnNames(final 
Collection<ColumnSegment> columns) {
-        Collection<String> result = new 
TreeSet<>(String.CASE_INSENSITIVE_ORDER);
-        for (ColumnSegment each : columns) {
-            if (!each.getOwner().isPresent()) {
-                result.add(each.getIdentifier().getValue());
-            }
-        }
-        return result;
-    }
-    
-    @HighFrequencyInvocation
-    private Map<String, String> findTableNameFromSubquery(final 
Collection<ColumnSegment> columns, final Map<String, String> ownerTableNames) {
-        if (ownerTableNames.size() == columns.size() || 
subqueryTables.isEmpty()) {
-            return Collections.emptyMap();
-        }
-        Map<String, String> result = new LinkedHashMap<>(columns.size(), 1F);
-        for (ColumnSegment each : columns) {
-            if (ownerTableNames.containsKey(each.getExpression())) {
-                continue;
-            }
-            String owner = each.getOwner().map(optional -> 
optional.getIdentifier().getValue()).orElse("");
-            Collection<SubqueryTableContext> subqueryTableContexts = 
subqueryTables.getOrDefault(owner, Collections.emptyList());
-            for (SubqueryTableContext subqueryTableContext : 
subqueryTableContexts) {
-                if 
(subqueryTableContext.getColumnNames().contains(each.getIdentifier().getValue()))
 {
-                    result.put(each.getExpression(), 
subqueryTableContext.getTableName());
-                }
-            }
-        }
-        return result;
-    }
-    
     /**
      * Get database name.
      *
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/ExpressionSegmentBinder.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/ExpressionSegmentBinder.java
index 5adaf40ff5d..78b395fc203 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/ExpressionSegmentBinder.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/ExpressionSegmentBinder.java
@@ -23,6 +23,7 @@ import com.google.common.collect.Multimap;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.shardingsphere.infra.binder.engine.segment.SegmentType;
+import 
org.apache.shardingsphere.infra.binder.engine.segment.expression.type.BetweenExpressionSegmentBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.expression.type.BinaryOperationExpressionBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.expression.type.ColumnSegmentBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.expression.type.ExistsSubqueryExpressionBinder;
@@ -33,6 +34,7 @@ import 
org.apache.shardingsphere.infra.binder.engine.segment.expression.type.Sub
 import 
org.apache.shardingsphere.infra.binder.engine.segment.from.context.TableSegmentBinderContext;
 import 
org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BetweenExpression;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BinaryOperationExpression;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExistsSubqueryExpression;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
@@ -84,6 +86,9 @@ public final class ExpressionSegmentBinder {
         if (segment instanceof FunctionSegment) {
             return FunctionExpressionSegmentBinder.bind((FunctionSegment) 
segment, parentSegmentType, binderContext, tableBinderContexts, 
outerTableBinderContexts);
         }
+        if (segment instanceof BetweenExpression) {
+            return BetweenExpressionSegmentBinder.bind((BetweenExpression) 
segment, binderContext, tableBinderContexts, outerTableBinderContexts);
+        }
         // TODO support more ExpressionSegment bound
         return segment;
     }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/BetweenExpressionSegmentBinder.java
similarity index 53%
copy from 
infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
copy to 
infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/BetweenExpressionSegmentBinder.java
index 8c96935e7e8..b12f2c5feaa 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/expression/type/BetweenExpressionSegmentBinder.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.infra.binder.engine.segment.where;
+package org.apache.shardingsphere.infra.binder.engine.segment.expression.type;
 
 import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString;
 import com.google.common.collect.Multimap;
@@ -25,27 +25,30 @@ import 
org.apache.shardingsphere.infra.binder.engine.segment.SegmentType;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.expression.ExpressionSegmentBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.from.context.TableSegmentBinderContext;
 import 
org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BetweenExpression;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
 
 /**
- * Where segment binder.
+ * Between expression binder.
  */
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class WhereSegmentBinder {
+public final class BetweenExpressionSegmentBinder {
     
     /**
-     * Bind where segment.
+     * Bind between expression.
      *
-     * @param segment where segment
+     * @param segment between expression segment
      * @param binderContext SQL statement binder context
      * @param tableBinderContexts table binder contexts
      * @param outerTableBinderContexts outer table binder contexts
-     * @return bound where segment
+     * @return bound between segment
      */
-    public static WhereSegment bind(final WhereSegment segment, final 
SQLStatementBinderContext binderContext,
-                                    final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> tableBinderContexts,
-                                    final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> outerTableBinderContexts) {
-        return new WhereSegment(segment.getStartIndex(), 
segment.getStopIndex(),
-                ExpressionSegmentBinder.bind(segment.getExpr(), 
SegmentType.PREDICATE, binderContext, tableBinderContexts, 
outerTableBinderContexts));
+    public static BetweenExpression bind(final BetweenExpression segment, 
final SQLStatementBinderContext binderContext,
+                                         final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> tableBinderContexts,
+                                         final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> outerTableBinderContexts) {
+        ExpressionSegment boundLeft = 
ExpressionSegmentBinder.bind(segment.getLeft(), SegmentType.PREDICATE, 
binderContext, tableBinderContexts, outerTableBinderContexts);
+        ExpressionSegment boundBetweenExpr = 
ExpressionSegmentBinder.bind(segment.getBetweenExpr(), SegmentType.PREDICATE, 
binderContext, tableBinderContexts, outerTableBinderContexts);
+        ExpressionSegment boundAndExpr = 
ExpressionSegmentBinder.bind(segment.getAndExpr(), SegmentType.PREDICATE, 
binderContext, tableBinderContexts, outerTableBinderContexts);
+        return new BetweenExpression(segment.getStartIndex(), 
segment.getStopIndex(), boundLeft, boundBetweenExpr, boundAndExpr, 
segment.isNot());
     }
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/order/GroupBySegmentBinder.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/order/GroupBySegmentBinder.java
new file mode 100644
index 00000000000..8d36597ed74
--- /dev/null
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/order/GroupBySegmentBinder.java
@@ -0,0 +1,71 @@
+/*
+ * 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.infra.binder.engine.segment.order;
+
+import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString;
+import com.google.common.collect.Multimap;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.apache.shardingsphere.infra.binder.engine.segment.SegmentType;
+import 
org.apache.shardingsphere.infra.binder.engine.segment.from.context.TableSegmentBinderContext;
+import 
org.apache.shardingsphere.infra.binder.engine.segment.order.item.OrderByItemSegmentBinder;
+import 
org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
+import 
org.apache.shardingsphere.infra.exception.kernel.metadata.ColumnNotFoundException;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.GroupBySegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.OrderByItemSegment;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+/**
+ * Group by segment binder.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class GroupBySegmentBinder {
+    
+    /**
+     * Bind group by segment.
+     *
+     * @param segment group by segment
+     * @param binderContext SQL statement binder context
+     * @param currentTableBinderContexts current table binder contexts
+     * @param tableBinderContexts table binder contexts
+     * @param outerTableBinderContexts outer table binder contexts
+     * @return bound group by segment
+     */
+    public static GroupBySegment bind(final GroupBySegment segment, final 
SQLStatementBinderContext binderContext,
+                                      final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> currentTableBinderContexts,
+                                      final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> tableBinderContexts,
+                                      final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> outerTableBinderContexts) {
+        Collection<OrderByItemSegment> boundGroupByItems = new LinkedList<>();
+        for (OrderByItemSegment each : segment.getGroupByItems()) {
+            boundGroupByItems.add(bind(binderContext, 
currentTableBinderContexts, tableBinderContexts, outerTableBinderContexts, 
each));
+        }
+        return new GroupBySegment(segment.getStartIndex(), 
segment.getStopIndex(), boundGroupByItems);
+    }
+    
+    private static OrderByItemSegment bind(final SQLStatementBinderContext 
binderContext, final Multimap<CaseInsensitiveString, TableSegmentBinderContext> 
currentTableBinderContexts,
+                                           final 
Multimap<CaseInsensitiveString, TableSegmentBinderContext> tableBinderContexts,
+                                           final 
Multimap<CaseInsensitiveString, TableSegmentBinderContext> 
outerTableBinderContexts, final OrderByItemSegment groupByItemSegment) {
+        try {
+            return OrderByItemSegmentBinder.bind(groupByItemSegment, 
binderContext, currentTableBinderContexts, outerTableBinderContexts, 
SegmentType.GROUP_BY);
+        } catch (final ColumnNotFoundException ignored) {
+            return OrderByItemSegmentBinder.bind(groupByItemSegment, 
binderContext, tableBinderContexts, outerTableBinderContexts, 
SegmentType.GROUP_BY);
+        }
+    }
+}
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/order/OrderBySegmentBinder.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/order/OrderBySegmentBinder.java
new file mode 100644
index 00000000000..426549e6014
--- /dev/null
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/order/OrderBySegmentBinder.java
@@ -0,0 +1,71 @@
+/*
+ * 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.infra.binder.engine.segment.order;
+
+import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString;
+import com.google.common.collect.Multimap;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.apache.shardingsphere.infra.binder.engine.segment.SegmentType;
+import 
org.apache.shardingsphere.infra.binder.engine.segment.from.context.TableSegmentBinderContext;
+import 
org.apache.shardingsphere.infra.binder.engine.segment.order.item.OrderByItemSegmentBinder;
+import 
org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
+import 
org.apache.shardingsphere.infra.exception.kernel.metadata.ColumnNotFoundException;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.OrderBySegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.OrderByItemSegment;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+/**
+ * Order by segment binder.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class OrderBySegmentBinder {
+    
+    /**
+     * Bind order by segment.
+     *
+     * @param segment order by segment
+     * @param binderContext SQL statement binder context
+     * @param currentTableBinderContexts current table binder contexts
+     * @param tableBinderContexts table binder contexts
+     * @param outerTableBinderContexts outer table binder contexts
+     * @return bound order by segment
+     */
+    public static OrderBySegment bind(final OrderBySegment segment, final 
SQLStatementBinderContext binderContext,
+                                      final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> currentTableBinderContexts,
+                                      final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> tableBinderContexts,
+                                      final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> outerTableBinderContexts) {
+        Collection<OrderByItemSegment> boundGroupByItems = new LinkedList<>();
+        for (OrderByItemSegment each : segment.getOrderByItems()) {
+            boundGroupByItems.add(bind(binderContext, 
currentTableBinderContexts, tableBinderContexts, outerTableBinderContexts, 
each));
+        }
+        return new OrderBySegment(segment.getStartIndex(), 
segment.getStopIndex(), boundGroupByItems);
+    }
+    
+    private static OrderByItemSegment bind(final SQLStatementBinderContext 
binderContext, final Multimap<CaseInsensitiveString, TableSegmentBinderContext> 
currentTableBinderContexts,
+                                           final 
Multimap<CaseInsensitiveString, TableSegmentBinderContext> tableBinderContexts,
+                                           final 
Multimap<CaseInsensitiveString, TableSegmentBinderContext> 
outerTableBinderContexts, final OrderByItemSegment orderByItemSegment) {
+        try {
+            return OrderByItemSegmentBinder.bind(orderByItemSegment, 
binderContext, currentTableBinderContexts, outerTableBinderContexts, 
SegmentType.ORDER_BY);
+        } catch (final ColumnNotFoundException ignored) {
+            return OrderByItemSegmentBinder.bind(orderByItemSegment, 
binderContext, tableBinderContexts, outerTableBinderContexts, 
SegmentType.ORDER_BY);
+        }
+    }
+}
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/order/item/ColumnOrderByItemSegmentBinder.java
similarity index 59%
copy from 
infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
copy to 
infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/order/item/ColumnOrderByItemSegmentBinder.java
index 8c96935e7e8..abedd2763b1 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/order/item/ColumnOrderByItemSegmentBinder.java
@@ -15,37 +15,38 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.infra.binder.engine.segment.where;
+package org.apache.shardingsphere.infra.binder.engine.segment.order.item;
 
 import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString;
 import com.google.common.collect.Multimap;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.shardingsphere.infra.binder.engine.segment.SegmentType;
-import 
org.apache.shardingsphere.infra.binder.engine.segment.expression.ExpressionSegmentBinder;
+import 
org.apache.shardingsphere.infra.binder.engine.segment.expression.type.ColumnSegmentBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.from.context.TableSegmentBinderContext;
 import 
org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ColumnOrderByItemSegment;
 
 /**
- * Where segment binder.
+ * Column order by item segment binder.
  */
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class WhereSegmentBinder {
+public final class ColumnOrderByItemSegmentBinder {
     
     /**
-     * Bind where segment.
+     * Bind column order by item segment.
      *
-     * @param segment where segment
+     * @param segment column order by item segment
      * @param binderContext SQL statement binder context
      * @param tableBinderContexts table binder contexts
      * @param outerTableBinderContexts outer table binder contexts
-     * @return bound where segment
+     * @param segmentType segment type
+     * @return bound column order by item segment
      */
-    public static WhereSegment bind(final WhereSegment segment, final 
SQLStatementBinderContext binderContext,
-                                    final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> tableBinderContexts,
-                                    final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> outerTableBinderContexts) {
-        return new WhereSegment(segment.getStartIndex(), 
segment.getStopIndex(),
-                ExpressionSegmentBinder.bind(segment.getExpr(), 
SegmentType.PREDICATE, binderContext, tableBinderContexts, 
outerTableBinderContexts));
+    public static ColumnOrderByItemSegment bind(final ColumnOrderByItemSegment 
segment, final SQLStatementBinderContext binderContext,
+                                                final 
Multimap<CaseInsensitiveString, TableSegmentBinderContext> tableBinderContexts,
+                                                final 
Multimap<CaseInsensitiveString, TableSegmentBinderContext> 
outerTableBinderContexts, final SegmentType segmentType) {
+        return new 
ColumnOrderByItemSegment(ColumnSegmentBinder.bind(segment.getColumn(), 
segmentType, binderContext, tableBinderContexts, outerTableBinderContexts), 
segment.getOrderDirection(),
+                segment.getNullsOrderType().orElse(null));
     }
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/order/item/ExpressionOrderByItemSegmentBinder.java
similarity index 60%
copy from 
infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
copy to 
infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/order/item/ExpressionOrderByItemSegmentBinder.java
index 8c96935e7e8..454fa2142f3 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/order/item/ExpressionOrderByItemSegmentBinder.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.infra.binder.engine.segment.where;
+package org.apache.shardingsphere.infra.binder.engine.segment.order.item;
 
 import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString;
 import com.google.common.collect.Multimap;
@@ -25,27 +25,28 @@ import 
org.apache.shardingsphere.infra.binder.engine.segment.SegmentType;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.expression.ExpressionSegmentBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.from.context.TableSegmentBinderContext;
 import 
org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ExpressionOrderByItemSegment;
 
 /**
- * Where segment binder.
+ * Expression order by item segment binder.
  */
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class WhereSegmentBinder {
+public final class ExpressionOrderByItemSegmentBinder {
     
     /**
-     * Bind where segment.
+     * Bind expression order by item segment.
      *
-     * @param segment where segment
+     * @param segment expression order by item segment
      * @param binderContext SQL statement binder context
      * @param tableBinderContexts table binder contexts
      * @param outerTableBinderContexts outer table binder contexts
-     * @return bound where segment
+     * @param segmentType segment type
+     * @return bound expression order by item segment
      */
-    public static WhereSegment bind(final WhereSegment segment, final 
SQLStatementBinderContext binderContext,
-                                    final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> tableBinderContexts,
-                                    final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> outerTableBinderContexts) {
-        return new WhereSegment(segment.getStartIndex(), 
segment.getStopIndex(),
-                ExpressionSegmentBinder.bind(segment.getExpr(), 
SegmentType.PREDICATE, binderContext, tableBinderContexts, 
outerTableBinderContexts));
+    public static ExpressionOrderByItemSegment bind(final 
ExpressionOrderByItemSegment segment, final SQLStatementBinderContext 
binderContext,
+                                                    final 
Multimap<CaseInsensitiveString, TableSegmentBinderContext> tableBinderContexts,
+                                                    final 
Multimap<CaseInsensitiveString, TableSegmentBinderContext> 
outerTableBinderContexts, final SegmentType segmentType) {
+        return new ExpressionOrderByItemSegment(segment.getStartIndex(), 
segment.getStopIndex(), segment.getExpression(), segment.getOrderDirection(), 
segment.getNullsOrderType().orElse(null),
+                ExpressionSegmentBinder.bind(segment.getExpr(), segmentType, 
binderContext, tableBinderContexts, outerTableBinderContexts));
     }
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/order/item/OrderByItemSegmentBinder.java
similarity index 51%
copy from 
infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
copy to 
infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/order/item/OrderByItemSegmentBinder.java
index 8c96935e7e8..b1e152b4938 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/order/item/OrderByItemSegmentBinder.java
@@ -15,37 +15,44 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.infra.binder.engine.segment.where;
+package org.apache.shardingsphere.infra.binder.engine.segment.order.item;
 
 import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString;
 import com.google.common.collect.Multimap;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.shardingsphere.infra.binder.engine.segment.SegmentType;
-import 
org.apache.shardingsphere.infra.binder.engine.segment.expression.ExpressionSegmentBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.from.context.TableSegmentBinderContext;
 import 
org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ColumnOrderByItemSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ExpressionOrderByItemSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.OrderByItemSegment;
 
 /**
- * Where segment binder.
+ * Order by item segment binder.
  */
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class WhereSegmentBinder {
+public final class OrderByItemSegmentBinder {
     
     /**
-     * Bind where segment.
+     * Bind order by item segment.
      *
-     * @param segment where segment
+     * @param segment order by item segment
      * @param binderContext SQL statement binder context
      * @param tableBinderContexts table binder contexts
      * @param outerTableBinderContexts outer table binder contexts
-     * @return bound where segment
+     * @param segmentType segment type
+     * @return bound order by item segment
      */
-    public static WhereSegment bind(final WhereSegment segment, final 
SQLStatementBinderContext binderContext,
-                                    final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> tableBinderContexts,
-                                    final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> outerTableBinderContexts) {
-        return new WhereSegment(segment.getStartIndex(), 
segment.getStopIndex(),
-                ExpressionSegmentBinder.bind(segment.getExpr(), 
SegmentType.PREDICATE, binderContext, tableBinderContexts, 
outerTableBinderContexts));
+    public static OrderByItemSegment bind(final OrderByItemSegment segment, 
final SQLStatementBinderContext binderContext,
+                                          final 
Multimap<CaseInsensitiveString, TableSegmentBinderContext> tableBinderContexts,
+                                          final 
Multimap<CaseInsensitiveString, TableSegmentBinderContext> 
outerTableBinderContexts, final SegmentType segmentType) {
+        if (segment instanceof ColumnOrderByItemSegment) {
+            return 
ColumnOrderByItemSegmentBinder.bind((ColumnOrderByItemSegment) segment, 
binderContext, tableBinderContexts, outerTableBinderContexts, segmentType);
+        }
+        if (segment instanceof ExpressionOrderByItemSegment) {
+            return 
ExpressionOrderByItemSegmentBinder.bind((ExpressionOrderByItemSegment) segment, 
binderContext, tableBinderContexts, outerTableBinderContexts, segmentType);
+        }
+        return segment;
     }
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/predicate/HavingSegmentBinder.java
similarity index 71%
copy from 
infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
copy to 
infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/predicate/HavingSegmentBinder.java
index 8c96935e7e8..d321b700a2f 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/predicate/HavingSegmentBinder.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.infra.binder.engine.segment.where;
+package org.apache.shardingsphere.infra.binder.engine.segment.predicate;
 
 import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString;
 import com.google.common.collect.Multimap;
@@ -25,27 +25,27 @@ import 
org.apache.shardingsphere.infra.binder.engine.segment.SegmentType;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.expression.ExpressionSegmentBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.from.context.TableSegmentBinderContext;
 import 
org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.HavingSegment;
 
 /**
- * Where segment binder.
+ * Having segment binder.
  */
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class WhereSegmentBinder {
+public final class HavingSegmentBinder {
     
     /**
-     * Bind where segment.
+     * Bind having segment.
      *
-     * @param segment where segment
+     * @param segment having segment
      * @param binderContext SQL statement binder context
      * @param tableBinderContexts table binder contexts
      * @param outerTableBinderContexts outer table binder contexts
-     * @return bound where segment
+     * @return bound having segment
      */
-    public static WhereSegment bind(final WhereSegment segment, final 
SQLStatementBinderContext binderContext,
-                                    final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> tableBinderContexts,
-                                    final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> outerTableBinderContexts) {
-        return new WhereSegment(segment.getStartIndex(), 
segment.getStopIndex(),
+    public static HavingSegment bind(final HavingSegment segment, final 
SQLStatementBinderContext binderContext,
+                                     final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> tableBinderContexts,
+                                     final Multimap<CaseInsensitiveString, 
TableSegmentBinderContext> outerTableBinderContexts) {
+        return new HavingSegment(segment.getStartIndex(), 
segment.getStopIndex(),
                 ExpressionSegmentBinder.bind(segment.getExpr(), 
SegmentType.PREDICATE, binderContext, tableBinderContexts, 
outerTableBinderContexts));
     }
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/predicate/WhereSegmentBinder.java
similarity index 97%
rename from 
infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
rename to 
infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/predicate/WhereSegmentBinder.java
index 8c96935e7e8..c9e57d1cb78 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinder.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/predicate/WhereSegmentBinder.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.infra.binder.engine.segment.where;
+package org.apache.shardingsphere.infra.binder.engine.segment.predicate;
 
 import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString;
 import com.google.common.collect.Multimap;
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/DeleteStatementBinder.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/DeleteStatementBinder.java
index 663c8f5bb45..30ad9a55199 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/DeleteStatementBinder.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/DeleteStatementBinder.java
@@ -23,7 +23,7 @@ import com.google.common.collect.Multimap;
 import lombok.SneakyThrows;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.from.TableSegmentBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.from.context.TableSegmentBinderContext;
-import 
org.apache.shardingsphere.infra.binder.engine.segment.where.WhereSegmentBinder;
+import 
org.apache.shardingsphere.infra.binder.engine.segment.predicate.WhereSegmentBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
 import 
org.apache.shardingsphere.sql.parser.statement.core.statement.dml.DeleteStatement;
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/SelectStatementBinder.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/SelectStatementBinder.java
index 47c8357c87d..521d949a899 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/SelectStatementBinder.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/SelectStatementBinder.java
@@ -25,14 +25,22 @@ import lombok.SneakyThrows;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.combine.CombineSegmentBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.from.TableSegmentBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.from.context.TableSegmentBinderContext;
+import 
org.apache.shardingsphere.infra.binder.engine.segment.from.context.type.SimpleTableSegmentBinderContext;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.lock.LockSegmentBinder;
+import 
org.apache.shardingsphere.infra.binder.engine.segment.order.GroupBySegmentBinder;
+import 
org.apache.shardingsphere.infra.binder.engine.segment.order.OrderBySegmentBinder;
+import 
org.apache.shardingsphere.infra.binder.engine.segment.predicate.HavingSegmentBinder;
+import 
org.apache.shardingsphere.infra.binder.engine.segment.predicate.WhereSegmentBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.projection.ProjectionsSegmentBinder;
-import 
org.apache.shardingsphere.infra.binder.engine.segment.where.WhereSegmentBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
+import 
org.apache.shardingsphere.infra.binder.engine.util.SubqueryTableBindUtils;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.statement.dml.SelectStatement;
+import 
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
 
+import java.util.Collection;
 import java.util.Optional;
 
 /**
@@ -57,16 +65,27 @@ public final class SelectStatementBinder implements 
SQLStatementBinder<SelectSta
         sqlStatement.getWhere().ifPresent(optional -> 
result.setWhere(WhereSegmentBinder.bind(optional, binderContext, 
tableBinderContexts, outerTableBinderContexts)));
         sqlStatement.getCombine().ifPresent(optional -> 
result.setCombine(CombineSegmentBinder.bind(optional, binderContext, 
outerTableBinderContexts)));
         sqlStatement.getLock().ifPresent(optional -> 
result.setLock(LockSegmentBinder.bind(optional, binderContext, 
tableBinderContexts, outerTableBinderContexts)));
+        Multimap<CaseInsensitiveString, TableSegmentBinderContext> 
currentTableBinderContexts = createCurrentTableBinderContexts(binderContext, 
result);
+        sqlStatement.getGroupBy().ifPresent(optional -> result.setGroupBy(
+                GroupBySegmentBinder.bind(optional, binderContext, 
currentTableBinderContexts, tableBinderContexts, outerTableBinderContexts)));
+        sqlStatement.getOrderBy().ifPresent(optional -> result.setOrderBy(
+                OrderBySegmentBinder.bind(optional, binderContext, 
currentTableBinderContexts, tableBinderContexts, outerTableBinderContexts)));
+        sqlStatement.getHaving().ifPresent(optional -> 
result.setHaving(HavingSegmentBinder.bind(optional, binderContext, 
currentTableBinderContexts, outerTableBinderContexts)));
         // TODO support other segment bind in select statement
         return result;
     }
     
+    private Multimap<CaseInsensitiveString, TableSegmentBinderContext> 
createCurrentTableBinderContexts(final SQLStatementBinderContext binderContext, 
final SelectStatement selectStatement) {
+        Multimap<CaseInsensitiveString, TableSegmentBinderContext> result = 
LinkedHashMultimap.create();
+        Collection<ProjectionSegment> subqueryProjections = 
SubqueryTableBindUtils.createSubqueryProjections(
+                selectStatement.getProjections().getProjections(), new 
IdentifierValue(""), binderContext.getSqlStatement().getDatabaseType());
+        result.put(new CaseInsensitiveString(""), new 
SimpleTableSegmentBinderContext(subqueryProjections));
+        return result;
+    }
+    
     @SneakyThrows(ReflectiveOperationException.class)
     private SelectStatement copy(final SelectStatement sqlStatement) {
         SelectStatement result = 
sqlStatement.getClass().getDeclaredConstructor().newInstance();
-        sqlStatement.getGroupBy().ifPresent(result::setGroupBy);
-        sqlStatement.getHaving().ifPresent(result::setHaving);
-        sqlStatement.getOrderBy().ifPresent(result::setOrderBy);
         sqlStatement.getLimit().ifPresent(result::setLimit);
         sqlStatement.getWindow().ifPresent(result::setWindow);
         sqlStatement.getModelSegment().ifPresent(result::setModelSegment);
@@ -74,6 +93,7 @@ public final class SelectStatementBinder implements 
SQLStatementBinder<SelectSta
         sqlStatement.getWithSegment().ifPresent(result::setWithSegment);
         
result.addParameterMarkerSegments(sqlStatement.getParameterMarkerSegments());
         result.getCommentSegments().addAll(sqlStatement.getCommentSegments());
+        result.getVariableNames().addAll(sqlStatement.getVariableNames());
         return result;
     }
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/UpdateStatementBinder.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/UpdateStatementBinder.java
index 2747106952d..1de69236fdd 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/UpdateStatementBinder.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/UpdateStatementBinder.java
@@ -24,7 +24,7 @@ import lombok.SneakyThrows;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.assign.AssignmentSegmentBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.from.TableSegmentBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.segment.from.context.TableSegmentBinderContext;
-import 
org.apache.shardingsphere.infra.binder.engine.segment.where.WhereSegmentBinder;
+import 
org.apache.shardingsphere.infra.binder.engine.segment.predicate.WhereSegmentBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinder;
 import 
org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
 import 
org.apache.shardingsphere.sql.parser.statement.core.statement.dml.UpdateStatement;
diff --git 
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/table/TablesContextTest.java
 
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/table/TablesContextTest.java
index 377c317dfb3..20fd15c36b2 100644
--- 
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/table/TablesContextTest.java
+++ 
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/table/TablesContextTest.java
@@ -17,10 +17,6 @@
 
 package org.apache.shardingsphere.infra.binder.context.segment.table;
 
-import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereColumn;
-import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
-import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.AliasSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.TableSegmentBoundInfo;
@@ -33,16 +29,13 @@ import org.junit.jupiter.api.Test;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Optional;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
 
 class TablesContextTest {
     
@@ -75,61 +68,6 @@ class TablesContextTest {
         assertThat(tablesContext.getTableNames(), 
is(Collections.singleton("tbl")));
     }
     
-    @Test
-    void assertFindTableNameWhenSingleTable() {
-        SimpleTableSegment tableSegment = createTableSegment("table_1", 
"tbl_1", "sharding_db_1");
-        ColumnSegment columnSegment = createColumnSegment(null, "col");
-        Map<String, String> actual = new 
TablesContext(Collections.singletonList(tableSegment)).findTableNames(Collections.singletonList(columnSegment),
 mock());
-        assertFalse(actual.isEmpty());
-        assertThat(actual.get("col"), is("table_1"));
-    }
-    
-    @Test
-    void assertFindTableNameWhenColumnSegmentOwnerPresent() {
-        SimpleTableSegment tableSegment1 = createTableSegment("table_1", 
"tbl_1", "sharding_db_1");
-        SimpleTableSegment tableSegment2 = createTableSegment("table_2", 
"tbl_2", "sharding_db_1");
-        ColumnSegment columnSegment = createColumnSegment("table_1", "col");
-        Map<String, String> actual = new 
TablesContext(Arrays.asList(tableSegment1, 
tableSegment2)).findTableNames(Collections.singletonList(columnSegment), 
mock());
-        assertFalse(actual.isEmpty());
-        assertThat(actual.get("table_1.col"), is("table_1"));
-    }
-    
-    @Test
-    void assertFindTableNameWhenColumnSegmentOwnerAbsent() {
-        SimpleTableSegment tableSegment1 = createTableSegment("table_1", 
"tbl_1", "sharding_db_1");
-        SimpleTableSegment tableSegment2 = createTableSegment("table_2", 
"tbl_2", "sharding_db_1");
-        ColumnSegment columnSegment = createColumnSegment(null, "col");
-        Map<String, String> actual = new 
TablesContext(Arrays.asList(tableSegment1, 
tableSegment2)).findTableNames(Collections.singletonList(columnSegment), 
mock());
-        assertTrue(actual.isEmpty());
-    }
-    
-    @Test
-    void 
assertFindTableNameWhenColumnSegmentOwnerAbsentAndSchemaMetaDataContainsColumn()
 {
-        SimpleTableSegment tableSegment1 = createTableSegment("table_1", 
"tbl_1", "sharding_db_1");
-        SimpleTableSegment tableSegment2 = createTableSegment("table_2", 
"tbl_2", "sharding_db_1");
-        ShardingSphereSchema schema = mock(ShardingSphereSchema.class);
-        when(schema.containsTable("table_1")).thenReturn(true);
-        ShardingSphereTable table = mock(ShardingSphereTable.class);
-        when(table.containsColumn("col")).thenReturn(true);
-        when(schema.getTable("table_1")).thenReturn(table);
-        ColumnSegment columnSegment = createColumnSegment(null, "col");
-        Map<String, String> actual = new 
TablesContext(Arrays.asList(tableSegment1, 
tableSegment2)).findTableNames(Collections.singletonList(columnSegment), 
schema);
-        assertThat(actual.get("col"), is("table_1"));
-    }
-    
-    @Test
-    void 
assertFindTableNameWhenColumnSegmentOwnerAbsentAndSchemaMetaDataContainsColumnInUpperCase()
 {
-        SimpleTableSegment tableSegment1 = createTableSegment("TABLE_1", 
"TBL_1", "sharding_db_1");
-        SimpleTableSegment tableSegment2 = createTableSegment("TABLE_2", 
"TBL_2", "sharding_db_1");
-        ShardingSphereTable table = new ShardingSphereTable("TABLE_1",
-                Collections.singletonList(new ShardingSphereColumn("COL", 0, 
false, false, true, true, false, false)), Collections.emptyList(), 
Collections.emptyList());
-        ShardingSphereSchema schema = new ShardingSphereSchema("foo_db", 
Collections.singleton(table), Collections.emptyList());
-        ColumnSegment columnSegment = createColumnSegment(null, "COL");
-        Map<String, String> actual = new 
TablesContext(Arrays.asList(tableSegment1, 
tableSegment2)).findTableNames(Collections.singletonList(columnSegment), 
schema);
-        assertFalse(actual.isEmpty());
-        assertThat(actual.get("col"), is("TABLE_1"));
-    }
-    
     private SimpleTableSegment createTableSegment(final String tableName, 
final String alias, final String databaseName) {
         TableNameSegment tableNameSegment = new TableNameSegment(0, 0, new 
IdentifierValue(tableName));
         tableNameSegment.setTableBoundInfo(new TableSegmentBoundInfo(new 
IdentifierValue(databaseName), new IdentifierValue(databaseName)));
@@ -139,14 +77,6 @@ class TablesContextTest {
         return result;
     }
     
-    private ColumnSegment createColumnSegment(final String owner, final String 
name) {
-        ColumnSegment result = new ColumnSegment(0, 0, new 
IdentifierValue(name));
-        if (null != owner) {
-            result.setOwner(new OwnerSegment(0, 0, new 
IdentifierValue(owner)));
-        }
-        return result;
-    }
-    
     @Test
     void assertGetSchemaNameWithSameSchemaAndSameTable() {
         SimpleTableSegment tableSegment1 = createTableSegment("table_1", 
"tbl_1", "sharding_db_1");
diff --git 
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinderTest.java
 
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/predicate/WhereSegmentBinderTest.java
similarity index 97%
rename from 
infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinderTest.java
rename to 
infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/predicate/WhereSegmentBinderTest.java
index 84815358e63..ebb18e15c6c 100644
--- 
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/where/WhereSegmentBinderTest.java
+++ 
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/engine/segment/predicate/WhereSegmentBinderTest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.infra.binder.engine.segment.where;
+package org.apache.shardingsphere.infra.binder.engine.segment.predicate;
 
 import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString;
 import com.google.common.collect.LinkedHashMultimap;

Reply via email to