This is an automated email from the ASF dual-hosted git repository.
panjuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new b8db81f optimize encrypt subquery projection rewrite logic (#13643)
b8db81f is described below
commit b8db81f51e533773a8992c4909cc4f623279a356
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Tue Nov 16 19:07:35 2021 +0800
optimize encrypt subquery projection rewrite logic (#13643)
* refactor EncryptProjectionTokenGenerator
* refactor EncryptProjectionTokenGenerator
* refactor EncryptProjectionTokenGenerator
* delete useless enum
* delete useless method
* delete useless method
* fix unit test error
* fix integration test error
* modify rewrite test case
---
.../impl/EncryptPredicateColumnTokenGenerator.java | 15 +-
.../impl/EncryptProjectionTokenGenerator.java | 229 +++++++--------------
.../route/engine/condition/ShardingConditions.java | 5 +-
.../merge/dql/ShardingDQLResultMergerTest.java | 10 +-
.../RowNumberDecoratorMergedResultTest.java | 7 +-
.../select/subquery/SubqueryTableContext.java | 20 +-
.../engine/SubqueryTableContextEngine.java | 50 +++++
.../infra/binder/segment/table/TablesContext.java | 41 +++-
.../statement/dml/SelectStatementContext.java | 40 ++--
.../binder/statement/dml/SubqueryTableContext.java | 88 --------
.../sql/common/util/SubqueryExtractUtil.java | 53 +----
.../resources/scenario/encrypt/case/insert.xml | 4 +-
.../encrypt/case/select_for_query_with_cipher.xml | 42 ++--
13 files changed, 248 insertions(+), 356 deletions(-)
diff --git
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptPredicateColumnTokenGenerator.java
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptPredicateColumnTokenGenerator.java
index c9a1af0..2f4e450 100644
---
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptPredicateColumnTokenGenerator.java
+++
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptPredicateColumnTokenGenerator.java
@@ -25,7 +25,6 @@ import
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.Col
import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
import
org.apache.shardingsphere.infra.binder.statement.dml.InsertStatementContext;
import
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
-import
org.apache.shardingsphere.infra.binder.statement.dml.SubqueryTableContext;
import org.apache.shardingsphere.infra.binder.type.WhereAvailable;
import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
import
org.apache.shardingsphere.infra.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
@@ -76,28 +75,22 @@ public final class EncryptPredicateColumnTokenGenerator
extends BaseEncryptSQLTo
Collection<AndPredicate> andPredicates =
ExpressionExtractUtil.getAndPredicates(each.getExpr());
Map<String, String> columnTableNames =
getColumnTableNames(sqlStatementContext, andPredicates);
for (AndPredicate predicate : andPredicates) {
- result.addAll(generateSQLTokens(sqlStatementContext,
predicate.getPredicates(), columnTableNames));
+ result.addAll(generateSQLTokens(predicate.getPredicates(),
columnTableNames));
}
}
return result;
}
- private Collection<SubstitutableColumnNameToken> generateSQLTokens(final
SQLStatementContext sqlStatementContext, final Collection<ExpressionSegment>
predicates,
- final
Map<String, String> columnTableNames) {
+ private Collection<SubstitutableColumnNameToken> generateSQLTokens(final
Collection<ExpressionSegment> predicates, final Map<String, String>
columnTableNames) {
Collection<SubstitutableColumnNameToken> result = new LinkedList<>();
- SubqueryTableContext subqueryTableContext = new SubqueryTableContext();
- if (sqlStatementContext instanceof SelectStatementContext) {
- subqueryTableContext = ((SelectStatementContext)
sqlStatementContext).getSubqueryTableContext();
- }
for (ExpressionSegment each : predicates) {
for (ColumnSegment column : ColumnExtractor.extract(each)) {
- int startIndex = column.getOwner().isPresent() ?
column.getOwner().get().getStopIndex() + 2 : column.getStartIndex();
- int stopIndex = column.getStopIndex();
-
subqueryTableContext.getAssistedQueryColumn(column).ifPresent(item ->
result.add(new SubstitutableColumnNameToken(startIndex, stopIndex,
getColumnProjections(item))));
Optional<EncryptTable> encryptTable =
findEncryptTable(columnTableNames, column);
if (!encryptTable.isPresent() ||
!encryptTable.get().findEncryptorName(column.getIdentifier().getValue()).isPresent())
{
continue;
}
+ int startIndex = column.getOwner().isPresent() ?
column.getOwner().get().getStopIndex() + 2 : column.getStartIndex();
+ int stopIndex = column.getStopIndex();
EncryptTable table = encryptTable.get();
if (Boolean.FALSE.equals(table.getQueryWithCipherColumn()) ||
!queryWithCipherColumn) {
Optional<String> plainColumn =
encryptTable.get().findPlainColumn(column.getIdentifier().getValue());
diff --git
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptProjectionTokenGenerator.java
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptProjectionTokenGenerator.java
index df3ac6f..71e195b 100644
---
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptProjectionTokenGenerator.java
+++
b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/EncryptProjectionTokenGenerator.java
@@ -26,24 +26,20 @@ import
org.apache.shardingsphere.infra.binder.segment.select.projection.Projecti
import
org.apache.shardingsphere.infra.binder.segment.select.projection.ProjectionsContext;
import
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
import
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ShorthandProjection;
+import org.apache.shardingsphere.infra.binder.segment.table.TablesContext;
import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
import
org.apache.shardingsphere.infra.binder.statement.dml.InsertStatementContext;
import
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
-import
org.apache.shardingsphere.infra.binder.statement.dml.SubqueryTableContext;
import org.apache.shardingsphere.infra.database.type.DatabaseType;
import
org.apache.shardingsphere.infra.rewrite.sql.token.generator.CollectionSQLTokenGenerator;
import
org.apache.shardingsphere.infra.rewrite.sql.token.generator.aware.PreviousSQLTokensAware;
import org.apache.shardingsphere.infra.rewrite.sql.token.pojo.SQLToken;
import
org.apache.shardingsphere.infra.rewrite.sql.token.pojo.generic.SubstitutableColumnNameToken;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
-import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ColumnProjectionSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionSegment;
-import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionsSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ShorthandProjectionSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment;
-import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SubqueryTableSegment;
-import
org.apache.shardingsphere.sql.parser.sql.common.util.SubqueryExtractUtil;
import java.util.Collection;
import java.util.Collections;
@@ -51,11 +47,11 @@ import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
-import java.util.stream.Collectors;
/**
* Projection token generator for encrypt.
*/
+@SuppressWarnings("rawtypes")
@Setter
public final class EncryptProjectionTokenGenerator extends
BaseEncryptSQLTokenGenerator
implements CollectionSQLTokenGenerator<SQLStatementContext>,
QueryWithCipherColumnAware, PreviousSQLTokensAware {
@@ -75,90 +71,106 @@ public final class EncryptProjectionTokenGenerator extends
BaseEncryptSQLTokenGe
@Override
public Collection<SubstitutableColumnNameToken> generateSQLTokens(final
SQLStatementContext sqlStatementContext) {
Collection<SubstitutableColumnNameToken> result = new
LinkedHashSet<>();
- SubqueryTableContext subqueryTableContext = new SubqueryTableContext();
if (sqlStatementContext instanceof InsertStatementContext) {
- result.addAll(generateSQLTokens(((InsertStatementContext)
sqlStatementContext).getInsertSelectContext().getSelectStatementContext(),
Optional.empty(), SubqueryEnum.INSERT_SELECT,
- subqueryTableContext));
+ SelectStatementContext selectStatementContext =
((InsertStatementContext)
sqlStatementContext).getInsertSelectContext().getSelectStatementContext();
+ result.addAll(generateSQLTokens(selectStatementContext));
}
if (sqlStatementContext instanceof SelectStatementContext) {
SelectStatementContext selectStatementContext =
(SelectStatementContext) sqlStatementContext;
- result.addAll(generateSQLTokens(selectStatementContext,
subqueryTableContext));
- result.addAll(generateSQLTokens(selectStatementContext,
Optional.empty(), SubqueryEnum.NONE, subqueryTableContext));
- }
- return result;
- }
-
- private Collection<SubstitutableColumnNameToken> generateSQLTokens(final
SelectStatementContext selectStatementContext, final SubqueryTableContext
subqueryTableContext) {
- if (!selectStatementContext.isContainsSubquery()) {
- return Collections.emptyList();
+ result.addAll(generateProjectionSQLTokens(selectStatementContext));
+ for (SelectStatementContext each :
selectStatementContext.getSubqueryContexts().values()) {
+ result.addAll(generateProjectionSQLTokens(each));
+ }
}
- Collection<SubstitutableColumnNameToken> result = new LinkedList<>();
-
result.addAll(SubqueryExtractUtil.getSubqueryTableSegmentsFromTableSegment(selectStatementContext.getSqlStatement().getFrom()).stream().map(
- each -> generateSQLTokens(selectStatementContext, each,
subqueryTableContext)).flatMap(Collection::stream).collect(Collectors.toList()));
-
result.addAll(SubqueryExtractUtil.getSubquerySegmentsFromProjections(selectStatementContext.getSqlStatement().getProjections()).stream().map(
- each -> generateSQLTokens(selectStatementContext, each,
SubqueryEnum.PROJECTION,
subqueryTableContext)).flatMap(Collection::stream).collect(Collectors.toList()));
- selectStatementContext.getWhere().ifPresent(where ->
result.addAll(SubqueryExtractUtil.getSubquerySegmentsFromExpression(where.getExpr()).stream().map(
- each -> generateSQLTokens(selectStatementContext, each,
SubqueryEnum.EXPRESSION,
subqueryTableContext)).flatMap(Collection::stream).collect(Collectors.toList())));
return result;
}
- private Collection<SubstitutableColumnNameToken> generateSQLTokens(final
SelectStatementContext selectStatementContext, final SubquerySegment
subquerySegment,
- final
SubqueryEnum subqueryEnum, final SubqueryTableContext subqueryTableContext) {
- return generateSQLTokens(new
SelectStatementContext(selectStatementContext.getMetaDataMap(),
selectStatementContext.getParameters(), subquerySegment.getSelect(),
- selectStatementContext.getSchemaName()), Optional.empty(),
subqueryEnum, subqueryTableContext);
- }
-
- private Collection<SubstitutableColumnNameToken> generateSQLTokens(final
SelectStatementContext selectStatementContext, final SubqueryTableSegment
subqueryTableSegment,
- final
SubqueryTableContext subqueryTableContext) {
- return generateSQLTokens(new
SelectStatementContext(selectStatementContext.getMetaDataMap(),
selectStatementContext.getParameters(),
subqueryTableSegment.getSubquery().getSelect(),
- selectStatementContext.getSchemaName()),
subqueryTableSegment.getAlias(), SubqueryEnum.NESTED_PROJECTION_TABLE_SEGMENT,
subqueryTableContext);
- }
-
- private Collection<SubstitutableColumnNameToken> generateSQLTokens(final
SelectStatementContext selectStatementContext, final Optional<String> alias,
- final
SubqueryEnum subqueryEnum, final SubqueryTableContext subqueryTableContext) {
+ private Collection<SubstitutableColumnNameToken>
generateProjectionSQLTokens(final SelectStatementContext
selectStatementContext) {
Collection<SubstitutableColumnNameToken> result = new
LinkedHashSet<>();
- ProjectionsSegment projectionsSegment =
selectStatementContext.getSqlStatement().getProjections();
for (String each :
selectStatementContext.getTablesContext().getTableNames()) {
- getEncryptRule().findEncryptTable(each).map(optional ->
generateSQLTokens(projectionsSegment, each, selectStatementContext, optional,
alias, subqueryEnum,
- subqueryTableContext)).ifPresent(result::addAll);
+ Optional<EncryptTable> encryptTable =
getEncryptRule().findEncryptTable(each);
+ if (!encryptTable.isPresent()) {
+ continue;
+ }
+ result.addAll(generateProjectionSQLTokens(selectStatementContext,
encryptTable.get(), each));
}
- selectStatementContext.setSubqueryTableContext(subqueryTableContext);
return result;
}
- private Collection<SubstitutableColumnNameToken> generateSQLTokens(final
ProjectionsSegment segment, final String tableName, final
SelectStatementContext selectStatementContext,
- final EncryptTable encryptTable, final Optional<String> alias,
final SubqueryEnum subqueryEnum, final SubqueryTableContext
subqueryTableContext) {
+ private Collection<SubstitutableColumnNameToken>
generateProjectionSQLTokens(final SelectStatementContext
selectStatementContext,
+
final EncryptTable encryptTable, final String tableName) {
Collection<SubstitutableColumnNameToken> result = new LinkedList<>();
- for (ProjectionSegment each : segment.getProjections()) {
+ boolean subqueryTable = selectStatementContext.isSubqueryTable();
+ for (ProjectionSegment each :
selectStatementContext.getSqlStatement().getProjections().getProjections()) {
if (each instanceof ColumnProjectionSegment) {
- if (!subqueryTableContext.isEmpty() &&
((ColumnProjectionSegment) each).getColumn().getOwner().isPresent()) {
- result.addAll(generateSQLTokens(each,
subqueryTableContext));
+ String columnName = ((ColumnProjectionSegment)
each).getColumn().getIdentifier().getValue();
+ Optional<String> owner = ((ColumnProjectionSegment)
each).getColumn().getOwner().map(optional ->
optional.getIdentifier().getValue());
+ if
(selectStatementContext.getTablesContext().findTableNameFromSubquery(columnName,
owner.orElse(null)).isPresent()) {
+
result.addAll(generateProjectionSQLTokens((ColumnProjectionSegment) each,
selectStatementContext.getTablesContext()));
}
- if
(encryptTable.getLogicColumns().contains(((ColumnProjectionSegment)
each).getColumn().getIdentifier().getValue())
+ if (encryptTable.getLogicColumns().contains(columnName)
&&
columnMatchTableAndCheckAmbiguous(selectStatementContext,
(ColumnProjectionSegment) each, tableName)) {
- result.add(generateSQLToken((ColumnProjectionSegment)
each, tableName, alias, subqueryEnum, subqueryTableContext));
+
result.add(generateProjectionSQLTokens((ColumnProjectionSegment) each,
tableName, subqueryTable));
}
}
if (isToGeneratedSQLToken(each, selectStatementContext,
tableName)) {
ShorthandProjection shorthandProjection =
getShorthandProjection((ShorthandProjectionSegment) each,
selectStatementContext.getProjectionsContext());
if (!shorthandProjection.getActualColumns().isEmpty()) {
- result.add(generateSQLToken((ShorthandProjectionSegment)
each, shorthandProjection, tableName, encryptTable,
selectStatementContext.getDatabaseType(), subqueryEnum));
+
result.add(generateProjectionSQLTokens((ShorthandProjectionSegment) each,
shorthandProjection,
+ tableName, encryptTable,
selectStatementContext.getDatabaseType(), subqueryTable));
}
}
}
return result;
}
- private Collection<SubstitutableColumnNameToken> generateSQLTokens(final
ProjectionSegment each, final SubqueryTableContext subqueryTableContext) {
- Collection<SubstitutableColumnNameToken> result = new LinkedList<>();
- ColumnSegment column = ((ColumnProjectionSegment) each).getColumn();
- int startIndex = column.getOwner().isPresent() ?
column.getOwner().get().getStopIndex() + 2 : column.getStartIndex();
- int stopIndex = column.getStopIndex();
- subqueryTableContext.getCipherColumn(column).ifPresent(item ->
- result.add(new SubstitutableColumnNameToken(startIndex, stopIndex,
getColumnProjections(item, column.getIdentifier().getValue()))));
- return result;
+ private Collection<SubstitutableColumnNameToken>
generateProjectionSQLTokens(final ColumnProjectionSegment segment, final
TablesContext tablesContext) {
+ ColumnSegment column = segment.getColumn();
+ String columnName = column.getIdentifier().getValue();
+ String owner = column.getOwner().map(optional ->
optional.getIdentifier().getValue()).orElse(null);
+ Optional<String> tableName =
tablesContext.findTableNameFromSubquery(columnName, owner);
+ if (tableName.isPresent()) {
+ String cipherColumn =
getEncryptRule().getCipherColumn(tableName.get(), columnName);
+ int startIndex = column.getOwner().isPresent() ?
column.getOwner().get().getStopIndex() + 2 : column.getStartIndex();
+ int stopIndex = column.getStopIndex();
+ return Collections.singletonList(new
SubstitutableColumnNameToken(startIndex, stopIndex,
Collections.singletonList(new ColumnProjection(null, cipherColumn,
columnName))));
+ }
+ return Collections.emptyList();
}
+ private SubstitutableColumnNameToken generateProjectionSQLTokens(final
ColumnProjectionSegment segment, final String tableName, final boolean
subqueryTable) {
+ Collection<ColumnProjection> projections = new LinkedList<>();
+ String encryptColumnName = getEncryptColumnName(tableName,
segment.getColumn().getIdentifier().getValue());
+ String alias =
segment.getAlias().orElse(segment.getColumn().getIdentifier().getValue());
+ projections.add(new ColumnProjection(null, encryptColumnName, alias));
+ Optional<String> assistedQueryColumn =
findAssistedQueryColumn(tableName,
segment.getColumn().getIdentifier().getValue());
+ if (subqueryTable && assistedQueryColumn.isPresent()) {
+ projections.add(new ColumnProjection(null,
assistedQueryColumn.get(), null));
+ }
+ return segment.getColumn().getOwner().isPresent()
+ ? new
SubstitutableColumnNameToken(segment.getColumn().getOwner().get().getStopIndex()
+ 2, segment.getStopIndex(), projections)
+ : new SubstitutableColumnNameToken(segment.getStartIndex(),
segment.getStopIndex(), projections);
+ }
+
+ private SubstitutableColumnNameToken generateProjectionSQLTokens(final
ShorthandProjectionSegment segment, final ShorthandProjection
shorthandProjection,
+ final
String tableName, final EncryptTable encryptTable, final DatabaseType
databaseType, final boolean subqueryTable) {
+ List<ColumnProjection> projections = new LinkedList<>();
+ for (ColumnProjection each :
shorthandProjection.getActualColumns().values()) {
+ if (encryptTable.getLogicColumns().contains(each.getName())) {
+ String owner = null == each.getOwner() ? null :
each.getOwner();
+ projections.add(new ColumnProjection(owner,
getEncryptColumnName(tableName, each.getName()), each.getName()));
+ Optional<String> assistedQueryColumn =
findAssistedQueryColumn(tableName, each.getName());
+ if (subqueryTable && assistedQueryColumn.isPresent()) {
+ projections.add(new ColumnProjection(owner,
assistedQueryColumn.get(), null));
+ }
+ } else {
+ projections.add(new ColumnProjection(each.getOwner(),
each.getName(), each.getAlias().orElse(null)));
+ }
+ }
+ previousSQLTokens.removeIf(each -> each.getStartIndex() ==
segment.getStartIndex());
+ return new SubstitutableColumnNameToken(segment.getStartIndex(),
segment.getStopIndex(), projections, databaseType.getQuoteCharacter());
+ }
+
private boolean columnMatchTableAndCheckAmbiguous(final
SelectStatementContext selectStatementContext, final ColumnProjectionSegment
columnProjectionSegment, final String tableName) {
return isOwnerExistsMatchTableAlias(selectStatementContext,
columnProjectionSegment, tableName)
|| isOwnerExistsMatchTableName(selectStatementContext,
columnProjectionSegment, tableName)
@@ -204,106 +216,7 @@ public final class EncryptProjectionTokenGenerator
extends BaseEncryptSQLTokenGe
Optional<OwnerSegment> ownerSegment = ((ShorthandProjectionSegment)
projectionSegment).getOwner();
return ownerSegment.map(segment ->
selectStatementContext.getTablesContext().findTableNameFromSQL(segment.getIdentifier().getValue()).orElse("").equalsIgnoreCase(tableName)).orElse(true);
}
-
- private SubstitutableColumnNameToken generateSQLToken(final
ColumnProjectionSegment segment, final String tableName, final Optional<String>
alias, final SubqueryEnum subqueryEnum,
- final
SubqueryTableContext subqueryTableContext) {
- String encryptColumnName = getEncryptColumnName(tableName,
segment.getColumn().getIdentifier().getValue());
- Collection<ColumnProjection> projections =
getColumnProjections(segment, tableName, alias, encryptColumnName, subqueryEnum,
- subqueryTableContext);
- return segment.getColumn().getOwner().isPresent()
- ? new
SubstitutableColumnNameToken(segment.getColumn().getOwner().get().getStopIndex()
+ 2, segment.getStopIndex(), projections)
- : new SubstitutableColumnNameToken(segment.getStartIndex(),
segment.getStopIndex(), projections);
- }
- private SubstitutableColumnNameToken generateSQLToken(final
ShorthandProjectionSegment segment, final ShorthandProjection
shorthandProjection, final String tableName,
- final EncryptTable
encryptTable, final DatabaseType databaseType, final SubqueryEnum subqueryEnum)
{
- List<ColumnProjection> projections = new LinkedList<>();
- for (ColumnProjection each :
shorthandProjection.getActualColumns().values()) {
- if (encryptTable.getLogicColumns().contains(each.getName())) {
- projections.addAll(getShorthandProjectionForSubquery(each,
tableName, subqueryEnum));
- } else {
- projections.add(columnProjection(each, each.getName(), null));
- }
- }
- previousSQLTokens.removeIf(each -> each.getStartIndex() ==
segment.getStartIndex());
- return new SubstitutableColumnNameToken(segment.getStartIndex(),
segment.getStopIndex(), projections, databaseType.getQuoteCharacter());
- }
-
- private Collection<ColumnProjection> getColumnProjections(final
ColumnProjectionSegment segment, final String tableName, final Optional<String>
alias, final String encryptColumnName,
- final
SubqueryEnum subqueryEnum, final SubqueryTableContext subqueryTableContext) {
- Collection<ColumnProjection> result = new LinkedList<>();
- if (SubqueryEnum.INSERT_SELECT.equals(subqueryEnum)) {
- result.addAll(getColumnProjectionsForInsertSelect(segment,
tableName, encryptColumnName));
- }
- if (SubqueryEnum.PROJECTION.equals(subqueryEnum)) {
- result.add(columnProjection(null, encryptColumnName, null));
- }
- if (SubqueryEnum.NESTED_PROJECTION_TABLE_SEGMENT.equals(subqueryEnum))
{
- result.add(columnProjection(null, encryptColumnName, null));
-
result.addAll(getColumnProjectionsForSubqueryProjectionOrTabSegment(segment,
tableName, alias, subqueryTableContext));
- }
- if (SubqueryEnum.EXPRESSION.equals(subqueryEnum)) {
- result.addAll(getColumnProjectionsForInExpression(segment,
tableName));
- }
- if (SubqueryEnum.NONE.equals(subqueryEnum)) {
- result.add(columnProjection(null, encryptColumnName,
segment.getAlias().orElse(segment.getColumn().getIdentifier().getValue())));
- }
- return result;
- }
-
- private Collection<ColumnProjection> getColumnProjections(final String
columnName, final String alias) {
- return Collections.singletonList(new ColumnProjection(null,
columnName, alias));
- }
-
- private Collection<ColumnProjection>
getColumnProjectionsForInsertSelect(final ColumnProjectionSegment segment,
final String tableName, final String encryptColumnName) {
- Collection<ColumnProjection> result = new LinkedList<>();
- result.add(columnProjection(null, encryptColumnName, null));
- assistedQueryColumnProjection(segment,
tableName).ifPresent(result::add);
- plainColumnProjection(segment, tableName).ifPresent(result::add);
- return result;
- }
-
- private Collection<ColumnProjection>
getColumnProjectionsForInExpression(final ColumnProjectionSegment segment,
final String tableName) {
- Collection<ColumnProjection> result = new LinkedList<>();
- assistedQueryColumnProjection(segment,
tableName).ifPresent(result::add);
- return result;
- }
-
- private Collection<ColumnProjection>
getColumnProjectionsForSubqueryProjectionOrTabSegment(final
ColumnProjectionSegment segment, final String tableName, final Optional<String>
alias,
-
final SubqueryTableContext subqueryTableContext) {
- Collection<ColumnProjection> result = new LinkedList<>();
- String plainColumn = segment.getColumn().getIdentifier().getValue();
- Optional<String> assistedQueryColumn =
findAssistedQueryColumn(tableName, plainColumn);
- assistedQueryColumn.ifPresent(each -> result.add(new
ColumnProjection(null, assistedQueryColumn.get(), null)));
- subqueryTableContext.put(alias, plainColumn,
getEncryptColumnName(tableName, plainColumn), assistedQueryColumn);
- return result;
- }
-
- private Collection<ColumnProjection>
getShorthandProjectionForSubquery(final ColumnProjection each, final String
tableName, final SubqueryEnum subqueryKind) {
- Collection<ColumnProjection> result = new LinkedList<>();
- if (SubqueryEnum.PROJECTION.equals(subqueryKind)) {
- result.add(columnProjection(each, getEncryptColumnName(tableName,
each.getName()), null));
- result.add(columnProjection(each,
findAssistedQueryColumn(tableName, each.getName()).get(), null));
- } else {
- result.add(columnProjection(each, getEncryptColumnName(tableName,
each.getName()), each.getName()));
- }
- return result;
- }
-
- private Optional<ColumnProjection> assistedQueryColumnProjection(final
ColumnProjectionSegment segment, final String tableName) {
- Optional<String> assistedQueryColumn =
findAssistedQueryColumn(tableName,
segment.getColumn().getIdentifier().getValue());
- return assistedQueryColumn.isPresent() ? Optional.of(new
ColumnProjection(null, assistedQueryColumn.get(), null)) : Optional.empty();
- }
-
- private Optional<ColumnProjection> plainColumnProjection(final
ColumnProjectionSegment segment, final String tableName) {
- Optional<String> plainColumn =
getEncryptRule().findPlainColumn(tableName,
segment.getColumn().getIdentifier().getValue());
- return plainColumn.isPresent() ? Optional.of(new
ColumnProjection(null, plainColumn.get(), null)) : Optional.empty();
- }
-
- private ColumnProjection columnProjection(final ColumnProjection each,
final String columnName, final String alias) {
- return new ColumnProjection((each == null || null == each.getOwner())
? null : each.getOwner(), columnName, alias);
- }
-
private Optional<String> findAssistedQueryColumn(final String tableName,
final String logicEncryptColumnName) {
Optional<String> plainColumn =
getEncryptRule().findPlainColumn(tableName, logicEncryptColumnName);
return plainColumn.isPresent() && !queryWithCipherColumn ? plainColumn
: getEncryptRule().findAssistedQueryColumn(tableName, logicEncryptColumnName);
diff --git
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/ShardingConditions.java
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/ShardingConditions.java
index b1a413e..58c91ce 100644
---
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/ShardingConditions.java
+++
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/condition/ShardingConditions.java
@@ -30,7 +30,6 @@ import
org.apache.shardingsphere.sharding.route.engine.condition.value.ShardingC
import org.apache.shardingsphere.sharding.rule.BindingTableRule;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
import org.apache.shardingsphere.sharding.rule.TableRule;
-import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SubqueryTableSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
import
org.apache.shardingsphere.sql.parser.sql.common.util.SafeNumberOperationUtil;
@@ -137,12 +136,12 @@ public final class ShardingConditions {
Collection<SelectStatement> result = new LinkedList<>();
if (sqlStatementContext instanceof SelectStatementContext) {
result.add(((SelectStatementContext)
sqlStatementContext).getSqlStatement());
- result.addAll(((SelectStatementContext)
sqlStatementContext).getSubquerySegments().stream().map(SubquerySegment::getSelect).collect(Collectors.toList()));
+ result.addAll(((SelectStatementContext)
sqlStatementContext).getSubqueryContexts().values().stream().map(SelectStatementContext::getSqlStatement).collect(Collectors.toList()));
}
if (sqlStatementContext instanceof InsertStatementContext && null !=
((InsertStatementContext) sqlStatementContext).getInsertSelectContext()) {
SelectStatementContext selectStatementContext =
((InsertStatementContext)
sqlStatementContext).getInsertSelectContext().getSelectStatementContext();
result.add(selectStatementContext.getSqlStatement());
-
result.addAll(selectStatementContext.getSubquerySegments().stream().map(SubquerySegment::getSelect).collect(Collectors.toList()));
+
result.addAll(selectStatementContext.getSubqueryContexts().values().stream().map(SelectStatementContext::getSqlStatement).collect(Collectors.toList()));
}
return result;
}
diff --git
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/ShardingDQLResultMergerTest.java
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/ShardingDQLResultMergerTest.java
index 1b41e46..418e876 100644
---
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/ShardingDQLResultMergerTest.java
+++
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/ShardingDQLResultMergerTest.java
@@ -129,7 +129,7 @@ public final class ShardingDQLResultMergerTest {
when(whereSegment.getExpr()).thenReturn(binaryOperationExpression);
SubqueryTableSegment subqueryTableSegment =
mock(SubqueryTableSegment.class);
SubquerySegment subquerySegment = mock(SubquerySegment.class);
- SelectStatement subSelectStatement = mock(SelectStatement.class);
+ SelectStatement subSelectStatement = mock(MySQLSelectStatement.class);
ProjectionsSegment subProjectionsSegment =
mock(ProjectionsSegment.class);
TopProjectionSegment topProjectionSegment =
mock(TopProjectionSegment.class);
when(topProjectionSegment.getAlias()).thenReturn("row_id");
@@ -202,7 +202,7 @@ public final class ShardingDQLResultMergerTest {
when(whereSegment.getExpr()).thenReturn(binaryOperationExpression);
SubqueryTableSegment subqueryTableSegment =
mock(SubqueryTableSegment.class);
SubquerySegment subquerySegment = mock(SubquerySegment.class);
- SelectStatement subSelectStatement = mock(SelectStatement.class);
+ SelectStatement subSelectStatement = mock(MySQLSelectStatement.class);
ProjectionsSegment subProjectionsSegment =
mock(ProjectionsSegment.class);
TopProjectionSegment topProjectionSegment =
mock(TopProjectionSegment.class);
when(topProjectionSegment.getAlias()).thenReturn("row_id");
@@ -281,7 +281,7 @@ public final class ShardingDQLResultMergerTest {
when(whereSegment.getExpr()).thenReturn(binaryOperationExpression);
SubqueryTableSegment subqueryTableSegment =
mock(SubqueryTableSegment.class);
SubquerySegment subquerySegment = mock(SubquerySegment.class);
- SelectStatement subSelectStatement = mock(SelectStatement.class);
+ SelectStatement subSelectStatement = mock(MySQLSelectStatement.class);
ProjectionsSegment subProjectionsSegment =
mock(ProjectionsSegment.class);
TopProjectionSegment topProjectionSegment =
mock(TopProjectionSegment.class);
when(topProjectionSegment.getAlias()).thenReturn("row_id");
@@ -360,7 +360,7 @@ public final class ShardingDQLResultMergerTest {
when(whereSegment.getExpr()).thenReturn(binaryOperationExpression);
SubqueryTableSegment subqueryTableSegment =
mock(SubqueryTableSegment.class);
SubquerySegment subquerySegment = mock(SubquerySegment.class);
- SelectStatement subSelectStatement = mock(SelectStatement.class);
+ SelectStatement subSelectStatement = mock(MySQLSelectStatement.class);
ProjectionsSegment subProjectionsSegment =
mock(ProjectionsSegment.class);
TopProjectionSegment topProjectionSegment =
mock(TopProjectionSegment.class);
when(topProjectionSegment.getAlias()).thenReturn("row_id");
@@ -443,7 +443,7 @@ public final class ShardingDQLResultMergerTest {
when(whereSegment.getExpr()).thenReturn(binaryOperationExpression);
SubqueryTableSegment subqueryTableSegment =
mock(SubqueryTableSegment.class);
SubquerySegment subquerySegment = mock(SubquerySegment.class);
- SelectStatement subSelectStatement = mock(SelectStatement.class);
+ SelectStatement subSelectStatement = mock(MySQLSelectStatement.class);
ProjectionsSegment subProjectionsSegment =
mock(ProjectionsSegment.class);
TopProjectionSegment topProjectionSegment =
mock(TopProjectionSegment.class);
when(topProjectionSegment.getAlias()).thenReturn("row_id");
diff --git
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/pagination/RowNumberDecoratorMergedResultTest.java
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/pagination/RowNumberDecoratorMergedResultTest.java
index ebef116..3277799 100644
---
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/pagination/RowNumberDecoratorMergedResultTest.java
+++
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/merge/dql/pagination/RowNumberDecoratorMergedResultTest.java
@@ -35,6 +35,7 @@ import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.Whe
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SubqueryTableSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
import
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
+import
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLSelectStatement;
import
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.dml.OracleSelectStatement;
import org.junit.Test;
@@ -62,7 +63,7 @@ public final class RowNumberDecoratorMergedResultTest {
when(whereSegment.getExpr()).thenReturn(binaryOperationExpression);
SubqueryTableSegment subqueryTableSegment =
mock(SubqueryTableSegment.class);
SubquerySegment subquerySegment = mock(SubquerySegment.class);
- SelectStatement subSelectStatement = mock(SelectStatement.class);
+ SelectStatement subSelectStatement = mock(MySQLSelectStatement.class);
ProjectionsSegment subProjectionsSegment =
mock(ProjectionsSegment.class);
TopProjectionSegment topProjectionSegment =
mock(TopProjectionSegment.class);
when(topProjectionSegment.getAlias()).thenReturn("row_id");
@@ -105,7 +106,7 @@ public final class RowNumberDecoratorMergedResultTest {
when(whereSegment.getExpr()).thenReturn(binaryOperationExpression);
SubqueryTableSegment subqueryTableSegment =
mock(SubqueryTableSegment.class);
SubquerySegment subquerySegment = mock(SubquerySegment.class);
- SelectStatement subSelectStatement = mock(SelectStatement.class);
+ SelectStatement subSelectStatement = mock(MySQLSelectStatement.class);
ProjectionsSegment subProjectionsSegment =
mock(ProjectionsSegment.class);
TopProjectionSegment topProjectionSegment =
mock(TopProjectionSegment.class);
when(topProjectionSegment.getAlias()).thenReturn("row_id");
@@ -137,7 +138,7 @@ public final class RowNumberDecoratorMergedResultTest {
when(whereSegment.getExpr()).thenReturn(binaryOperationExpression);
SubqueryTableSegment subqueryTableSegment =
mock(SubqueryTableSegment.class);
SubquerySegment subquerySegment = mock(SubquerySegment.class);
- SelectStatement subSelectStatement = mock(SelectStatement.class);
+ SelectStatement subSelectStatement = mock(MySQLSelectStatement.class);
ProjectionsSegment subProjectionsSegment =
mock(ProjectionsSegment.class);
TopProjectionSegment topProjectionSegment =
mock(TopProjectionSegment.class);
when(topProjectionSegment.getAlias()).thenReturn("row_id");
diff --git
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/SubqueryEnum.java
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/subquery/SubqueryTableContext.java
similarity index 67%
rename from
shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/SubqueryEnum.java
rename to
shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/subquery/SubqueryTableContext.java
index e5891f8..8179349 100644
---
a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/impl/SubqueryEnum.java
+++
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/subquery/SubqueryTableContext.java
@@ -15,11 +15,23 @@
* limitations under the License.
*/
-package org.apache.shardingsphere.encrypt.rewrite.token.generator.impl;
+package org.apache.shardingsphere.infra.binder.segment.select.subquery;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import java.util.Collection;
/**
- * Subquery enum.
+ * Subquery table context.
*/
-public enum SubqueryEnum {
- NONE, INSERT_SELECT, PROJECTION, NESTED_PROJECTION_TABLE_SEGMENT,
EXPRESSION
+@RequiredArgsConstructor
+@Getter
+public final class SubqueryTableContext {
+
+ private final String tableName;
+
+ private final String alias;
+
+ private final Collection<String> columnNames;
}
diff --git
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/subquery/engine/SubqueryTableContextEngine.java
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/subquery/engine/SubqueryTableContextEngine.java
new file mode 100644
index 0000000..1a3f243
--- /dev/null
+++
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/subquery/engine/SubqueryTableContextEngine.java
@@ -0,0 +1,50 @@
+/*
+ * 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.infra.binder.segment.select.subquery.engine;
+
+import
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
+import
org.apache.shardingsphere.infra.binder.segment.select.subquery.SubqueryTableContext;
+import
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Subquery table context engine.
+ */
+public final class SubqueryTableContextEngine {
+
+ /**
+ * Create subquery table contexts.
+ *
+ * @param subqueryContext subquery context
+ * @param alias subquery alias
+ * @return subquery table context collection
+ */
+ public Collection<SubqueryTableContext> createSubqueryTableContexts(final
SelectStatementContext subqueryContext, final String alias) {
+ Collection<SubqueryTableContext> result = new LinkedList<>();
+ List<String> columnNames =
subqueryContext.getProjectionsContext().getExpandProjections().stream()
+ .filter(each -> each instanceof ColumnProjection).map(each ->
((ColumnProjection) each).getName()).collect(Collectors.toList());
+ for (String each : subqueryContext.getTablesContext().getTableNames())
{
+ result.add(new SubqueryTableContext(each, alias, columnNames));
+ }
+ return result;
+ }
+}
diff --git
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/table/TablesContext.java
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/table/TablesContext.java
index 7c9e088..e69bc8f 100644
---
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/table/TablesContext.java
+++
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/table/TablesContext.java
@@ -21,9 +21,14 @@ import com.google.common.base.Preconditions;
import lombok.Getter;
import lombok.ToString;
import
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
+import
org.apache.shardingsphere.infra.binder.segment.select.subquery.SubqueryTableContext;
+import
org.apache.shardingsphere.infra.binder.segment.select.subquery.engine.SubqueryTableContextEngine;
+import
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SubqueryTableSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableSegment;
import java.util.Collection;
import java.util.Collections;
@@ -47,21 +52,37 @@ public final class TablesContext {
private final Map<String, SimpleTableSegment> uniqueTables = new
HashMap<>();
+ private final Map<String, Collection<SubqueryTableContext>> subqueryTables
= new HashMap<>();
+
private final Collection<String> schemaNames = new HashSet<>();
public TablesContext(final SimpleTableSegment tableSegment) {
- this(null == tableSegment ? Collections.emptyList() :
Collections.singletonList(tableSegment));
+ this(Collections.singletonList(tableSegment));
}
public TablesContext(final Collection<SimpleTableSegment> tableSegments) {
+ this(tableSegments, Collections.emptyMap());
+ }
+
+ public TablesContext(final Collection<? extends TableSegment>
tableSegments, final Map<Integer, SelectStatementContext> subqueryContexts) {
if (tableSegments.isEmpty()) {
return;
}
- for (SimpleTableSegment each : tableSegments) {
+ Collection<SimpleTableSegment> simpleTableSegments =
tableSegments.stream().filter(each
+ -> each instanceof SimpleTableSegment).map(each ->
(SimpleTableSegment) each).collect(Collectors.toList());
+ for (SimpleTableSegment each : simpleTableSegments) {
originalTables.add(each);
uniqueTables.putIfAbsent(each.getTableName().getIdentifier().getValue(), each);
each.getOwner().ifPresent(optional ->
schemaNames.add(optional.getIdentifier().getValue()));
}
+ Collection<SubqueryTableSegment> subqueryTableSegments =
tableSegments.stream().filter(each
+ -> each instanceof SubqueryTableSegment).map(each ->
(SubqueryTableSegment) each).collect(Collectors.toList());
+ for (SubqueryTableSegment each : subqueryTableSegments) {
+ SelectStatementContext subqueryContext =
subqueryContexts.get(each.getSubquery().getStartIndex());
+ subqueryContext.setSubqueryTable(true);
+ Collection<SubqueryTableContext> subqueryTableContexts = new
SubqueryTableContextEngine().createSubqueryTableContexts(subqueryContext,
each.getAlias().orElse(null));
+
subqueryTables.putAll(subqueryTableContexts.stream().collect(Collectors.groupingBy(SubqueryTableContext::getAlias)));
+ }
}
/**
@@ -122,6 +143,7 @@ public final class TablesContext {
/**
* Find table name from SQL.
+ *
* @param tableNameOrAlias table name or alias
* @return table name
*/
@@ -179,6 +201,21 @@ public final class TablesContext {
}
/**
+ * Find table name from subquery.
+ *
+ * @param columnName column name
+ * @param owner column owner
+ * @return table name
+ */
+ public Optional<String> findTableNameFromSubquery(final String columnName,
final String owner) {
+ Collection<SubqueryTableContext> subqueryTableContexts =
subqueryTables.get(owner);
+ if (null != subqueryTableContexts) {
+ return subqueryTableContexts.stream().filter(each ->
each.getColumnNames().contains(columnName)).map(SubqueryTableContext::getTableName).findFirst();
+ }
+ return Optional.empty();
+ }
+
+ /**
* Get schema name.
*
* @return schema name
diff --git
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
index 251ad8b..44126cf 100644
---
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
+++
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
@@ -51,11 +51,15 @@ import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.Te
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.WhereSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.JoinTableSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SubqueryTableSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
import org.apache.shardingsphere.sql.parser.sql.common.util.SQLUtil;
import
org.apache.shardingsphere.sql.parser.sql.common.util.SubqueryExtractUtil;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -77,32 +81,35 @@ public final class SelectStatementContext extends
CommonSQLStatementContext<Sele
private final PaginationContext paginationContext;
- private final Collection<SubquerySegment> subquerySegments;
+ private final Map<Integer, SelectStatementContext> subqueryContexts;
private final String schemaName;
-
- private final Map<String, ShardingSphereMetaData> metaDataMap;
-
- private final List<Object> parameters;
-
+
@Setter
- private SubqueryTableContext subqueryTableContext;
-
+ private boolean subqueryTable;
+
public SelectStatementContext(final Map<String, ShardingSphereMetaData>
metaDataMap, final List<Object> parameters, final SelectStatement sqlStatement,
final String defaultSchemaName) {
super(sqlStatement);
- this.metaDataMap = metaDataMap;
- this.parameters = parameters;
- tablesContext = new TablesContext(getAllSimpleTableSegments());
+ subqueryContexts = createSubqueryContexts(metaDataMap, parameters,
defaultSchemaName);
+ tablesContext = new TablesContext(getAllTableSegments(),
subqueryContexts);
ShardingSphereSchema schema = getSchema(metaDataMap,
defaultSchemaName);
groupByContext = new
GroupByContextEngine().createGroupByContext(sqlStatement);
orderByContext = new
OrderByContextEngine().createOrderBy(sqlStatement, groupByContext);
projectionsContext = new ProjectionsContextEngine(schema,
getDatabaseType())
.createProjectionsContext(getSqlStatement().getFrom(),
getSqlStatement().getProjections(), groupByContext, orderByContext);
paginationContext = new
PaginationContextEngine().createPaginationContext(sqlStatement,
projectionsContext, parameters);
- subquerySegments =
SubqueryExtractUtil.getSubquerySegments(getSqlStatement());
schemaName = defaultSchemaName;
}
+ private Map<Integer, SelectStatementContext> createSubqueryContexts(final
Map<String, ShardingSphereMetaData> metaDataMap, final List<Object> parameters,
final String defaultSchemaName) {
+ Collection<SubquerySegment> subquerySegments =
SubqueryExtractUtil.getSubquerySegments(getSqlStatement());
+ Map<Integer, SelectStatementContext> result = new
HashMap<>(subquerySegments.size(), 1);
+ for (SubquerySegment each : subquerySegments) {
+ result.put(each.getStartIndex(), new
SelectStatementContext(metaDataMap, parameters, each.getSelect(),
defaultSchemaName));
+ }
+ return result;
+ }
+
private ShardingSphereSchema getSchema(final Map<String,
ShardingSphereMetaData> metaDataMap, final String defaultSchemaName) {
String schemaName =
tablesContext.getSchemaName().orElse(defaultSchemaName);
ShardingSphereMetaData metaData = metaDataMap.get(schemaName);
@@ -127,7 +134,7 @@ public final class SelectStatementContext extends
CommonSQLStatementContext<Sele
* @return whether contains subquery or not
*/
public boolean isContainsSubquery() {
- return !subquerySegments.isEmpty();
+ return !subqueryContexts.isEmpty();
}
/**
@@ -242,9 +249,12 @@ public final class SelectStatementContext extends
CommonSQLStatementContext<Sele
return getSqlStatement().getWhere();
}
- private Collection<SimpleTableSegment> getAllSimpleTableSegments() {
+ private Collection<TableSegment> getAllTableSegments() {
+ Collection<TableSegment> result = new LinkedList<>();
TableExtractor tableExtractor = new TableExtractor();
tableExtractor.extractTablesFromSelect(getSqlStatement());
- return tableExtractor.getRewriteTables();
+ result.addAll(tableExtractor.getRewriteTables());
+ result.addAll(tableExtractor.getTableContext().stream().filter(each ->
each instanceof SubqueryTableSegment).collect(Collectors.toList()));
+ return result;
}
}
diff --git
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SubqueryTableContext.java
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SubqueryTableContext.java
deleted file mode 100644
index f6ccea5..0000000
---
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SubqueryTableContext.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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.infra.binder.statement.dml;
-
-import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Optional;
-
-/**
- * Subquery table context.
- */
-public final class SubqueryTableContext {
-
- private final Map<String, Map<String, Map<String, String>>>
rewriteMetaDataMap;
-
- public SubqueryTableContext() {
- this.rewriteMetaDataMap = new LinkedHashMap<>();
- }
-
- /**
- * Put rewrite meta data map.
- * @param alias alias
- * @param plainColumn plainColumn
- * @param cipherColumn cipherColumn
- * @param assistedQueryColumn assistedQueryColumn
- */
- public void put(final Optional<String> alias, final String plainColumn,
final String cipherColumn, final Optional<String> assistedQueryColumn) {
- Map<String, String> rewriteColumnMap = new HashMap<>();
- rewriteColumnMap.put("cipherColumn", cipherColumn);
- assistedQueryColumn.ifPresent(each ->
rewriteColumnMap.put("assistedQueryColumn", each));
- alias.ifPresent(each -> rewriteMetaDataMap.put(each,
Collections.singletonMap(plainColumn, rewriteColumnMap)));
- }
-
- /**
- * Get cipherColumn.
- * @param column ColumnSegment
- * @return cipherColumn
- */
- public Optional<String> getCipherColumn(final ColumnSegment column) {
- return getColumn(column, "cipherColumn");
- }
-
- /**
- * Get assistedQueryColumn.
- * @param column ColumnSegment
- * @return assistedQueryColumn
- */
- public Optional<String> getAssistedQueryColumn(final ColumnSegment column)
{
- return getColumn(column, "assistedQueryColumn");
- }
-
- private Optional<String> getColumn(final ColumnSegment column, final
String columnName) {
- String alias = column.getOwner().isPresent() ?
column.getOwner().get().getIdentifier().getValue() : "";
- String plainColumn = column.getIdentifier().getValue();
- Map<String, Map<String, String>> rewriteColumnMap =
rewriteMetaDataMap.get(alias);
- if (null != rewriteColumnMap &&
rewriteColumnMap.containsKey(plainColumn)) {
- return
Optional.ofNullable(rewriteColumnMap.get(plainColumn).get(columnName));
- }
- return Optional.empty();
- }
-
- /**
- * Get rewriteMetaDataMap is empty or not.
- * @return rewriteMetaDataMap is empty or not
- */
- public boolean isEmpty() {
- return rewriteMetaDataMap.isEmpty();
- }
-}
diff --git
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/SubqueryExtractUtil.java
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/SubqueryExtractUtil.java
index 6e07cd0..4ad3609 100644
---
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/SubqueryExtractUtil.java
+++
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/SubqueryExtractUtil.java
@@ -59,14 +59,8 @@ public final class SubqueryExtractUtil {
}
return result;
}
-
- /**
- * Get subquery segment from projections.
- *
- * @param projections ProjectionsSegment
- * @return subquery segment collection
- */
- public static Collection<SubquerySegment>
getSubquerySegmentsFromProjections(final ProjectionsSegment projections) {
+
+ private static Collection<SubquerySegment>
getSubquerySegmentsFromProjections(final ProjectionsSegment projections) {
if (null == projections || projections.getProjections().isEmpty()) {
return Collections.emptyList();
}
@@ -81,37 +75,8 @@ public final class SubqueryExtractUtil {
}
return result;
}
-
- /**
- * Get subquery table segment from tableSegment.
- *
- * @param tableSegment TableSegment
- * @return subquery table segment collection
- */
- public static Collection<SubqueryTableSegment>
getSubqueryTableSegmentsFromTableSegment(final TableSegment tableSegment) {
- if (null == tableSegment) {
- return Collections.emptyList();
- }
- Collection<SubqueryTableSegment> result = new LinkedList<>();
- if (tableSegment instanceof SubqueryTableSegment) {
- SubqueryTableSegment subqueryTableSegment = (SubqueryTableSegment)
tableSegment;
- result.add(subqueryTableSegment);
-
result.addAll(getSubqueryTableSegmentsFromTableSegment(subqueryTableSegment.getSubquery().getSelect().getFrom()));
- }
- if (tableSegment instanceof JoinTableSegment) {
-
result.addAll(getSubqueryTableSegmentsFromTableSegment(((JoinTableSegment)
tableSegment).getLeft()));
-
result.addAll(getSubqueryTableSegmentsFromTableSegment(((JoinTableSegment)
tableSegment).getRight()));
- }
- return result;
- }
-
- /**
- * Get subquery segment from tableSegment.
- *
- * @param tableSegment TableSegment
- * @return subquery segment collection
- */
- public static Collection<SubquerySegment>
getSubquerySegmentsFromTableSegment(final TableSegment tableSegment) {
+
+ private static Collection<SubquerySegment>
getSubquerySegmentsFromTableSegment(final TableSegment tableSegment) {
if (null == tableSegment) {
return Collections.emptyList();
}
@@ -127,14 +92,8 @@ public final class SubqueryExtractUtil {
}
return result;
}
-
- /**
- * Get subquery segment from expression.
- *
- * @param expressionSegment ExpressionSegment
- * @return subquery table segment collection
- */
- public static Collection<SubquerySegment>
getSubquerySegmentsFromExpression(final ExpressionSegment expressionSegment) {
+
+ private static Collection<SubquerySegment>
getSubquerySegmentsFromExpression(final ExpressionSegment expressionSegment) {
Collection<SubquerySegment> result = new LinkedList<>();
if (expressionSegment instanceof SubqueryExpressionSegment) {
SubquerySegment subquerySegment = ((SubqueryExpressionSegment)
expressionSegment).getSubquery();
diff --git
a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/insert.xml
b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/insert.xml
index 0e98b70..5c27454 100644
---
a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/insert.xml
+++
b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/insert.xml
@@ -68,8 +68,8 @@
</rewrite-assertion>
<rewrite-assertion id="insert_select_encrypt_rewrite" db-types="MySQL">
- <input sql="INSERT INTO t_account(account_id, certificate_number,
password, amount) SELECT account_id, certificate_number, password, amount from
t_account_bak where certificate_number = ?" parameters="111X"/>
- <output sql="INSERT INTO t_account(account_id,
cipher_certificate_number, assisted_query_certificate_number, cipher_password,
assisted_query_password, cipher_amount) SELECT account_id,
cipher_certificate_number, assisted_query_certificate_number,
plain_certificate_number, cipher_password, assisted_query_password,
plain_password, cipher_amount, plain_amount from t_account_bak where
assisted_query_certificate_number = ?" parameters="assisted_query_111X" />
+ <input sql="INSERT INTO t_account(account_id, certificate_number,
password, amount) SELECT account_id, certificate_number, password, amount FROM
t_account_bak WHERE certificate_number = ?" parameters="111X"/>
+ <output sql="INSERT INTO t_account(account_id,
cipher_certificate_number, assisted_query_certificate_number, cipher_password,
assisted_query_password, cipher_amount) SELECT account_id,
cipher_certificate_number AS certificate_number, cipher_password AS password,
cipher_amount AS amount FROM t_account_bak WHERE
assisted_query_certificate_number = ?" parameters="assisted_query_111X" />
</rewrite-assertion>
<rewrite-assertion id="insert_values_without_columns_for_literals"
db-types="MySQL">
diff --git
a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/select_for_query_with_cipher.xml
b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/select_for_query_with_cipher.xml
index dc0092b..4ed2c3a 100644
---
a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/select_for_query_with_cipher.xml
+++
b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/select_for_query_with_cipher.xml
@@ -89,33 +89,39 @@
<output sql="SELECT a.account_id, a.cipher_password AS password,
a.cipher_amount AS a, a.status AS s FROM t_account_bak AS a WHERE
a.cipher_amount in (?, ?)" parameters="encrypt_1000, encrypt_2000" />
</rewrite-assertion>
- <rewrite-assertion id="select_with_projection_not_nested_subquery"
db-types="MySQL">
- <input sql="SELECT u.certificate_number, u.password, (select o.amount
from t_account_bak o where o.certificate_number=u.certificate_number) amount
FROM t_account u, t_account_bak c where u.certificate_number =
c.certificate_number and u.password=?" parameters="1" />-->
- <output sql="SELECT u.cipher_certificate_number AS certificate_number,
u.cipher_password AS password, (select o.cipher_amount from t_account_bak o
where o.certificate_number=u.assisted_query_certificate_number) amount FROM
t_account u, t_account_bak c where u.assisted_query_certificate_number =
c.assisted_query_certificate_number and u.assisted_query_password=?"
parameters="assisted_query_1" />
+ <rewrite-assertion id="select_not_nested_subquery_in_projection"
db-types="MySQL">
+ <input sql="SELECT u.certificate_number, u.password, (SELECT o.amount
FROM t_account_bak o WHERE o.certificate_number=u.certificate_number) amount
FROM t_account u, t_account_bak c WHERE u.certificate_number =
c.certificate_number and u.password=?" parameters="1" />
+ <output sql="SELECT u.cipher_certificate_number AS certificate_number,
u.cipher_password AS password, (SELECT o.cipher_amount AS amount FROM
t_account_bak o WHERE o.certificate_number=u.assisted_query_certificate_number)
amount FROM t_account u, t_account_bak c WHERE
u.assisted_query_certificate_number = c.assisted_query_certificate_number and
u.assisted_query_password=?" parameters="assisted_query_1" />
</rewrite-assertion>
- <rewrite-assertion id="select_with_tabsegment_not_nested_subquery"
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.cipher_certificate_number AS certificate_number FROM (select
cipher_certificate_number, assisted_query_certificate_number from t_account) o,
t_account u where
o.assisted_query_certificate_number=u.assisted_query_certificate_number and
u.assisted_query_password=?" parameters="assisted_query_1" />
+ <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.cipher_certificate_number AS certificate_number FROM (SELECT
cipher_certificate_number AS certificate_number,
assisted_query_certificate_number FROM t_account) o, t_account u WHERE
o.assisted_query_certificate_number=u.assisted_query_certificate_number AND
u.assisted_query_password=?" parameters="assisted_query_1" />
</rewrite-assertion>
- <rewrite-assertion id="select_with_expression_not_nested_subquery1"
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" />
+ <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.cipher_certificate_number AS certificate_number FROM (SELECT
`t_account`.`account_id`, `t_account`.`cipher_certificate_number` AS
certificate_number, `t_account`.`assisted_query_certificate_number`,
`t_account`.`cipher_password` AS password,
`t_account`.`assisted_query_password`, `t_account`.`cipher_amount` AS amount,
`t_account`.`status` FROM t_account) o, t_account u WHERE
o.assisted_query_certifica [...]
+ </rewrite-assertion>
+ <!-- TODO support subuqery rewrite in predicate
+ <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" />
</rewrite-assertion>
- <rewrite-assertion id="select_with_expression_not_nested_subquery2"
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" />
+ <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" />
</rewrite-assertion>
- <rewrite-assertion id="select_with_expression_not_nested_subquery3"
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" />
+ <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" />
</rewrite-assertion>
- <rewrite-assertion id="select_with_expression_not_nested_subquery4"
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" />
+ <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" />
</rewrite-assertion>
+ -->
</rewrite-assertions>