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">