This is an automated email from the ASF dual-hosted git repository.
zhaojinchao 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 27638ef7803 Add SubqueryNestedInBinaryOperationEncryptorChecker and
refactor encrypt sql rewrite (#38245)
27638ef7803 is described below
commit 27638ef780347c32387ffa56bfd90639fd93b4f4
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Fri Feb 27 18:57:38 2026 +0800
Add SubqueryNestedInBinaryOperationEncryptorChecker and refactor encrypt
sql rewrite (#38245)
* Add SubqueryNestedInBinaryOperationEncryptorChecker and refactor encrypt
sql rewrite
* Fix sql rewrite it
---
...eryNestedInBinaryOperationEncryptorChecker.java | 133 ++++++++++++++++++
.../encrypt/enums/EncryptDerivedColumnSuffix.java | 6 +-
.../EncryptProjectionTokenGenerator.java | 140 +++++++++++++++----
.../EncryptPredicateColumnTokenGeneratorTest.java | 2 +-
.../dml/expression/type/ColumnSegmentBinder.java | 48 ++++++-
.../dml/from/type/SubqueryTableSegmentBinder.java | 5 +-
.../pojo/generic/SubstitutableColumnNameToken.java | 11 +-
.../parser/statement/core/enums/SubqueryType.java | 2 +-
.../statement/core/extractor/ColumnExtractor.java | 45 +++++++
.../core/extractor/ExpressionExtractor.java | 148 +++++++++++++++++++++
.../core/extractor/SubqueryExtractor.java | 40 +++++-
.../generic/bound/ColumnSegmentBoundInfo.java | 5 +
.../query-with-cipher/dml/insert/insert-select.xml | 4 +-
.../dml/select/select-subquery.xml | 32 ++---
.../dml/select/select-subquery.xml | 16 +--
15 files changed, 571 insertions(+), 66 deletions(-)
diff --git
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/checker/cryptographic/SubqueryNestedInBinaryOperationEncryptorChecker.java
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/checker/cryptographic/SubqueryNestedInBinaryOperationEncryptorChecker.java
new file mode 100644
index 00000000000..1bbf54b91b9
--- /dev/null
+++
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/checker/cryptographic/SubqueryNestedInBinaryOperationEncryptorChecker.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.encrypt.checker.cryptographic;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import
org.apache.shardingsphere.encrypt.rewrite.token.comparator.EncryptorComparator;
+import org.apache.shardingsphere.encrypt.rule.EncryptRule;
+import org.apache.shardingsphere.infra.exception.ShardingSpherePreconditions;
+import
org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.RowExpression;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubqueryExpressionSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubquerySegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ColumnProjectionSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.ColumnSegmentBoundInfo;
+import
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Subquery nested in binary operation encryptor checker.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class SubqueryNestedInBinaryOperationEncryptorChecker {
+
+ /**
+ * Check whether binary operations with subquery use same encryptor.
+ *
+ * @param left left expression
+ * @param right right expression
+ * @param encryptRule encrypt rule
+ * @param scenario scenario
+ */
+ public static void checkIsSame(final ExpressionSegment left, final
ExpressionSegment right, final EncryptRule encryptRule, final String scenario) {
+ if (isNotColumnAndSubquery(left) || isNotColumnAndSubquery(right)) {
+ return;
+ }
+ if (left instanceof RowExpression) {
+ checkRowExpressionEncryptor((RowExpression) left, right,
encryptRule, scenario);
+ return;
+ }
+ if (right instanceof RowExpression) {
+ checkRowExpressionEncryptor((RowExpression) right, left,
encryptRule, scenario);
+ return;
+ }
+ ColumnSegmentBoundInfo leftColumnInfo = left instanceof ColumnSegment
? ((ColumnSegment) left).getColumnBoundInfo() :
getSubqueryColumnBoundInfo(left);
+ ColumnSegmentBoundInfo rightColumnInfo = right instanceof
ColumnSegment ? ((ColumnSegment) right).getColumnBoundInfo() :
getSubqueryColumnBoundInfo(right);
+ checkEncryptorIsSame(leftColumnInfo, rightColumnInfo, encryptRule,
scenario);
+ }
+
+ private static void checkRowExpressionEncryptor(final RowExpression
rowExpression, final ExpressionSegment otherExpression, final EncryptRule
encryptRule, final String scenario) {
+ List<ColumnSegmentBoundInfo> rowColumnInfos =
getRowExpressionColumnBoundInfos(rowExpression);
+ List<ColumnSegmentBoundInfo> otherColumnInfos =
getExpressionColumnBoundInfos(otherExpression, rowColumnInfos.size());
+ for (int i = 0; i < rowColumnInfos.size(); i++) {
+ checkEncryptorIsSame(rowColumnInfos.get(i),
otherColumnInfos.get(i), encryptRule, scenario);
+ }
+ }
+
+ private static List<ColumnSegmentBoundInfo>
getRowExpressionColumnBoundInfos(final RowExpression rowExpression) {
+ List<ColumnSegmentBoundInfo> result = new ArrayList<>();
+ for (ExpressionSegment each : rowExpression.getItems()) {
+ if (each instanceof ColumnSegment) {
+ result.add(((ColumnSegment) each).getColumnBoundInfo());
+ }
+ }
+ return result;
+ }
+
+ private static List<ColumnSegmentBoundInfo>
getExpressionColumnBoundInfos(final ExpressionSegment expression, final int
expectedSize) {
+ if (expression instanceof SubqueryExpressionSegment || expression
instanceof SubquerySegment) {
+ return getSubqueryColumnBoundInfos(expression, expectedSize);
+ }
+ throw new UnsupportedSQLOperationException("Row expression can only
compare with subquery");
+ }
+
+ private static List<ColumnSegmentBoundInfo>
getSubqueryColumnBoundInfos(final ExpressionSegment expression, final int
expectedSize) {
+ ShardingSpherePreconditions.checkState(expression instanceof
SubqueryExpressionSegment || expression instanceof SubquerySegment,
+ () -> new UnsupportedSQLOperationException(String.format("only
support subquery expression or subquery segment, but got %s",
expression.getClass().getName())));
+ SubquerySegment subquerySegment = expression instanceof
SubquerySegment ? (SubquerySegment) expression : ((SubqueryExpressionSegment)
expression).getSubquery();
+ Collection<ProjectionSegment> projections =
subquerySegment.getSelect().getProjections().getProjections();
+ ShardingSpherePreconditions.checkState(projections.size() ==
expectedSize,
+ () -> new
UnsupportedSQLOperationException(String.format("Subquery column count %d does
not match row expression column count %d", projections.size(), expectedSize)));
+ List<ColumnSegmentBoundInfo> result = new ArrayList<>();
+ for (ProjectionSegment each : projections) {
+ result.add(each instanceof ColumnProjectionSegment
+ ? ((ColumnProjectionSegment)
each).getColumn().getColumnBoundInfo()
+ : new ColumnSegmentBoundInfo(new
IdentifierValue(each.getColumnLabel())));
+ }
+ return result;
+ }
+
+ private static ColumnSegmentBoundInfo getSubqueryColumnBoundInfo(final
ExpressionSegment expression) {
+ ShardingSpherePreconditions.checkState(expression instanceof
SubqueryExpressionSegment || expression instanceof SubquerySegment,
+ () -> new UnsupportedSQLOperationException(String.format("only
support subquery expression or subquery segment, but got %s",
expression.getClass().getName())));
+ SubquerySegment subquerySegment = expression instanceof
SubquerySegment ? (SubquerySegment) expression : ((SubqueryExpressionSegment)
expression).getSubquery();
+ ProjectionSegment projection =
subquerySegment.getSelect().getProjections().getProjections().iterator().next();
+ return projection instanceof ColumnProjectionSegment
+ ? ((ColumnProjectionSegment)
projection).getColumn().getColumnBoundInfo()
+ : new ColumnSegmentBoundInfo(new
IdentifierValue(projection.getColumnLabel()));
+ }
+
+ private static boolean isNotColumnAndSubquery(final ExpressionSegment
expression) {
+ return !(expression instanceof ColumnSegment) && !(expression
instanceof RowExpression) && !(expression instanceof SubqueryExpressionSegment)
&& !(expression instanceof SubquerySegment);
+ }
+
+ private static void checkEncryptorIsSame(final ColumnSegmentBoundInfo
leftColumnInfo, final ColumnSegmentBoundInfo rightColumnInfo, final EncryptRule
encryptRule, final String scenario) {
+ if (EncryptorComparator.isSame(encryptRule, leftColumnInfo,
rightColumnInfo)) {
+ return;
+ }
+ String reason = "Can not use different encryptor for " +
leftColumnInfo + " and " + rightColumnInfo + " in " + scenario;
+ throw new UnsupportedSQLOperationException(reason);
+ }
+}
diff --git
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/enums/EncryptDerivedColumnSuffix.java
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/enums/EncryptDerivedColumnSuffix.java
index 742f0c4a222..7cf71277de5 100644
---
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/enums/EncryptDerivedColumnSuffix.java
+++
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/enums/EncryptDerivedColumnSuffix.java
@@ -28,9 +28,9 @@ import
org.apache.shardingsphere.database.connector.core.type.DatabaseTypeRegist
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public enum EncryptDerivedColumnSuffix {
- CIPHER("_CIPHER"),
- ASSISTED_QUERY("_ASSISTED"),
- LIKE_QUERY("_LIKE");
+ CIPHER("_C"),
+ ASSISTED_QUERY("_A"),
+ LIKE_QUERY("_L");
private final String suffix;
diff --git
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/projection/EncryptProjectionTokenGenerator.java
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/projection/EncryptProjectionTokenGenerator.java
index deedc8ee6bf..10a998b551b 100644
---
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/projection/EncryptProjectionTokenGenerator.java
+++
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/projection/EncryptProjectionTokenGenerator.java
@@ -18,6 +18,11 @@
package org.apache.shardingsphere.encrypt.rewrite.token.generator.projection;
import lombok.RequiredArgsConstructor;
+import
org.apache.shardingsphere.database.connector.core.metadata.database.enums.QuoteCharacter;
+import
org.apache.shardingsphere.database.connector.core.metadata.database.metadata.DialectDatabaseMetaData;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import
org.apache.shardingsphere.database.connector.core.type.DatabaseTypeRegistry;
+import
org.apache.shardingsphere.encrypt.checker.cryptographic.SubqueryNestedInBinaryOperationEncryptorChecker;
import org.apache.shardingsphere.encrypt.enums.EncryptDerivedColumnSuffix;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
import org.apache.shardingsphere.encrypt.rule.column.EncryptColumn;
@@ -31,15 +36,20 @@ import
org.apache.shardingsphere.infra.binder.context.segment.select.projection.
import
org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.ColumnProjection;
import
org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.ShorthandProjection;
import
org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
-import
org.apache.shardingsphere.database.connector.core.metadata.database.enums.QuoteCharacter;
-import
org.apache.shardingsphere.database.connector.core.metadata.database.metadata.DialectDatabaseMetaData;
-import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
-import
org.apache.shardingsphere.database.connector.core.type.DatabaseTypeRegistry;
import
org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException;
import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.SQLToken;
import
org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.generic.SubstitutableColumnNameToken;
import org.apache.shardingsphere.sql.parser.statement.core.enums.SubqueryType;
import
org.apache.shardingsphere.sql.parser.statement.core.enums.TableSourceType;
+import
org.apache.shardingsphere.sql.parser.statement.core.extractor.ExpressionExtractor;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BetweenExpression;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BinaryOperationExpression;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExistsSubqueryExpression;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.InExpression;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.QuantifySubqueryExpression;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubqueryExpressionSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubquerySegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ColumnProjectionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ShorthandProjectionSegment;
@@ -49,8 +59,10 @@ import
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.Iden
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map.Entry;
import java.util.Optional;
/**
@@ -82,35 +94,98 @@ public final class EncryptProjectionTokenGenerator {
* @return generated SQL tokens
*/
public Collection<SQLToken> generateSQLTokens(final SelectStatementContext
selectStatementContext) {
- Collection<SQLToken> result = new LinkedList<>();
- selectStatementContext.getSubqueryContexts().values().forEach(each ->
result.addAll(generateSQLTokens(each)));
- result.addAll(generateSelectSQLTokens(selectStatementContext));
+ return generateSQLTokens(selectStatementContext, "");
+ }
+
+ private Collection<SQLToken> generateSQLTokens(final
SelectStatementContext selectStatementContext, final String operator) {
+ Collection<SQLToken> result = new
LinkedList<>(generateSelectSQLTokens(selectStatementContext, operator));
+ Collection<Integer> processedSubqueryStartIndexes = new HashSet<>();
+ for (ExpressionSegment each :
ExpressionExtractor.getNestedSubqueryCompareExpressions(selectStatementContext.getSqlStatement()))
{
+ if (each instanceof BinaryOperationExpression) {
+ BinaryOperationExpression binaryExpression =
(BinaryOperationExpression) each;
+ checkBinaryOperationEncryptor(binaryExpression);
+ generateExpressionSQLTokens(binaryExpression.getLeft(),
selectStatementContext, processedSubqueryStartIndexes, result,
binaryExpression.getOperator());
+ generateExpressionSQLTokens(binaryExpression.getRight(),
selectStatementContext, processedSubqueryStartIndexes, result,
binaryExpression.getOperator());
+ } else if (each instanceof InExpression) {
+ InExpression inExpression = (InExpression) each;
+ checkInExpressionEncryptor(inExpression);
+ generateExpressionSQLTokens(inExpression.getLeft(),
selectStatementContext, processedSubqueryStartIndexes, result, "IN");
+ generateExpressionSQLTokens(inExpression.getRight(),
selectStatementContext, processedSubqueryStartIndexes, result, "IN");
+ } else if (each instanceof BetweenExpression) {
+ BetweenExpression betweenExpression = (BetweenExpression) each;
+ generateExpressionSQLTokens(betweenExpression.getLeft(),
selectStatementContext, processedSubqueryStartIndexes, result, "BETWEEN");
+
generateExpressionSQLTokens(betweenExpression.getBetweenExpr(),
selectStatementContext, processedSubqueryStartIndexes, result, "BETWEEN");
+ generateExpressionSQLTokens(betweenExpression.getAndExpr(),
selectStatementContext, processedSubqueryStartIndexes, result, "BETWEEN");
+ }
+ }
+ for (Entry<Integer, SelectStatementContext> entry :
selectStatementContext.getSubqueryContexts().entrySet()) {
+ if (!processedSubqueryStartIndexes.contains(entry.getKey())) {
+ result.addAll(generateSQLTokens(entry.getValue(), operator));
+ }
+ }
return result;
}
- private Collection<SQLToken> generateSelectSQLTokens(final
SelectStatementContext selectStatementContext) {
+ private void checkBinaryOperationEncryptor(final BinaryOperationExpression
binaryExpression) {
+
SubqueryNestedInBinaryOperationEncryptorChecker.checkIsSame(binaryExpression.getLeft(),
binaryExpression.getRight(), rule, "binary operation with subquery");
+ }
+
+ private void checkInExpressionEncryptor(final InExpression inExpression) {
+
SubqueryNestedInBinaryOperationEncryptorChecker.checkIsSame(inExpression.getLeft(),
inExpression.getRight(), rule, "IN expression with subquery");
+ }
+
+ private void generateExpressionSQLTokens(final ExpressionSegment
expressionSegment, final SelectStatementContext selectStatementContext, final
Collection<Integer> processedSubqueryStartIndexes,
+ final Collection<SQLToken>
result, final String operator) {
+ Integer subqueryStartIndex = getSubqueryStartIndex(expressionSegment);
+ if (null != subqueryStartIndex &&
processedSubqueryStartIndexes.add(subqueryStartIndex)) {
+ SelectStatementContext subqueryContext =
selectStatementContext.getSubqueryContexts().get(subqueryStartIndex);
+ if (null != subqueryContext) {
+ result.addAll(generateSQLTokens(subqueryContext, operator));
+ }
+ }
+ }
+
+ private Integer getSubqueryStartIndex(final ExpressionSegment
expressionSegment) {
+ if (expressionSegment instanceof SubqueryExpressionSegment) {
+ return ((SubqueryExpressionSegment)
expressionSegment).getSubquery().getStartIndex();
+ }
+ if (expressionSegment instanceof SubquerySegment) {
+ return expressionSegment.getStartIndex();
+ }
+ if (expressionSegment instanceof QuantifySubqueryExpression) {
+ return ((QuantifySubqueryExpression)
expressionSegment).getSubquery().getStartIndex();
+ }
+ if (expressionSegment instanceof ExistsSubqueryExpression) {
+ return ((ExistsSubqueryExpression)
expressionSegment).getSubquery().getStartIndex();
+ }
+ return null;
+ }
+
+ private Collection<SQLToken> generateSelectSQLTokens(final
SelectStatementContext selectStatementContext, final String operator) {
Collection<SQLToken> result = new LinkedList<>();
for (ProjectionSegment each :
selectStatementContext.getSqlStatement().getProjections().getProjections()) {
if (each instanceof ColumnProjectionSegment) {
- generateSQLToken(selectStatementContext,
(ColumnProjectionSegment) each).ifPresent(result::add);
+ generateSQLToken(selectStatementContext,
(ColumnProjectionSegment) each, operator).ifPresent(result::add);
} else if (each instanceof ShorthandProjectionSegment) {
ShorthandProjectionSegment shorthandSegment =
(ShorthandProjectionSegment) each;
Collection<Projection> actualColumns =
getShorthandProjection(shorthandSegment,
selectStatementContext.getProjectionsContext()).getActualColumns();
if (!actualColumns.isEmpty()) {
- result.add(generateSQLToken(shorthandSegment,
actualColumns, selectStatementContext.getSqlStatement().getDatabaseType(),
selectStatementContext.getSubqueryType()));
+ result.add(generateSQLToken(shorthandSegment,
actualColumns, selectStatementContext.getSqlStatement().getDatabaseType(),
+ selectStatementContext.getSubqueryType(),
selectStatementContext, operator));
}
}
}
return result;
}
- private Optional<SubstitutableColumnNameToken> generateSQLToken(final
SelectStatementContext selectStatementContext, final ColumnProjectionSegment
columnSegment) {
+ private Optional<SubstitutableColumnNameToken> generateSQLToken(final
SelectStatementContext selectStatementContext, final ColumnProjectionSegment
columnSegment,
+ final
String operator) {
ColumnProjection columnProjection =
buildColumnProjection(columnSegment);
String columnName = columnProjection.getOriginalColumn().getValue();
Optional<EncryptTable> encryptTable =
rule.findEncryptTable(columnProjection.getOriginalTable().getValue());
if (encryptTable.isPresent() &&
encryptTable.get().isEncryptColumn(columnName)) {
EncryptColumn encryptColumn =
encryptTable.get().getEncryptColumn(columnName);
- Collection<Projection> projections =
generateProjections(encryptColumn, columnProjection,
selectStatementContext.getSubqueryType());
+ Collection<Projection> projections =
generateProjections(encryptColumn, columnProjection,
selectStatementContext.getSubqueryType(), operator);
int startIndex = getStartIndex(columnSegment);
int stopIndex = getStopIndex(columnSegment);
previousSQLTokens.removeIf(each -> each.getStartIndex() ==
startIndex);
@@ -120,7 +195,7 @@ public final class EncryptProjectionTokenGenerator {
}
private SubstitutableColumnNameToken generateSQLToken(final
ShorthandProjectionSegment segment, final Collection<Projection> actualColumns,
final DatabaseType databaseType,
- final SubqueryType
subqueryType) {
+ final SubqueryType
subqueryType, final SelectStatementContext selectStatementContext, final String
operator) {
Collection<Projection> projections = new LinkedList<>();
for (Projection each : actualColumns) {
if (each instanceof ColumnProjection) {
@@ -128,7 +203,7 @@ public final class EncryptProjectionTokenGenerator {
Optional<EncryptTable> encryptTable =
rule.findEncryptTable(columnProjection.getOriginalTable().getValue());
if (encryptTable.isPresent() &&
encryptTable.get().isEncryptColumn(columnProjection.getOriginalColumn().getValue()))
{
EncryptColumn encryptColumn =
encryptTable.get().getEncryptColumn(columnProjection.getOriginalColumn().getValue());
- projections.addAll(generateProjections(encryptColumn,
columnProjection, subqueryType));
+ projections.addAll(generateProjections(encryptColumn,
columnProjection, subqueryType, operator));
continue;
}
}
@@ -160,7 +235,7 @@ public final class EncryptProjectionTokenGenerator {
segment.getColumn().getLeftParentheses().orElse(null),
segment.getColumn().getRightParentheses().orElse(null),
segment.getColumn().getColumnBoundInfo());
}
- private Collection<Projection> generateProjections(final EncryptColumn
encryptColumn, final ColumnProjection columnProjection, final SubqueryType
subqueryType) {
+ private Collection<Projection> generateProjections(final EncryptColumn
encryptColumn, final ColumnProjection columnProjection, final SubqueryType
subqueryType, final String subqueryOperator) {
if (null == subqueryType || SubqueryType.PROJECTION == subqueryType) {
return Collections.singleton(generateProjection(encryptColumn,
columnProjection));
}
@@ -168,9 +243,9 @@ public final class EncryptProjectionTokenGenerator {
return generateProjectionsInTableSegmentSubquery(encryptColumn,
columnProjection);
}
if (SubqueryType.PREDICATE == subqueryType) {
- return
Collections.singleton(generateProjectionInPredicateSubquery(encryptColumn,
columnProjection));
+ return
Collections.singleton(generateProjectionInPredicateSubquery(encryptColumn,
columnProjection, subqueryOperator));
}
- if (SubqueryType.INSERT_SELECT == subqueryType ||
SubqueryType.VIEW_DEFINITION == subqueryType) {
+ if (SubqueryType.INSERT_SELECT == subqueryType) {
return generateProjectionsInInsertSelectSubquery(encryptColumn,
columnProjection);
}
throw new UnsupportedSQLOperationException(
@@ -245,29 +320,42 @@ public final class EncryptProjectionTokenGenerator {
columnProjection.getRightParentheses().orElse(null)));
}
- private ColumnProjection generateProjectionInPredicateSubquery(final
EncryptColumn encryptColumn, final ColumnProjection columnProjection) {
+ private Projection generateProjectionInPredicateSubquery(final
EncryptColumn encryptColumn, final ColumnProjection columnProjection, final
String subqueryOperator) {
QuoteCharacter quoteCharacter =
columnProjection.getName().getQuoteCharacter();
ParenthesesSegment leftParentheses =
columnProjection.getLeftParentheses().orElse(null);
ParenthesesSegment rightParentheses =
columnProjection.getRightParentheses().orElse(null);
IdentifierValue owner = columnProjection.getOwner().orElse(null);
- return encryptColumn.getAssistedQuery()
- .map(optional -> new ColumnProjection(owner, new
IdentifierValue(optional.getName(), quoteCharacter), null, databaseType,
leftParentheses, rightParentheses))
- .orElseGet(() -> new ColumnProjection(owner, new
IdentifierValue(encryptColumn.getCipher().getName(), quoteCharacter),
columnProjection.getAlias().orElse(columnProjection.getName()),
- databaseType, leftParentheses, rightParentheses));
+ // SPEX CHANGED: BEGIN
+ Optional<String> derivedColumnName =
getDerivedColumnName(encryptColumn, columnProjection);
+ String columnProjectionName = derivedColumnName.orElseGet(() ->
columnProjection.getName().getValue());
+ if (!derivedColumnName.isPresent()) {
+ columnProjectionName =
encryptColumn.getAssistedQuery().map(AssistedQueryColumnItem::getName).orElse(encryptColumn.getCipher().getName());
+ }
+ return new ColumnProjection(owner, new
IdentifierValue(columnProjectionName, quoteCharacter),
+
columnProjection.getAlias().orElse(columnProjection.getName()), databaseType,
leftParentheses, rightParentheses);
+ }
+
+ private Optional<String> getDerivedColumnName(final EncryptColumn
encryptColumn, final ColumnProjection columnProjection) {
+ if (TableSourceType.TEMPORARY_TABLE ==
columnProjection.getColumnBoundInfo().getTableSourceType()) {
+ EncryptDerivedColumnSuffix derivedColumnSuffix =
encryptColumn.getAssistedQuery().map(optional ->
EncryptDerivedColumnSuffix.ASSISTED_QUERY).orElse(EncryptDerivedColumnSuffix.CIPHER);
+ return
Optional.of(derivedColumnSuffix.getDerivedColumnName(columnProjection.getName().getValue(),
databaseType));
+ }
+ return Optional.empty();
}
private Collection<Projection>
generateProjectionsInInsertSelectSubquery(final EncryptColumn encryptColumn,
final ColumnProjection columnProjection) {
- QuoteCharacter quoteCharacter =
columnProjection.getName().getQuoteCharacter();
- IdentifierValue columnName = new
IdentifierValue(encryptColumn.getCipher().getName(), quoteCharacter);
+ IdentifierValue columnName = new
IdentifierValue(encryptColumn.getCipher().getName(),
columnProjection.getName().getQuoteCharacter());
Collection<Projection> result = new LinkedList<>();
ParenthesesSegment leftParentheses =
columnProjection.getLeftParentheses().orElse(null);
ParenthesesSegment rightParentheses =
columnProjection.getRightParentheses().orElse(null);
result.add(new
ColumnProjection(columnProjection.getOwner().orElse(null), columnName, null,
databaseType, leftParentheses, rightParentheses));
IdentifierValue columOwner = columnProjection.getOwner().orElse(null);
encryptColumn.getAssistedQuery()
- .ifPresent(optional -> result.add(new
ColumnProjection(columOwner, new IdentifierValue(optional.getName(),
quoteCharacter), null, databaseType, leftParentheses, rightParentheses)));
+ .ifPresent(optional -> result.add(
+ new ColumnProjection(columOwner, new
IdentifierValue(optional.getName(),
dialectDatabaseMetaData.getQuoteCharacter()), null, databaseType,
leftParentheses, rightParentheses)));
encryptColumn.getLikeQuery()
- .ifPresent(optional -> result.add(new
ColumnProjection(columOwner, new IdentifierValue(optional.getName(),
quoteCharacter), null, databaseType, leftParentheses, rightParentheses)));
+ .ifPresent(optional -> result.add(
+ new ColumnProjection(columOwner, new
IdentifierValue(optional.getName(),
dialectDatabaseMetaData.getQuoteCharacter()), null, databaseType,
leftParentheses, rightParentheses)));
return result;
}
diff --git
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/predicate/EncryptPredicateColumnTokenGeneratorTest.java
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/predicate/EncryptPredicateColumnTokenGeneratorTest.java
index 5cf38f26dd3..96cccf283d3 100644
---
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/predicate/EncryptPredicateColumnTokenGeneratorTest.java
+++
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/predicate/EncryptPredicateColumnTokenGeneratorTest.java
@@ -47,6 +47,6 @@ class EncryptPredicateColumnTokenGeneratorTest {
void assertGenerateSQLTokenFromGenerateNewSQLToken() {
Collection<SQLToken> substitutableColumnNameTokens =
generator.generateSQLTokens(EncryptGeneratorFixtureBuilder.createUpdateStatementContext());
assertThat(substitutableColumnNameTokens.size(), is(1));
- assertThat(((SubstitutableColumnNameToken)
substitutableColumnNameTokens.iterator().next()).toString(null),
is("pwd_ASSISTED"));
+ assertThat(((SubstitutableColumnNameToken)
substitutableColumnNameTokens.iterator().next()).toString(null), is("pwd_A"));
}
}
diff --git
a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/expression/type/ColumnSegmentBinder.java
b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/expression/type/ColumnSegmentBinder.java
index f44b163d477..498a06d7cec 100644
---
a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/expression/type/ColumnSegmentBinder.java
+++
b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/expression/type/ColumnSegmentBinder.java
@@ -36,8 +36,12 @@ import
org.apache.shardingsphere.infra.exception.kernel.metadata.ColumnNotFoundE
import
org.apache.shardingsphere.infra.exception.kernel.syntax.AmbiguousColumnException;
import
org.apache.shardingsphere.sql.parser.statement.core.enums.TableSourceType;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.FunctionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ColumnProjectionSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ExpressionProjectionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.SubqueryProjectionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.ColumnSegmentBoundInfo;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.TableSegmentBoundInfo;
@@ -120,7 +124,7 @@ public final class ColumnSegmentBinder {
return getTableBinderContextByOwner(owner, tableBinderContexts,
outerTableBinderContexts, binderContext.getExternalTableBinderContexts());
}
if (!binderContext.getJoinTableProjectionSegments().isEmpty() &&
isNeedUseJoinTableProjectionBind(segment, parentSegmentType, binderContext)) {
- return Collections.singleton(new
SimpleTableSegmentBinderContext(binderContext.getJoinTableProjectionSegments(),
TableSourceType.TEMPORARY_TABLE));
+ return Collections.singleton(new
SimpleTableSegmentBinderContext(binderContext.getJoinTableProjectionSegments(),
TableSourceType.MIXED_TABLE));
}
return tableBinderContexts.values();
}
@@ -154,10 +158,12 @@ public final class ColumnSegmentBinder {
final
SQLStatementBinderContext binderContext) {
ColumnSegmentInfo result =
getInputInfoFromTableBinderContexts(tableBinderContexts, segment,
parentSegmentType);
if (!result.getInputColumnSegment().isPresent()) {
- result = new
ColumnSegmentInfo(findInputColumnSegmentFromOuterTable(segment,
outerTableBinderContexts).orElse(null), TableSourceType.TEMPORARY_TABLE);
+ ColumnSegment inputColumnSegment =
findInputColumnSegmentFromOuterTable(segment,
outerTableBinderContexts).orElse(null);
+ result = new ColumnSegmentInfo(inputColumnSegment, null ==
inputColumnSegment ? TableSourceType.TEMPORARY_TABLE :
inputColumnSegment.getColumnBoundInfo().getTableSourceType());
}
if (!result.getInputColumnSegment().isPresent()) {
- result = new
ColumnSegmentInfo(findInputColumnSegmentFromExternalTables(segment,
binderContext.getExternalTableBinderContexts()).orElse(null),
TableSourceType.TEMPORARY_TABLE);
+ ColumnSegment inputColumnSegment =
findInputColumnSegmentFromExternalTables(segment,
binderContext.getExternalTableBinderContexts()).orElse(null);
+ result = new ColumnSegmentInfo(inputColumnSegment, null ==
inputColumnSegment ? TableSourceType.TEMPORARY_TABLE :
inputColumnSegment.getColumnBoundInfo().getTableSourceType());
}
if (!result.getInputColumnSegment().isPresent()) {
result = new
ColumnSegmentInfo(findInputColumnSegmentByVariables(segment,
binderContext.getSqlStatement().getVariableNames()).orElse(null),
TableSourceType.TEMPORARY_TABLE);
@@ -184,6 +190,9 @@ public final class ColumnSegmentBinder {
() -> new
AmbiguousColumnException(segment.getExpression(),
SEGMENT_TYPE_MESSAGES.getOrDefault(parentSegmentType,
UNKNOWN_SEGMENT_TYPE_MESSAGE)));
}
inputColumnSegment = getColumnSegment(projectionSegment.get());
+ // SPEX ADDED: BEGIN
+ // NOTE: MIXED_TABLE 用于表示 JOIN
之后的字段,其中可能会包含部分物理表字段,以及派生的临时表字段,同层级查询的 ORDER BY, GROUP BY, HAVING 会引用 JOIN 之后的字段
+ // SPEX ADDED: END
tableSourceType = TableSourceType.MIXED_TABLE ==
each.getTableSourceType() ?
getTableSourceTypeFromInputColumn(inputColumnSegment) :
each.getTableSourceType();
if (each instanceof SimpleTableSegmentBinderContext &&
((SimpleTableSegmentBinderContext) each).isFromWithSegment()) {
break;
@@ -200,9 +209,38 @@ public final class ColumnSegmentBinder {
if (projectionSegment instanceof ColumnProjectionSegment) {
return ((ColumnProjectionSegment) projectionSegment).getColumn();
}
+ // SPEX ADDED: BEGIN
+ if (projectionSegment instanceof ExpressionProjectionSegment
+ && ((ExpressionProjectionSegment) projectionSegment).getExpr()
instanceof FunctionSegment) {
+ Optional<ColumnSegment> columnSegment =
getFirstColumnParameter(((FunctionSegment) ((ExpressionProjectionSegment)
projectionSegment).getExpr()).getParameters());
+ if (columnSegment.isPresent()) {
+ return columnSegment.get();
+ }
+ }
+ if (projectionSegment instanceof SubqueryProjectionSegment && 1 ==
((SubqueryProjectionSegment)
projectionSegment).getSubquery().getSelect().getProjections().getProjections().size())
{
+ return getColumnSegment(((SubqueryProjectionSegment)
projectionSegment).getSubquery().getSelect().getProjections().getProjections().iterator().next());
+ }
+ // SPEX ADDED: END
return new ColumnSegment(0, 0, new
IdentifierValue(projectionSegment.getColumnLabel()));
}
+ private static Optional<ColumnSegment> getFirstColumnParameter(final
Collection<ExpressionSegment> parameters) {
+ int count = 0;
+ ColumnSegment columnSegment = null;
+ // TODO consider how to bind multi parameters
+ for (ExpressionSegment each : parameters) {
+ if (each instanceof ColumnSegment) {
+ count++;
+ columnSegment = (ColumnSegment) each;
+ }
+ }
+ if (1 == count) {
+ return Optional.of(columnSegment);
+ } else {
+ return Optional.empty();
+ }
+ }
+
private static Optional<ColumnSegment>
findInputColumnSegmentByPivotColumns(final ColumnSegment segment, final
Collection<String> pivotColumnNames) {
return pivotColumnNames.isEmpty() ||
!pivotColumnNames.contains(segment.getIdentifier().getValue()) ?
Optional.empty() : Optional.of(new ColumnSegment(0, 0,
segment.getIdentifier()));
}
@@ -313,7 +351,9 @@ public final class ColumnSegmentBinder {
: segmentOriginalTable;
IdentifierValue segmentOriginalColumn =
segment.getColumnBoundInfo().getOriginalColumn();
IdentifierValue originalColumn =
Optional.ofNullable(inputColumnSegment).map(optional ->
optional.getColumnBoundInfo().getOriginalColumn()).orElse(segmentOriginalColumn);
- return new ColumnSegmentBoundInfo(new
TableSegmentBoundInfo(originalDatabase, originalSchema), originalTable,
originalColumn, tableSourceType);
+ ColumnSegmentBoundInfo result = new ColumnSegmentBoundInfo(new
TableSegmentBoundInfo(originalDatabase, originalSchema), originalTable,
originalColumn, tableSourceType);
+
Optional.ofNullable(inputColumnSegment).flatMap(ColumnSegment::getOwner).ifPresent(result::setOwner);
+ return result;
}
@RequiredArgsConstructor
diff --git
a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/from/type/SubqueryTableSegmentBinder.java
b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/from/type/SubqueryTableSegmentBinder.java
index 12300a8fe04..db4b5ebff70 100644
---
a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/from/type/SubqueryTableSegmentBinder.java
+++
b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/from/type/SubqueryTableSegmentBinder.java
@@ -18,6 +18,7 @@
package org.apache.shardingsphere.infra.binder.engine.segment.dml.from.type;
import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString;
+import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
@@ -62,7 +63,9 @@ public final class SubqueryTableSegmentBinder {
binderContext.getMetaData(),
binderContext.getCurrentDatabaseName(), binderContext.getHintValueContext(),
segment.getSubquery().getSelect());
subqueryBinderContext.getExternalTableBinderContexts().putAll(binderContext.getExternalTableBinderContexts());
subqueryBinderContext.getCommonTableExpressionsSegmentsUniqueAliases().addAll(binderContext.getCommonTableExpressionsSegmentsUniqueAliases());
- SelectStatement boundSubSelect = new
SelectStatementBinder(outerTableBinderContexts).bind(segment.getSubquery().getSelect(),
subqueryBinderContext);
+ Multimap<CaseInsensitiveString, TableSegmentBinderContext>
subqueryOuterTableBinderContexts =
LinkedHashMultimap.create(outerTableBinderContexts);
+ subqueryOuterTableBinderContexts.putAll(tableBinderContexts);
+ SelectStatement boundSubSelect = new
SelectStatementBinder(subqueryOuterTableBinderContexts).bind(segment.getSubquery().getSelect(),
subqueryBinderContext);
binderContext.getCommonTableExpressionsSegmentsUniqueAliases().addAll(subqueryBinderContext.getCommonTableExpressionsSegmentsUniqueAliases());
SubquerySegment boundSubquerySegment = new
SubquerySegment(segment.getSubquery().getStartIndex(),
segment.getSubquery().getStopIndex(), boundSubSelect,
segment.getSubquery().getText());
IdentifierValue subqueryTableName =
segment.getAliasSegment().map(AliasSegment::getIdentifier).orElseGet(() -> new
IdentifierValue(""));
diff --git
a/infra/rewrite/core/src/main/java/org/apache/shardingsphere/infra/rewrite/sql/token/common/pojo/generic/SubstitutableColumnNameToken.java
b/infra/rewrite/core/src/main/java/org/apache/shardingsphere/infra/rewrite/sql/token/common/pojo/generic/SubstitutableColumnNameToken.java
index ff664098d33..ecff4f7980b 100644
---
a/infra/rewrite/core/src/main/java/org/apache/shardingsphere/infra/rewrite/sql/token/common/pojo/generic/SubstitutableColumnNameToken.java
+++
b/infra/rewrite/core/src/main/java/org/apache/shardingsphere/infra/rewrite/sql/token/common/pojo/generic/SubstitutableColumnNameToken.java
@@ -24,6 +24,7 @@ import
org.apache.shardingsphere.database.connector.core.type.DatabaseType;
import
org.apache.shardingsphere.database.connector.core.type.DatabaseTypeRegistry;
import
org.apache.shardingsphere.infra.binder.context.segment.select.projection.Projection;
import
org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.ColumnProjection;
+import
org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.DerivedProjection;
import
org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.RouteUnitAware;
import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.SQLToken;
import
org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.Substitutable;
@@ -63,8 +64,13 @@ public final class SubstitutableColumnNameToken extends
SQLToken implements Subs
@Override
public String toString(final RouteUnit routeUnit) {
- Map<String, String> logicAndActualTables =
getLogicAndActualTables(routeUnit);
StringBuilder result = new StringBuilder();
+ appendProjections(routeUnit, result);
+ return result.toString();
+ }
+
+ private void appendProjections(final RouteUnit routeUnit, final
StringBuilder result) {
+ Map<String, String> logicAndActualTables =
getLogicAndActualTables(routeUnit);
int index = 0;
for (Projection each : projections) {
if (index > 0) {
@@ -73,7 +79,6 @@ public final class SubstitutableColumnNameToken extends
SQLToken implements Subs
result.append(getColumnExpression(each, logicAndActualTables));
index++;
}
- return result.toString();
}
private Map<String, String> getLogicAndActualTables(final RouteUnit
routeUnit) {
@@ -91,6 +96,8 @@ public final class SubstitutableColumnNameToken extends
SQLToken implements Subs
StringBuilder builder = new StringBuilder();
if (projection instanceof ColumnProjection) {
appendColumnProjection((ColumnProjection) projection,
logicActualTableNames, builder);
+ } else if (projection instanceof DerivedProjection) {
+ builder.append(projection.getExpression());
} else {
builder.append(quoteCharacter.wrap(projection.getColumnLabel()));
}
diff --git
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/enums/SubqueryType.java
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/enums/SubqueryType.java
index dfb1fd59ff5..78990134e31 100644
---
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/enums/SubqueryType.java
+++
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/enums/SubqueryType.java
@@ -22,5 +22,5 @@ package
org.apache.shardingsphere.sql.parser.statement.core.enums;
*/
public enum SubqueryType {
- PROJECTION, TABLE, JOIN, PREDICATE, INSERT_SELECT, EXISTS, WITH,
VIEW_DEFINITION, UPDATE_JOIN, DELETE_JOIN
+ PROJECTION, TABLE, JOIN, PREDICATE, INSERT_SELECT, EXISTS, WITH,
VIEW_DEFINITION, UPDATE_JOIN, DELETE_JOIN, GROUP_BY, ORDER_BY, FUNCTION
}
diff --git
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/extractor/ColumnExtractor.java
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/extractor/ColumnExtractor.java
index 513684908eb..f6e927238fa 100644
---
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/extractor/ColumnExtractor.java
+++
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/extractor/ColumnExtractor.java
@@ -22,10 +22,14 @@ import lombok.NoArgsConstructor;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BetweenExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BinaryOperationExpression;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.CaseWhenExpression;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.CollateExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.FunctionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.InExpression;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.NotExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.RowExpression;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.UnaryOperationExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.complex.CommonTableExpressionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.AggregationProjectionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ColumnProjectionSegment;
@@ -84,6 +88,45 @@ public final class ColumnExtractor {
if (expression instanceof FunctionSegment) {
extractColumnsInFunctionSegment((FunctionSegment) expression,
result);
}
+ if (expression instanceof CaseWhenExpression) {
+ extractColumnsInCaseWhenExpression((CaseWhenExpression)
expression, result);
+ }
+ if (expression instanceof NotExpression) {
+ result.addAll(extract(((NotExpression)
expression).getExpression()));
+ }
+ if (expression instanceof UnaryOperationExpression) {
+ result.addAll(extract(((UnaryOperationExpression)
expression).getExpression()));
+ }
+ if (expression instanceof CollateExpression) {
+ ((CollateExpression) expression).getExpr().ifPresent(optional ->
result.addAll(extract(optional)));
+ }
+ if (expression instanceof RowExpression) {
+ extractColumnsInRowExpression((RowExpression) expression, result);
+ }
+ return result;
+ }
+
+ private static void extractColumnsInCaseWhenExpression(final
CaseWhenExpression expression, final Collection<ColumnSegment> result) {
+ if (null != expression.getCaseExpr()) {
+
result.addAll(extractIncludeColumnSegment(expression.getCaseExpr()));
+ }
+ if (null != expression.getWhenExprs()) {
+
expression.getWhenExprs().stream().map(ColumnExtractor::extractIncludeColumnSegment).forEach(result::addAll);
+ }
+ if (null != expression.getThenExprs()) {
+
expression.getThenExprs().stream().map(ColumnExtractor::extractIncludeColumnSegment).forEach(result::addAll);
+ }
+ if (null != expression.getElseExpr()) {
+
result.addAll(extractIncludeColumnSegment(expression.getElseExpr()));
+ }
+ }
+
+ private static Collection<ColumnSegment> extractIncludeColumnSegment(final
ExpressionSegment expression) {
+ Collection<ColumnSegment> result = new LinkedList<>();
+ if (expression instanceof ColumnSegment) {
+ result.add((ColumnSegment) expression);
+ }
+ result.addAll(extract(expression));
return result;
}
@@ -136,6 +179,8 @@ public final class ColumnExtractor {
for (ExpressionSegment each : expression.getItems()) {
if (each instanceof ColumnSegment) {
result.add((ColumnSegment) each);
+ } else {
+ result.addAll(extract(each));
}
}
}
diff --git
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/extractor/ExpressionExtractor.java
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/extractor/ExpressionExtractor.java
index 53bd982365c..254ed1388fd 100644
---
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/extractor/ExpressionExtractor.java
+++
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/extractor/ExpressionExtractor.java
@@ -26,11 +26,13 @@ import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.datetime.
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BetweenExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BinaryOperationExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.CaseWhenExpression;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.CollateExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.FunctionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.InExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ListExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.NotExpression;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.QuantifySubqueryExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.TypeCastExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ValuesExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
@@ -39,11 +41,14 @@ import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subq
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.AggregationProjectionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ExpressionProjectionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.IntervalExpressionProjection;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.join.OuterJoinExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.multiset.MultisetExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.AndPredicate;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.match.MatchAgainstExpression;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.JoinTableSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
import java.util.ArrayList;
import java.util.Collection;
@@ -298,4 +303,147 @@ public final class ExpressionExtractor {
}
return result;
}
+
+ /**
+ * Get nested subquery compare expressions from select statement.
+ * Extract expressions where a subquery is connected by comparison
operators (=, !=, <>, >, <, >=, <=).
+ *
+ * @param selectStatement select statement
+ * @return collection of expressions containing subquery with comparison
operators
+ */
+ public static Collection<ExpressionSegment>
getNestedSubqueryCompareExpressions(final SelectStatement selectStatement) {
+ Collection<ExpressionSegment> result = new LinkedList<>();
+ extractSubqueryCompareExpressionsFromProjections(result,
selectStatement);
+ extractSubqueryCompareExpressionsFromWhere(result, selectStatement);
+ extractSubqueryCompareExpressionsFromHaving(result, selectStatement);
+ extractSubqueryCompareExpressionsFromJoin(result, selectStatement);
+ return result;
+ }
+
+ private static void extractSubqueryCompareExpressionsFromProjections(final
Collection<ExpressionSegment> result, final SelectStatement selectStatement) {
+ for (ProjectionSegment each :
selectStatement.getProjections().getProjections()) {
+ if (each instanceof ExpressionProjectionSegment) {
+ extractSubqueryCompareExpressionsFromExpression(result,
((ExpressionProjectionSegment) each).getExpr());
+ }
+ }
+ }
+
+ private static void extractSubqueryCompareExpressionsFromWhere(final
Collection<ExpressionSegment> result, final SelectStatement selectStatement) {
+ if (selectStatement.getWhere().isPresent()) {
+ extractSubqueryCompareExpressionsFromExpression(result,
selectStatement.getWhere().get().getExpr());
+ }
+ }
+
+ private static void extractSubqueryCompareExpressionsFromHaving(final
Collection<ExpressionSegment> result, final SelectStatement selectStatement) {
+ if (selectStatement.getHaving().isPresent()) {
+ extractSubqueryCompareExpressionsFromExpression(result,
selectStatement.getHaving().get().getExpr());
+ }
+ }
+
+ private static void extractSubqueryCompareExpressionsFromJoin(final
Collection<ExpressionSegment> result, final SelectStatement selectStatement) {
+ if (selectStatement.getFrom().isPresent() &&
selectStatement.getFrom().get() instanceof JoinTableSegment) {
+ extractSubqueryCompareExpressionsFromJoinTableSegment(result,
(JoinTableSegment) selectStatement.getFrom().get());
+ }
+ }
+
+ private static void
extractSubqueryCompareExpressionsFromJoinTableSegment(final
Collection<ExpressionSegment> result, final JoinTableSegment joinTableSegment) {
+ if (null != joinTableSegment.getCondition()) {
+ extractSubqueryCompareExpressionsFromExpression(result,
joinTableSegment.getCondition());
+ }
+ if (joinTableSegment.getLeft() instanceof JoinTableSegment) {
+ extractSubqueryCompareExpressionsFromJoinTableSegment(result,
(JoinTableSegment) joinTableSegment.getLeft());
+ }
+ if (joinTableSegment.getRight() instanceof JoinTableSegment) {
+ extractSubqueryCompareExpressionsFromJoinTableSegment(result,
(JoinTableSegment) joinTableSegment.getRight());
+ }
+ }
+
+ private static void extractSubqueryCompareExpressionsFromExpression(final
Collection<ExpressionSegment> result, final ExpressionSegment
expressionSegment) {
+ if (expressionSegment instanceof BinaryOperationExpression) {
+ BinaryOperationExpression binaryExpression =
(BinaryOperationExpression) expressionSegment;
+ if (isComparisonOperator(binaryExpression.getOperator()) &&
containsSubquery(binaryExpression)) {
+ result.add(binaryExpression);
+ }
+ extractSubqueryCompareExpressionsFromExpression(result,
binaryExpression.getLeft());
+ extractSubqueryCompareExpressionsFromExpression(result,
binaryExpression.getRight());
+ }
+ if (expressionSegment instanceof FunctionSegment) {
+ for (ExpressionSegment each : ((FunctionSegment)
expressionSegment).getParameters()) {
+ extractSubqueryCompareExpressionsFromExpression(result, each);
+ }
+ }
+ if (expressionSegment instanceof CaseWhenExpression) {
+ CaseWhenExpression caseWhenExpression = (CaseWhenExpression)
expressionSegment;
+ extractSubqueryCompareExpressionsFromExpression(result,
caseWhenExpression.getCaseExpr());
+ caseWhenExpression.getWhenExprs().forEach(each ->
extractSubqueryCompareExpressionsFromExpression(result, each));
+ caseWhenExpression.getThenExprs().forEach(each ->
extractSubqueryCompareExpressionsFromExpression(result, each));
+ extractSubqueryCompareExpressionsFromExpression(result,
caseWhenExpression.getElseExpr());
+ }
+ if (expressionSegment instanceof BetweenExpression) {
+ BetweenExpression betweenExpression = (BetweenExpression)
expressionSegment;
+ if (containsSubqueryInBetween(betweenExpression)) {
+ result.add(betweenExpression);
+ }
+ extractSubqueryCompareExpressionsFromExpression(result,
betweenExpression.getLeft());
+ extractSubqueryCompareExpressionsFromExpression(result,
betweenExpression.getBetweenExpr());
+ extractSubqueryCompareExpressionsFromExpression(result,
betweenExpression.getAndExpr());
+ }
+ if (expressionSegment instanceof InExpression) {
+ InExpression inExpression = (InExpression) expressionSegment;
+ if (containsSubqueryInIn(inExpression)) {
+ result.add(inExpression);
+ }
+ extractSubqueryCompareExpressionsFromExpression(result,
inExpression.getLeft());
+ extractSubqueryCompareExpressionsFromExpression(result,
inExpression.getRight());
+ }
+ if (expressionSegment instanceof NotExpression) {
+ extractSubqueryCompareExpressionsFromExpression(result,
((NotExpression) expressionSegment).getExpression());
+ }
+ if (expressionSegment instanceof ListExpression) {
+ for (ExpressionSegment each : ((ListExpression)
expressionSegment).getItems()) {
+ extractSubqueryCompareExpressionsFromExpression(result, each);
+ }
+ }
+ if (expressionSegment instanceof CollateExpression) {
+ ((CollateExpression)
expressionSegment).getExpr().ifPresent(optional ->
extractSubqueryCompareExpressionsFromExpression(result, optional));
+ }
+ if (expressionSegment instanceof TypeCastExpression) {
+ extractSubqueryCompareExpressionsFromExpression(result,
((TypeCastExpression) expressionSegment).getExpression());
+ }
+ }
+
+ private static boolean containsSubqueryInBetween(final BetweenExpression
betweenExpression) {
+ return isSubqueryExpression(betweenExpression.getLeft())
+ || isSubqueryExpression(betweenExpression.getBetweenExpr())
+ || isSubqueryExpression(betweenExpression.getAndExpr());
+ }
+
+ private static boolean containsSubqueryInIn(final InExpression
inExpression) {
+ return isSubqueryExpression(inExpression.getLeft()) ||
isSubqueryExpression(inExpression.getRight());
+ }
+
+ private static boolean isComparisonOperator(final String operator) {
+ if (null == operator) {
+ return false;
+ }
+ String upperOperator = operator.toUpperCase();
+ return "=".equals(upperOperator) || "!=".equals(upperOperator) ||
"<>".equals(upperOperator)
+ || ">".equals(upperOperator) || "<".equals(upperOperator)
+ || ">=".equals(upperOperator) || "<=".equals(upperOperator);
+ }
+
+ private static boolean containsSubquery(final BinaryOperationExpression
binaryExpression) {
+ return isSubqueryExpression(binaryExpression.getLeft()) ||
isSubqueryExpression(binaryExpression.getRight());
+ }
+
+ private static boolean isSubqueryExpression(final ExpressionSegment
expressionSegment) {
+ if (expressionSegment instanceof SubqueryExpressionSegment ||
expressionSegment instanceof SubquerySegment
+ || expressionSegment instanceof QuantifySubqueryExpression) {
+ return true;
+ }
+ if (expressionSegment instanceof ListExpression) {
+ return ((ListExpression)
expressionSegment).getItems().stream().anyMatch(ExpressionExtractor::isSubqueryExpression);
+ }
+ return false;
+ }
}
diff --git
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/extractor/SubqueryExtractor.java
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/extractor/SubqueryExtractor.java
index 79f5157e6b0..7d0ca5e5b75 100644
---
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/extractor/SubqueryExtractor.java
+++
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/extractor/SubqueryExtractor.java
@@ -41,6 +41,10 @@ import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.Expr
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionsSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.SubqueryProjectionSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.GroupBySegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.OrderBySegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ExpressionOrderByItemSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.OrderByItemSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.match.MatchAgainstExpression;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.JoinTableSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SubqueryTableSegment;
@@ -83,6 +87,15 @@ public final class SubqueryExtractor {
if (selectStatement.getWith().isPresent()) {
extractSubquerySegmentsFromCTEs(result,
selectStatement.getWith().get().getCommonTableExpressions(), needRecursive);
}
+ if (selectStatement.getOrderBy().isPresent()) {
+ extractSubquerySegmentsFromOrderBy(result,
selectStatement.getOrderBy().get(), needRecursive);
+ }
+ if (selectStatement.getGroupBy().isPresent()) {
+ extractSubquerySegmentsFromGroupBy(result,
selectStatement.getGroupBy().get(), needRecursive);
+ }
+ if (selectStatement.getHaving().isPresent()) {
+ extractSubquerySegmentsFromWhere(result,
selectStatement.getHaving().get().getExpr(), needRecursive);
+ }
}
private static void extractSubquerySegmentsFromCTEs(final
List<SubquerySegment> result, final Collection<CommonTableExpressionSegment>
withSegment, final boolean needRecursive) {
@@ -93,9 +106,31 @@ public final class SubqueryExtractor {
}
}
+ private static void extractSubquerySegmentsFromOrderBy(final
List<SubquerySegment> result, final OrderBySegment orderBySegment, final
boolean needRecursive) {
+ for (OrderByItemSegment each : orderBySegment.getOrderByItems()) {
+ if (each instanceof ExpressionOrderByItemSegment) {
+ extractSubquerySegmentsFromExpression(result,
((ExpressionOrderByItemSegment) each).getExpr(), SubqueryType.ORDER_BY,
needRecursive);
+ }
+ }
+ }
+
+ private static void extractSubquerySegmentsFromGroupBy(final
List<SubquerySegment> result, final GroupBySegment groupBySegment, final
boolean needRecursive) {
+ for (OrderByItemSegment each : groupBySegment.getGroupByItems()) {
+ if (each instanceof ExpressionOrderByItemSegment) {
+ extractSubquerySegmentsFromExpression(result,
((ExpressionOrderByItemSegment) each).getExpr(), SubqueryType.GROUP_BY,
needRecursive);
+ }
+ }
+ }
+
private static void extractRecursive(final boolean needRecursive, final
List<SubquerySegment> result, final SelectStatement select, final SubqueryType
parentSubqueryType) {
if (needRecursive) {
extractSubquerySegments(result, select, true, parentSubqueryType);
+ if (!select.getSubqueryType().isPresent() && parentSubqueryType !=
null) {
+ select.setSubqueryType(parentSubqueryType);
+ }
+ if (parentSubqueryType == SubqueryType.WITH) {
+ select.setSubqueryType(SubqueryType.WITH);
+ }
}
}
@@ -122,6 +157,7 @@ public final class SubqueryExtractor {
if (tableSegment instanceof JoinTableSegment) {
extractSubquerySegmentsFromJoinTableSegment(result,
((JoinTableSegment) tableSegment).getLeft(), needRecursive);
extractSubquerySegmentsFromJoinTableSegment(result,
((JoinTableSegment) tableSegment).getRight(), needRecursive);
+ extractSubquerySegmentsFromExpression(result, ((JoinTableSegment)
tableSegment).getCondition(), SubqueryType.PREDICATE, needRecursive);
}
}
@@ -187,13 +223,13 @@ public final class SubqueryExtractor {
extractSubquerySegmentsFromExpression(result, ((NotExpression)
expressionSegment).getExpression(), subqueryType, needRecursive);
}
if (expressionSegment instanceof FunctionSegment) {
- ((FunctionSegment) expressionSegment).getParameters().forEach(each
-> extractSubquerySegmentsFromExpression(result, each, subqueryType,
needRecursive));
+ ((FunctionSegment) expressionSegment).getParameters().forEach(each
-> extractSubquerySegmentsFromExpression(result, each, SubqueryType.FUNCTION,
needRecursive));
}
if (expressionSegment instanceof MatchAgainstExpression) {
extractSubquerySegmentsFromExpression(result,
((MatchAgainstExpression) expressionSegment).getExpr(), subqueryType,
needRecursive);
}
if (expressionSegment instanceof CaseWhenExpression) {
- extractSubquerySegmentsFromCaseWhenExpression(result,
(CaseWhenExpression) expressionSegment, subqueryType, needRecursive);
+ extractSubquerySegmentsFromCaseWhenExpression(result,
(CaseWhenExpression) expressionSegment, SubqueryType.FUNCTION, needRecursive);
}
if (expressionSegment instanceof CollateExpression) {
extractSubquerySegmentsFromExpression(result, ((CollateExpression)
expressionSegment).getCollateName(), subqueryType, needRecursive);
diff --git
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/generic/bound/ColumnSegmentBoundInfo.java
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/generic/bound/ColumnSegmentBoundInfo.java
index dba37e23024..9750ab2b72c 100644
---
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/generic/bound/ColumnSegmentBoundInfo.java
+++
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/generic/bound/ColumnSegmentBoundInfo.java
@@ -18,7 +18,9 @@
package
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound;
import lombok.Getter;
+import lombok.Setter;
import
org.apache.shardingsphere.sql.parser.statement.core.enums.TableSourceType;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
/**
@@ -35,6 +37,9 @@ public final class ColumnSegmentBoundInfo {
private final TableSourceType tableSourceType;
+ @Setter
+ private OwnerSegment owner;
+
public ColumnSegmentBoundInfo(final IdentifierValue originalColumn) {
this(null, null, originalColumn, TableSourceType.PHYSICAL_TABLE);
}
diff --git
a/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/insert/insert-select.xml
b/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/insert/insert-select.xml
index bb9aa775e61..9254646792c 100644
---
a/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/insert/insert-select.xml
+++
b/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/insert/insert-select.xml
@@ -19,12 +19,12 @@
<rewrite-assertions yaml-rule="scenario/encrypt/config/query-with-cipher.yaml">
<rewrite-assertion id="insert_select_account_bak_for_parameters"
db-types="MySQL">
<input sql="INSERT INTO t_account_detail (account_id,
certificate_number, password, amount, status) SELECT 40, certificate_number,
password, amount, status FROM t_account WHERE certificate_number = ?"
parameters="cert1" />
- <output sql="INSERT INTO t_account_detail (account_id,
`cipher_certificate_number`, `assisted_query_certificate_number`,
`like_query_certificate_number`, `cipher_password`, `assisted_query_password`,
`like_query_password`, `cipher_amount`, status) SELECT 40,
cipher_certificate_number, assisted_query_certificate_number,
like_query_certificate_number, cipher_password, assisted_query_password,
like_query_password, cipher_amount, status FROM t_account WHERE
`assisted_query_certificat [...]
+ <output sql="INSERT INTO t_account_detail (account_id,
`cipher_certificate_number`, `assisted_query_certificate_number`,
`like_query_certificate_number`, `cipher_password`, `assisted_query_password`,
`like_query_password`, `cipher_amount`, status) SELECT 40,
cipher_certificate_number, `assisted_query_certificate_number`,
`like_query_certificate_number`, cipher_password, `assisted_query_password`,
`like_query_password`, cipher_amount, status FROM t_account WHERE
`assisted_query_ce [...]
</rewrite-assertion>
<rewrite-assertion id="insert_select_account_bak_for_literal"
db-types="MySQL">
<input sql="INSERT INTO t_account_detail (account_id,
certificate_number, password, amount, status) SELECT 40, certificate_number,
password, amount, status FROM t_account WHERE certificate_number = 'cert1'" />
- <output sql="INSERT INTO t_account_detail (account_id,
`cipher_certificate_number`, `assisted_query_certificate_number`,
`like_query_certificate_number`, `cipher_password`, `assisted_query_password`,
`like_query_password`, `cipher_amount`, status) SELECT 40,
cipher_certificate_number, assisted_query_certificate_number,
like_query_certificate_number, cipher_password, assisted_query_password,
like_query_password, cipher_amount, status FROM t_account WHERE
`assisted_query_certificat [...]
+ <output sql="INSERT INTO t_account_detail (account_id,
`cipher_certificate_number`, `assisted_query_certificate_number`,
`like_query_certificate_number`, `cipher_password`, `assisted_query_password`,
`like_query_password`, `cipher_amount`, status) SELECT 40,
cipher_certificate_number, `assisted_query_certificate_number`,
`like_query_certificate_number`, cipher_password, `assisted_query_password`,
`like_query_password`, cipher_amount, status FROM t_account WHERE
`assisted_query_ce [...]
</rewrite-assertion>
<rewrite-assertion id="insert_select_account_bak_for_literal_and_quote"
db-types="MySQL">
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 541ec7a0801..2377c0ab510 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
@@ -24,62 +24,62 @@
<rewrite-assertion id="select_not_nested_subquery_in_table_segment"
db-types="MySQL">
<input sql="SELECT u.amount, u.password, o.certificate_number FROM
(SELECT certificate_number FROM t_account) o, t_account u WHERE
o.certificate_number=u.certificate_number AND u.password=?" parameters="1" />
- <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, o.certificate_number_CIPHER AS certificate_number FROM (SELECT
cipher_certificate_number AS certificate_number_CIPHER,
assisted_query_certificate_number AS certificate_number_ASSISTED,
like_query_certificate_number AS certificate_number_LIKE FROM t_account) o,
t_account u WHERE
o.certificate_number_ASSISTED=u.`assisted_query_certificate_number` AND
u.`assisted_query_password`=?" parameters="assisted [...]
+ <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, o.certificate_number_C AS certificate_number FROM (SELECT
cipher_certificate_number AS certificate_number_C,
assisted_query_certificate_number AS certificate_number_A,
like_query_certificate_number AS certificate_number_L FROM t_account) o,
t_account u WHERE o.certificate_number_A=u.`assisted_query_certificate_number`
AND u.`assisted_query_password`=?" parameters="assisted_query_1" />
</rewrite-assertion>
<rewrite-assertion id="select_not_nested_subquery_in_table_segment_refed"
db-types="MySQL">
<input sql="SELECT u.amount, u.password, o.certificate_number FROM
(SELECT certificate_number FROM t_account_bak) o, t_account u WHERE
o.certificate_number=u.certificate_number AND u.password=?" parameters="1" />
- <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, o.certificate_number_CIPHER AS certificate_number FROM (SELECT
cipher_certificate_number AS certificate_number_CIPHER,
assisted_query_certificate_number AS certificate_number_ASSISTED,
like_query_certificate_number AS certificate_number_LIKE FROM t_account_bak) o,
t_account u WHERE
o.certificate_number_ASSISTED=u.`assisted_query_certificate_number` AND
u.`assisted_query_password`=?" parameters="assi [...]
+ <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, o.certificate_number_C AS certificate_number FROM (SELECT
cipher_certificate_number AS certificate_number_C,
assisted_query_certificate_number AS certificate_number_A,
like_query_certificate_number AS certificate_number_L FROM t_account_bak) o,
t_account u WHERE o.certificate_number_A=u.`assisted_query_certificate_number`
AND u.`assisted_query_password`=?" parameters="assisted_query_1" />
</rewrite-assertion>
<rewrite-assertion id="select_not_nested_subquery_in_table_segment_alias"
db-types="MySQL">
<input sql="SELECT o.certificate_number FROM (SELECT
a.certificate_number FROM t_account a) o" />
- <output sql="SELECT o.certificate_number_CIPHER AS certificate_number
FROM (SELECT a.cipher_certificate_number AS certificate_number_CIPHER,
a.assisted_query_certificate_number AS certificate_number_ASSISTED,
a.like_query_certificate_number AS certificate_number_LIKE FROM t_account a) o"
/>
+ <output sql="SELECT o.certificate_number_C AS certificate_number FROM
(SELECT a.cipher_certificate_number AS certificate_number_C,
a.assisted_query_certificate_number AS certificate_number_A,
a.like_query_certificate_number AS certificate_number_L FROM t_account a) o" />
</rewrite-assertion>
<rewrite-assertion
id="select_not_nested_subquery_in_table_segment_with_shorthand_project_alias"
db-types="MySQL">
<input sql="SELECT u.amount, u.password, o.certificate_number FROM
(SELECT a.* FROM t_account a) o, t_account u WHERE
o.certificate_number=u.certificate_number AND u.password=?" parameters="1" />
- <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, o.certificate_number_CIPHER AS certificate_number FROM (SELECT
a.`account_id`, a.`cipher_certificate_number` AS `certificate_number_CIPHER`,
a.`assisted_query_certificate_number` AS `certificate_number_ASSISTED`,
a.`like_query_certificate_number` AS `certificate_number_LIKE`,
a.`cipher_password` AS `password_CIPHER`, a.`assisted_query_password` AS
`password_ASSISTED`, a.`like_query_password` AS `pas [...]
+ <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, o.certificate_number_C AS certificate_number FROM (SELECT
a.`account_id`, a.`cipher_certificate_number` AS `certificate_number_C`,
a.`assisted_query_certificate_number` AS `certificate_number_A`,
a.`like_query_certificate_number` AS `certificate_number_L`,
a.`cipher_password` AS `password_C`, a.`assisted_query_password` AS
`password_A`, a.`like_query_password` AS `password_L`, a.`cipher_amount` AS `
[...]
</rewrite-assertion>
<rewrite-assertion
id="select_not_nested_subquery_in_table_segment_with_shorthand_project_alias_quote"
db-types="MySQL">
<input sql="SELECT u.amount, u.password, o.certificate_number FROM
(SELECT a.* FROM t_account `a`) o, t_account u WHERE
o.certificate_number=u.certificate_number AND u.password=?" parameters="1" />
- <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, o.certificate_number_CIPHER AS certificate_number FROM (SELECT
`a`.`account_id`, `a`.`cipher_certificate_number` AS
`certificate_number_CIPHER`, `a`.`assisted_query_certificate_number` AS
`certificate_number_ASSISTED`, `a`.`like_query_certificate_number` AS
`certificate_number_LIKE`, `a`.`cipher_password` AS `password_CIPHER`,
`a`.`assisted_query_password` AS `password_ASSISTED`, `a`.`like_query_pas [...]
+ <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, o.certificate_number_C AS certificate_number FROM (SELECT
`a`.`account_id`, `a`.`cipher_certificate_number` AS `certificate_number_C`,
`a`.`assisted_query_certificate_number` AS `certificate_number_A`,
`a`.`like_query_certificate_number` AS `certificate_number_L`,
`a`.`cipher_password` AS `password_C`, `a`.`assisted_query_password` AS
`password_A`, `a`.`like_query_password` AS `password_L`, `a`.`cip [...]
</rewrite-assertion>
<rewrite-assertion
id="select_not_nested_subquery_in_table_segment_with_shorthand_project"
db-types="MySQL">
<input sql="SELECT u.amount, u.password, o.certificate_number FROM
(SELECT * FROM t_account) o, t_account u WHERE
o.certificate_number=u.certificate_number AND u.password=?" parameters="1" />
- <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, o.certificate_number_CIPHER AS certificate_number FROM (SELECT
t_account.`account_id`, t_account.`cipher_certificate_number` AS
`certificate_number_CIPHER`, t_account.`assisted_query_certificate_number` AS
`certificate_number_ASSISTED`, t_account.`like_query_certificate_number` AS
`certificate_number_LIKE`, t_account.`cipher_password` AS `password_CIPHER`,
t_account.`assisted_query_password` AS `pas [...]
+ <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, o.certificate_number_C AS certificate_number FROM (SELECT
t_account.`account_id`, t_account.`cipher_certificate_number` AS
`certificate_number_C`, t_account.`assisted_query_certificate_number` AS
`certificate_number_A`, t_account.`like_query_certificate_number` AS
`certificate_number_L`, t_account.`cipher_password` AS `password_C`,
t_account.`assisted_query_password` AS `password_A`, t_account.`like [...]
</rewrite-assertion>
<rewrite-assertion
id="select_not_nested_subquery_in_predicate_right_equal_condition"
db-types="MySQL">
<input sql="SELECT u.amount, u.password, u.certificate_number FROM
t_account_bak u, t_account c WHERE u.certificate_number=(SELECT
certificate_number FROM t_account WHERE password=?) AND u.password=?"
parameters="1, 2" />
- <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, u.`cipher_certificate_number` AS certificate_number FROM
t_account_bak u, t_account c WHERE
u.`assisted_query_certificate_number`=(SELECT assisted_query_certificate_number
FROM t_account WHERE `assisted_query_password`=?) AND
u.`assisted_query_password`=?" parameters="assisted_query_1, assisted_query_2"
/>
+ <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, u.`cipher_certificate_number` AS certificate_number FROM
t_account_bak u, t_account c WHERE
u.`assisted_query_certificate_number`=(SELECT assisted_query_certificate_number
AS certificate_number FROM t_account WHERE `assisted_query_password`=?) AND
u.`assisted_query_password`=?" parameters="assisted_query_1, assisted_query_2"
/>
</rewrite-assertion>
<rewrite-assertion
id="select_not_nested_subquery_in_predicate_left_equal_condition"
db-types="MySQL">
<input sql="SELECT u.amount, u.password, u.certificate_number FROM
t_account_bak u, t_account c WHERE (SELECT certificate_number FROM t_account
WHERE password=?)=u.certificate_number AND u.password=?" parameters="1, 2" />
- <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, u.`cipher_certificate_number` AS certificate_number FROM
t_account_bak u, t_account c WHERE (SELECT assisted_query_certificate_number
FROM t_account WHERE
`assisted_query_password`=?)=u.`assisted_query_certificate_number` AND
u.`assisted_query_password`=?" parameters="assisted_query_1, assisted_query_2"
/>
+ <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, u.`cipher_certificate_number` AS certificate_number FROM
t_account_bak u, t_account c WHERE (SELECT assisted_query_certificate_number AS
certificate_number FROM t_account WHERE
`assisted_query_password`=?)=u.`assisted_query_certificate_number` AND
u.`assisted_query_password`=?" parameters="assisted_query_1, assisted_query_2"
/>
</rewrite-assertion>
<rewrite-assertion id="select_not_nested_subquery_in_table_with_alias"
db-types="MySQL">
<input sql="SELECT count(*) as cnt FROM (SELECT ab.certificate_number
FROM t_account ab) X" />
- <output sql="SELECT count(*) as cnt FROM (SELECT
ab.cipher_certificate_number AS certificate_number_CIPHER,
ab.assisted_query_certificate_number AS certificate_number_ASSISTED,
ab.like_query_certificate_number AS certificate_number_LIKE FROM t_account ab)
X" />
+ <output sql="SELECT count(*) as cnt FROM (SELECT
ab.cipher_certificate_number AS certificate_number_C,
ab.assisted_query_certificate_number AS certificate_number_A,
ab.like_query_certificate_number AS certificate_number_L FROM t_account ab) X"
/>
</rewrite-assertion>
<rewrite-assertion
id="select_not_nested_subquery_in_predicate_left_and_right_equal_condition"
db-types="MySQL">
<input sql="SELECT u.amount, u.password, u.certificate_number FROM
t_account_bak u, t_account c WHERE (SELECT certificate_number FROM t_account
WHERE password=?)=(SELECT certificate_number FROM t_account_bak WHERE
password=?) AND u.password=?" parameters="1, 2, 3" />
- <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, u.`cipher_certificate_number` AS certificate_number FROM
t_account_bak u, t_account c WHERE (SELECT assisted_query_certificate_number
FROM t_account WHERE `assisted_query_password`=?)=(SELECT
assisted_query_certificate_number FROM t_account_bak WHERE
`assisted_query_password`=?) AND u.`assisted_query_password`=?"
parameters="assisted_query_1, assisted_query_2, assisted_query_3" />
+ <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, u.`cipher_certificate_number` AS certificate_number FROM
t_account_bak u, t_account c WHERE (SELECT assisted_query_certificate_number AS
certificate_number FROM t_account WHERE `assisted_query_password`=?)=(SELECT
assisted_query_certificate_number AS certificate_number FROM t_account_bak
WHERE `assisted_query_password`=?) AND u.`assisted_query_password`=?"
parameters="assisted_query_1, assisted_quer [...]
</rewrite-assertion>
<rewrite-assertion id="select_not_nested_subquery_in_predicate_exists"
db-types="MySQL">
<input sql="SELECT u.amount, u.password, u.certificate_number FROM
t_account_bak u WHERE EXISTS(SELECT b.certificate_number from t_account b where
b.certificate_number=u.certificate_number)" />
- <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, u.`cipher_certificate_number` AS certificate_number FROM
t_account_bak u WHERE EXISTS(SELECT b.assisted_query_certificate_number from
t_account b where
b.`assisted_query_certificate_number`=u.`assisted_query_certificate_number`)" />
+ <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, u.`cipher_certificate_number` AS certificate_number FROM
t_account_bak u WHERE EXISTS(SELECT b.assisted_query_certificate_number AS
certificate_number from t_account b where
b.`assisted_query_certificate_number`=u.`assisted_query_certificate_number`)" />
</rewrite-assertion>
<rewrite-assertion id="select_not_nested_subquery_in_predicate_not_exists"
db-types="MySQL">
<input sql="SELECT u.amount, u.password, u.certificate_number FROM
t_account_bak u WHERE NOT EXISTS(SELECT b.certificate_number from t_account b
where b.certificate_number=u.certificate_number)" />
- <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, u.`cipher_certificate_number` AS certificate_number FROM
t_account_bak u WHERE NOT EXISTS(SELECT b.assisted_query_certificate_number
from t_account b where
b.`assisted_query_certificate_number`=u.`assisted_query_certificate_number`)" />
+ <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, u.`cipher_certificate_number` AS certificate_number FROM
t_account_bak u WHERE NOT EXISTS(SELECT b.assisted_query_certificate_number AS
certificate_number from t_account b where
b.`assisted_query_certificate_number`=u.`assisted_query_certificate_number`)" />
</rewrite-assertion>
<rewrite-assertion id="select_not_nested_subquery_in_predicate_not_exists"
db-types="Oracle">
@@ -89,12 +89,12 @@
<rewrite-assertion
id="select_not_nested_subquery_in_predicate_in_condition" db-types="MySQL">
<input sql="SELECT u.amount, u.password, u.certificate_number FROM
t_account_bak u, t_account c WHERE u.certificate_number IN (SELECT
certificate_number FROM t_account WHERE password=?) AND u.password=?"
parameters="1, 2" />
- <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, u.`cipher_certificate_number` AS certificate_number FROM
t_account_bak u, t_account c WHERE u.`assisted_query_certificate_number` IN
(SELECT assisted_query_certificate_number FROM t_account WHERE
`assisted_query_password`=?) AND u.`assisted_query_password`=?"
parameters="assisted_query_1, assisted_query_2" />
+ <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password, u.`cipher_certificate_number` AS certificate_number FROM
t_account_bak u, t_account c WHERE u.`assisted_query_certificate_number` IN
(SELECT assisted_query_certificate_number AS certificate_number FROM t_account
WHERE `assisted_query_password`=?) AND u.`assisted_query_password`=?"
parameters="assisted_query_1, assisted_query_2" />
</rewrite-assertion>
<rewrite-assertion
id="select_not_nested_subquery_in_tablesegment_from_alias" db-types="MySQL">
<input sql="SELECT b.certificate_number, b.amount FROM (SELECT
a.certificate_number as certificate_number, a.amount FROM t_account a WHERE
a.amount = 1373) b" />
- <output sql="SELECT b.certificate_number_CIPHER AS certificate_number,
b.amount_CIPHER AS amount FROM (SELECT a.cipher_certificate_number AS
certificate_number_CIPHER, a.assisted_query_certificate_number AS
certificate_number_ASSISTED, a.like_query_certificate_number AS
certificate_number_LIKE, a.cipher_amount AS amount_CIPHER FROM t_account a
WHERE a.`cipher_amount` = 'encrypt_1373') b" />
+ <output sql="SELECT b.certificate_number_C AS certificate_number,
b.amount_C AS amount FROM (SELECT a.cipher_certificate_number AS
certificate_number_C, a.assisted_query_certificate_number AS
certificate_number_A, a.like_query_certificate_number AS certificate_number_L,
a.cipher_amount AS amount_C FROM t_account a WHERE a.`cipher_amount` =
'encrypt_1373') b" />
</rewrite-assertion>
<rewrite-assertion id="select_with_exists_sub_query" db-types="MySQL">
@@ -104,11 +104,11 @@
<rewrite-assertion id="select_sub_query_with_group_by" db-types="MySQL">
<input sql="SELECT COUNT(1) AS cnt FROM (SELECT a.amount FROM
t_account a GROUP BY a.amount DESC ) AS tmp" />
- <output sql="SELECT COUNT(1) AS cnt FROM (SELECT a.cipher_amount AS
amount_CIPHER FROM t_account a GROUP BY a.`cipher_amount` DESC ) AS tmp" />
+ <output sql="SELECT COUNT(1) AS cnt FROM (SELECT a.cipher_amount AS
amount_C FROM t_account a GROUP BY a.`cipher_amount` DESC ) AS tmp" />
</rewrite-assertion>
<rewrite-assertion id="select_concat_in_subquery" db-types="MySQL">
<input sql="SELECT COUNT(*) FROM (SELECT * FROM (SELECT password FROM
t_account WHERE password like concat('%', 'zhangsan', '%')) t) TOTAL" />
- <output sql="SELECT COUNT(*) FROM (SELECT t.password_CIPHER,
t.password_ASSISTED, t.password_LIKE FROM (SELECT cipher_password AS
password_CIPHER, assisted_query_password AS password_ASSISTED,
like_query_password AS password_LIKE FROM t_account WHERE `like_query_password`
like concat('like_query_%', 'like_query_zhangsan', 'like_query_%')) t) TOTAL" />
+ <output sql="SELECT COUNT(*) FROM (SELECT t.password_C, t.password_A,
t.password_L FROM (SELECT cipher_password AS password_C,
assisted_query_password AS password_A, like_query_password AS password_L FROM
t_account WHERE `like_query_password` like concat('like_query_%',
'like_query_zhangsan', 'like_query_%')) t) TOTAL" />
</rewrite-assertion>
</rewrite-assertions>
diff --git
a/test/it/rewriter/src/test/resources/scenario/mix/case/query-with-cipher/dml/select/select-subquery.xml
b/test/it/rewriter/src/test/resources/scenario/mix/case/query-with-cipher/dml/select/select-subquery.xml
index 7426785d90e..6abdbf6d71b 100644
---
a/test/it/rewriter/src/test/resources/scenario/mix/case/query-with-cipher/dml/select/select-subquery.xml
+++
b/test/it/rewriter/src/test/resources/scenario/mix/case/query-with-cipher/dml/select/select-subquery.xml
@@ -19,25 +19,25 @@
<rewrite-assertions yaml-rule="scenario/mix/config/query-with-cipher.yaml">
<rewrite-assertion id="select_not_nested_subquery_in_table_alias"
db-types="MySQL">
<input sql="SELECT count(*) as cnt FROM (SELECT ab.password FROM
t_account ab) X" />
- <output sql="SELECT count(*) as cnt FROM (SELECT ab.cipher_password AS
password_CIPHER, ab.assisted_query_password AS password_ASSISTED FROM
t_account_0 ab) X" />
- <output sql="SELECT count(*) as cnt FROM (SELECT ab.cipher_password AS
password_CIPHER, ab.assisted_query_password AS password_ASSISTED FROM
t_account_1 ab) X" />
+ <output sql="SELECT count(*) as cnt FROM (SELECT ab.cipher_password AS
password_C, ab.assisted_query_password AS password_A FROM t_account_0 ab) X" />
+ <output sql="SELECT count(*) as cnt FROM (SELECT ab.cipher_password AS
password_C, ab.assisted_query_password AS password_A FROM t_account_1 ab) X" />
</rewrite-assertion>
<rewrite-assertion
id="select_not_nested_subquery_in_table_segment_with_shorthand_project_alias"
db-types="MySQL">
<input sql="SELECT u.amount, u.password FROM (SELECT a.* FROM
t_account a) o, t_account u WHERE u.password=?" parameters="1" />
- <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password FROM (SELECT a.`account_id`, a.`cipher_password` AS
`password_CIPHER`, a.`assisted_query_password` AS `password_ASSISTED`,
a.`cipher_amount` AS `amount_CIPHER` FROM t_account_0 a) o, t_account_0 u WHERE
u.`assisted_query_password`=?" parameters="assisted_query_1" />
- <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password FROM (SELECT a.`account_id`, a.`cipher_password` AS
`password_CIPHER`, a.`assisted_query_password` AS `password_ASSISTED`,
a.`cipher_amount` AS `amount_CIPHER` FROM t_account_1 a) o, t_account_1 u WHERE
u.`assisted_query_password`=?" parameters="assisted_query_1" />
+ <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password FROM (SELECT a.`account_id`, a.`cipher_password` AS `password_C`,
a.`assisted_query_password` AS `password_A`, a.`cipher_amount` AS `amount_C`
FROM t_account_0 a) o, t_account_0 u WHERE u.`assisted_query_password`=?"
parameters="assisted_query_1" />
+ <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password FROM (SELECT a.`account_id`, a.`cipher_password` AS `password_C`,
a.`assisted_query_password` AS `password_A`, a.`cipher_amount` AS `amount_C`
FROM t_account_1 a) o, t_account_1 u WHERE u.`assisted_query_password`=?"
parameters="assisted_query_1" />
</rewrite-assertion>
<rewrite-assertion
id="select_not_nested_subquery_in_table_segment_with_shorthand_project_alias_quote"
db-types="MySQL">
<input sql="SELECT u.amount, u.password FROM (SELECT `a`.* FROM
t_account `a`) o, t_account u WHERE u.password=?" parameters="1" />
- <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password FROM (SELECT `a`.`account_id`, `a`.`cipher_password` AS
`password_CIPHER`, `a`.`assisted_query_password` AS `password_ASSISTED`,
`a`.`cipher_amount` AS `amount_CIPHER` FROM t_account_0 `a`) o, t_account_0 u
WHERE u.`assisted_query_password`=?" parameters="assisted_query_1" />
- <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password FROM (SELECT `a`.`account_id`, `a`.`cipher_password` AS
`password_CIPHER`, `a`.`assisted_query_password` AS `password_ASSISTED`,
`a`.`cipher_amount` AS `amount_CIPHER` FROM t_account_1 `a`) o, t_account_1 u
WHERE u.`assisted_query_password`=?" parameters="assisted_query_1" />
+ <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password FROM (SELECT `a`.`account_id`, `a`.`cipher_password` AS
`password_C`, `a`.`assisted_query_password` AS `password_A`,
`a`.`cipher_amount` AS `amount_C` FROM t_account_0 `a`) o, t_account_0 u WHERE
u.`assisted_query_password`=?" parameters="assisted_query_1" />
+ <output sql="SELECT u.`cipher_amount` AS amount, u.`cipher_password`
AS password FROM (SELECT `a`.`account_id`, `a`.`cipher_password` AS
`password_C`, `a`.`assisted_query_password` AS `password_A`,
`a`.`cipher_amount` AS `amount_C` FROM t_account_1 `a`) o, t_account_1 u WHERE
u.`assisted_query_password`=?" parameters="assisted_query_1" />
</rewrite-assertion>
<rewrite-assertion id="select_not_nested_subquery_in_table_segment_alias"
db-types="MySQL">
<input sql="SELECT o.password FROM (SELECT a.password FROM t_account
a) o" />
- <output sql="SELECT o.password_CIPHER AS password FROM (SELECT
a.cipher_password AS password_CIPHER, a.assisted_query_password AS
password_ASSISTED FROM t_account_0 a) o" />
- <output sql="SELECT o.password_CIPHER AS password FROM (SELECT
a.cipher_password AS password_CIPHER, a.assisted_query_password AS
password_ASSISTED FROM t_account_1 a) o" />
+ <output sql="SELECT o.password_C AS password FROM (SELECT
a.cipher_password AS password_C, a.assisted_query_password AS password_A FROM
t_account_0 a) o" />
+ <output sql="SELECT o.password_C AS password FROM (SELECT
a.cipher_password AS password_C, a.assisted_query_password AS password_A FROM
t_account_1 a) o" />
</rewrite-assertion>
</rewrite-assertions>