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

panjuan 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 92b02d1  Extract ColumnSegment interface and optimize 
EncryptPredicateColumnTokenGenerator logic (#15736)
92b02d1 is described below

commit 92b02d1e3c92bdda11418480af3d9de3565537c2
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Wed Mar 2 18:57:20 2022 +0800

    Extract ColumnSegment interface and optimize 
EncryptPredicateColumnTokenGenerator logic (#15736)
---
 .../merge/dql/EncryptAlgorithmMetaData.java        |  4 +-
 .../rewrite/condition/EncryptConditionEngine.java  | 44 +++--------
 .../context/EncryptSQLRewriteContextDecorator.java | 10 ++-
 .../EncryptOrderByItemTokenGenerator.java          | 25 ++----
 .../EncryptPredicateColumnTokenGenerator.java      | 91 ++++++----------------
 .../generator/EncryptProjectionTokenGenerator.java |  2 +-
 .../merge/dql/EncryptAlgorithmMetaDataTest.java    |  4 +-
 .../impl/WhereClauseShardingConditionEngine.java   | 37 ++-------
 .../shardingsphere/sharding/rule/ShardingRule.java | 23 +++---
 .../sharding/rule/ShardingRuleTest.java            | 21 ++---
 .../infra/binder/segment/table/TablesContext.java  | 71 ++++++++++++-----
 .../statement/dml/DeleteStatementContext.java      | 10 +++
 .../statement/dml/SelectStatementContext.java      | 22 ++++--
 .../statement/dml/UpdateStatementContext.java      | 10 +++
 .../infra/binder/type/WhereAvailable.java          |  8 ++
 .../binder/segment/table/TablesContextTest.java    | 33 ++++----
 .../common/segment/dml/column/ColumnSegment.java   |  9 +++
 .../parser/sql/common/util/ColumnExtractor.java    | 22 ++++++
 18 files changed, 223 insertions(+), 223 deletions(-)

diff --git 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaData.java
 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaData.java
index 20daaad..840d0d7 100644
--- 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaData.java
+++ 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaData.java
@@ -78,8 +78,8 @@ public final class EncryptAlgorithmMetaData {
         if (!columnProjection.isPresent()) {
             return Optional.empty();
         }
-        Map<String, String> columnTableNames = 
selectStatementContext.getTablesContext().findTableName(Collections.singletonList(columnProjection.get()),
 schema);
-        Optional<String> tableName = findTableName(columnProjection.get(), 
columnTableNames);
+        Map<String, String> expressionTableNames = 
selectStatementContext.getTablesContext().findTableNamesByColumnProjection(Collections.singletonList(columnProjection.get()),
 schema);
+        Optional<String> tableName = findTableName(columnProjection.get(), 
expressionTableNames);
         return tableName.map(optional -> 
EncryptContextBuilder.build(schemaName, optional, 
columnProjection.get().getName(), encryptRule));
     }
     
diff --git 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/condition/EncryptConditionEngine.java
 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/condition/EncryptConditionEngine.java
index c6d5853..28bbc78 100644
--- 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/condition/EncryptConditionEngine.java
+++ 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/condition/EncryptConditionEngine.java
@@ -20,8 +20,8 @@ package org.apache.shardingsphere.encrypt.rewrite.condition;
 import lombok.RequiredArgsConstructor;
 import 
org.apache.shardingsphere.encrypt.rewrite.condition.impl.EncryptEqualCondition;
 import 
org.apache.shardingsphere.encrypt.rewrite.condition.impl.EncryptInCondition;
+import org.apache.shardingsphere.encrypt.rule.EncryptColumn;
 import org.apache.shardingsphere.encrypt.rule.EncryptRule;
-import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
 import org.apache.shardingsphere.infra.binder.segment.table.TablesContext;
 import org.apache.shardingsphere.infra.exception.ShardingSphereException;
 import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
@@ -78,36 +78,37 @@ public final class EncryptConditionEngine {
      * Create encrypt conditions.
      *
      * @param whereSegments where segments
+     * @param columnSegments column segments
      * @param tablesContext tables context
      * @return encrypt conditions
      */
-    public Collection<EncryptCondition> createEncryptConditions(final 
Collection<WhereSegment> whereSegments, final TablesContext tablesContext) {
+    public Collection<EncryptCondition> createEncryptConditions(final 
Collection<WhereSegment> whereSegments, 
+                                                                final 
Collection<ColumnSegment> columnSegments, final TablesContext tablesContext) {
         Collection<EncryptCondition> result = new LinkedList<>();
+        Map<String, String> expressionTableNames = 
tablesContext.findTableNamesByColumnSegment(columnSegments, schema);
         for (WhereSegment each : whereSegments) {
             Collection<AndPredicate> andPredicates = 
ExpressionExtractUtil.getAndPredicates(each.getExpr());
-            Map<String, String> columnTableNames = 
getColumnTableNames(tablesContext, andPredicates);
             for (AndPredicate predicate : andPredicates) {
-                addEncryptConditions(result, predicate.getPredicates(), 
columnTableNames);
+                addEncryptConditions(result, predicate.getPredicates(), 
expressionTableNames);
             }
         }
         return result;
     }
     
-    private void addEncryptConditions(final Collection<EncryptCondition> 
encryptConditions, final Collection<ExpressionSegment> predicates, final 
Map<String, String> columnTableNames) {
+    private void addEncryptConditions(final Collection<EncryptCondition> 
encryptConditions, final Collection<ExpressionSegment> predicates, final 
Map<String, String> expressionTableNames) {
         Collection<Integer> stopIndexes = new HashSet<>(predicates.size(), 1);
         for (ExpressionSegment each : predicates) {
             if (stopIndexes.add(each.getStopIndex())) {
-                addEncryptConditions(encryptConditions, each, 
columnTableNames);
+                addEncryptConditions(encryptConditions, each, 
expressionTableNames);
             }
         }
     }
     
-    private void addEncryptConditions(final Collection<EncryptCondition> 
encryptConditions, final ExpressionSegment expression, final Map<String, 
String> columnTableNames) {
+    private void addEncryptConditions(final Collection<EncryptCondition> 
encryptConditions, final ExpressionSegment expression, final Map<String, 
String> expressionTableNames) {
         for (ColumnSegment each : ColumnExtractor.extract(expression)) {
-            ColumnProjection projection = buildColumnProjection(each);
-            Optional<String> tableName = 
Optional.ofNullable(columnTableNames.get(projection.getExpression()));
-            Optional<EncryptCondition> encryptCondition = 
tableName.isPresent() 
-                    && encryptRule.findEncryptColumn(tableName.get(), 
projection.getName()).isPresent() ? createEncryptCondition(expression, 
tableName.get()) : Optional.empty();
+            String tableName = 
expressionTableNames.getOrDefault(each.getExpression(), "");
+            Optional<EncryptColumn> encryptColumn = 
encryptRule.findEncryptColumn(tableName, each.getIdentifier().getValue());
+            Optional<EncryptCondition> encryptCondition = 
encryptColumn.isPresent() ? createEncryptCondition(expression, tableName) : 
Optional.empty();
             encryptCondition.ifPresent(encryptConditions::add);
         }
     }
@@ -136,27 +137,6 @@ public final class EncryptConditionEngine {
         return Optional.empty();
     }
     
-    private Map<String, String> getColumnTableNames(final TablesContext 
tablesContext, final Collection<AndPredicate> andPredicates) {
-        Collection<ColumnProjection> columns = new LinkedList<>();
-        for (AndPredicate each : andPredicates) {
-            addColumnProjections(columns, each);
-        }
-        return tablesContext.findTableName(columns, schema);
-    }
-    
-    private void addColumnProjections(final Collection<ColumnProjection> 
columns, final AndPredicate predicate) {
-        for (ExpressionSegment each : predicate.getPredicates()) {
-            for (ColumnSegment column : ColumnExtractor.extract(each)) {
-                columns.add(buildColumnProjection(column));
-            }
-        }
-    }
-    
-    private ColumnProjection buildColumnProjection(final ColumnSegment 
segment) {
-        String owner = segment.getOwner().map(optional -> 
optional.getIdentifier().getValue()).orElse(null);
-        return new ColumnProjection(owner, segment.getIdentifier().getValue(), 
null);
-    }
-    
     private Optional<EncryptCondition> createCompareEncryptCondition(final 
String tableName, final BinaryOperationExpression expression, final 
ExpressionSegment compareRightValue) {
         if (!(expression.getLeft() instanceof ColumnSegment)) {
             return Optional.empty();
diff --git 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/context/EncryptSQLRewriteContextDecorator.java
 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/context/EncryptSQLRewriteContextDecorator.java
index 5f6c3fc..6ab5232 100644
--- 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/context/EncryptSQLRewriteContextDecorator.java
+++ 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/context/EncryptSQLRewriteContextDecorator.java
@@ -31,6 +31,7 @@ import 
org.apache.shardingsphere.infra.rewrite.context.SQLRewriteContextDecorato
 import 
org.apache.shardingsphere.infra.rewrite.parameter.rewriter.ParameterRewriter;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.generator.SQLTokenGenerator;
 import org.apache.shardingsphere.infra.route.context.RouteContext;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.WhereSegment;
 
 import java.util.Collection;
@@ -62,9 +63,12 @@ public final class EncryptSQLRewriteContextDecorator 
implements SQLRewriteContex
     
     private Collection<EncryptCondition> getEncryptConditions(final 
EncryptRule encryptRule, final SQLRewriteContext sqlRewriteContext) {
         SQLStatementContext<?> sqlStatementContext = 
sqlRewriteContext.getSqlStatementContext();
-        Collection<WhereSegment> whereSegments = sqlStatementContext 
instanceof WhereAvailable ? ((WhereAvailable) 
sqlStatementContext).getWhereSegments() : Collections.emptyList();
-        return whereSegments.isEmpty() ? Collections.emptyList() 
-                : new EncryptConditionEngine(encryptRule, 
sqlRewriteContext.getSchema()).createEncryptConditions(whereSegments, 
sqlStatementContext.getTablesContext());
+        if (!(sqlStatementContext instanceof WhereAvailable)) {
+            return Collections.emptyList();
+        }
+        Collection<WhereSegment> whereSegments = ((WhereAvailable) 
sqlStatementContext).getWhereSegments();
+        Collection<ColumnSegment> columnSegments = ((WhereAvailable) 
sqlStatementContext).getColumnSegments();
+        return new EncryptConditionEngine(encryptRule, 
sqlRewriteContext.getSchema()).createEncryptConditions(whereSegments, 
columnSegments, sqlStatementContext.getTablesContext());
     }
     
     @SuppressWarnings("rawtypes")
diff --git 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptOrderByItemTokenGenerator.java
 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptOrderByItemTokenGenerator.java
index dec2928..af56eb0 100644
--- 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptOrderByItemTokenGenerator.java
+++ 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptOrderByItemTokenGenerator.java
@@ -62,7 +62,7 @@ public final class EncryptOrderByItemTokenGenerator 
implements CollectionSQLToke
         for (OrderByItem each : getOrderByItems(sqlStatementContext)) {
             if (each.getSegment() instanceof ColumnOrderByItemSegment) {
                 ColumnSegment columnSegment = ((ColumnOrderByItemSegment) 
each.getSegment()).getColumn();
-                Map<String, String> columnTableNames = 
sqlStatementContext.getTablesContext().findTableName(Collections.singletonList(buildColumnProjection(columnSegment)),
 schema);
+                Map<String, String> columnTableNames = 
sqlStatementContext.getTablesContext().findTableNamesByColumnSegment(Collections.singletonList(columnSegment),
 schema);
                 
result.addAll(generateSQLTokensWithColumnSegments(Collections.singletonList(columnSegment),
 columnTableNames));
             }
         }
@@ -72,25 +72,25 @@ public final class EncryptOrderByItemTokenGenerator 
implements CollectionSQLToke
     private Collection<SubstitutableColumnNameToken> 
generateSQLTokensWithColumnSegments(final Collection<ColumnSegment> 
columnSegments, final Map<String, String> columnTableNames) {
         Collection<SubstitutableColumnNameToken> result = new LinkedList<>();
         for (ColumnSegment column : columnSegments) {
-            Optional<String> tableName = findTableName(columnTableNames, 
buildColumnProjection(column));
-            Optional<EncryptTable> encryptTable = tableName.flatMap(optional 
-> encryptRule.findEncryptTable(optional));
+            String tableName = 
columnTableNames.getOrDefault(column.getExpression(), "");
+            Optional<EncryptTable> encryptTable = 
encryptRule.findEncryptTable(tableName);
             if (!encryptTable.isPresent() || 
!encryptTable.get().findEncryptorName(column.getIdentifier().getValue()).isPresent())
 {
                 continue;
             }
             int startIndex = column.getOwner().isPresent() ? 
column.getOwner().get().getStopIndex() + 2 : column.getStartIndex();
             int stopIndex = column.getStopIndex();
-            boolean queryWithCipherColumn = 
encryptRule.isQueryWithCipherColumn(tableName.orElse(""));
+            boolean queryWithCipherColumn = 
encryptRule.isQueryWithCipherColumn(tableName);
             if (!queryWithCipherColumn) {
                 Optional<String> plainColumn = 
encryptTable.get().findPlainColumn(column.getIdentifier().getValue());
                 if (plainColumn.isPresent()) {
-                    result.add(new SubstitutableColumnNameToken(startIndex, 
stopIndex, getColumnProjections(plainColumn.get())));
+                    result.add(new SubstitutableColumnNameToken(startIndex, 
stopIndex, createColumnProjections(plainColumn.get())));
                     continue;
                 }
             }
             Optional<String> assistedQueryColumn = 
encryptTable.get().findAssistedQueryColumn(column.getIdentifier().getValue());
             SubstitutableColumnNameToken encryptColumnNameToken = 
assistedQueryColumn.map(columnName
-                -> new SubstitutableColumnNameToken(startIndex, stopIndex, 
getColumnProjections(columnName))).orElseGet(()
-                    -> new SubstitutableColumnNameToken(startIndex, stopIndex, 
getColumnProjections(encryptTable.get().getCipherColumn(column.getIdentifier().getValue()))));
+                -> new SubstitutableColumnNameToken(startIndex, stopIndex, 
createColumnProjections(columnName))).orElseGet(()
+                    -> new SubstitutableColumnNameToken(startIndex, stopIndex, 
createColumnProjections(encryptTable.get().getCipherColumn(column.getIdentifier().getValue()))));
             result.add(encryptColumnNameToken);
         }
         return result;
@@ -126,16 +126,7 @@ public final class EncryptOrderByItemTokenGenerator 
implements CollectionSQLToke
         return false;
     }
     
-    private ColumnProjection buildColumnProjection(final ColumnSegment 
segment) {
-        String owner = segment.getOwner().map(optional -> 
optional.getIdentifier().getValue()).orElse(null);
-        return new ColumnProjection(owner, segment.getIdentifier().getValue(), 
null);
-    }
-    
-    private Optional<String> findTableName(final Map<String, String> 
columnTableNames, final ColumnProjection column) {
-        return 
Optional.ofNullable(columnTableNames.get(column.getExpression()));
-    }
-    
-    private Collection<ColumnProjection> getColumnProjections(final String 
columnName) {
+    private Collection<ColumnProjection> createColumnProjections(final String 
columnName) {
         return Collections.singletonList(new ColumnProjection(null, 
columnName, null));
     }
 }
diff --git 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptPredicateColumnTokenGenerator.java
 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptPredicateColumnTokenGenerator.java
index b5219dd..c2dc94d 100644
--- 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptPredicateColumnTokenGenerator.java
+++ 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptPredicateColumnTokenGenerator.java
@@ -29,16 +29,10 @@ import 
org.apache.shardingsphere.infra.rewrite.sql.token.generator.CollectionSQL
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.generator.aware.SchemaMetaDataAware;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.pojo.generic.SubstitutableColumnNameToken;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
-import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
-import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.AndPredicate;
-import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.WhereSegment;
-import org.apache.shardingsphere.sql.parser.sql.common.util.ColumnExtractor;
-import 
org.apache.shardingsphere.sql.parser.sql.common.util.ExpressionExtractUtil;
 
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashSet;
-import java.util.LinkedList;
 import java.util.Map;
 import java.util.Optional;
 
@@ -61,76 +55,39 @@ public final class EncryptPredicateColumnTokenGenerator 
implements CollectionSQL
     @SuppressWarnings("rawtypes")
     @Override
     public Collection<SubstitutableColumnNameToken> generateSQLTokens(final 
SQLStatementContext sqlStatementContext) {
-        Collection<SubstitutableColumnNameToken> result = new 
LinkedHashSet<>();
-        Collection<WhereSegment> whereSegments = sqlStatementContext 
instanceof WhereAvailable 
-                ? ((WhereAvailable) sqlStatementContext).getWhereSegments() : 
Collections.emptyList();
-        for (WhereSegment each : whereSegments) {
-            Collection<AndPredicate> andPredicates = 
ExpressionExtractUtil.getAndPredicates(each.getExpr());
-            Map<String, String> columnTableNames = 
getColumnTableNames(sqlStatementContext, andPredicates);
-            for (AndPredicate predicate : andPredicates) {
-                result.addAll(generateSQLTokens(predicate.getPredicates(), 
columnTableNames));
-            }
-        }
-        return result;
+        Collection<ColumnSegment> columnSegments = sqlStatementContext 
instanceof WhereAvailable ? ((WhereAvailable) 
sqlStatementContext).getColumnSegments() : Collections.emptyList();
+        Map<String, String> columnExpressionTableNames = 
sqlStatementContext.getTablesContext().findTableNamesByColumnSegment(columnSegments,
 schema);
+        return generateSQLTokens(columnSegments, columnExpressionTableNames);
     }
     
-    private Collection<SubstitutableColumnNameToken> generateSQLTokens(final 
Collection<ExpressionSegment> predicates, final Map<String, String> 
columnTableNames) {
-        Collection<SubstitutableColumnNameToken> result = new LinkedList<>();
-        for (ExpressionSegment each : predicates) {
-            for (ColumnSegment column : ColumnExtractor.extract(each)) {
-                Optional<String> tableName = findTableName(columnTableNames, 
buildColumnProjection(column));
-                Optional<EncryptTable> encryptTable = 
tableName.flatMap(optional -> encryptRule.findEncryptTable(optional));
-                if (!encryptTable.isPresent() || 
!encryptTable.get().findEncryptorName(column.getIdentifier().getValue()).isPresent())
 {
+    private Collection<SubstitutableColumnNameToken> generateSQLTokens(final 
Collection<ColumnSegment> columnSegments, final Map<String, String> 
columnExpressionTableNames) {
+        Collection<SubstitutableColumnNameToken> result = new 
LinkedHashSet<>();
+        for (ColumnSegment each : columnSegments) {
+            String tableName = 
Optional.ofNullable(columnExpressionTableNames.get(each.getExpression())).orElse("");
+            Optional<EncryptTable> encryptTable = 
encryptRule.findEncryptTable(tableName);
+            if (!encryptTable.isPresent() || 
!encryptTable.get().findEncryptColumn(each.getIdentifier().getValue()).isPresent())
 {
+                continue;
+            }
+            int startIndex = each.getOwner().isPresent() ? 
each.getOwner().get().getStopIndex() + 2 : each.getStartIndex();
+            int stopIndex = each.getStopIndex();
+            boolean queryWithCipherColumn = 
encryptRule.isQueryWithCipherColumn(tableName);
+            if (!queryWithCipherColumn) {
+                Optional<String> plainColumn = 
encryptTable.get().findPlainColumn(each.getIdentifier().getValue());
+                if (plainColumn.isPresent()) {
+                    result.add(new SubstitutableColumnNameToken(startIndex, 
stopIndex, createColumnProjections(plainColumn.get())));
                     continue;
                 }
-                int startIndex = column.getOwner().isPresent() ? 
column.getOwner().get().getStopIndex() + 2 : column.getStartIndex();
-                int stopIndex = column.getStopIndex();
-                boolean queryWithCipherColumn = 
encryptRule.isQueryWithCipherColumn(tableName.orElse(""));
-                if (!queryWithCipherColumn) {
-                    Optional<String> plainColumn = 
encryptTable.get().findPlainColumn(column.getIdentifier().getValue());
-                    if (plainColumn.isPresent()) {
-                        result.add(new 
SubstitutableColumnNameToken(startIndex, stopIndex, 
buildColumnProjections(plainColumn.get())));
-                        continue;
-                    }
-                }
-                Optional<String> assistedQueryColumn = 
encryptTable.get().findAssistedQueryColumn(column.getIdentifier().getValue());
-                SubstitutableColumnNameToken encryptColumnNameToken = 
assistedQueryColumn.map(columnName
-                    -> new SubstitutableColumnNameToken(startIndex, stopIndex, 
buildColumnProjections(columnName))).orElseGet(()
-                        -> new SubstitutableColumnNameToken(startIndex, 
stopIndex, 
buildColumnProjections(encryptTable.get().getCipherColumn(column.getIdentifier().getValue()))));
-                result.add(encryptColumnNameToken);
             }
+            Optional<String> assistedQueryColumn = 
encryptTable.get().findAssistedQueryColumn(each.getIdentifier().getValue());
+            SubstitutableColumnNameToken encryptColumnNameToken = 
assistedQueryColumn.map(columnName
+                -> new SubstitutableColumnNameToken(startIndex, stopIndex, 
createColumnProjections(columnName))).orElseGet(()
+                    -> new SubstitutableColumnNameToken(startIndex, stopIndex, 
createColumnProjections(encryptTable.get().getCipherColumn(each.getIdentifier().getValue()))));
+            result.add(encryptColumnNameToken);
         }
         return result;
     }
     
-    private Map<String, String> getColumnTableNames(final 
SQLStatementContext<?> sqlStatementContext, final Collection<AndPredicate> 
andPredicates) {
-        Collection<ColumnProjection> columns = new LinkedList<>();
-        for (AndPredicate each : andPredicates) {
-            columns.addAll(getColumnProjections(each));
-        }
-        return sqlStatementContext.getTablesContext().findTableName(columns, 
schema);
-    }
-    
-    private Collection<ColumnProjection> getColumnProjections(final 
AndPredicate predicate) {
-        Collection<ColumnProjection> result = new LinkedList<>();
-        for (ExpressionSegment each : predicate.getPredicates()) {
-            for (ColumnSegment columnSegment : ColumnExtractor.extract(each)) {
-                result.add(buildColumnProjection(columnSegment));
-            }
-        }
-        return result;
-    }
-    
-    private ColumnProjection buildColumnProjection(final ColumnSegment 
segment) {
-        String owner = segment.getOwner().map(optional -> 
optional.getIdentifier().getValue()).orElse(null);
-        return new ColumnProjection(owner, segment.getIdentifier().getValue(), 
null);
-    }
-    
-    private Collection<ColumnProjection> buildColumnProjections(final String 
columnName) {
+    private Collection<ColumnProjection> createColumnProjections(final String 
columnName) {
         return Collections.singletonList(new ColumnProjection(null, 
columnName, null));
     }
-    
-    private Optional<String> findTableName(final Map<String, String> 
columnTableNames, final ColumnProjection column) {
-        return 
Optional.ofNullable(columnTableNames.get(column.getExpression()));
-    }
 }
diff --git 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
index 05de85c..dd8f21a 100644
--- 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
+++ 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
@@ -137,7 +137,7 @@ public final class EncryptProjectionTokenGenerator 
implements CollectionSQLToken
                 columns.addAll(((ShorthandProjection) 
projection).getActualColumns().values());
             }
         }
-        return 
selectStatementContext.getTablesContext().findTableName(columns, schema);
+        return 
selectStatementContext.getTablesContext().findTableNamesByColumnProjection(columns,
 schema);
     }
     
     private Collection<SelectStatementContext> 
getSelectStatementContexts(final SelectStatementContext selectStatementContext) 
{
diff --git 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaDataTest.java
 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaDataTest.java
index e30acb4..d5b1d4f 100644
--- 
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaDataTest.java
+++ 
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaDataTest.java
@@ -89,7 +89,7 @@ public final class EncryptAlgorithmMetaDataTest {
     public void assertFindEncryptContextByMetaData() {
         Map<String, String> columnTableNames = new HashMap<>();
         columnTableNames.put(columnProjection.getExpression(), "t_order");
-        
when(tablesContext.findTableName(Collections.singletonList(columnProjection), 
schema)).thenReturn(columnTableNames);
+        
when(tablesContext.findTableNamesByColumnProjection(Collections.singletonList(columnProjection),
 schema)).thenReturn(columnTableNames);
         EncryptAlgorithmMetaData encryptAlgorithmMetaData = new 
EncryptAlgorithmMetaData(DefaultSchema.LOGIC_NAME, schema, encryptRule, 
selectStatementContext);
         Optional<EncryptContext> actual = 
encryptAlgorithmMetaData.findEncryptContext(1);
         assertTrue(actual.isPresent());
@@ -100,7 +100,7 @@ public final class EncryptAlgorithmMetaDataTest {
     
     @Test
     public void assertFindEncryptContextByStatementContext() {
-        
when(tablesContext.findTableName(Collections.singletonList(columnProjection), 
schema)).thenReturn(Collections.emptyMap());
+        
when(tablesContext.findTableNamesByColumnProjection(Collections.singletonList(columnProjection),
 schema)).thenReturn(Collections.emptyMap());
         when(tablesContext.getTableNames()).thenReturn(Arrays.asList("t_user", 
"t_user_item", "t_order_item"));
         when(encryptRule.findEncryptor("t_order_item", 
"id")).thenReturn(Optional.of(encryptAlgorithm));
         EncryptAlgorithmMetaData encryptAlgorithmMetaData = new 
EncryptAlgorithmMetaData(DefaultSchema.LOGIC_NAME, schema, encryptRule, 
selectStatementContext);
diff --git 
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/impl/WhereClauseShardingConditionEngine.java
 
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/impl/WhereClauseShardingConditionEngine.java
index ad2fc87..38a7c04 100644
--- 
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/impl/WhereClauseShardingConditionEngine.java
+++ 
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/impl/WhereClauseShardingConditionEngine.java
@@ -19,7 +19,6 @@ package 
org.apache.shardingsphere.sharding.route.engine.condition.engine.impl;
 
 import com.google.common.collect.Range;
 import lombok.RequiredArgsConstructor;
-import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.binder.type.WhereAvailable;
 import org.apache.shardingsphere.infra.exception.ShardingSphereException;
@@ -67,19 +66,20 @@ public final class WhereClauseShardingConditionEngine 
implements ShardingConditi
         if (!(sqlStatementContext instanceof WhereAvailable)) {
             return Collections.emptyList();
         }
+        Collection<ColumnSegment> columnSegments = ((WhereAvailable) 
sqlStatementContext).getColumnSegments();
+        Map<String, String> columnExpressionTableNames = 
sqlStatementContext.getTablesContext().findTableNamesByColumnSegment(columnSegments,
 schema);
         List<ShardingCondition> result = new ArrayList<>();
         for (WhereSegment each : ((WhereAvailable) 
sqlStatementContext).getWhereSegments()) {
-            result.addAll(createShardingConditions(sqlStatementContext, 
each.getExpr(), parameters));
+            result.addAll(createShardingConditions(each.getExpr(), parameters, 
columnExpressionTableNames));
         }
         return result;
     }
     
-    private Collection<ShardingCondition> createShardingConditions(final 
SQLStatementContext<?> sqlStatementContext, final ExpressionSegment expression, 
final List<Object> parameters) {
+    private Collection<ShardingCondition> createShardingConditions(final 
ExpressionSegment expression, final List<Object> parameters, final Map<String, 
String> columnExpressionTableNames) {
         Collection<AndPredicate> andPredicates = 
ExpressionExtractUtil.getAndPredicates(expression);
-        Map<String, String> columnTableNames = 
getColumnTableNames(sqlStatementContext, andPredicates);
         Collection<ShardingCondition> result = new LinkedList<>();
         for (AndPredicate each : andPredicates) {
-            Map<Column, Collection<ShardingConditionValue>> 
shardingConditionValues = createShardingConditionValueMap(each.getPredicates(), 
parameters, columnTableNames);
+            Map<Column, Collection<ShardingConditionValue>> 
shardingConditionValues = createShardingConditionValueMap(each.getPredicates(), 
parameters, columnExpressionTableNames);
             if (shardingConditionValues.isEmpty()) {
                 return Collections.emptyList();
             }
@@ -91,37 +91,12 @@ public final class WhereClauseShardingConditionEngine 
implements ShardingConditi
         return result;
     }
     
-    private Map<String, String> getColumnTableNames(final 
SQLStatementContext<?> sqlStatementContext, final Collection<AndPredicate> 
andPredicates) {
-        Collection<ColumnProjection> result = new LinkedList<>();
-        for (AndPredicate each : andPredicates) {
-            for (ExpressionSegment expression : each.getPredicates()) {
-                result.addAll(createColumnProjections(expression));
-            }
-        }
-        return sqlStatementContext.getTablesContext().findTableName(result, 
schema);
-    }
-    
-    private Collection<ColumnProjection> createColumnProjections(final 
ExpressionSegment expression) {
-        Collection<ColumnProjection> result = new LinkedList<>();
-        for (ColumnSegment each : ColumnExtractor.extract(expression)) {
-            ColumnProjection columnProjection = buildColumnProjection(each);
-            result.add(columnProjection);
-        }
-        return result;
-    }
-    
-    private ColumnProjection buildColumnProjection(final ColumnSegment 
segment) {
-        String owner = segment.getOwner().map(optional -> 
optional.getIdentifier().getValue()).orElse(null);
-        return new ColumnProjection(owner, segment.getIdentifier().getValue(), 
null);
-    }
-    
     private Map<Column, Collection<ShardingConditionValue>> 
createShardingConditionValueMap(final Collection<ExpressionSegment> predicates, 
                                                                                
             final List<Object> parameters, final Map<String, String> 
columnTableNames) {
         Map<Column, Collection<ShardingConditionValue>> result = new 
HashMap<>(predicates.size(), 1);
         for (ExpressionSegment each : predicates) {
             for (ColumnSegment columnSegment : ColumnExtractor.extract(each)) {
-                ColumnProjection projection = 
buildColumnProjection(columnSegment);
-                Optional<String> tableName = 
Optional.ofNullable(columnTableNames.get(projection.getExpression()));
+                Optional<String> tableName = 
Optional.ofNullable(columnTableNames.get(columnSegment.getExpression()));
                 Optional<String> shardingColumn = tableName.flatMap(optional 
-> shardingRule.findShardingColumn(columnSegment.getIdentifier().getValue(), 
optional));
                 if (!tableName.isPresent() || !shardingColumn.isPresent()) {
                     continue;
diff --git 
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java
 
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java
index e3d1a45..6ed3731 100644
--- 
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java
+++ 
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java
@@ -20,7 +20,6 @@ package org.apache.shardingsphere.sharding.rule;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Splitter;
 import lombok.Getter;
-import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
 import 
org.apache.shardingsphere.infra.config.algorithm.ShardingSphereAlgorithmFactory;
@@ -638,11 +637,11 @@ public final class ShardingRule implements SchemaRule, 
DataNodeContainedRule, Ta
             if (!isJoinConditionExpression(each)) {
                 continue;
             }
-            ColumnProjection leftColumn = 
buildColumnProjection((ColumnSegment) ((BinaryOperationExpression) 
each).getLeft());
-            ColumnProjection rightColumn = 
buildColumnProjection((ColumnSegment) ((BinaryOperationExpression) 
each).getRight());
-            Map<String, String> columnTableNames = 
select.getTablesContext().findTableName(Arrays.asList(leftColumn, rightColumn), 
schema);
-            Optional<TableRule> leftTableRule = 
findTableRule(columnTableNames.get(leftColumn.getExpression()));
-            Optional<TableRule> rightTableRule = 
findTableRule(columnTableNames.get(rightColumn.getExpression()));
+            ColumnSegment leftColumn = (ColumnSegment) 
((BinaryOperationExpression) each).getLeft();
+            ColumnSegment rightColumn = (ColumnSegment) 
((BinaryOperationExpression) each).getRight();
+            Map<String, String> columnExpressionTableNames = 
select.getTablesContext().findTableNamesByColumnSegment(Arrays.asList(leftColumn,
 rightColumn), schema);
+            Optional<TableRule> leftTableRule = 
findTableRule(columnExpressionTableNames.get(leftColumn.getExpression()));
+            Optional<TableRule> rightTableRule = 
findTableRule(columnExpressionTableNames.get(rightColumn.getExpression()));
             if (!leftTableRule.isPresent() || !rightTableRule.isPresent()) {
                 continue;
             }
@@ -650,19 +649,15 @@ public final class ShardingRule implements SchemaRule, 
DataNodeContainedRule, Ta
                     ? 
getDatabaseShardingStrategyConfiguration(leftTableRule.get()) : 
getTableShardingStrategyConfiguration(leftTableRule.get());
             ShardingStrategyConfiguration rightConfiguration = 
isDatabaseJoinCondition
                     ? 
getDatabaseShardingStrategyConfiguration(rightTableRule.get()) : 
getTableShardingStrategyConfiguration(rightTableRule.get());
-            if (findShardingColumn(leftConfiguration, 
leftColumn.getName()).isPresent() && findShardingColumn(rightConfiguration, 
rightColumn.getName()).isPresent()) {
-                result.add(columnTableNames.get(leftColumn.getExpression()));
-                result.add(columnTableNames.get(rightColumn.getExpression()));
+            if (findShardingColumn(leftConfiguration, 
leftColumn.getIdentifier().getValue()).isPresent() 
+                    && findShardingColumn(rightConfiguration, 
rightColumn.getIdentifier().getValue()).isPresent()) {
+                
result.add(columnExpressionTableNames.get(leftColumn.getExpression()));
+                
result.add(columnExpressionTableNames.get(rightColumn.getExpression()));
             }
         }
         return result;
     }
     
-    private ColumnProjection buildColumnProjection(final ColumnSegment 
segment) {
-        String owner = segment.getOwner().map(optional -> 
optional.getIdentifier().getValue()).orElse(null);
-        return new ColumnProjection(owner, segment.getIdentifier().getValue(), 
null);
-    }
-    
     private boolean isJoinConditionExpression(final ExpressionSegment 
expression) {
         if (!(expression instanceof BinaryOperationExpression)) {
             return false;
diff --git 
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/rule/ShardingRuleTest.java
 
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/rule/ShardingRuleTest.java
index eb3850b..e05210e 100644
--- 
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/rule/ShardingRuleTest.java
+++ 
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/rule/ShardingRuleTest.java
@@ -17,7 +17,6 @@
 
 package org.apache.shardingsphere.sharding.rule;
 
-import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
 import org.apache.shardingsphere.infra.binder.segment.table.TablesContext;
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
@@ -484,8 +483,7 @@ public final class ShardingRuleTest {
         
when(sqlStatementContext.getSqlStatement()).thenReturn(selectStatement);
         when(sqlStatementContext.isContainsJoinQuery()).thenReturn(true);
         ShardingSphereSchema schema = mock(ShardingSphereSchema.class);
-        
when(sqlStatementContext.getTablesContext().findTableName(Arrays.asList(buildColumnProjection(leftDatabaseJoin),
 
-                buildColumnProjection(rightDatabaseJoin)), 
schema)).thenReturn(createColumnTableNameMap());
+        
when(sqlStatementContext.getTablesContext().findTableNamesByColumnSegment(Arrays.asList(leftDatabaseJoin,
 rightDatabaseJoin), schema)).thenReturn(createColumnTableNameMap());
         assertFalse(createMaximumShardingRule().isAllBindingTables(schema, 
sqlStatementContext, Arrays.asList("logic_Table", "sub_Logic_Table")));
     }
     
@@ -505,7 +503,7 @@ public final class ShardingRuleTest {
                 new SimpleTableSegment(new TableNameSegment(0, 0, new 
IdentifierValue("LOGIC_TABLE"))),
                 new SimpleTableSegment(new TableNameSegment(0, 0, new 
IdentifierValue("SUB_LOGIC_TABLE")))
         );
-        TablesContext tablesContext = new TablesContext(tableSegments, 
Collections.EMPTY_MAP);
+        TablesContext tablesContext = new TablesContext(tableSegments, 
Collections.emptyMap());
         when(sqlStatementContext.getTablesContext()).thenReturn(tablesContext);
         ShardingSphereSchema schema = mock(ShardingSphereSchema.class);
         
when(schema.getAllColumnNames("LOGIC_TABLE")).thenReturn(Arrays.asList("user_id",
 "order_id"));
@@ -530,10 +528,8 @@ public final class ShardingRuleTest {
         
when(sqlStatementContext.getSqlStatement()).thenReturn(selectStatement);
         when(sqlStatementContext.isContainsJoinQuery()).thenReturn(true);
         ShardingSphereSchema schema = mock(ShardingSphereSchema.class);
-        
when(sqlStatementContext.getTablesContext().findTableName(Arrays.asList(buildColumnProjection(leftDatabaseJoin),
 
-                buildColumnProjection(rightDatabaseJoin)), 
schema)).thenReturn(createColumnTableNameMap());
-        
when(sqlStatementContext.getTablesContext().findTableName(Arrays.asList(buildColumnProjection(leftTableJoin),
 
-                buildColumnProjection(rightTableJoin)), 
schema)).thenReturn(createColumnTableNameMap());
+        
when(sqlStatementContext.getTablesContext().findTableNamesByColumnSegment(Arrays.asList(leftDatabaseJoin,
 rightDatabaseJoin), schema)).thenReturn(createColumnTableNameMap());
+        
when(sqlStatementContext.getTablesContext().findTableNamesByColumnSegment(Arrays.asList(leftTableJoin,
 rightTableJoin), schema)).thenReturn(createColumnTableNameMap());
         assertTrue(createMaximumShardingRule().isAllBindingTables(schema, 
sqlStatementContext, Arrays.asList("logic_Table", "sub_Logic_Table")));
     }
     
@@ -560,7 +556,9 @@ public final class ShardingRuleTest {
     
     private ColumnSegment createColumnSegment(final String columnName, final 
String owner) {
         ColumnSegment result = new ColumnSegment(0, 0, new 
IdentifierValue(columnName));
-        result.setOwner(new OwnerSegment(0, 0, new IdentifierValue(owner)));
+        if (null != owner) {
+            result.setOwner(new OwnerSegment(0, 0, new 
IdentifierValue(owner)));
+        }
         return result;
     }
     
@@ -573,11 +571,6 @@ public final class ShardingRuleTest {
         return result;
     }
     
-    private ColumnProjection buildColumnProjection(final ColumnSegment 
segment) {
-        String owner = segment.getOwner().map(optional -> 
optional.getIdentifier().getValue()).orElse(null);
-        return new ColumnProjection(owner, segment.getIdentifier().getValue(), 
null);
-    }
-    
     @Test
     public void assertGetLogicTablesByActualTable() {
         
assertThat(createShardingRuleWithSameActualTablesButDifferentLogicTables().getLogicTablesByActualTable("table_0"),
diff --git 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/table/TablesContext.java
 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/table/TablesContext.java
index c76bbbd..26615ed 100644
--- 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/table/TablesContext.java
+++ 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/table/TablesContext.java
@@ -25,9 +25,12 @@ import 
org.apache.shardingsphere.infra.binder.segment.select.subquery.SubqueryTa
 import 
org.apache.shardingsphere.infra.binder.segment.select.subquery.engine.SubqueryTableContextEngine;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
 import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SubqueryTableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -102,13 +105,13 @@ public final class TablesContext {
     }
     
     /**
-     * Find table name.
+     * Find expression table name map by column segment.
      *
-     * @param columns column projection collection
+     * @param columns column segment collection
      * @param schema schema meta data
-     * @return table name map
+     * @return expression table name map
      */
-    public Map<String, String> findTableName(final 
Collection<ColumnProjection> columns, final ShardingSphereSchema schema) {
+    public Map<String, String> findTableNamesByColumnSegment(final 
Collection<ColumnSegment> columns, final ShardingSphereSchema schema) {
         if (1 == tables.size()) {
             return findTableNameFromSingleTable(columns);
         }
@@ -119,18 +122,46 @@ public final class TablesContext {
         return result;
     }
     
-    private Map<String, String> findTableNameFromSubquery(final 
Collection<ColumnProjection> columns, final Map<String, String> 
ownerTableNames) {
+    /**
+     * Find expression table name map by column projection.
+     *
+     * @param columns column segment collection
+     * @param schema schema meta data
+     * @return expression table name map
+     */
+    public Map<String, String> findTableNamesByColumnProjection(final 
Collection<ColumnProjection> columns, final ShardingSphereSchema schema) {
+        Collection<ColumnSegment> result = new LinkedList<>();
+        for (ColumnProjection each : columns) {
+            ColumnSegment columnSegment = new ColumnSegment(0, 0, new 
IdentifierValue(each.getName()));
+            if (null != each.getOwner()) {
+                columnSegment.setOwner(new OwnerSegment(0, 0, new 
IdentifierValue(each.getOwner())));
+            }
+            result.add(columnSegment);
+        }
+        return findTableNamesByColumnSegment(result, schema);
+    }
+    
+    private ColumnSegment createColumnSegment(final ColumnProjection 
projection) {
+        ColumnSegment result = new ColumnSegment(0, 0, new 
IdentifierValue(projection.getName()));
+        if (null != projection.getOwner()) {
+            result.setOwner(new OwnerSegment(0, 0, new 
IdentifierValue(projection.getOwner())));
+        }
+        return result;
+    }
+    
+    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(), 1);
-        for (ColumnProjection each : columns) {
+        for (ColumnSegment each : columns) {
             if (ownerTableNames.containsKey(each.getExpression())) {
                 continue;
             }
-            Collection<SubqueryTableContext> subqueryTableContexts = 
subqueryTables.getOrDefault(each.getOwner(), Collections.emptyList());
+            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.getName())) {
+                if 
(subqueryTableContext.getColumnNames().contains(each.getIdentifier().getValue()))
 {
                     result.put(each.getExpression(), 
subqueryTableContext.getTableName());
                 }
             }
@@ -138,27 +169,27 @@ public final class TablesContext {
         return result;
     }
     
-    private Map<String, String> findTableNameFromSingleTable(final 
Collection<ColumnProjection> columns) {
+    private Map<String, String> findTableNameFromSingleTable(final 
Collection<ColumnSegment> columns) {
         String tableName = 
tables.iterator().next().getTableName().getIdentifier().getValue();
         Map<String, String> result = new 
TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-        for (ColumnProjection each : columns) {
+        for (ColumnSegment each : columns) {
             result.putIfAbsent(each.getExpression(), tableName);
         }
         return result;
     }
     
-    private Map<String, Collection<String>> getOwnerColumnNames(final 
Collection<ColumnProjection> columns) {
+    private Map<String, Collection<String>> getOwnerColumnNames(final 
Collection<ColumnSegment> columns) {
         Map<String, Collection<String>> result = new 
TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-        for (ColumnProjection each : columns) {
-            if (null == each.getOwner()) {
+        for (ColumnSegment each : columns) {
+            if (!each.getOwner().isPresent()) {
                 continue;
             }
-            result.computeIfAbsent(each.getOwner(), unused -> new 
LinkedList<>()).add(each.getExpression());
+            
result.computeIfAbsent(each.getOwner().get().getIdentifier().getValue(), unused 
-> new LinkedList<>()).add(each.getExpression());
         }
         return result;
     }
     
-    private Map<String, String> findTableNameFromSQL(final 
Collection<ColumnProjection> columns) {
+    private Map<String, String> findTableNameFromSQL(final 
Collection<ColumnSegment> columns) {
         Map<String, Collection<String>> ownerColumnNames = 
getOwnerColumnNames(columns);
         if (ownerColumnNames.isEmpty()) {
             return Collections.emptyMap();
@@ -177,7 +208,7 @@ public final class TablesContext {
         return result;
     }
     
-    private Map<String, String> findTableNameFromMetaData(final 
Collection<ColumnProjection> columns, final ShardingSphereSchema schema) {
+    private Map<String, String> findTableNameFromMetaData(final 
Collection<ColumnSegment> columns, final ShardingSphereSchema schema) {
         Collection<String> noOwnerColumnNames = getNoOwnerColumnNames(columns);
         if (noOwnerColumnNames.isEmpty()) {
             return Collections.emptyMap();
@@ -194,11 +225,11 @@ public final class TablesContext {
         return result;
     }
     
-    private Collection<String> getNoOwnerColumnNames(final 
Collection<ColumnProjection> columns) {
+    private Collection<String> getNoOwnerColumnNames(final 
Collection<ColumnSegment> columns) {
         Collection<String> result = new 
TreeSet<>(String.CASE_INSENSITIVE_ORDER);
-        for (ColumnProjection each : columns) {
-            if (null == each.getOwner()) {
-                result.add(each.getName());
+        for (ColumnSegment each : columns) {
+            if (!each.getOwner().isPresent()) {
+                result.add(each.getIdentifier().getValue());
             }
         }
         return result;
diff --git 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/DeleteStatementContext.java
 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/DeleteStatementContext.java
index 685c997..6aa4aff 100644
--- 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/DeleteStatementContext.java
+++ 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/DeleteStatementContext.java
@@ -23,9 +23,11 @@ import 
org.apache.shardingsphere.infra.binder.statement.CommonSQLStatementContex
 import org.apache.shardingsphere.infra.binder.type.TableAvailable;
 import org.apache.shardingsphere.infra.binder.type.WhereAvailable;
 import 
org.apache.shardingsphere.sql.parser.sql.common.extractor.TableExtractor;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.WhereSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.DeleteStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.util.ColumnExtractor;
 
 import java.util.Collection;
 import java.util.HashMap;
@@ -42,10 +44,13 @@ public final class DeleteStatementContext extends 
CommonSQLStatementContext<Dele
     
     private final Collection<WhereSegment> whereSegments = new LinkedList<>();
     
+    private final Collection<ColumnSegment> columnSegments = new 
LinkedList<>();
+    
     public DeleteStatementContext(final DeleteStatement sqlStatement) {
         super(sqlStatement);
         tablesContext = new TablesContext(getAllSimpleTableSegments());
         getSqlStatement().getWhere().ifPresent(whereSegments::add);
+        ColumnExtractor.extractColumnSegments(columnSegments, whereSegments);
     }
     
     private Collection<SimpleTableSegment> getAllSimpleTableSegments() {
@@ -78,4 +83,9 @@ public final class DeleteStatementContext extends 
CommonSQLStatementContext<Dele
     public Collection<WhereSegment> getWhereSegments() {
         return whereSegments;
     }
+    
+    @Override
+    public Collection<ColumnSegment> getColumnSegments() {
+        return columnSegments;
+    }
 }
diff --git 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
index 7b158e3..e60ce3f 100644
--- 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
+++ 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
@@ -45,6 +45,7 @@ import 
org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
 import 
org.apache.shardingsphere.sql.parser.sql.common.constant.ParameterMarkerType;
 import org.apache.shardingsphere.sql.parser.sql.common.constant.SubqueryType;
 import 
org.apache.shardingsphere.sql.parser.sql.common.extractor.TableExtractor;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment;
@@ -59,6 +60,7 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.Sim
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SubqueryTableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.util.ColumnExtractor;
 import 
org.apache.shardingsphere.sql.parser.sql.common.util.ExpressionExtractUtil;
 import org.apache.shardingsphere.sql.parser.sql.common.util.SQLUtil;
 import 
org.apache.shardingsphere.sql.parser.sql.common.util.SubqueryExtractUtil;
@@ -91,6 +93,8 @@ public final class SelectStatementContext extends 
CommonSQLStatementContext<Sele
     
     private final Collection<WhereSegment> whereSegments = new LinkedList<>();
     
+    private final Collection<ColumnSegment> columnSegments = new 
LinkedList<>();
+    
     private SubqueryType subqueryType;
     
     private boolean needAggregateRewrite;
@@ -100,7 +104,8 @@ public final class SelectStatementContext extends 
CommonSQLStatementContext<Sele
     public SelectStatementContext(final Map<String, ShardingSphereMetaData> 
metaDataMap, final List<Object> parameters,
                                   final SelectStatement sqlStatement, final 
String defaultSchemaName) {
         super(sqlStatement);
-        whereSegments.addAll(getWhereSegments(sqlStatement));
+        extractWhereSegments(whereSegments, sqlStatement);
+        ColumnExtractor.extractColumnSegments(columnSegments, whereSegments);
         subqueryContexts = createSubqueryContexts(metaDataMap, parameters, 
defaultSchemaName);
         tablesContext = new TablesContext(getAllTableSegments(), 
subqueryContexts);
         ShardingSphereSchema schema = getSchema(metaDataMap, 
defaultSchemaName);
@@ -300,12 +305,15 @@ public final class SelectStatementContext extends 
CommonSQLStatementContext<Sele
         return whereSegments;
     }
     
-    private Collection<WhereSegment> getWhereSegments(final SelectStatement 
selectStatement) {
-        Collection<WhereSegment> result = new LinkedList<>();
-        selectStatement.getWhere().ifPresent(result::add);
-        
result.addAll(WhereExtractUtil.getSubqueryWhereSegments(selectStatement));
-        result.addAll(WhereExtractUtil.getJoinWhereSegments(selectStatement));
-        return result;
+    @Override
+    public Collection<ColumnSegment> getColumnSegments() {
+        return columnSegments;
+    }
+    
+    private void extractWhereSegments(final Collection<WhereSegment> 
whereSegments, final SelectStatement selectStatement) {
+        selectStatement.getWhere().ifPresent(whereSegments::add);
+        
whereSegments.addAll(WhereExtractUtil.getSubqueryWhereSegments(selectStatement));
+        
whereSegments.addAll(WhereExtractUtil.getJoinWhereSegments(selectStatement));
     }
     
     private Collection<TableSegment> getAllTableSegments() {
diff --git 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/UpdateStatementContext.java
 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/UpdateStatementContext.java
index 6074d09..1c472ae 100644
--- 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/UpdateStatementContext.java
+++ 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/UpdateStatementContext.java
@@ -23,9 +23,11 @@ import 
org.apache.shardingsphere.infra.binder.statement.CommonSQLStatementContex
 import org.apache.shardingsphere.infra.binder.type.TableAvailable;
 import org.apache.shardingsphere.infra.binder.type.WhereAvailable;
 import 
org.apache.shardingsphere.sql.parser.sql.common.extractor.TableExtractor;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.WhereSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.UpdateStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.util.ColumnExtractor;
 
 import java.util.Collection;
 import java.util.LinkedList;
@@ -40,10 +42,13 @@ public final class UpdateStatementContext extends 
CommonSQLStatementContext<Upda
     
     private final Collection<WhereSegment> whereSegments = new LinkedList<>();
     
+    private final Collection<ColumnSegment> columnSegments = new 
LinkedList<>();
+    
     public UpdateStatementContext(final UpdateStatement sqlStatement) {
         super(sqlStatement);
         tablesContext = new TablesContext(getAllSimpleTableSegments());
         getSqlStatement().getWhere().ifPresent(whereSegments::add);
+        ColumnExtractor.extractColumnSegments(columnSegments, whereSegments);
     }
     
     private Collection<SimpleTableSegment> getAllSimpleTableSegments() {
@@ -61,4 +66,9 @@ public final class UpdateStatementContext extends 
CommonSQLStatementContext<Upda
     public Collection<WhereSegment> getWhereSegments() {
         return whereSegments;
     }
+    
+    @Override
+    public Collection<ColumnSegment> getColumnSegments() {
+        return columnSegments;
+    }
 }
diff --git 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/type/WhereAvailable.java
 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/type/WhereAvailable.java
index 79c6f93..f4de8d6 100644
--- 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/type/WhereAvailable.java
+++ 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/type/WhereAvailable.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.infra.binder.type;
 
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.WhereSegment;
 
 import java.util.Collection;
@@ -32,4 +33,11 @@ public interface WhereAvailable {
      * @return where segments
      */
     Collection<WhereSegment> getWhereSegments();
+    
+    /**
+     * Get column segments.
+     *
+     * @return column segments
+     */
+    Collection<ColumnSegment> getColumnSegments();
 }
diff --git 
a/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/table/TablesContextTest.java
 
b/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/table/TablesContextTest.java
index fd8f004..cbd1a62 100644
--- 
a/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/table/TablesContextTest.java
+++ 
b/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/table/TablesContextTest.java
@@ -18,10 +18,10 @@
 package org.apache.shardingsphere.infra.binder.segment.table;
 
 import com.google.common.collect.Sets;
-import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
 import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.metadata.schema.model.ColumnMetaData;
 import org.apache.shardingsphere.infra.metadata.schema.model.TableMetaData;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.AliasSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
@@ -60,8 +60,9 @@ public final class TablesContextTest {
     @Test
     public void assertFindTableNameWhenSingleTable() {
         SimpleTableSegment tableSegment = createTableSegment("table_1", 
"tbl_1");
-        ColumnProjection columnProjection = createColumnProjection(null, 
"col", null);
-        Map<String, String> actual = new 
TablesContext(Collections.singletonList(tableSegment)).findTableName(Collections.singletonList(columnProjection),
 mock(ShardingSphereSchema.class));
+        ColumnSegment columnSegment = createColumnSegment(null, "col");
+        Map<String, String> actual = new 
TablesContext(Collections.singletonList(tableSegment))
+                
.findTableNamesByColumnSegment(Collections.singletonList(columnSegment), 
mock(ShardingSphereSchema.class));
         assertFalse(actual.isEmpty());
         assertThat(actual.get("col"), is("table_1"));
     }
@@ -70,8 +71,9 @@ public final class TablesContextTest {
     public void assertFindTableNameWhenColumnSegmentOwnerPresent() {
         SimpleTableSegment tableSegment1 = createTableSegment("table_1", 
"tbl_1");
         SimpleTableSegment tableSegment2 = createTableSegment("table_2", 
"tbl_2");
-        ColumnProjection columnProjection = createColumnProjection("table_1", 
"col", "");
-        Map<String, String> actual = new 
TablesContext(Arrays.asList(tableSegment1, 
tableSegment2)).findTableName(Collections.singletonList(columnProjection), 
mock(ShardingSphereSchema.class));
+        ColumnSegment columnSegment = createColumnSegment("table_1", "col");
+        Map<String, String> actual = new 
TablesContext(Arrays.asList(tableSegment1, tableSegment2))
+                
.findTableNamesByColumnSegment(Collections.singletonList(columnSegment), 
mock(ShardingSphereSchema.class));
         assertFalse(actual.isEmpty());
         assertThat(actual.get("table_1.col"), is("table_1"));
     }
@@ -80,8 +82,9 @@ public final class TablesContextTest {
     public void assertFindTableNameWhenColumnSegmentOwnerAbsent() {
         SimpleTableSegment tableSegment1 = createTableSegment("table_1", 
"tbl_1");
         SimpleTableSegment tableSegment2 = createTableSegment("table_2", 
"tbl_2");
-        ColumnProjection columnProjection = createColumnProjection(null, 
"col", null);
-        Map<String, String> actual = new 
TablesContext(Arrays.asList(tableSegment1, 
tableSegment2)).findTableName(Collections.singletonList(columnProjection), 
mock(ShardingSphereSchema.class));
+        ColumnSegment columnSegment = createColumnSegment(null, "col");
+        Map<String, String> actual = new 
TablesContext(Arrays.asList(tableSegment1, tableSegment2))
+                
.findTableNamesByColumnSegment(Collections.singletonList(columnSegment), 
mock(ShardingSphereSchema.class));
         assertTrue(actual.isEmpty());
     }
     
@@ -91,8 +94,8 @@ public final class TablesContextTest {
         SimpleTableSegment tableSegment2 = createTableSegment("table_2", 
"tbl_2");
         ShardingSphereSchema schema = mock(ShardingSphereSchema.class);
         
when(schema.getAllColumnNames("table_1")).thenReturn(Collections.singletonList("col"));
-        ColumnProjection columnProjection = createColumnProjection(null, 
"col", null);
-        Map<String, String> actual = new 
TablesContext(Arrays.asList(tableSegment1, 
tableSegment2)).findTableName(Collections.singletonList(columnProjection), 
schema);
+        ColumnSegment columnSegment = createColumnSegment(null, "col");
+        Map<String, String> actual = new 
TablesContext(Arrays.asList(tableSegment1, 
tableSegment2)).findTableNamesByColumnSegment(Collections.singletonList(columnSegment),
 schema);
         assertFalse(actual.isEmpty());
         assertThat(actual.get("col"), is("table_1"));
     }
@@ -105,8 +108,8 @@ public final class TablesContextTest {
                 Arrays.asList(new ColumnMetaData("COL", 0, false, false, 
true)),
                 Collections.EMPTY_LIST);
         ShardingSphereSchema schema = new 
ShardingSphereSchema(Arrays.asList(tableMetaData).stream().collect(Collectors.toMap(TableMetaData::getName,
 v -> v)));
-        ColumnProjection columnProjection = createColumnProjection(null, 
"COL", null);
-        Map<String, String> actual = new 
TablesContext(Arrays.asList(tableSegment1, 
tableSegment2)).findTableName(Collections.singletonList(columnProjection), 
schema);
+        ColumnSegment columnSegment = createColumnSegment(null, "COL");
+        Map<String, String> actual = new 
TablesContext(Arrays.asList(tableSegment1, 
tableSegment2)).findTableNamesByColumnSegment(Collections.singletonList(columnSegment),
 schema);
         assertFalse(actual.isEmpty());
         assertThat(actual.get("col"), is("TABLE_1"));
     }
@@ -118,8 +121,12 @@ public final class TablesContextTest {
         return result;
     }
     
-    private ColumnProjection createColumnProjection(final String owner, final 
String name, final String alias) {
-        return new ColumnProjection(owner, name, alias);
+    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
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/column/ColumnSegment.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/column/ColumnSegment.java
index fecf406..c2c2bee 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/column/ColumnSegment.java
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/column/ColumnSegment.java
@@ -57,6 +57,15 @@ public final class ColumnSegment implements 
ExpressionSegment, OwnerAvailable {
             : String.join(".", 
owner.getIdentifier().getValueWithQuoteCharacters(), 
identifier.getValueWithQuoteCharacters());
     }
     
+    /**
+     * Get expression.
+     * 
+     * @return expression
+     */
+    public String getExpression() {
+        return null == owner ? identifier.getValue() : 
owner.getIdentifier().getValue() + "." + identifier.getValue();
+    }
+    
     @Override
     public Optional<OwnerSegment> getOwner() {
         return Optional.ofNullable(owner);
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/ColumnExtractor.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/ColumnExtractor.java
index 1acfaa9..4ff6313 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/ColumnExtractor.java
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/ColumnExtractor.java
@@ -24,6 +24,8 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BetweenE
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.InExpression;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.AndPredicate;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.WhereSegment;
 
 import java.util.Collection;
 import java.util.LinkedList;
@@ -58,4 +60,24 @@ public final class ColumnExtractor {
         }
         return result;
     }
+    
+    /**
+     * Extract column segments.
+     *
+     * @param columnSegments column segments
+     * @param whereSegments where segments
+     */
+    public static void extractColumnSegments(final Collection<ColumnSegment> 
columnSegments, final Collection<WhereSegment> whereSegments) {
+        for (WhereSegment each : whereSegments) {
+            for (AndPredicate andPredicate : 
ExpressionExtractUtil.getAndPredicates(each.getExpr())) {
+                extractColumnSegments(columnSegments, andPredicate);
+            }
+        }
+    }
+    
+    private static void extractColumnSegments(final Collection<ColumnSegment> 
columnSegments, final AndPredicate andPredicate) {
+        for (ExpressionSegment each : andPredicate.getPredicates()) {
+            columnSegments.addAll(ColumnExtractor.extract(each));
+        }
+    }
 }

Reply via email to