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

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


The following commit(s) were added to refs/heads/master by this push:
     new b5008ce5680 Fix encrypt ShorthandProjection expand with/ without quote 
(#26033)
b5008ce5680 is described below

commit b5008ce5680b471cd49b00c09aa25d18f90b3f38
Author: Chuxin Chen <[email protected]>
AuthorDate: Tue Jun 6 10:30:27 2023 +0800

    Fix encrypt ShorthandProjection expand with/ without quote (#26033)
    
    * Fix encrypt ShorthandProjection expand quote
    
    * Fix encrypt ShorthandProjection expand quote
    
    * Fix encrypt ShorthandProjection expand quote
---
 .../EncryptCreateTableTokenGenerator.java          | 14 +++--
 .../EncryptIndexColumnTokenGenerator.java          |  9 +--
 .../EncryptOrderByItemTokenGenerator.java          | 11 ++--
 .../EncryptPredicateColumnTokenGenerator.java      | 12 ++--
 .../generator/EncryptProjectionTokenGenerator.java | 29 ++++++----
 .../generator/InsertCipherNameTokenGenerator.java  |  4 +-
 .../segment/select/projection/Projection.java      |  6 +-
 .../select/projection/engine/ProjectionEngine.java | 33 ++++++-----
 .../impl/AggregationDistinctProjection.java        |  3 +-
 .../projection/impl/AggregationProjection.java     |  3 +-
 .../select/projection/impl/ColumnProjection.java   | 41 +++++++++++---
 .../select/projection/impl/DerivedProjection.java  |  3 +-
 .../projection/impl/ExpressionProjection.java      |  3 +-
 .../projection/impl/ParameterMarkerProjection.java |  3 +-
 .../projection/impl/ShorthandProjection.java       |  5 +-
 .../select/projection/impl/SubqueryProjection.java |  3 +-
 .../projection/engine/ProjectionEngineTest.java    | 65 ++++++++++++----------
 .../pojo/generic/SubstitutableColumnNameToken.java |  4 +-
 .../generic/SubstitutableColumnNameTokenTest.java  |  6 +-
 .../common/value/identifier/IdentifierValue.java   |  2 +
 .../dml/select/select-subquery.xml                 |  2 +-
 21 files changed, 165 insertions(+), 96 deletions(-)

diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptCreateTableTokenGenerator.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptCreateTableTokenGenerator.java
index c437cd7d927..34c146ccc4d 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptCreateTableTokenGenerator.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptCreateTableTokenGenerator.java
@@ -29,6 +29,7 @@ import 
org.apache.shardingsphere.infra.rewrite.sql.token.pojo.SQLToken;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.pojo.generic.RemoveToken;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.pojo.generic.SubstitutableColumnNameToken;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.column.ColumnDefinitionSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -80,22 +81,25 @@ public final class EncryptCreateTableTokenGenerator 
implements CollectionSQLToke
     }
     
     private SQLToken getCipherColumnToken(final String tableName, final String 
columnName, final ColumnDefinitionSegment column, final int stopIndex) {
-        return new SubstitutableColumnNameToken(stopIndex + 1, 
column.getColumnName().getStopIndex(), 
getColumnProjections(encryptRule.getCipherColumn(tableName, columnName)));
+        return new SubstitutableColumnNameToken(stopIndex + 1, 
column.getColumnName().getStopIndex(), getColumnProjections(new 
IdentifierValue(encryptRule.getCipherColumn(tableName, columnName),
+                column.getColumnName().getIdentifier().getQuoteCharacter())));
     }
     
     private Optional<? extends SQLToken> getAssistedQueryColumnToken(final 
String tableName, final String columnName, final ColumnDefinitionSegment column,
                                                                      final int 
stopIndex, final boolean lastColumn) {
         Optional<String> assistedQueryColumn = 
encryptRule.findAssistedQueryColumn(tableName, columnName);
-        return assistedQueryColumn.map(optional -> new 
SubstitutableColumnNameToken(stopIndex + 1, 
column.getColumnName().getStopIndex(), getColumnProjections(optional), 
lastColumn));
+        return assistedQueryColumn.map(optional -> new 
SubstitutableColumnNameToken(stopIndex + 1, 
column.getColumnName().getStopIndex(),
+                getColumnProjections(new IdentifierValue(optional, 
column.getColumnName().getIdentifier().getQuoteCharacter())), lastColumn));
     }
     
     private Optional<? extends SQLToken> getLikeQueryColumnToken(final String 
tableName, final String columnName, final ColumnDefinitionSegment column,
                                                                  final int 
stopIndex, final boolean lastColumn) {
         Optional<String> likeQueryColumn = 
encryptRule.findLikeQueryColumn(tableName, columnName);
-        return likeQueryColumn.map(optional -> new 
SubstitutableColumnNameToken(stopIndex + 1, 
column.getColumnName().getStopIndex(), getColumnProjections(optional), 
lastColumn));
+        return likeQueryColumn.map(optional -> new 
SubstitutableColumnNameToken(stopIndex + 1, 
column.getColumnName().getStopIndex(),
+                getColumnProjections(new IdentifierValue(optional, 
column.getColumnName().getIdentifier().getQuoteCharacter())), lastColumn));
     }
     
-    private Collection<ColumnProjection> getColumnProjections(final String 
columnName) {
-        return Collections.singletonList(new ColumnProjection(null, 
columnName, null));
+    private Collection<ColumnProjection> getColumnProjections(final 
IdentifierValue columnIdentifier) {
+        return Collections.singletonList(new ColumnProjection(null, 
columnIdentifier, null));
     }
 }
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptIndexColumnTokenGenerator.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptIndexColumnTokenGenerator.java
index 1cda09c5565..6846c421df4 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptIndexColumnTokenGenerator.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptIndexColumnTokenGenerator.java
@@ -29,6 +29,7 @@ import 
org.apache.shardingsphere.infra.rewrite.sql.token.pojo.SQLToken;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.pojo.generic.SubstitutableColumnNameToken;
 import org.apache.shardingsphere.sql.parser.sql.common.enums.QuoteCharacter;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -72,17 +73,17 @@ public final class EncryptIndexColumnTokenGenerator 
implements CollectionSQLToke
     }
     
     private Optional<SQLToken> getAssistedQueryColumnToken(final int 
startIndex, final int stopIndex, final String columnName, final QuoteCharacter 
quoteCharacter) {
-        Collection<ColumnProjection> columnProjections = 
getColumnProjections(columnName);
+        Collection<ColumnProjection> columnProjections = 
getColumnProjections(columnName, quoteCharacter);
         return Optional.of(new SubstitutableColumnNameToken(startIndex, 
stopIndex, columnProjections, quoteCharacter, Collections.emptyList()));
     }
     
     private Optional<SQLToken> getCipherColumnToken(final String tableName, 
final int startIndex, final int stopIndex, final String columnName, final 
QuoteCharacter quoteCharacter) {
         String cipherColumn = encryptRule.getCipherColumn(tableName, 
columnName);
-        Collection<ColumnProjection> columnProjections = 
getColumnProjections(cipherColumn);
+        Collection<ColumnProjection> columnProjections = 
getColumnProjections(cipherColumn, quoteCharacter);
         return Optional.of(new SubstitutableColumnNameToken(startIndex, 
stopIndex, columnProjections, quoteCharacter, Collections.emptyList()));
     }
     
-    private Collection<ColumnProjection> getColumnProjections(final String 
columnName) {
-        return Collections.singletonList(new ColumnProjection(null, 
columnName, null));
+    private Collection<ColumnProjection> getColumnProjections(final String 
columnName, final QuoteCharacter quoteCharacter) {
+        return Collections.singletonList(new ColumnProjection(null, new 
IdentifierValue(columnName, quoteCharacter), null));
     }
 }
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptOrderByItemTokenGenerator.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptOrderByItemTokenGenerator.java
index a6016f85e79..8aaf70eb0c5 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptOrderByItemTokenGenerator.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptOrderByItemTokenGenerator.java
@@ -31,8 +31,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.SQLToken;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.pojo.generic.SubstitutableColumnNameToken;
+import org.apache.shardingsphere.sql.parser.sql.common.enums.QuoteCharacter;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.ColumnOrderByItemSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -84,8 +86,9 @@ public final class EncryptOrderByItemTokenGenerator 
implements CollectionSQLToke
             int startIndex = column.getOwner().isPresent() ? 
column.getOwner().get().getStopIndex() + 2 : column.getStartIndex();
             int stopIndex = column.getStopIndex();
             Optional<String> assistedQueryColumn = 
encryptTable.get().findAssistedQueryColumn(column.getIdentifier().getValue());
-            SubstitutableColumnNameToken encryptColumnNameToken = 
assistedQueryColumn.map(optional -> new 
SubstitutableColumnNameToken(startIndex, stopIndex, 
createColumnProjections(optional)))
-                    .orElseGet(() -> new 
SubstitutableColumnNameToken(startIndex, stopIndex, 
createColumnProjections(encryptTable.get().getCipherColumn(column.getIdentifier().getValue()))));
+            SubstitutableColumnNameToken encryptColumnNameToken = 
assistedQueryColumn.map(optional -> new 
SubstitutableColumnNameToken(startIndex, stopIndex,
+                    createColumnProjections(optional, 
column.getIdentifier().getQuoteCharacter()))).orElseGet(() -> new 
SubstitutableColumnNameToken(startIndex, stopIndex,
+                            
createColumnProjections(encryptTable.get().getCipherColumn(column.getIdentifier().getValue()),
 column.getIdentifier().getQuoteCharacter())));
             result.add(encryptColumnNameToken);
         }
         return result;
@@ -121,7 +124,7 @@ public final class EncryptOrderByItemTokenGenerator 
implements CollectionSQLToke
         return false;
     }
     
-    private Collection<ColumnProjection> createColumnProjections(final String 
columnName) {
-        return Collections.singletonList(new ColumnProjection(null, 
columnName, null));
+    private Collection<ColumnProjection> createColumnProjections(final String 
columnName, final QuoteCharacter quoteCharacter) {
+        return Collections.singletonList(new ColumnProjection(null, new 
IdentifierValue(columnName, quoteCharacter), null));
     }
 }
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptPredicateColumnTokenGenerator.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptPredicateColumnTokenGenerator.java
index 295ec9d3cad..ff99bafa75d 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptPredicateColumnTokenGenerator.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptPredicateColumnTokenGenerator.java
@@ -32,12 +32,14 @@ import 
org.apache.shardingsphere.infra.rewrite.sql.token.generator.aware.SchemaM
 import org.apache.shardingsphere.infra.rewrite.sql.token.pojo.SQLToken;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.pojo.generic.SubstitutableColumnNameToken;
 import 
org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
+import org.apache.shardingsphere.sql.parser.sql.common.enums.QuoteCharacter;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 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.predicate.AndPredicate;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.WhereSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.util.ExpressionExtractUtils;
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -98,10 +100,12 @@ public final class EncryptPredicateColumnTokenGenerator 
implements CollectionSQL
         if (includesLike(whereSegments, columnSegment)) {
             Optional<String> likeQueryColumn = 
encryptTable.findLikeQueryColumn(logicColumn);
             
ShardingSpherePreconditions.checkState(likeQueryColumn.isPresent(), () -> new 
UnsupportedEncryptSQLException("LIKE"));
-            return new SubstitutableColumnNameToken(startIndex, stopIndex, 
createColumnProjections(likeQueryColumn.get()));
+            return new SubstitutableColumnNameToken(startIndex, stopIndex, 
createColumnProjections(likeQueryColumn.get(), 
columnSegment.getIdentifier().getQuoteCharacter()));
         }
         Collection<ColumnProjection> columnProjections =
-                
encryptTable.findAssistedQueryColumn(logicColumn).map(this::createColumnProjections).orElseGet(()
 -> createColumnProjections(encryptTable.getCipherColumn(logicColumn)));
+                encryptTable.findAssistedQueryColumn(logicColumn).map(optional 
-> createColumnProjections(optional, 
columnSegment.getIdentifier().getQuoteCharacter()))
+                        .orElseGet(() -> 
createColumnProjections(encryptTable.getCipherColumn(logicColumn),
+                                
columnSegment.getIdentifier().getQuoteCharacter()));
         return new SubstitutableColumnNameToken(startIndex, stopIndex, 
columnProjections);
     }
     
@@ -131,7 +135,7 @@ public final class EncryptPredicateColumnTokenGenerator 
implements CollectionSQL
         return columnSegment instanceof ColumnSegment && 
columnSegment.getStartIndex() == targetColumnSegment.getStartIndex() && 
columnSegment.getStopIndex() == targetColumnSegment.getStopIndex();
     }
     
-    private Collection<ColumnProjection> createColumnProjections(final String 
columnName) {
-        return Collections.singletonList(new ColumnProjection(null, 
columnName, null));
+    private Collection<ColumnProjection> createColumnProjections(final String 
columnName, final QuoteCharacter quoteCharacter) {
+        return Collections.singletonList(new ColumnProjection(null, new 
IdentifierValue(columnName, quoteCharacter), null));
     }
 }
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
index e0791152a70..19904b6c759 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
@@ -38,6 +38,9 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.enums.SubqueryType;
 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.ShorthandProjectionSegment;
+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.value.identifier.IdentifierValue;
 
 import java.util.Collection;
 import java.util.LinkedHashSet;
@@ -113,7 +116,7 @@ public final class EncryptProjectionTokenGenerator 
implements CollectionSQLToken
         for (ColumnProjection each : columnProjections) {
             String tableName = columnTableNames.get(each.getExpression());
             if (null == tableName || 
!encryptRule.findStandardEncryptor(tableName, each.getName()).isPresent()) {
-                projections.add(new ColumnProjection(each.getOwner(), 
each.getName(), each.getAlias().orElse(null)));
+                projections.add(new 
ColumnProjection(each.getOwnerIdentifier(), each.getNameIdentifier(), 
each.getAlias().isPresent() ? each.getAliasIdentifier() : null));
             } else {
                 projections.addAll(generateProjections(tableName, each, 
subqueryType, true, segment));
             }
@@ -125,8 +128,8 @@ public final class EncryptProjectionTokenGenerator 
implements CollectionSQLToken
     }
     
     private ColumnProjection buildColumnProjection(final 
ColumnProjectionSegment segment) {
-        String owner = segment.getColumn().getOwner().map(optional -> 
optional.getIdentifier().getValue()).orElse(null);
-        return new ColumnProjection(owner, 
segment.getColumn().getIdentifier().getValue(), 
segment.getAliasName().orElse(null));
+        IdentifierValue owner = 
segment.getColumn().getOwner().map(OwnerSegment::getIdentifier).orElse(null);
+        return new ColumnProjection(owner, 
segment.getColumn().getIdentifier(), segment.getAliasName().isPresent() ? 
segment.getAlias().map(AliasSegment::getIdentifier).orElse(null) : null);
     }
     
     private Map<String, String> getColumnTableNames(final 
SelectStatementContext selectStatementContext) {
@@ -163,36 +166,40 @@ public final class EncryptProjectionTokenGenerator 
implements CollectionSQLToken
         if (shorthand || null == column.getOwner()) {
             return column;
         }
-        return new ColumnProjection(null, column.getName(), 
column.getAlias().isPresent() ? column.getAlias().get() : null);
+        return new ColumnProjection(null, column.getNameIdentifier(), 
column.getAlias().isPresent() ? column.getAliasIdentifier() : null);
     }
     
     private ColumnProjection generatePredicateSubqueryProjection(final String 
tableName, final ColumnProjection column) {
         Optional<String> assistedQueryColumn = 
encryptRule.findAssistedQueryColumn(tableName, column.getName());
         if (assistedQueryColumn.isPresent()) {
-            return new ColumnProjection(column.getOwner(), 
assistedQueryColumn.get(), null);
+            return new ColumnProjection(column.getOwnerIdentifier(), new 
IdentifierValue(assistedQueryColumn.get(), 
column.getNameIdentifier().getQuoteCharacter()), null);
         }
         String cipherColumn = encryptRule.getCipherColumn(tableName, 
column.getName());
-        return new ColumnProjection(column.getOwner(), cipherColumn, null);
+        return new ColumnProjection(column.getOwnerIdentifier(), new 
IdentifierValue(cipherColumn, column.getNameIdentifier().getQuoteCharacter()), 
null);
     }
     
     private Collection<ColumnProjection> 
generateTableSubqueryProjections(final String tableName, final ColumnProjection 
column, final boolean shorthand) {
         Collection<ColumnProjection> result = new LinkedList<>();
-        result.add(distinctOwner(new ColumnProjection(column.getOwner(), 
encryptRule.getCipherColumn(tableName, column.getName()), null), shorthand));
+        result.add(distinctOwner(new 
ColumnProjection(column.getOwnerIdentifier(), new 
IdentifierValue(encryptRule.getCipherColumn(tableName, column.getName()),
+                column.getNameIdentifier().getQuoteCharacter()), null), 
shorthand));
         Optional<String> assistedQueryColumn = 
encryptRule.findAssistedQueryColumn(tableName, column.getName());
-        assistedQueryColumn.ifPresent(optional -> result.add(new 
ColumnProjection(column.getOwner(), optional, null)));
+        assistedQueryColumn.ifPresent(optional -> result.add(new 
ColumnProjection(column.getOwnerIdentifier(), new IdentifierValue(optional, 
column.getNameIdentifier().getQuoteCharacter()), null)));
         return result;
     }
     
     private Collection<ColumnProjection> 
generateExistsSubqueryProjections(final String tableName, final 
ColumnProjection column, final boolean shorthand) {
         Collection<ColumnProjection> result = new LinkedList<>();
-        result.add(distinctOwner(new ColumnProjection(column.getOwner(), 
encryptRule.getCipherColumn(tableName, column.getName()), null), shorthand));
+        result.add(distinctOwner(new 
ColumnProjection(column.getOwnerIdentifier(), new 
IdentifierValue(encryptRule.getCipherColumn(tableName, column.getName()),
+                column.getNameIdentifier().getQuoteCharacter()), null), 
shorthand));
         return result;
     }
     
     private ColumnProjection generateCommonProjection(final String tableName, 
final ColumnProjection column, final ShorthandProjectionSegment segment) {
         String encryptColumnName = getEncryptColumnName(tableName, 
column.getName());
-        String owner = null == segment || !segment.getOwner().isPresent() ? 
column.getOwner() : segment.getOwner().get().getIdentifier().getValue();
-        return new ColumnProjection(owner, encryptColumnName, 
column.getAlias().orElse(column.getName()));
+        IdentifierValue owner = (null == segment || 
!segment.getOwner().isPresent()) ? column.getOwnerIdentifier() : 
segment.getOwner().get().getIdentifier();
+        return new ColumnProjection(owner, new 
IdentifierValue(encryptColumnName, 
column.getNameIdentifier().getQuoteCharacter()), column.getAlias().isPresent()
+                ? column.getAliasIdentifier()
+                : column.getNameIdentifier());
     }
     
     private String getEncryptColumnName(final String tableName, final String 
logicEncryptColumnName) {
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/InsertCipherNameTokenGenerator.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/InsertCipherNameTokenGenerator.java
index a473d7bbde2..ba458e4577a 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/InsertCipherNameTokenGenerator.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/InsertCipherNameTokenGenerator.java
@@ -29,6 +29,7 @@ import 
org.apache.shardingsphere.infra.rewrite.sql.token.pojo.SQLToken;
 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 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -61,7 +62,8 @@ public final class InsertCipherNameTokenGenerator implements 
CollectionSQLTokenG
         Collection<SQLToken> result = new LinkedList<>();
         for (ColumnSegment each : sqlSegment.get().getColumns()) {
             if 
(logicAndCipherColumns.containsKey(each.getIdentifier().getValue())) {
-                Collection<ColumnProjection> projections = 
Collections.singletonList(new ColumnProjection(null, 
logicAndCipherColumns.get(each.getIdentifier().getValue()), null));
+                Collection<ColumnProjection> projections = 
Collections.singletonList(new ColumnProjection(null, new 
IdentifierValue(logicAndCipherColumns.get(each.getIdentifier().getValue()),
+                        each.getIdentifier().getQuoteCharacter()), null));
                 result.add(new 
SubstitutableColumnNameToken(each.getStartIndex(), each.getStopIndex(), 
projections));
             }
         }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/Projection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/Projection.java
index 5b58c4c25f9..fcdca992712 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/Projection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/Projection.java
@@ -17,6 +17,8 @@
 
 package org.apache.shardingsphere.infra.binder.segment.select.projection;
 
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
+
 import java.util.Optional;
 
 /**
@@ -48,8 +50,8 @@ public interface Projection {
     /**
      * Clone with owner.
      * 
-     * @param ownerName owner name
+     * @param ownerIdentifier owner identifier
      * @return new projection
      */
-    Projection cloneWithOwner(String ownerName);
+    Projection cloneWithOwner(IdentifierValue ownerIdentifier);
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngine.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngine.java
index da5e37b9642..2f1eb8fe1d1 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngine.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngine.java
@@ -46,11 +46,14 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.Expressi
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ShorthandProjectionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.SubqueryProjectionSegment;
+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.JoinTableSegment;
 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.statement.dml.SelectStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -119,17 +122,19 @@ public final class ProjectionEngine {
     }
     
     private ShorthandProjection createProjection(final TableSegment table, 
final ShorthandProjectionSegment projectionSegment) {
-        String owner = projectionSegment.getOwner().map(optional -> 
optional.getIdentifier().getValue()).orElse(null);
+        IdentifierValue owner = 
projectionSegment.getOwner().map(OwnerSegment::getIdentifier).orElse(null);
         Collection<Projection> projections = new LinkedHashSet<>();
         projections.addAll(getShorthandColumnsFromSimpleTableSegment(table, 
owner));
         projections.addAll(getShorthandColumnsFromSubqueryTableSegment(table));
         projections.addAll(getShorthandColumnsFromJoinTableSegment(table, 
owner, projectionSegment));
-        return new ShorthandProjection(owner, projections);
+        return new ShorthandProjection(null == owner ? null : 
owner.getValue(), projections);
     }
     
     private ColumnProjection createProjection(final ColumnProjectionSegment 
projectionSegment) {
-        String owner = projectionSegment.getColumn().getOwner().isPresent() ? 
projectionSegment.getColumn().getOwner().get().getIdentifier().getValue() : 
null;
-        return new ColumnProjection(owner, 
projectionSegment.getColumn().getIdentifier().getValue(), 
projectionSegment.getAliasName().orElse(null));
+        IdentifierValue owner = 
projectionSegment.getColumn().getOwner().isPresent() ? 
projectionSegment.getColumn().getOwner().get().getIdentifier() : null;
+        return new ColumnProjection(owner, 
projectionSegment.getColumn().getIdentifier(), 
projectionSegment.getAliasName().isPresent()
+                ? 
projectionSegment.getAlias().map(AliasSegment::getIdentifier).orElse(null)
+                : null);
     }
     
     private ExpressionProjection createProjection(final 
ExpressionProjectionSegment projectionSegment) {
@@ -157,7 +162,7 @@ public final class ProjectionEngine {
         return result;
     }
     
-    private Collection<ColumnProjection> 
getShorthandColumnsFromSimpleTableSegment(final TableSegment table, final 
String owner) {
+    private Collection<ColumnProjection> 
getShorthandColumnsFromSimpleTableSegment(final TableSegment table, final 
IdentifierValue owner) {
         if (!(table instanceof SimpleTableSegment)) {
             return Collections.emptyList();
         }
@@ -169,9 +174,10 @@ public final class ProjectionEngine {
         ShardingSpherePreconditions.checkNotNull(schema, () -> new 
SchemaNotFoundException(schemaName));
         Collection<ColumnProjection> result = new LinkedList<>();
         if (null == owner) {
-            schema.getVisibleColumnNames(tableName).stream().map(each -> new 
ColumnProjection(tableAlias, each, null)).forEach(result::add);
-        } else if (owner.equalsIgnoreCase(tableAlias)) {
-            schema.getVisibleColumnNames(tableName).stream().map(each -> new 
ColumnProjection(owner, each, null)).forEach(result::add);
+            schema.getVisibleColumnNames(tableName).stream().map(each -> new 
ColumnProjection(table.getAlias().map(AliasSegment::getIdentifier)
+                    .orElse(((SimpleTableSegment) 
table).getTableName().getIdentifier()), new IdentifierValue(each, 
databaseType.getQuoteCharacter()), null)).forEach(result::add);
+        } else if (owner.getValue().equalsIgnoreCase(tableAlias)) {
+            schema.getVisibleColumnNames(tableName).stream().map(each -> new 
ColumnProjection(owner, new IdentifierValue(each, 
databaseType.getQuoteCharacter()), null)).forEach(result::add);
         }
         return result;
     }
@@ -183,12 +189,11 @@ public final class ProjectionEngine {
         SelectStatement subSelectStatement = ((SubqueryTableSegment) 
table).getSubquery().getSelect();
         Collection<Projection> projections = 
subSelectStatement.getProjections().getProjections().stream().map(each -> 
createProjection(subSelectStatement.getFrom(), each).orElse(null))
                 .filter(Objects::nonNull).collect(Collectors.toList());
-        String subqueryTableAlias = table.getAliasName().orElse(null);
-        return getSubqueryTableActualProjections(projections, 
subqueryTableAlias);
+        return getSubqueryTableActualProjections(projections, 
table.getAlias().map(AliasSegment::getIdentifier).orElse(null));
     }
     
-    private Collection<Projection> getSubqueryTableActualProjections(final 
Collection<Projection> projections, final String subqueryTableAlias) {
-        if (Strings.isNullOrEmpty(subqueryTableAlias)) {
+    private Collection<Projection> getSubqueryTableActualProjections(final 
Collection<Projection> projections, final IdentifierValue subqueryTableAlias) {
+        if (null == subqueryTableAlias || 
Strings.isNullOrEmpty(subqueryTableAlias.getValue())) {
             return getActualProjections(projections);
         }
         Collection<Projection> result = new LinkedList<>();
@@ -202,7 +207,7 @@ public final class ProjectionEngine {
         return result;
     }
     
-    private Collection<Projection> 
getShorthandColumnsFromJoinTableSegment(final TableSegment table, final String 
owner, final ProjectionSegment projectionSegment) {
+    private Collection<Projection> 
getShorthandColumnsFromJoinTableSegment(final TableSegment table, final 
IdentifierValue owner, final ProjectionSegment projectionSegment) {
         if (!(table instanceof JoinTableSegment)) {
             return Collections.emptyList();
         }
@@ -211,7 +216,7 @@ public final class ProjectionEngine {
         Collection<Projection> remainingProjections = new LinkedList<>();
         for (Projection each : getOriginalProjections(joinTable, 
projectionSegment)) {
             Collection<Projection> actualProjections = 
getActualProjections(Collections.singletonList(each));
-            if (joinTable.getUsing().isEmpty() && !joinTable.isNatural() || 
null != owner && each.getExpression().contains(owner)) {
+            if (joinTable.getUsing().isEmpty() && !joinTable.isNatural() || 
null != owner && each.getExpression().contains(owner.getValue())) {
                 result.addAll(actualProjections);
             } else {
                 remainingProjections.addAll(actualProjections);
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/AggregationDistinctProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/AggregationDistinctProjection.java
index 0d9635f8701..d3651f0966a 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/AggregationDistinctProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/AggregationDistinctProjection.java
@@ -21,6 +21,7 @@ import lombok.Getter;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.Projection;
 import org.apache.shardingsphere.infra.database.type.DatabaseType;
 import org.apache.shardingsphere.sql.parser.sql.common.enums.AggregationType;
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 /**
  * Aggregation distinct projection.
@@ -52,7 +53,7 @@ public final class AggregationDistinctProjection extends 
AggregationProjection {
     }
     
     @Override
-    public Projection cloneWithOwner(final String ownerName) {
+    public Projection cloneWithOwner(final IdentifierValue ownerIdentifier) {
         // TODO replace column owner when AggregationDistinctProjection 
contains owner
         return new AggregationDistinctProjection(startIndex, stopIndex, 
getType(), getInnerExpression(), getAlias().orElse(null), 
distinctInnerExpression, getDatabaseType());
     }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/AggregationProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/AggregationProjection.java
index 7a479b9cf92..f91ca5d9d1f 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/AggregationProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/AggregationProjection.java
@@ -26,6 +26,7 @@ import 
org.apache.shardingsphere.infra.binder.segment.select.projection.Projecti
 import org.apache.shardingsphere.infra.database.type.DatabaseType;
 import 
org.apache.shardingsphere.infra.database.type.SchemaSupportedDatabaseType;
 import org.apache.shardingsphere.sql.parser.sql.common.enums.AggregationType;
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -74,7 +75,7 @@ public class AggregationProjection implements Projection {
     }
     
     @Override
-    public Projection cloneWithOwner(final String ownerName) {
+    public Projection cloneWithOwner(final IdentifierValue owner) {
         // TODO replace column owner when AggregationProjection contains owner
         AggregationProjection result = new AggregationProjection(type, 
innerExpression, alias, databaseType);
         result.setIndex(index);
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ColumnProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ColumnProjection.java
index 43702fda063..65b074d0a48 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ColumnProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ColumnProjection.java
@@ -22,6 +22,8 @@ import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import lombok.ToString;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.Projection;
+import org.apache.shardingsphere.sql.parser.sql.common.enums.QuoteCharacter;
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Optional;
 
@@ -34,29 +36,52 @@ import java.util.Optional;
 @ToString
 public final class ColumnProjection implements Projection {
     
-    private final String owner;
+    private final IdentifierValue ownerIdentifier;
     
-    private final String name;
+    private final IdentifierValue nameIdentifier;
     
-    private final String alias;
+    private final IdentifierValue aliasIdentifier;
+    
+    public ColumnProjection(final String owner, final String name, final 
String alias) {
+        this(null == owner ? null : new IdentifierValue(owner, 
QuoteCharacter.NONE), new IdentifierValue(name, QuoteCharacter.NONE),
+                null == alias ? null : new IdentifierValue(alias, 
QuoteCharacter.NONE));
+    }
+    
+    /**
+     * Get column name.
+     * 
+     * @return column name
+     */
+    public String getName() {
+        return nameIdentifier.getValue();
+    }
+    
+    /**
+     * Get owner.
+     * 
+     * @return owner
+     */
+    public String getOwner() {
+        return null == ownerIdentifier ? null : ownerIdentifier.getValue();
+    }
     
     @Override
     public String getExpression() {
-        return null == owner ? name : owner + "." + name;
+        return null == getOwner() ? getName() : getOwner() + "." + getName();
     }
     
     @Override
     public String getColumnLabel() {
-        return getAlias().orElse(name);
+        return getAlias().orElse(getName());
     }
     
     @Override
     public Optional<String> getAlias() {
-        return Optional.ofNullable(alias);
+        return 
Optional.ofNullable(aliasIdentifier).map(IdentifierValue::getValue);
     }
     
     @Override
-    public Projection cloneWithOwner(final String ownerName) {
-        return new ColumnProjection(ownerName, name, alias);
+    public Projection cloneWithOwner(final IdentifierValue ownerIdentifier) {
+        return new ColumnProjection(ownerIdentifier, nameIdentifier, 
aliasIdentifier);
     }
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/DerivedProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/DerivedProjection.java
index 05d75a2e904..f05b47aaf39 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/DerivedProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/DerivedProjection.java
@@ -23,6 +23,7 @@ import lombok.RequiredArgsConstructor;
 import lombok.ToString;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.Projection;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.SQLSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Optional;
 
@@ -52,7 +53,7 @@ public final class DerivedProjection implements Projection {
     }
     
     @Override
-    public Projection cloneWithOwner(final String ownerName) {
+    public Projection cloneWithOwner(final IdentifierValue ownerIdentifier) {
         return new DerivedProjection(expression, alias, 
derivedProjectionSegment);
     }
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ExpressionProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ExpressionProjection.java
index 97d9199f7f3..91ec030aac4 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ExpressionProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ExpressionProjection.java
@@ -22,6 +22,7 @@ import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import lombok.ToString;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.Projection;
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Optional;
 
@@ -49,7 +50,7 @@ public final class ExpressionProjection implements Projection 
{
     }
     
     @Override
-    public Projection cloneWithOwner(final String ownerName) {
+    public Projection cloneWithOwner(final IdentifierValue ownerIdentifier) {
         // TODO replace column owner when ExpressionProjection contains owner
         return new ExpressionProjection(expression, alias);
     }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ParameterMarkerProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ParameterMarkerProjection.java
index 0a6b452c7e7..3c5609ac769 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ParameterMarkerProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ParameterMarkerProjection.java
@@ -23,6 +23,7 @@ import lombok.RequiredArgsConstructor;
 import lombok.ToString;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.Projection;
 import 
org.apache.shardingsphere.sql.parser.sql.common.enums.ParameterMarkerType;
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Optional;
 
@@ -57,7 +58,7 @@ public final class ParameterMarkerProjection implements 
Projection {
     }
     
     @Override
-    public Projection cloneWithOwner(final String ownerName) {
+    public Projection cloneWithOwner(final IdentifierValue ownerIdentifier) {
         return new ParameterMarkerProjection(parameterMarkerIndex, 
parameterMarkerType, alias);
     }
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ShorthandProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ShorthandProjection.java
index 9640828101c..f503f04fa32 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ShorthandProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/ShorthandProjection.java
@@ -23,6 +23,7 @@ import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import lombok.ToString;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.Projection;
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Collection;
 import java.util.LinkedList;
@@ -81,7 +82,7 @@ public final class ShorthandProjection implements Projection {
     }
     
     @Override
-    public Projection cloneWithOwner(final String ownerName) {
-        return new ShorthandProjection(ownerName, actualColumns);
+    public Projection cloneWithOwner(final IdentifierValue ownerIdentifier) {
+        return new ShorthandProjection(ownerIdentifier.getValue(), 
actualColumns);
     }
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/SubqueryProjection.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/SubqueryProjection.java
index 15769e62a27..2c88e929214 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/SubqueryProjection.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/impl/SubqueryProjection.java
@@ -22,6 +22,7 @@ import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import lombok.ToString;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.Projection;
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 
 import java.util.Optional;
 
@@ -49,7 +50,7 @@ public final class SubqueryProjection implements Projection {
     }
     
     @Override
-    public Projection cloneWithOwner(final String ownerName) {
+    public Projection cloneWithOwner(final IdentifierValue ownerIdentifier) {
         return new SubqueryProjection(expression, alias);
     }
 }
diff --git 
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngineTest.java
 
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngineTest.java
index e8488eb6c2e..5b9c6a11f00 100644
--- 
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngineTest.java
+++ 
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/select/projection/engine/ProjectionEngineTest.java
@@ -31,6 +31,7 @@ import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSp
 import org.apache.shardingsphere.infra.util.spi.type.typed.TypedSPILoader;
 import org.apache.shardingsphere.sql.parser.sql.common.enums.AggregationType;
 import org.apache.shardingsphere.sql.parser.sql.common.enums.JoinType;
+import org.apache.shardingsphere.sql.parser.sql.common.enums.QuoteCharacter;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.complex.CommonExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
@@ -102,6 +103,7 @@ class ProjectionEngineTest {
     void 
assertCreateProjectionWhenProjectionSegmentInstanceOfShorthandProjectionSegmentAndDuplicateTableSegment()
 {
         SimpleTableSegment table = new SimpleTableSegment(new 
TableNameSegment(0, 0, new IdentifierValue("t_order")));
         
when(schema.getVisibleColumnNames("t_order")).thenReturn(Arrays.asList("order_id",
 "content"));
+        when(databaseType.getQuoteCharacter()).thenReturn(QuoteCharacter.NONE);
         Optional<Projection> actual = new 
ProjectionEngine(DefaultDatabase.LOGIC_NAME,
                 Collections.singletonMap(DefaultDatabase.LOGIC_NAME, schema), 
databaseType).createProjection(table, new ShorthandProjectionSegment(0, 0));
         assertTrue(actual.isPresent());
@@ -181,11 +183,12 @@ class ProjectionEngineTest {
     
     @Test
     void 
assertCreateProjectionWhenProjectionSegmentInstanceOfShorthandProjectionSegmentAndJoinTableSegment()
 {
-        SimpleTableSegment ordersTableSegment = new SimpleTableSegment(new 
TableNameSegment(0, 0, new IdentifierValue("t_order")));
         
when(schema.getVisibleColumnNames("t_order")).thenReturn(Arrays.asList("order_id",
 "customer_id"));
+        when(databaseType.getQuoteCharacter()).thenReturn(QuoteCharacter.NONE);
         SimpleTableSegment customersTableSegment = new SimpleTableSegment(new 
TableNameSegment(0, 0, new IdentifierValue("t_customer")));
         
when(schema.getVisibleColumnNames("t_customer")).thenReturn(Collections.singletonList("customer_id"));
         JoinTableSegment table = new JoinTableSegment();
+        SimpleTableSegment ordersTableSegment = new SimpleTableSegment(new 
TableNameSegment(0, 0, new IdentifierValue("t_order")));
         table.setLeft(ordersTableSegment);
         table.setRight(customersTableSegment);
         table.setCondition(new CommonExpressionSegment(0, 0, 
"t_order.customer_id=t_customer.customer_id"));
@@ -277,7 +280,7 @@ class ProjectionEngineTest {
         assertTrue(actual.isPresent());
         assertThat(actual.get(), instanceOf(ShorthandProjection.class));
         assertThat(((ShorthandProjection) 
actual.get()).getActualColumns().size(), is(6));
-        assertThat(((ShorthandProjection) actual.get()).getActualColumns(), 
is(crateExpectedColumnsWithOwner()));
+        assertThat(((ShorthandProjection) actual.get()).getActualColumns(), 
is(crateExpectedColumnsWithOwner(TypedSPILoader.getService(DatabaseType.class, 
"PostgreSQL"))));
     }
     
     @Test
@@ -290,7 +293,7 @@ class ProjectionEngineTest {
         assertTrue(actual.isPresent());
         assertThat(actual.get(), instanceOf(ShorthandProjection.class));
         assertThat(((ShorthandProjection) 
actual.get()).getActualColumns().size(), is(6));
-        assertThat(((ShorthandProjection) actual.get()).getActualColumns(), 
is(crateExpectedColumnsWithOwner()));
+        assertThat(((ShorthandProjection) actual.get()).getActualColumns(), 
is(crateExpectedColumnsWithOwner(TypedSPILoader.getService(DatabaseType.class, 
"MySQL"))));
     }
     
     private JoinTableSegment createJoinTableSegmentWithUsingColumn() {
@@ -309,40 +312,42 @@ class ProjectionEngineTest {
     
     private Collection<Projection> 
crateExpectedColumnsWithoutOwnerForPostgreSQL() {
         Collection<Projection> result = new LinkedHashSet<>();
-        result.add(new ColumnProjection("o", "user_id", null));
-        result.add(new ColumnProjection("o", "order_id", null));
-        result.add(new ColumnProjection("o", "creation_date", null));
-        result.add(new ColumnProjection("o", "status", null));
-        result.add(new ColumnProjection("o", "merchant_id", null));
-        result.add(new ColumnProjection("o", "remark", null));
-        result.add(new ColumnProjection("i", "item_id", null));
-        result.add(new ColumnProjection("i", "product_id", null));
-        result.add(new ColumnProjection("i", "quantity", null));
+        DatabaseType postgresDatabaseType = 
TypedSPILoader.getService(DatabaseType.class, "PostgreSQL");
+        result.add(new ColumnProjection(new IdentifierValue("o"), new 
IdentifierValue("user_id", postgresDatabaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("o"), new 
IdentifierValue("order_id", postgresDatabaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("o"), new 
IdentifierValue("creation_date", postgresDatabaseType.getQuoteCharacter()), 
null));
+        result.add(new ColumnProjection(new IdentifierValue("o"), new 
IdentifierValue("status", postgresDatabaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("o"), new 
IdentifierValue("merchant_id", postgresDatabaseType.getQuoteCharacter()), 
null));
+        result.add(new ColumnProjection(new IdentifierValue("o"), new 
IdentifierValue("remark", postgresDatabaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("i"), new 
IdentifierValue("item_id", postgresDatabaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("i"), new 
IdentifierValue("product_id", postgresDatabaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("i"), new 
IdentifierValue("quantity", postgresDatabaseType.getQuoteCharacter()), null));
         return result;
     }
     
     private Collection<Projection> crateExpectedColumnsWithoutOwnerForMySQL() {
         Collection<Projection> result = new LinkedHashSet<>();
-        result.add(new ColumnProjection("i", "order_id", null));
-        result.add(new ColumnProjection("i", "user_id", null));
-        result.add(new ColumnProjection("i", "creation_date", null));
-        result.add(new ColumnProjection("i", "item_id", null));
-        result.add(new ColumnProjection("i", "product_id", null));
-        result.add(new ColumnProjection("i", "quantity", null));
-        result.add(new ColumnProjection("o", "status", null));
-        result.add(new ColumnProjection("o", "merchant_id", null));
-        result.add(new ColumnProjection("o", "remark", null));
+        DatabaseType mysqlDatabaseType = 
TypedSPILoader.getService(DatabaseType.class, "MySQL");
+        result.add(new ColumnProjection(new IdentifierValue("i"), new 
IdentifierValue("order_id", mysqlDatabaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("i"), new 
IdentifierValue("user_id", mysqlDatabaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("i"), new 
IdentifierValue("creation_date", mysqlDatabaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("i"), new 
IdentifierValue("item_id", mysqlDatabaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("i"), new 
IdentifierValue("product_id", mysqlDatabaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("i"), new 
IdentifierValue("quantity", mysqlDatabaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("o"), new 
IdentifierValue("status", mysqlDatabaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("o"), new 
IdentifierValue("merchant_id", mysqlDatabaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("o"), new 
IdentifierValue("remark", mysqlDatabaseType.getQuoteCharacter()), null));
         return result;
     }
     
-    private Collection<Projection> crateExpectedColumnsWithOwner() {
+    private Collection<Projection> crateExpectedColumnsWithOwner(final 
DatabaseType databaseType) {
         Collection<Projection> result = new LinkedHashSet<>();
-        result.add(new ColumnProjection("o", "order_id", null));
-        result.add(new ColumnProjection("o", "user_id", null));
-        result.add(new ColumnProjection("o", "status", null));
-        result.add(new ColumnProjection("o", "merchant_id", null));
-        result.add(new ColumnProjection("o", "remark", null));
-        result.add(new ColumnProjection("o", "creation_date", null));
+        result.add(new ColumnProjection(new IdentifierValue("o"), new 
IdentifierValue("order_id", databaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("o"), new 
IdentifierValue("user_id", databaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("o"), new 
IdentifierValue("status", databaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("o"), new 
IdentifierValue("merchant_id", databaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("o"), new 
IdentifierValue("remark", databaseType.getQuoteCharacter()), null));
+        result.add(new ColumnProjection(new IdentifierValue("o"), new 
IdentifierValue("creation_date", databaseType.getQuoteCharacter()), null));
         return result;
     }
     
@@ -381,7 +386,7 @@ class ProjectionEngineTest {
         assertTrue(actual.isPresent());
         assertThat(actual.get(), instanceOf(ShorthandProjection.class));
         assertThat(((ShorthandProjection) 
actual.get()).getActualColumns().size(), is(6));
-        assertThat(((ShorthandProjection) actual.get()).getActualColumns(), 
is(crateExpectedColumnsWithOwner()));
+        assertThat(((ShorthandProjection) actual.get()).getActualColumns(), 
is(crateExpectedColumnsWithOwner(TypedSPILoader.getService(DatabaseType.class, 
"PostgreSQL"))));
     }
     
     @Test
@@ -394,7 +399,7 @@ class ProjectionEngineTest {
         assertTrue(actual.isPresent());
         assertThat(actual.get(), instanceOf(ShorthandProjection.class));
         assertThat(((ShorthandProjection) 
actual.get()).getActualColumns().size(), is(6));
-        assertThat(((ShorthandProjection) actual.get()).getActualColumns(), 
is(crateExpectedColumnsWithOwner()));
+        assertThat(((ShorthandProjection) actual.get()).getActualColumns(), 
is(crateExpectedColumnsWithOwner(TypedSPILoader.getService(DatabaseType.class, 
"MySQL"))));
     }
     
     private JoinTableSegment createJoinTableSegmentWithNaturalJoin() {
diff --git 
a/infra/rewrite/src/main/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameToken.java
 
b/infra/rewrite/src/main/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameToken.java
index 33fdcdbef0a..be67b190489 100644
--- 
a/infra/rewrite/src/main/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameToken.java
+++ 
b/infra/rewrite/src/main/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameToken.java
@@ -128,9 +128,9 @@ public final class SubstitutableColumnNameToken extends 
SQLToken implements Subs
             QuoteCharacter ownerQuoteCharacter = 
tableAliasSegments.containsKey(owner.toLowerCase()) ? 
tableAliasSegments.get(owner.toLowerCase()).getIdentifier().getQuoteCharacter() 
: quoteCharacter;
             
builder.append(ownerQuoteCharacter.wrap(logicActualTableNames.getOrDefault(owner,
 owner))).append('.');
         }
-        builder.append(quoteCharacter.wrap(columnProjection.getName()));
+        
builder.append(columnProjection.getNameIdentifier().getQuoteCharacter().wrap(columnProjection.getName()));
         if (columnProjection.getAlias().isPresent()) {
-            builder.append(" AS 
").append(quoteCharacter.wrap(columnProjection.getAlias().get()));
+            builder.append(" AS 
").append(columnProjection.getAliasIdentifier().getQuoteCharacter().wrap(columnProjection.getAlias().get()));
         }
         return builder.toString();
     }
diff --git 
a/infra/rewrite/src/test/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameTokenTest.java
 
b/infra/rewrite/src/test/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameTokenTest.java
index d09b5634f6d..806d2e738d5 100644
--- 
a/infra/rewrite/src/test/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameTokenTest.java
+++ 
b/infra/rewrite/src/test/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameTokenTest.java
@@ -43,13 +43,15 @@ class SubstitutableColumnNameTokenTest {
     
     @Test
     void assertToStringWithQuote() {
-        Collection<ColumnProjection> projections = 
Collections.singletonList(new ColumnProjection(null, "id", "id"));
+        Collection<ColumnProjection> projections = 
Collections.singletonList(new ColumnProjection(null,
+                new IdentifierValue("id", QuoteCharacter.BACK_QUOTE), new 
IdentifierValue("id", QuoteCharacter.BACK_QUOTE)));
         assertThat(new SubstitutableColumnNameToken(0, 1, projections, 
QuoteCharacter.BACK_QUOTE, 
Collections.emptyList()).toString(mock(RouteUnit.class)), is("`id` AS `id`"));
     }
     
     @Test
     void assertToStringWithAliasQuote() {
-        Collection<ColumnProjection> projections = 
Collections.singletonList(new ColumnProjection("temp", "id", "id"));
+        Collection<ColumnProjection> projections = 
Collections.singletonList(new ColumnProjection(new IdentifierValue("temp", 
QuoteCharacter.BACK_QUOTE),
+                new IdentifierValue("id", QuoteCharacter.BACK_QUOTE), new 
IdentifierValue("id", QuoteCharacter.BACK_QUOTE)));
         SimpleTableSegment tableSegment = new SimpleTableSegment(new 
TableNameSegment(0, 0, new IdentifierValue("t_order")));
         tableSegment.setAlias(new AliasSegment(0, 0, new 
IdentifierValue("`temp`")));
         assertThat(new SubstitutableColumnNameToken(0, 1, projections, 
QuoteCharacter.BACK_QUOTE, 
Collections.singletonList(tableSegment)).toString(mock(RouteUnit.class)), 
is("`temp`.`id` AS `id`"));
diff --git 
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/value/identifier/IdentifierValue.java
 
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/value/identifier/IdentifierValue.java
index b49c611ed96..65e6493b701 100644
--- 
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/value/identifier/IdentifierValue.java
+++ 
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/value/identifier/IdentifierValue.java
@@ -18,6 +18,7 @@
 package org.apache.shardingsphere.sql.parser.sql.common.value.identifier;
 
 import com.google.common.base.Strings;
+import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import lombok.ToString;
@@ -30,6 +31,7 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.value.ValueASTNode;
  */
 @RequiredArgsConstructor
 @Getter
+@EqualsAndHashCode
 @ToString
 public final class IdentifierValue implements ValueASTNode<String> {
     
diff --git 
a/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/select/select-subquery.xml
 
b/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/select/select-subquery.xml
index f2559faf53d..34cc55636b7 100644
--- 
a/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/select/select-subquery.xml
+++ 
b/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/select/select-subquery.xml
@@ -94,7 +94,7 @@
 
     <rewrite-assertion 
id="select_not_nested_subquery_in_tablesegment_ref_shorthand" db-types="MySQL">
         <input sql="SELECT b.* FROM (SELECT a.certificate_number as 
certificate_number, a.amount FROM t_account a WHERE a.amount = 1373) b" />
-        <output sql="SELECT b.`cipher_certificate_number` AS 
`certificate_number`, b.`cipher_amount` AS `amount` FROM (SELECT 
a.cipher_certificate_number, a.assisted_query_certificate_number, 
a.cipher_amount FROM t_account a WHERE a.cipher_amount = 'encrypt_1373') b" />
+        <output sql="SELECT b.cipher_certificate_number AS certificate_number, 
b.cipher_amount AS amount FROM (SELECT a.cipher_certificate_number, 
a.assisted_query_certificate_number, a.cipher_amount FROM t_account a WHERE 
a.cipher_amount = 'encrypt_1373') b" />
     </rewrite-assertion>
 
     <rewrite-assertion id="select_with_exists_sub_query" db-types="MySQL">

Reply via email to