You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2023/06/06 02:30:36 UTC
[shardingsphere] branch master updated: Fix encrypt ShorthandProjection expand with/ without quote (#26033)
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 <ch...@qq.com>
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">