You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by pa...@apache.org on 2021/07/14 11:44:50 UTC

[shardingsphere] branch master updated: fix sql rewrite error when integrate sharding and encrypt (#11334)

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 3b2a730  fix sql rewrite error when integrate sharding and encrypt (#11334)
3b2a730 is described below

commit 3b2a730cf7e80acda2af56d684f963d37d9c63f1
Author: Zhengqiang Duan <st...@gmail.com>
AuthorDate: Wed Jul 14 19:44:23 2021 +0800

    fix sql rewrite error when integrate sharding and encrypt (#11334)
    
    * fix sql rewrite error when integrate sharding and encrypt
    
    * fix test case
---
 .../impl/EncryptCreateTableTokenGenerator.java     | 14 ++--
 .../impl/EncryptPredicateColumnTokenGenerator.java | 21 ++++--
 .../impl/EncryptProjectionTokenGenerator.java      | 22 +++---
 .../impl/InsertCipherNameTokenGenerator.java       |  9 ++-
 .../infra/rewrite/context/SQLRewriteContext.java   |  6 +-
 .../pojo/generic/SubstitutableColumnNameToken.java | 63 ++++++++++++++---
 .../generic/SubstitutableColumnNameTokenTest.java  |  9 ++-
 .../segment/dml/item/ColumnProjectionSegment.java  |  6 +-
 .../main/resources/case/dml/select-expression.xml  |  2 +-
 .../main/resources/case/dml/select-group-by.xml    |  4 +-
 .../src/main/resources/case/dml/select-join.xml    |  6 +-
 .../main/resources/case/dml/select-order-by.xml    |  6 +-
 .../dml/select-pagination-group-by-order-by.xml    | 80 +++++++++++-----------
 .../main/resources/case/dml/select-pagination.xml  | 60 ++++++++--------
 .../src/main/resources/case/dml/select.xml         |  8 +--
 .../mix/case/select_for_query_with_cipher.xml      | 11 ++-
 .../mix/case/select_for_query_with_plain.xml       | 11 ++-
 17 files changed, 200 insertions(+), 138 deletions(-)

diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptCreateTableTokenGenerator.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptCreateTableTokenGenerator.java
index 9fa46ee..914f890 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptCreateTableTokenGenerator.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptCreateTableTokenGenerator.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
 import com.google.common.collect.Lists;
 import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
 import org.apache.shardingsphere.encrypt.spi.EncryptAlgorithm;
+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.ddl.CreateTableStatementContext;
 import org.apache.shardingsphere.infra.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
@@ -29,6 +30,7 @@ import org.apache.shardingsphere.infra.rewrite.sql.token.pojo.generic.Substituta
 import org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.column.ColumnDefinitionSegment;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Optional;
@@ -72,19 +74,23 @@ public final class EncryptCreateTableTokenGenerator extends BaseEncryptSQLTokenG
     }
     
     private SubstitutableColumnNameToken getCipherColumnToken(final String tableName, final String columnName, final ColumnDefinitionSegment column, final int stopIndex) {
-        String cipherColumn = getEncryptRule().getCipherColumn(tableName, columnName);
-        return new SubstitutableColumnNameToken(stopIndex + 1, column.getColumnName().getStopIndex(), cipherColumn);
+        return new SubstitutableColumnNameToken(stopIndex + 1, column.getColumnName().getStopIndex(), 
+                getColumnProjections(getEncryptRule().getCipherColumn(tableName, columnName)));
     }
     
     private Optional<SubstitutableColumnNameToken> getAssistedQueryColumnToken(final String tableName, final String columnName, final ColumnDefinitionSegment column, 
                                                                                final int stopIndex, final boolean lastColumn) {
         Optional<String> assistedQueryColumn = getEncryptRule().findAssistedQueryColumn(tableName, columnName);
-        return assistedQueryColumn.map(optional -> new SubstitutableColumnNameToken(stopIndex + 1, column.getColumnName().getStopIndex(), optional, lastColumn));
+        return assistedQueryColumn.map(optional -> new SubstitutableColumnNameToken(stopIndex + 1, column.getColumnName().getStopIndex(), getColumnProjections(optional), lastColumn));
     }
     
     private Optional<SubstitutableColumnNameToken> getPlainColumnToken(final String tableName, final String columnName, final ColumnDefinitionSegment column, 
                                                                        final int stopIndex, final boolean lastColumn) {
         Optional<String> plainColumn = getEncryptRule().findPlainColumn(tableName, columnName);
-        return plainColumn.map(optional -> new SubstitutableColumnNameToken(stopIndex + 1, column.getColumnName().getStopIndex(), optional, lastColumn));
+        return plainColumn.map(optional -> new SubstitutableColumnNameToken(stopIndex + 1, column.getColumnName().getStopIndex(), getColumnProjections(optional), lastColumn));
+    }
+    
+    private Collection<ColumnProjection> getColumnProjections(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/impl/EncryptPredicateColumnTokenGenerator.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptPredicateColumnTokenGenerator.java
index 69f0971..01925de 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptPredicateColumnTokenGenerator.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptPredicateColumnTokenGenerator.java
@@ -22,19 +22,21 @@ import lombok.Setter;
 import org.apache.shardingsphere.encrypt.rewrite.aware.QueryWithCipherColumnAware;
 import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
 import org.apache.shardingsphere.encrypt.rule.EncryptTable;
+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.metadata.schema.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
 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.infra.metadata.schema.ShardingSphereSchema;
-import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
-import org.apache.shardingsphere.infra.binder.type.WhereAvailable;
 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.util.ExpressionBuilder;
 import org.apache.shardingsphere.sql.parser.sql.common.util.ColumnExtractor;
+import org.apache.shardingsphere.sql.parser.sql.common.util.ExpressionBuilder;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.Optional;
@@ -83,13 +85,14 @@ public final class EncryptPredicateColumnTokenGenerator extends BaseEncryptSQLTo
             if (!queryWithCipherColumn) {
                 Optional<String> plainColumn = encryptTable.get().findPlainColumn(column.get().getIdentifier().getValue());
                 if (plainColumn.isPresent()) {
-                    result.add(new SubstitutableColumnNameToken(startIndex, stopIndex, plainColumn.get()));
+                    result.add(new SubstitutableColumnNameToken(startIndex, stopIndex, getColumnProjections(plainColumn.get())));
                     continue;
                 }
             }
             Optional<String> assistedQueryColumn = encryptTable.get().findAssistedQueryColumn(column.get().getIdentifier().getValue());
-            SubstitutableColumnNameToken encryptColumnNameToken = assistedQueryColumn.map(columnName -> new SubstitutableColumnNameToken(startIndex, stopIndex, columnName))
-                    .orElseGet(() -> new SubstitutableColumnNameToken(startIndex, stopIndex, encryptTable.get().getCipherColumn(column.get().getIdentifier().getValue())));
+            SubstitutableColumnNameToken encryptColumnNameToken = assistedQueryColumn.map(columnName 
+                -> new SubstitutableColumnNameToken(startIndex, stopIndex, getColumnProjections(columnName))).orElseGet(() 
+                    -> new SubstitutableColumnNameToken(startIndex, stopIndex, getColumnProjections(encryptTable.get().getCipherColumn(column.get().getIdentifier().getValue()))));
             result.add(encryptColumnNameToken);
         }
         return result;
@@ -98,4 +101,8 @@ public final class EncryptPredicateColumnTokenGenerator extends BaseEncryptSQLTo
     private Optional<EncryptTable> findEncryptTable(final SQLStatementContext sqlStatementContext, final ColumnSegment column) {
         return sqlStatementContext.getTablesContext().findTableName(column, schema).flatMap(tableName -> getEncryptRule().findEncryptTable(tableName));
     }
+    
+    private Collection<ColumnProjection> getColumnProjections(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/impl/EncryptProjectionTokenGenerator.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptProjectionTokenGenerator.java
index 054c6ff..957ffac 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptProjectionTokenGenerator.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptProjectionTokenGenerator.java
@@ -17,7 +17,6 @@
 
 package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
 
-import com.google.common.base.Joiner;
 import lombok.Setter;
 import org.apache.shardingsphere.encrypt.rewrite.aware.QueryWithCipherColumnAware;
 import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
@@ -31,7 +30,6 @@ import org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementConte
 import org.apache.shardingsphere.infra.database.type.DatabaseType;
 import org.apache.shardingsphere.infra.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
 import org.apache.shardingsphere.infra.rewrite.sql.token.pojo.generic.SubstitutableColumnNameToken;
-import org.apache.shardingsphere.sql.parser.sql.common.constant.QuoteCharacter;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ColumnProjectionSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionsSegment;
@@ -95,26 +93,24 @@ public final class EncryptProjectionTokenGenerator extends BaseEncryptSQLTokenGe
     
     private SubstitutableColumnNameToken generateSQLToken(final ColumnProjectionSegment segment, final String tableName) {
         String encryptColumnName = getEncryptColumnName(tableName, segment.getColumn().getIdentifier().getValue());
-        if (!segment.getAlias().isPresent()) {
-            encryptColumnName += " AS " + segment.getColumn().getIdentifier().getValue();
-        }
-        return segment.getColumn().getOwner().isPresent() ? new SubstitutableColumnNameToken(segment.getColumn().getOwner().get().getStopIndex() + 2, segment.getStopIndex(), encryptColumnName)
-                : new SubstitutableColumnNameToken(segment.getStartIndex(), segment.getStopIndex(), encryptColumnName);
+        String alias = segment.getAlias().orElse(segment.getColumn().getIdentifier().getValue());
+        Collection<ColumnProjection> projections = Collections.singletonList(new ColumnProjection(null, encryptColumnName, alias));
+        return segment.getColumn().getOwner().isPresent() 
+                ? new SubstitutableColumnNameToken(segment.getColumn().getOwner().get().getStopIndex() + 2, segment.getStopIndex(), projections) 
+                : new SubstitutableColumnNameToken(segment.getStartIndex(), segment.getStopIndex(), projections);
     }
     
     private SubstitutableColumnNameToken generateSQLToken(final ShorthandProjectionSegment segment,
                                                           final ShorthandProjection shorthandProjection, final String tableName, final EncryptTable encryptTable, final DatabaseType databaseType) {
-        QuoteCharacter quoteCharacter = databaseType.getQuoteCharacter();
-        List<String> shorthandExtensionProjections = new LinkedList<>();
+        List<ColumnProjection> projections = new LinkedList<>();
         for (ColumnProjection each : shorthandProjection.getActualColumns()) {
             if (encryptTable.getLogicColumns().contains(each.getName())) {
-                shorthandExtensionProjections.add(new ColumnProjection(null == each.getOwner() ? null : quoteCharacter.wrap(each.getOwner()),
-                        quoteCharacter.wrap(getEncryptColumnName(tableName, each.getName())), each.getName()).getExpressionWithAlias());
+                projections.add(new ColumnProjection(null == each.getOwner() ? null : each.getOwner(), getEncryptColumnName(tableName, each.getName()), each.getName()));
             } else {
-                shorthandExtensionProjections.add(null == each.getOwner() ? quoteCharacter.wrap(each.getName()) : quoteCharacter.wrap(each.getOwner()) + "." + quoteCharacter.wrap(each.getName()));
+                projections.add(new ColumnProjection(null == each.getOwner() ? null : each.getOwner(), each.getName(), null));
             }
         }
-        return new SubstitutableColumnNameToken(segment.getStartIndex(), segment.getStopIndex(), Joiner.on(", ").join(shorthandExtensionProjections));
+        return new SubstitutableColumnNameToken(segment.getStartIndex(), segment.getStopIndex(), projections, databaseType.getQuoteCharacter());
     }
     
     private String getEncryptColumnName(final String tableName, final String logicEncryptColumnName) {
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/InsertCipherNameTokenGenerator.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/InsertCipherNameTokenGenerator.java
index b50953f..9578732 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/InsertCipherNameTokenGenerator.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/InsertCipherNameTokenGenerator.java
@@ -19,14 +19,16 @@ package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
 
 import com.google.common.base.Preconditions;
 import org.apache.shardingsphere.encrypt.rewrite.token.generator.BaseEncryptSQLTokenGenerator;
+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.InsertStatementContext;
-import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
-import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.InsertColumnsSegment;
 import org.apache.shardingsphere.infra.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
 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.column.InsertColumnsSegment;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.Map;
 import java.util.Optional;
@@ -53,7 +55,8 @@ public final class InsertCipherNameTokenGenerator extends BaseEncryptSQLTokenGen
         Collection<SubstitutableColumnNameToken> result = new LinkedList<>();
         for (ColumnSegment each : sqlSegment.get().getColumns()) {
             if (logicAndCipherColumns.containsKey(each.getIdentifier().getValue())) {
-                result.add(new SubstitutableColumnNameToken(each.getStartIndex(), each.getStopIndex(), logicAndCipherColumns.get(each.getIdentifier().getValue())));
+                Collection<ColumnProjection> projections = Collections.singletonList(new ColumnProjection(null, logicAndCipherColumns.get(each.getIdentifier().getValue()), null));
+                result.add(new SubstitutableColumnNameToken(each.getStartIndex(), each.getStopIndex(), projections));
             }
         }
         return result;
diff --git a/shardingsphere-infra/shardingsphere-infra-rewrite/src/main/java/org/apache/shardingsphere/infra/rewrite/context/SQLRewriteContext.java b/shardingsphere-infra/shardingsphere-infra-rewrite/src/main/java/org/apache/shardingsphere/infra/rewrite/context/SQLRewriteContext.java
index 0a1adeb..9dafc54 100644
--- a/shardingsphere-infra/shardingsphere-infra-rewrite/src/main/java/org/apache/shardingsphere/infra/rewrite/context/SQLRewriteContext.java
+++ b/shardingsphere-infra/shardingsphere-infra-rewrite/src/main/java/org/apache/shardingsphere/infra/rewrite/context/SQLRewriteContext.java
@@ -19,6 +19,9 @@ package org.apache.shardingsphere.infra.rewrite.context;
 
 import lombok.AccessLevel;
 import lombok.Getter;
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
+import org.apache.shardingsphere.infra.binder.statement.dml.InsertStatementContext;
+import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.rewrite.parameter.builder.ParameterBuilder;
 import org.apache.shardingsphere.infra.rewrite.parameter.builder.impl.GroupedParameterBuilder;
 import org.apache.shardingsphere.infra.rewrite.parameter.builder.impl.StandardParameterBuilder;
@@ -26,9 +29,6 @@ import org.apache.shardingsphere.infra.rewrite.sql.token.generator.SQLTokenGener
 import org.apache.shardingsphere.infra.rewrite.sql.token.generator.SQLTokenGenerators;
 import org.apache.shardingsphere.infra.rewrite.sql.token.generator.builder.DefaultTokenGeneratorBuilder;
 import org.apache.shardingsphere.infra.rewrite.sql.token.pojo.SQLToken;
-import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
-import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
-import org.apache.shardingsphere.infra.binder.statement.dml.InsertStatementContext;
 
 import java.util.Collection;
 import java.util.LinkedList;
diff --git a/shardingsphere-infra/shardingsphere-infra-rewrite/src/main/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameToken.java b/shardingsphere-infra/shardingsphere-infra-rewrite/src/main/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameToken.java
index db32a9a..e989cbe 100644
--- a/shardingsphere-infra/shardingsphere-infra-rewrite/src/main/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameToken.java
+++ b/shardingsphere-infra/shardingsphere-infra-rewrite/src/main/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameToken.java
@@ -17,40 +17,87 @@
 
 package org.apache.shardingsphere.infra.rewrite.sql.token.pojo.generic;
 
+import com.google.common.base.Joiner;
+import com.google.common.base.Strings;
 import lombok.EqualsAndHashCode;
 import lombok.Getter;
+import org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
+import org.apache.shardingsphere.infra.rewrite.sql.token.pojo.RouteUnitAware;
 import org.apache.shardingsphere.infra.rewrite.sql.token.pojo.SQLToken;
 import org.apache.shardingsphere.infra.rewrite.sql.token.pojo.Substitutable;
+import org.apache.shardingsphere.infra.route.context.RouteMapper;
+import org.apache.shardingsphere.infra.route.context.RouteUnit;
+import org.apache.shardingsphere.sql.parser.sql.common.constant.QuoteCharacter;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * Substitutable column name token.
  */
 @EqualsAndHashCode
-public final class SubstitutableColumnNameToken extends SQLToken implements Substitutable {
+public final class SubstitutableColumnNameToken extends SQLToken implements Substitutable, RouteUnitAware {
     
     @Getter
     private final int stopIndex;
     
-    private final String columnName;
+    private final Collection<ColumnProjection> projections;
     
     private final boolean lastColumn;
     
-    public SubstitutableColumnNameToken(final int startIndex, final int stopIndex, final String columnName) {
+    private final QuoteCharacter quoteCharacter;
+    
+    public SubstitutableColumnNameToken(final int startIndex, final int stopIndex, final Collection<ColumnProjection> projections) {
         super(startIndex);
         this.stopIndex = stopIndex;
-        this.columnName = columnName;
         this.lastColumn = false;
+        this.quoteCharacter = QuoteCharacter.NONE;
+        this.projections = projections;
     }
     
-    public SubstitutableColumnNameToken(final int startIndex, final int stopIndex, final String columnName, final boolean lastColumn) {
+    public SubstitutableColumnNameToken(final int startIndex, final int stopIndex, final Collection<ColumnProjection> projections, final boolean lastColumn) {
         super(startIndex);
         this.stopIndex = stopIndex;
-        this.columnName = columnName;
         this.lastColumn = lastColumn;
+        this.quoteCharacter = QuoteCharacter.NONE;
+        this.projections = projections;
+    }
+    
+    public SubstitutableColumnNameToken(final int startIndex, final int stopIndex, final Collection<ColumnProjection> projections, final QuoteCharacter quoteCharacter) {
+        super(startIndex);
+        this.stopIndex = stopIndex;
+        this.lastColumn = false;
+        this.quoteCharacter = quoteCharacter;
+        this.projections = projections;
     }
     
     @Override
-    public String toString() {
-        return lastColumn ? ", " + columnName : columnName;
+    public String toString(final RouteUnit routeUnit) {
+        Map<String, String> logicAndActualTables = getLogicAndActualTables(routeUnit);
+        Collection<String> columnNames = new LinkedList<>();
+        for (ColumnProjection each : projections) {
+            columnNames.add(getColumnName(each, logicAndActualTables));
+        }
+        String allColumnNames = Joiner.on(", ").join(columnNames);
+        return lastColumn ? ", " + allColumnNames : allColumnNames;
+    }
+    
+    private Map<String, String> getLogicAndActualTables(final RouteUnit routeUnit) {
+        return routeUnit.getTableMappers().stream().collect(Collectors.toMap(RouteMapper::getLogicName, RouteMapper::getActualName, (oldValue, currentValue) -> oldValue));
+    }
+    
+    private String getColumnName(final ColumnProjection columnProjection, final Map<String, String> logicActualTableNames) {
+        StringBuilder builder = new StringBuilder();
+        String owner = columnProjection.getOwner();
+        if (!Strings.isNullOrEmpty(owner)) {
+            builder.append(quoteCharacter.wrap(logicActualTableNames.getOrDefault(owner, owner))).append(".");
+        }
+        builder.append(quoteCharacter.wrap(columnProjection.getName()));
+        if (columnProjection.getAlias().isPresent()) {
+            builder.append(" AS ").append(columnProjection.getAlias().get());
+        }
+        return builder.toString();
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-rewrite/src/test/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameTokenTest.java b/shardingsphere-infra/shardingsphere-infra-rewrite/src/test/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameTokenTest.java
index a0773d6..02b0808 100644
--- a/shardingsphere-infra/shardingsphere-infra-rewrite/src/test/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameTokenTest.java
+++ b/shardingsphere-infra/shardingsphere-infra-rewrite/src/test/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameTokenTest.java
@@ -17,15 +17,22 @@
 
 package org.apache.shardingsphere.infra.rewrite.sql.token.pojo.generic;
 
+import org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
+import org.apache.shardingsphere.infra.route.context.RouteUnit;
 import org.junit.Test;
 
+import java.util.Collection;
+import java.util.Collections;
+
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
 
 public final class SubstitutableColumnNameTokenTest {
     
     @Test
     public void assertToString() {
-        assertThat(new SubstitutableColumnNameToken(0, 1, "id").toString(), is("id"));
+        Collection<ColumnProjection> projections = Collections.singletonList(new ColumnProjection(null, "id", null));
+        assertThat(new SubstitutableColumnNameToken(0, 1, projections).toString(mock(RouteUnit.class)), is("id"));
     }
 }
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/item/ColumnProjectionSegment.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/item/ColumnProjectionSegment.java
index 678a217..2a11ada 100644
--- a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/item/ColumnProjectionSegment.java
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/item/ColumnProjectionSegment.java
@@ -19,9 +19,9 @@ package org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item;
 
 import lombok.Getter;
 import lombok.Setter;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.AliasAvailable;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.AliasSegment;
-import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 
 import java.util.Optional;
 
@@ -52,8 +52,6 @@ public final class ColumnProjectionSegment implements ProjectionSegment, AliasAv
     
     @Override
     public int getStopIndex() {
-        return column.getStopIndex();
-        // TODO
-        // return null == alias ? alias.getStopIndex() : column.getStopIndex();
+        return null == alias ? column.getStopIndex() : alias.getStopIndex();
     }
 }
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-expression.xml b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-expression.xml
index c8349e2..626f2df 100644
--- a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-expression.xml
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-expression.xml
@@ -116,7 +116,7 @@
             <shorthand-projection start-index="7" stop-index="9">
                 <owner start-index="7" stop-index="7" name="t"/>
             </shorthand-projection>
-            <column-projection start-index="11" stop-index="19" name="item_id" alias="item_id">
+            <column-projection start-index="11" stop-index="30" name="item_id" alias="item_id">
                 <owner start-index="11" stop-index="11" name="o"/>
             </column-projection>
             <expression-projection text="case when t.status = 'init' then '已启用' when t.status = 'failed' then '已停用' end" start-index="33" stop-index="124" alias="stateName"/>
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-group-by.xml b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-group-by.xml
index 9c0604d..a7c4846 100644
--- a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-group-by.xml
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-group-by.xml
@@ -258,7 +258,7 @@
             <simple-table name="t_order" alias="o" start-index="26" stop-index="34" />
         </from>
         <projections start-index="7" stop-index="19">
-            <column-projection name="user_id" alias="uid" start-index="7" stop-index="15">
+            <column-projection name="user_id" alias="uid" start-index="7" stop-index="19">
                 <owner name="o" start-index="7" stop-index="7" />
             </column-projection>
         </projections>
@@ -315,7 +315,7 @@
         </from>
         <projections start-index="7" stop-index="51">
             <aggregation-projection type="SUM" inner-expression="(order_id)" alias="orders_sum" start-index="7" stop-index="19" />
-            <column-projection name="user_id" alias="key" start-index="36" stop-index="42" />
+            <column-projection name="user_id" alias="key" start-index="36" stop-index="51" />
         </projections>
         <group-by>
             <column-item name="key" start-delimiter="`" end-delimiter="`" start-index="75" stop-index="79" />
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-join.xml b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-join.xml
index 596b52e..82be313 100644
--- a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-join.xml
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-join.xml
@@ -265,10 +265,10 @@
             </join-table>
         </from>
         <projections start-index="7" stop-index="77">
-            <column-projection name="department_id" alias="d_dept_id" start-index="7" stop-index="21">
+            <column-projection name="department_id" alias="d_dept_id" start-index="7" stop-index="34">
                 <owner name="d" start-index="7" stop-index="7"/>
             </column-projection>
-            <column-projection name="department_id" alias="e_dept_id" start-index="37" stop-index="51">
+            <column-projection name="department_id" alias="e_dept_id" start-index="37" stop-index="64">
                 <owner name="e" start-index="37" stop-index="37"/>
             </column-projection>
             <column-projection name="last_name" start-index="67" stop-index="77">
@@ -298,7 +298,7 @@
             </join-table>
         </from>
         <projections start-index="7" stop-index="47">
-            <column-projection name="department_id" alias="d_e_dept_id" start-index="7" stop-index="19"/>
+            <column-projection name="department_id" alias="d_e_dept_id" start-index="7" stop-index="34"/>
             <column-projection name="last_name" start-index="37" stop-index="47">
                 <owner name="e" start-index="37" stop-index="37"/>
             </column-projection>
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-order-by.xml b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-order-by.xml
index 35a8f1e..e1a3db4 100644
--- a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-order-by.xml
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-order-by.xml
@@ -96,7 +96,7 @@
             <simple-table name="t_order" alias="o" start-index="40" stop-index="48" />
         </from>
         <projections start-index="7" stop-index="33">
-            <column-projection name="order_id" alias="gen_order_id_" start-index="7" stop-index="16">
+            <column-projection name="order_id" alias="gen_order_id_" start-index="7" stop-index="33">
                 <owner name="o" start-index="7" stop-index="7" />
             </column-projection>
         </projections>
@@ -177,7 +177,7 @@
             <simple-table name="t_order" alias="o" start-index="40" stop-index="48" />
         </from>
         <projections start-index="7" stop-index="33">
-            <column-projection name="order_id" alias="gen_order_id_" start-index="7" stop-index="16">
+            <column-projection name="order_id" alias="gen_order_id_" start-index="7" stop-index="33">
                 <owner name="o" start-index="7" stop-index="7" />
             </column-projection>
         </projections>
@@ -194,7 +194,7 @@
             <simple-table name="t_order" alias="o" start-index="40" stop-index="48" />
         </from>
         <projections start-index="7" stop-index="33">
-            <column-projection name="order_id" alias="gen_order_id_" start-index="7" stop-index="16">
+            <column-projection name="order_id" alias="gen_order_id_" start-index="7" stop-index="33">
                 <owner name="o" start-index="7" stop-index="7" />
             </column-projection>
         </projections>
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-pagination-group-by-order-by.xml b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-pagination-group-by-order-by.xml
index 975fc0a..f79d651 100644
--- a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-pagination-group-by-order-by.xml
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-pagination-group-by-order-by.xml
@@ -259,13 +259,13 @@
                             <column-projection name="item_id" start-index="84" stop-index="92">
                                 <owner name="i" start-index="84" stop-index="84"/>
                             </column-projection>
-                            <column-projection name="order_id" alias="order_id" start-index="95" stop-index="104">
+                            <column-projection name="order_id" alias="order_id" start-index="95" stop-index="116">
                                 <owner name="o" start-index="95" stop-index="95"/>
                             </column-projection>
-                            <column-projection name="status" alias="status" start-index="119" stop-index="126">
+                            <column-projection name="status" alias="status" start-index="119" stop-index="136">
                                 <owner name="o" start-index="119" stop-index="119"/>
                             </column-projection>
-                            <column-projection name="user_id" alias="user_id" start-index="139" stop-index="147">
+                            <column-projection name="user_id" alias="user_id" start-index="139" stop-index="158">
                                 <owner name="o" start-index="139" stop-index="139"/>
                             </column-projection>
                         </projections>
@@ -403,13 +403,13 @@
                             <column-projection name="item_id" start-index="102" stop-index="110">
                                 <owner name="i" start-index="102" stop-index="102"/>
                             </column-projection>
-                            <column-projection name="order_id" alias="order_id" start-index="113" stop-index="122">
+                            <column-projection name="order_id" alias="order_id" start-index="113" stop-index="134">
                                 <owner name="o" start-index="113" stop-index="113"/>
                             </column-projection>
-                            <column-projection name="status" alias="status" start-index="137" stop-index="144">
+                            <column-projection name="status" alias="status" start-index="137" stop-index="154">
                                 <owner name="o" start-index="137" stop-index="137"/>
                             </column-projection>
-                            <column-projection name="user_id" alias="user_id" start-index="157" stop-index="165">
+                            <column-projection name="user_id" alias="user_id" start-index="157" stop-index="176">
                                 <owner name="o" start-index="157" stop-index="157"/>
                             </column-projection>
                         </projections>
@@ -547,13 +547,13 @@
                             <column-projection name="item_id" start-index="86" stop-index="94">
                                 <owner name="i" start-index="86" stop-index="86"/>
                             </column-projection>
-                            <column-projection name="order_id" alias="order_id" start-index="97" stop-index="106">
+                            <column-projection name="order_id" alias="order_id" start-index="97" stop-index="118">
                                 <owner name="o" start-index="97" stop-index="97"/>
                             </column-projection>
-                            <column-projection name="status" alias="status" start-index="121" stop-index="128">
+                            <column-projection name="status" alias="status" start-index="121" stop-index="138">
                                 <owner name="o" start-index="121" stop-index="121"/>
                             </column-projection>
-                            <column-projection name="user_id" alias="user_id" start-index="141" stop-index="149">
+                            <column-projection name="user_id" alias="user_id" start-index="141" stop-index="160">
                                 <owner name="o" start-index="141" stop-index="141"/>
                             </column-projection>
                         </projections>
@@ -691,13 +691,13 @@
                             <column-projection name="item_id" start-index="104" stop-index="112">
                                 <owner name="i" start-index="104" stop-index="104"/>
                             </column-projection>
-                            <column-projection name="order_id" alias="order_id" start-index="115" stop-index="124">
+                            <column-projection name="order_id" alias="order_id" start-index="115" stop-index="136">
                                 <owner name="o" start-index="115" stop-index="115"/>
                             </column-projection>
-                            <column-projection name="status" alias="status" start-index="139" stop-index="146">
+                            <column-projection name="status" alias="status" start-index="139" stop-index="156">
                                 <owner name="o" start-index="139" stop-index="139"/>
                             </column-projection>
-                            <column-projection name="user_id" alias="user_id" start-index="159" stop-index="167">
+                            <column-projection name="user_id" alias="user_id" start-index="159" stop-index="178">
                                 <owner name="o" start-index="159" stop-index="159"/>
                             </column-projection>
                         </projections>
@@ -835,13 +835,13 @@
                             <column-projection name="item_id" start-index="84" stop-index="92">
                                 <owner name="i" start-index="84" stop-index="84"/>
                             </column-projection>
-                            <column-projection name="order_id" alias="order_id" start-index="95" stop-index="104">
+                            <column-projection name="order_id" alias="order_id" start-index="95" stop-index="116">
                                 <owner name="o" start-index="95" stop-index="95"/>
                             </column-projection>
-                            <column-projection name="status" alias="status" start-index="119" stop-index="126">
+                            <column-projection name="status" alias="status" start-index="119" stop-index="136">
                                 <owner name="o" start-index="119" stop-index="119"/>
                             </column-projection>
-                            <column-projection name="user_id" alias="user_id" start-index="139" stop-index="147">
+                            <column-projection name="user_id" alias="user_id" start-index="139" stop-index="158">
                                 <owner name="o" start-index="139" stop-index="139"/>
                             </column-projection>
                         </projections>
@@ -979,13 +979,13 @@
                             <column-projection name="item_id" start-index="102" stop-index="110">
                                 <owner name="i" start-index="102" stop-index="102"/>
                             </column-projection>
-                            <column-projection name="order_id" alias="order_id" start-index="113" stop-index="122">
+                            <column-projection name="order_id" alias="order_id" start-index="113" stop-index="134">
                                 <owner name="o" start-index="113" stop-index="113"/>
                             </column-projection>
-                            <column-projection name="status" alias="status" start-index="137" stop-index="144">
+                            <column-projection name="status" alias="status" start-index="137" stop-index="154">
                                 <owner name="o" start-index="137" stop-index="137"/>
                             </column-projection>
-                            <column-projection name="user_id" alias="user_id" start-index="157" stop-index="165">
+                            <column-projection name="user_id" alias="user_id" start-index="157" stop-index="176">
                                 <owner name="o" start-index="157" stop-index="157"/>
                             </column-projection>
                         </projections>
@@ -1123,13 +1123,13 @@
                             <column-projection name="item_id" start-index="86" stop-index="94">
                                 <owner name="i" start-index="86" stop-index="86"/>
                             </column-projection>
-                            <column-projection name="order_id" alias="order_id" start-index="97" stop-index="106">
+                            <column-projection name="order_id" alias="order_id" start-index="97" stop-index="118">
                                 <owner name="o" start-index="97" stop-index="97"/>
                             </column-projection>
-                            <column-projection name="status" alias="status" start-index="121" stop-index="128">
+                            <column-projection name="status" alias="status" start-index="121" stop-index="138">
                                 <owner name="o" start-index="121" stop-index="121"/>
                             </column-projection>
-                            <column-projection name="user_id" alias="user_id" start-index="141" stop-index="149">
+                            <column-projection name="user_id" alias="user_id" start-index="141" stop-index="160">
                                 <owner name="o" start-index="141" stop-index="141"/>
                             </column-projection>
                         </projections>
@@ -1267,13 +1267,13 @@
                             <column-projection name="item_id" start-index="104" stop-index="112">
                                 <owner name="i" start-index="104" stop-index="104"/>
                             </column-projection>
-                            <column-projection name="order_id" alias="order_id" start-index="115" stop-index="124">
+                            <column-projection name="order_id" alias="order_id" start-index="115" stop-index="136">
                                 <owner name="o" start-index="115" stop-index="115"/>
                             </column-projection>
-                            <column-projection name="status" alias="status" start-index="139" stop-index="146">
+                            <column-projection name="status" alias="status" start-index="139" stop-index="156">
                                 <owner name="o" start-index="139" stop-index="139"/>
                             </column-projection>
-                            <column-projection name="user_id" alias="user_id" start-index="159" stop-index="167">
+                            <column-projection name="user_id" alias="user_id" start-index="159" stop-index="178">
                                 <owner name="o" start-index="159" stop-index="159"/>
                             </column-projection>
                         </projections>
@@ -1408,20 +1408,20 @@
                             <shorthand-projection start-index="22" stop-index="27">
                                 <owner start-index="22" stop-index="25" name="row_"/>
                             </shorthand-projection>
-                            <column-projection start-index="30" stop-index="35" name="rownum" alias="rownum_"/>
+                            <column-projection start-index="30" stop-index="43" name="rownum" alias="rownum_"/>
                         </projections>
                         <from>
                             <subquery-table alias="row_">
                                 <subquery>
                                     <select>
                                         <projections start-index="58" stop-index="139">
-                                            <column-projection start-index="58" stop-index="73" name="order_id" alias="order_id">
+                                            <column-projection start-index="58" stop-index="85" name="order_id" alias="order_id">
                                                 <owner start-index="58" stop-index="64" name="order0_"/>
                                             </column-projection>
-                                            <column-projection start-index="88" stop-index="101" name="status" alias="status">
+                                            <column-projection start-index="88" stop-index="111" name="status" alias="status">
                                                 <owner start-index="88" stop-index="94" name="order0_"/>
                                             </column-projection>
-                                            <column-projection start-index="114" stop-index="128" name="user_id" alias="user_id">
+                                            <column-projection start-index="114" stop-index="139" name="user_id" alias="user_id">
                                                 <owner start-index="114" stop-index="120" name="order0_"/>
                                             </column-projection>
                                         </projections>
@@ -1579,20 +1579,20 @@
                             <shorthand-projection start-index="22" stop-index="27">
                                 <owner start-index="22" stop-index="25" name="row_"/>
                             </shorthand-projection>
-                            <column-projection start-index="30" stop-index="35" name="rownum" alias="rownum_"/>
+                            <column-projection start-index="30" stop-index="43" name="rownum" alias="rownum_"/>
                         </projections>
                         <from>
                             <subquery-table alias="row_">
                                 <subquery>
                                     <select>
                                         <projections start-index="58" stop-index="139">
-                                            <column-projection start-index="58" stop-index="73" name="order_id" alias="order_id">
+                                            <column-projection start-index="58" stop-index="85" name="order_id" alias="order_id">
                                                 <owner start-index="58" stop-index="64" name="order0_"/>
                                             </column-projection>
-                                            <column-projection start-index="88" stop-index="101" name="status" alias="status">
+                                            <column-projection start-index="88" stop-index="111" name="status" alias="status">
                                                 <owner start-index="88" stop-index="94" name="order0_"/>
                                             </column-projection>
-                                            <column-projection start-index="114" stop-index="128" name="user_id" alias="user_id">
+                                            <column-projection start-index="114" stop-index="139" name="user_id" alias="user_id">
                                                 <owner start-index="114" stop-index="120" name="order0_"/>
                                             </column-projection>
                                         </projections>
@@ -1750,20 +1750,20 @@
                             <shorthand-projection start-index="22" stop-index="27">
                                 <owner start-index="22" stop-index="25" name="row_"/>
                             </shorthand-projection>
-                            <column-projection start-index="30" stop-index="35" name="rownum" alias="rownum_"/>
+                            <column-projection start-index="30" stop-index="43" name="rownum" alias="rownum_"/>
                         </projections>
                         <from>
                             <subquery-table alias="row_">
                                 <subquery>
                                     <select>
                                         <projections start-index="58" stop-index="139">
-                                            <column-projection start-index="58" stop-index="73" name="order_id" alias="order_id">
+                                            <column-projection start-index="58" stop-index="85" name="order_id" alias="order_id">
                                                 <owner start-index="58" stop-index="64" name="order0_"/>
                                             </column-projection>
-                                            <column-projection start-index="88" stop-index="101" name="status" alias="status">
+                                            <column-projection start-index="88" stop-index="111" name="status" alias="status">
                                                 <owner start-index="88" stop-index="94" name="order0_"/>
                                             </column-projection>
-                                            <column-projection start-index="114" stop-index="128" name="user_id" alias="user_id">
+                                            <column-projection start-index="114" stop-index="139" name="user_id" alias="user_id">
                                                 <owner start-index="114" stop-index="120" name="order0_"/>
                                             </column-projection>
                                         </projections>
@@ -1921,20 +1921,20 @@
                             <shorthand-projection start-index="22" stop-index="27">
                                 <owner start-index="22" stop-index="25" name="row_"/>
                             </shorthand-projection>
-                            <column-projection start-index="30" stop-index="35" name="rownum" alias="rownum_"/>
+                            <column-projection start-index="30" stop-index="43" name="rownum" alias="rownum_"/>
                         </projections>
                         <from>
                             <subquery-table alias="row_">
                                 <subquery>
                                     <select>
                                         <projections start-index="58" stop-index="139">
-                                            <column-projection start-index="58" stop-index="73" name="order_id" alias="order_id">
+                                            <column-projection start-index="58" stop-index="85" name="order_id" alias="order_id">
                                                 <owner start-index="58" stop-index="64" name="order0_"/>
                                             </column-projection>
-                                            <column-projection start-index="88" stop-index="101" name="status" alias="status">
+                                            <column-projection start-index="88" stop-index="111" name="status" alias="status">
                                                 <owner start-index="88" stop-index="94" name="order0_"/>
                                             </column-projection>
-                                            <column-projection start-index="114" stop-index="128" name="user_id" alias="user_id">
+                                            <column-projection start-index="114" stop-index="139" name="user_id" alias="user_id">
                                                 <owner start-index="114" stop-index="120" name="order0_"/>
                                             </column-projection>
                                         </projections>
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-pagination.xml b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-pagination.xml
index dc7884d..26872a8 100644
--- a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-pagination.xml
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select-pagination.xml
@@ -468,13 +468,13 @@
                             <column-projection name="item_id" start-index="86" stop-index="94">
                                 <owner name="i" start-index="86" stop-index="86" />
                             </column-projection>
-                            <column-projection name="order_id" alias="order_id" start-index="97" stop-index="106">
+                            <column-projection name="order_id" alias="order_id" start-index="97" stop-index="118">
                                 <owner name="o" start-index="97" stop-index="97" />
                             </column-projection>
-                            <column-projection name="status" alias="status" start-index="121" stop-index="128">
+                            <column-projection name="status" alias="status" start-index="121" stop-index="138">
                                 <owner name="o" start-index="121" stop-index="121" />
                             </column-projection>
-                            <column-projection name="user_id" alias="user_id" start-index="141" stop-index="149">
+                            <column-projection name="user_id" alias="user_id" start-index="141" stop-index="160">
                                 <owner name="o" start-index="141" stop-index="141" />
                             </column-projection>
                         </projections>
@@ -591,13 +591,13 @@
                             <column-projection name="item_id" start-index="104" stop-index="112">
                                 <owner name="i" start-index="104" stop-index="104" />
                             </column-projection>
-                            <column-projection name="order_id" alias="order_id" start-index="115" stop-index="124">
+                            <column-projection name="order_id" alias="order_id" start-index="115" stop-index="136">
                                 <owner name="o" start-index="115" stop-index="115" />
                             </column-projection>
-                            <column-projection name="status" alias="status" start-index="139" stop-index="146">
+                            <column-projection name="status" alias="status" start-index="139" stop-index="156">
                                 <owner name="o" start-index="139" stop-index="139" />
                             </column-projection>
-                            <column-projection name="user_id" alias="user_id" start-index="159" stop-index="167">
+                            <column-projection name="user_id" alias="user_id" start-index="159" stop-index="178">
                                 <owner name="o" start-index="159" stop-index="159" />
                             </column-projection>
                         </projections>
@@ -932,13 +932,13 @@
                             <column-projection name="item_id" start-index="86" stop-index="94">
                                 <owner name="i" start-index="86" stop-index="86" />
                             </column-projection>
-                            <column-projection name="order_id" alias="order_id" start-index="97" stop-index="106">
+                            <column-projection name="order_id" alias="order_id" start-index="97" stop-index="118">
                                 <owner name="o" start-index="97" stop-index="97" />
                             </column-projection>
-                            <column-projection name="status" alias="status" start-index="121" stop-index="128">
+                            <column-projection name="status" alias="status" start-index="121" stop-index="138">
                                 <owner name="o" start-index="121" stop-index="121" />
                             </column-projection>
-                            <column-projection name="user_id" alias="user_id" start-index="141" stop-index="149">
+                            <column-projection name="user_id" alias="user_id" start-index="141" stop-index="160">
                                 <owner name="o" start-index="141" stop-index="141" />
                             </column-projection>
                         </projections>
@@ -1071,13 +1071,13 @@
                             <column-projection name="item_id" start-index="104" stop-index="112">
                                 <owner name="i" start-index="104" stop-index="104" />
                             </column-projection>
-                            <column-projection name="order_id" alias="order_id" start-index="115" stop-index="124">
+                            <column-projection name="order_id" alias="order_id" start-index="115" stop-index="136">
                                 <owner name="o" start-index="115" stop-index="115" />
                             </column-projection>
-                            <column-projection name="status" alias="status" start-index="139" stop-index="146">
+                            <column-projection name="status" alias="status" start-index="139" stop-index="156">
                                 <owner name="o" start-index="139" stop-index="139" />
                             </column-projection>
-                            <column-projection name="user_id" alias="user_id" start-index="159" stop-index="167">
+                            <column-projection name="user_id" alias="user_id" start-index="159" stop-index="178">
                                 <owner name="o" start-index="159" stop-index="159" />
                             </column-projection>
                         </projections>
@@ -1210,13 +1210,13 @@
                             <column-projection name="item_id" start-index="86" stop-index="94">
                                 <owner name="i" start-index="86" stop-index="86" />
                             </column-projection>
-                            <column-projection name="order_id" alias="order_id" start-index="97" stop-index="106">
+                            <column-projection name="order_id" alias="order_id" start-index="97" stop-index="118">
                                 <owner name="o" start-index="97" stop-index="97" />
                             </column-projection>
-                            <column-projection name="status" alias="status" start-index="121" stop-index="128">
+                            <column-projection name="status" alias="status" start-index="121" stop-index="138">
                                 <owner name="o" start-index="121" stop-index="121" />
                             </column-projection>
-                            <column-projection name="user_id" alias="user_id" start-index="141" stop-index="149">
+                            <column-projection name="user_id" alias="user_id" start-index="141" stop-index="160">
                                 <owner name="o" start-index="141" stop-index="141" />
                             </column-projection>
                         </projections>
@@ -1349,13 +1349,13 @@
                             <column-projection name="item_id" start-index="104" stop-index="112">
                                 <owner name="i" start-index="104" stop-index="104" />
                             </column-projection>
-                            <column-projection name="order_id" alias="order_id" start-index="115" stop-index="124">
+                            <column-projection name="order_id" alias="order_id" start-index="115" stop-index="136">
                                 <owner name="o" start-index="115" stop-index="115" />
                             </column-projection>
-                            <column-projection name="status" alias="status" start-index="139" stop-index="146">
+                            <column-projection name="status" alias="status" start-index="139" stop-index="156">
                                 <owner name="o" start-index="139" stop-index="139" />
                             </column-projection>
-                            <column-projection name="user_id" alias="user_id" start-index="159" stop-index="167">
+                            <column-projection name="user_id" alias="user_id" start-index="159" stop-index="178">
                                 <owner name="o" start-index="159" stop-index="159" />
                             </column-projection>
                         </projections>
@@ -1485,20 +1485,20 @@
                             <shorthand-projection start-index="22" stop-index="27">
                                 <owner start-index="22" stop-index="25" name="row_" />
                             </shorthand-projection>
-                            <column-projection start-index="30" stop-index="35" name="rownum" alias="rownum_" />
+                            <column-projection start-index="30" stop-index="43" name="rownum" alias="rownum_" />
                         </projections>
                         <from>
                             <subquery-table start-index="50" stop-index="339" alias="row_">
                                 <subquery>
                                     <select>
                                         <projections start-index="58" stop-index="139" >
-                                            <column-projection start-index="58" stop-index="73" name="order_id" alias="order_id">
+                                            <column-projection start-index="58" stop-index="85" name="order_id" alias="order_id">
                                                 <owner start-index="58" stop-index="64" name="order0_" />
                                             </column-projection>
-                                            <column-projection start-index="88" stop-index="101" name="status" alias="status">
+                                            <column-projection start-index="88" stop-index="111" name="status" alias="status">
                                                 <owner start-index="88" stop-index="94" name="order0_" />
                                             </column-projection>
-                                            <column-projection start-index="114" stop-index="128" name="user_id" alias="user_id">
+                                            <column-projection start-index="114" stop-index="139" name="user_id" alias="user_id">
                                                 <owner start-index="114" stop-index="120" name="order0_" />
                                             </column-projection>
                                         </projections>
@@ -1635,20 +1635,20 @@
                             <shorthand-projection start-index="22" stop-index="27">
                                 <owner start-index="22" stop-index="25" name="row_" />
                             </shorthand-projection>
-                            <column-projection start-index="30" stop-index="35" name="rownum" alias="rownum_" />
+                            <column-projection start-index="30" stop-index="43" name="rownum" alias="rownum_" />
                         </projections>
                         <from>
                             <subquery-table start-index="50" stop-index="339" alias="row_">
                                 <subquery>
                                     <select>
                                         <projections start-index="58" stop-index="139" >
-                                            <column-projection start-index="58" stop-index="73" name="order_id" alias="order_id">
+                                            <column-projection start-index="58" stop-index="85" name="order_id" alias="order_id">
                                                 <owner start-index="58" stop-index="64" name="order0_" />
                                             </column-projection>
-                                            <column-projection start-index="88" stop-index="101" name="status" alias="status">
+                                            <column-projection start-index="88" stop-index="111" name="status" alias="status">
                                                 <owner start-index="88" stop-index="94" name="order0_" />
                                             </column-projection>
-                                            <column-projection start-index="114" stop-index="128" name="user_id" alias="user_id">
+                                            <column-projection start-index="114" stop-index="139" name="user_id" alias="user_id">
                                                 <owner start-index="114" stop-index="120" name="order0_" />
                                             </column-projection>
                                         </projections>
@@ -1801,20 +1801,20 @@
                             <shorthand-projection start-index="22" stop-index="27">
                                 <owner start-index="22" stop-index="25" name="row_" />
                             </shorthand-projection>
-                            <column-projection start-index="30" stop-index="35" name="rownum" alias="rownum_" />
+                            <column-projection start-index="30" stop-index="43" name="rownum" alias="rownum_" />
                         </projections>
                         <from>
                             <subquery-table start-index="50" stop-index="339" alias="row_">
                                 <subquery>
                                     <select>
                                         <projections start-index="58" stop-index="139" >
-                                            <column-projection start-index="58" stop-index="73" name="order_id" alias="order_id">
+                                            <column-projection start-index="58" stop-index="85" name="order_id" alias="order_id">
                                                 <owner start-index="58" stop-index="64" name="order0_" />
                                             </column-projection>
-                                            <column-projection start-index="88" stop-index="101" name="status" alias="status">
+                                            <column-projection start-index="88" stop-index="111" name="status" alias="status">
                                                 <owner start-index="88" stop-index="94" name="order0_" />
                                             </column-projection>
-                                            <column-projection start-index="114" stop-index="128" name="user_id" alias="user_id">
+                                            <column-projection start-index="114" stop-index="139" name="user_id" alias="user_id">
                                                 <owner start-index="114" stop-index="120" name="order0_" />
                                             </column-projection>
                                         </projections>
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select.xml b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select.xml
index b9bf451..1397783 100644
--- a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select.xml
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/dml/select.xml
@@ -1669,7 +1669,7 @@
             <simple-table name="t_order_item" alias="length" start-index="36" stop-index="54" />
         </from>
         <projections start-index="7" stop-index="29">
-            <column-projection name="item_id" alias="password" start-index="7" stop-index="20">
+            <column-projection name="item_id" alias="password" start-index="7" stop-index="29">
                 <owner name="length" start-index="7" stop-index="12" />
             </column-projection>>
         </projections>
@@ -2502,7 +2502,7 @@
             <simple-table name="t_order" start-index="31" stop-index="37" />
         </from>
         <projections start-index="7" stop-index="24">
-            <column-projection alias="status" name="status" start-index="7" stop-index="12" />
+            <column-projection alias="status" name="status" start-index="7" stop-index="24" />
         </projections>
     </select>
 
@@ -2511,7 +2511,7 @@
             <simple-table name="t_order" start-index="31" stop-index="37" />
         </from>
         <projections start-index="7" stop-index="24">
-            <column-projection name="status" alias="status" start-index="7" stop-index="12" />
+            <column-projection name="status" alias="status" start-index="7" stop-index="24" />
         </projections>
     </select>
 
@@ -3027,7 +3027,7 @@
             </join-table>
         </from>
         <projections start-index="7" stop-index="107">
-            <column-projection name="department_id" alias="Department" start-index="7" stop-index="21">
+            <column-projection name="department_id" alias="Department" start-index="7" stop-index="34">
                 <owner name="a" start-index="7" stop-index="7" />
             </column-projection>
             <expression-projection text="a.num_emp/b.total_count" alias="%_Employees" start-index="37" stop-index="73" />
diff --git a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/mix/case/select_for_query_with_cipher.xml b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/mix/case/select_for_query_with_cipher.xml
index 97dc7fb..d715ea5 100644
--- a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/mix/case/select_for_query_with_cipher.xml
+++ b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/mix/case/select_for_query_with_cipher.xml
@@ -42,12 +42,11 @@
         <output sql="SELECT t_account_1.account_id, t_account_1.cipher_password AS password, t_account_1.cipher_amount AS a, status AS s FROM t_account_1 WHERE t_account_1.account_id = 1 AND t_account_1.assisted_query_password = 'assisted_query_aaa' AND t_account_1.cipher_amount = 'encrypt_1000' AND t_account_1.status = 'OK'" />
     </rewrite-assertion>
     
-    <!-- FIXME #9510 should rewrite owner table as sharding table -->
-<!--    <rewrite-assertion id="select_with_unqualified_shorthand">-->
-<!--        <input sql="SELECT * FROM t_account" />-->
-<!--        <output sql="SELECT `t_account_0`.`account_id`, `t_account_0`.`cipher_password` AS password, `t_account_0`.`cipher_amount` AS amount, `t_account_0`.`status` FROM t_account_0" />-->
-<!--        <output sql="SELECT `t_account_1`.`account_id`, `t_account_1`.`cipher_password` AS password, `t_account_1`.`cipher_amount` AS amount, `t_account_1`.`status` FROM t_account_1" />-->
-<!--    </rewrite-assertion>-->
+    <rewrite-assertion id="select_with_unqualified_shorthand">
+        <input sql="SELECT * FROM t_account" />
+        <output sql="SELECT `t_account_0`.`account_id`, `t_account_0`.`cipher_password` AS password, `t_account_0`.`cipher_amount` AS amount, `t_account_0`.`status` FROM t_account_0" />
+        <output sql="SELECT `t_account_1`.`account_id`, `t_account_1`.`cipher_password` AS password, `t_account_1`.`cipher_amount` AS amount, `t_account_1`.`status` FROM t_account_1" />
+    </rewrite-assertion>
     
     <rewrite-assertion id="select_with_qualified_shorthand">
         <input sql="SELECT a.* FROM t_account a" />
diff --git a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/mix/case/select_for_query_with_plain.xml b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/mix/case/select_for_query_with_plain.xml
index d3184d7..ca70cc8 100644
--- a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/mix/case/select_for_query_with_plain.xml
+++ b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/mix/case/select_for_query_with_plain.xml
@@ -27,12 +27,11 @@
         <output sql="SELECT a.account_id, a.plain_password AS password, a.plain_amount AS a, a.status AS s FROM t_account_bak_1 AS a WHERE a.account_id = 1 AND a.plain_password = 'aaa' AND a.plain_amount = 1000 AND a.status = 'OK'" />
     </rewrite-assertion>
     
-    <!-- FIXME #9510 should rewrite owner table as sharding table -->
-<!--    <rewrite-assertion id="select_with_unqualified_shorthand">-->
-<!--        <input sql="SELECT * FROM t_account_bak" />-->
-<!--        <output sql="SELECT `t_account_bak_0`.`account_id`, `t_account_bak_0`.`plain_password` AS password, `t_account_bak_0`.`plain_amount` AS amount, `t_account_bak_0`.`status` FROM t_account_bak_0" />-->
-<!--        <output sql="SELECT `t_account_bak_1`.`account_id`, `t_account_bak_1`.`plain_password` AS password, `t_account_bak_1`.`plain_amount` AS amount, `t_account_bak_1`.`status` FROM t_account_bak_1" />-->
-<!--    </rewrite-assertion>-->
+    <rewrite-assertion id="select_with_unqualified_shorthand">
+        <input sql="SELECT * FROM t_account_bak" />
+        <output sql="SELECT `t_account_bak_0`.`account_id`, `t_account_bak_0`.`plain_password` AS password, `t_account_bak_0`.`plain_amount` AS amount, `t_account_bak_0`.`status` FROM t_account_bak_0" />
+        <output sql="SELECT `t_account_bak_1`.`account_id`, `t_account_bak_1`.`plain_password` AS password, `t_account_bak_1`.`plain_amount` AS amount, `t_account_bak_1`.`status` FROM t_account_bak_1" />
+    </rewrite-assertion>
     
     <rewrite-assertion id="select_with_qualified_shorthand">
         <input sql="SELECT a.* FROM t_account_bak a" />