Skip to content

Commit cf0b19a

Browse files
authored
Remove TablesContext#findTableNames method and implement select order by, group by bind logic (#34123)
* Remove TablesContext#findTableNames method and use sql bind info to replace * fix unit test * optimize select statement binder * update release note
1 parent d187256 commit cf0b19a

29 files changed

Lines changed: 498 additions & 298 deletions

File tree

RELEASE-NOTES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
1. SQL Binder: Add sql bind logic for create table statement - [#34074](https://github.com/apache/shardingsphere/pull/34074)
3838
1. SQL Binder: Support create index statement sql bind - [#34112](https://github.com/apache/shardingsphere/pull/34112)
3939
1. SQL Parser: Support MySQL update with statement parse - [#34126](https://github.com/apache/shardingsphere/pull/34126)
40+
1. SQL Binder: Remove TablesContext#findTableNames method and implement select order by, group by bind logic - [#34123](https://github.com/apache/shardingsphere/pull/34123)
4041

4142
### Bug Fixes
4243

features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/checker/sql/orderby/EncryptOrderByItemSupportedChecker.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@
3232
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ColumnOrderByItemSegment;
3333

3434
import java.util.Collection;
35-
import java.util.Collections;
3635
import java.util.LinkedList;
37-
import java.util.Map;
3836
import java.util.Optional;
3937

4038
/**
@@ -64,7 +62,7 @@ private boolean containsOrderByItem(final SelectStatementContext sqlStatementCon
6462
public void check(final EncryptRule rule, final ShardingSphereDatabase database, final ShardingSphereSchema currentSchema, final SelectStatementContext sqlStatementContext) {
6563
for (OrderByItem each : getOrderByItems(sqlStatementContext)) {
6664
if (each.getSegment() instanceof ColumnOrderByItemSegment) {
67-
checkColumnOrderByItem(rule, currentSchema, sqlStatementContext, ((ColumnOrderByItemSegment) each.getSegment()).getColumn());
65+
checkColumnOrderByItem(rule, ((ColumnOrderByItemSegment) each.getSegment()).getColumn());
6866
}
6967
}
7068
}
@@ -80,10 +78,8 @@ private Collection<OrderByItem> getOrderByItems(final SelectStatementContext sql
8078
return result;
8179
}
8280

83-
private void checkColumnOrderByItem(final EncryptRule rule, final ShardingSphereSchema schema, final SelectStatementContext sqlStatementContext, final ColumnSegment columnSegment) {
84-
Map<String, String> columnTableNames = sqlStatementContext.getTablesContext().findTableNames(Collections.singleton(columnSegment), schema);
85-
String tableName = columnTableNames.getOrDefault(columnSegment.getExpression(), "");
86-
Optional<EncryptTable> encryptTable = rule.findEncryptTable(tableName);
81+
private void checkColumnOrderByItem(final EncryptRule rule, final ColumnSegment columnSegment) {
82+
Optional<EncryptTable> encryptTable = rule.findEncryptTable(columnSegment.getColumnBoundInfo().getOriginalTable().getValue());
8783
String columnName = columnSegment.getIdentifier().getValue();
8884
ShardingSpherePreconditions.checkState(!encryptTable.isPresent() || !encryptTable.get().isEncryptColumn(columnName), () -> new UnsupportedEncryptSQLException("ORDER BY"));
8985
}

features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/checker/sql/predicate/EncryptPredicateColumnSupportedChecker.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import org.apache.shardingsphere.infra.binder.context.extractor.SQLStatementContextExtractor;
2626
import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
2727
import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext;
28-
import org.apache.shardingsphere.infra.binder.context.type.TableAvailable;
2928
import org.apache.shardingsphere.infra.binder.context.type.WhereAvailable;
3029
import org.apache.shardingsphere.infra.checker.SupportedSQLChecker;
3130
import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
@@ -40,7 +39,6 @@
4039
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
4140

4241
import java.util.Collection;
43-
import java.util.Map;
4442
import java.util.Optional;
4543

4644
/**
@@ -60,13 +58,12 @@ public void check(final EncryptRule rule, final ShardingSphereDatabase database,
6058
Collection<BinaryOperationExpression> joinConditions = SQLStatementContextExtractor.getJoinConditions((WhereAvailable) sqlStatementContext, allSubqueryContexts);
6159
ShardingSpherePreconditions.checkState(JoinConditionsEncryptorComparator.isSame(joinConditions, rule),
6260
() -> new UnsupportedSQLOperationException("Can not use different encryptor in join condition"));
63-
check(rule, currentSchema, (WhereAvailable) sqlStatementContext);
61+
check(rule, (WhereAvailable) sqlStatementContext);
6462
}
6563

66-
private void check(final EncryptRule rule, final ShardingSphereSchema schema, final WhereAvailable sqlStatementContext) {
67-
Map<String, String> columnExpressionTableNames = ((TableAvailable) sqlStatementContext).getTablesContext().findTableNames(sqlStatementContext.getColumnSegments(), schema);
64+
private void check(final EncryptRule rule, final WhereAvailable sqlStatementContext) {
6865
for (ColumnSegment each : sqlStatementContext.getColumnSegments()) {
69-
Optional<EncryptTable> encryptTable = rule.findEncryptTable(columnExpressionTableNames.getOrDefault(each.getExpression(), ""));
66+
Optional<EncryptTable> encryptTable = rule.findEncryptTable(each.getColumnBoundInfo().getOriginalTable().getValue());
7067
String columnName = each.getIdentifier().getValue();
7168
if (encryptTable.isPresent() && encryptTable.get().isEncryptColumn(columnName) && includesLike(sqlStatementContext.getWhereSegments(), each)) {
7269
String tableName = encryptTable.get().getTable();

features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/condition/EncryptConditionEngine.java

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,8 @@
2424
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
2525
import org.apache.shardingsphere.encrypt.rule.table.EncryptTable;
2626
import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation;
27-
import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
28-
import org.apache.shardingsphere.infra.binder.context.type.TableAvailable;
29-
import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
3027
import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
3128
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
32-
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
3329
import org.apache.shardingsphere.sql.parser.statement.core.extractor.ColumnExtractor;
3430
import org.apache.shardingsphere.sql.parser.statement.core.extractor.ExpressionExtractor;
3531
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
@@ -43,13 +39,11 @@
4339
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubqueryExpressionSegment;
4440
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.AndPredicate;
4541
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
46-
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.ColumnSegmentBoundInfo;
4742

4843
import java.util.Collection;
4944
import java.util.HashSet;
5045
import java.util.LinkedList;
5146
import java.util.List;
52-
import java.util.Map;
5347
import java.util.Optional;
5448
import java.util.Set;
5549
import java.util.TreeSet;
@@ -89,44 +83,36 @@ public final class EncryptConditionEngine {
8983
* Create encrypt conditions.
9084
*
9185
* @param whereSegments where segments
92-
* @param columnSegments column segments
93-
* @param sqlStatementContext SQL statement context
94-
* @param databaseName database name
9586
* @return encrypt conditions
9687
*/
97-
public Collection<EncryptCondition> createEncryptConditions(final Collection<WhereSegment> whereSegments, final Collection<ColumnSegment> columnSegments,
98-
final SQLStatementContext sqlStatementContext, final String databaseName) {
88+
public Collection<EncryptCondition> createEncryptConditions(final Collection<WhereSegment> whereSegments) {
9989
Collection<EncryptCondition> result = new LinkedList<>();
100-
String defaultSchema = new DatabaseTypeRegistry(sqlStatementContext.getDatabaseType()).getDefaultSchemaName(databaseName);
101-
ShardingSphereSchema schema = ((TableAvailable) sqlStatementContext).getTablesContext().getSchemaName().map(database::getSchema).orElseGet(() -> database.getSchema(defaultSchema));
102-
Map<String, String> expressionTableNames = ((TableAvailable) sqlStatementContext).getTablesContext().findTableNames(columnSegments, schema);
10390
for (WhereSegment each : whereSegments) {
10491
Collection<AndPredicate> andPredicates = ExpressionExtractor.extractAndPredicates(each.getExpr());
10592
for (AndPredicate predicate : andPredicates) {
106-
addEncryptConditions(result, predicate.getPredicates(), expressionTableNames);
93+
addEncryptConditions(result, predicate.getPredicates());
10794
}
10895
}
10996
return result;
11097
}
11198

112-
private void addEncryptConditions(final Collection<EncryptCondition> encryptConditions, final Collection<ExpressionSegment> predicates, final Map<String, String> expressionTableNames) {
99+
private void addEncryptConditions(final Collection<EncryptCondition> encryptConditions, final Collection<ExpressionSegment> predicates) {
113100
Collection<Integer> stopIndexes = new HashSet<>(predicates.size(), 1F);
114101
for (ExpressionSegment each : predicates) {
115102
if (stopIndexes.add(each.getStopIndex())) {
116-
addEncryptConditions(encryptConditions, each, expressionTableNames);
103+
addEncryptConditions(encryptConditions, each);
117104
}
118105
}
119106
}
120107

121-
private void addEncryptConditions(final Collection<EncryptCondition> encryptConditions, final ExpressionSegment expression, final Map<String, String> expressionTableNames) {
108+
private void addEncryptConditions(final Collection<EncryptCondition> encryptConditions, final ExpressionSegment expression) {
122109
if (!findNotContainsNullLiteralsExpression(expression).isPresent()) {
123110
return;
124111
}
125112
for (ColumnSegment each : ColumnExtractor.extract(expression)) {
126-
ColumnSegmentBoundInfo columnBoundInfo = each.getColumnBoundInfo();
127-
String tableName = columnBoundInfo.getOriginalTable().getValue().isEmpty() ? expressionTableNames.getOrDefault(each.getExpression(), "") : columnBoundInfo.getOriginalTable().getValue();
113+
String tableName = each.getColumnBoundInfo().getOriginalTable().getValue();
128114
Optional<EncryptTable> encryptTable = rule.findEncryptTable(tableName);
129-
if (encryptTable.isPresent() && encryptTable.get().isEncryptColumn(each.getIdentifier().getValue())) {
115+
if (encryptTable.isPresent() && encryptTable.get().isEncryptColumn(each.getColumnBoundInfo().getOriginalColumn().getValue())) {
130116
createEncryptCondition(expression, tableName).ifPresent(encryptConditions::add);
131117
}
132118
}

features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/context/EncryptSQLRewriteContextDecorator.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import org.apache.shardingsphere.infra.rewrite.parameter.rewriter.ParameterRewritersBuilder;
3838
import org.apache.shardingsphere.infra.rewrite.sql.token.common.generator.builder.SQLTokenGeneratorBuilder;
3939
import org.apache.shardingsphere.infra.route.context.RouteContext;
40-
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
4140
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
4241

4342
import java.util.Collection;
@@ -93,9 +92,7 @@ private Collection<EncryptCondition> createEncryptConditions(final EncryptRule r
9392
}
9493
Collection<SelectStatementContext> allSubqueryContexts = SQLStatementContextExtractor.getAllSubqueryContexts(sqlStatementContext);
9594
Collection<WhereSegment> whereSegments = SQLStatementContextExtractor.getWhereSegments((WhereAvailable) sqlStatementContext, allSubqueryContexts);
96-
Collection<ColumnSegment> columnSegments = SQLStatementContextExtractor.getColumnSegments((WhereAvailable) sqlStatementContext, allSubqueryContexts);
97-
return new EncryptConditionEngine(rule, sqlRewriteContext.getDatabase()).createEncryptConditions(whereSegments, columnSegments, sqlStatementContext,
98-
sqlRewriteContext.getDatabase().getName());
95+
return new EncryptConditionEngine(rule, sqlRewriteContext.getDatabase()).createEncryptConditions(whereSegments);
9996
}
10097

10198
private void rewriteParameters(final SQLRewriteContext sqlRewriteContext, final Collection<ParameterRewriter> parameterRewriters) {

features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/select/EncryptGroupByItemTokenGenerator.java

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@
3030
import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext;
3131
import org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter;
3232
import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
33-
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
3433
import org.apache.shardingsphere.infra.rewrite.sql.token.common.generator.CollectionSQLTokenGenerator;
35-
import org.apache.shardingsphere.infra.rewrite.sql.token.common.generator.aware.SchemaMetaDataAware;
3634
import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.SQLToken;
3735
import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.generic.SubstitutableColumnNameToken;
3836
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
@@ -42,7 +40,6 @@
4240
import java.util.Collection;
4341
import java.util.Collections;
4442
import java.util.LinkedList;
45-
import java.util.Map;
4643
import java.util.Optional;
4744

4845
/**
@@ -51,14 +48,10 @@
5148
@HighFrequencyInvocation
5249
@RequiredArgsConstructor
5350
@Setter
54-
public final class EncryptGroupByItemTokenGenerator implements CollectionSQLTokenGenerator<SelectStatementContext>, SchemaMetaDataAware {
51+
public final class EncryptGroupByItemTokenGenerator implements CollectionSQLTokenGenerator<SelectStatementContext> {
5552

5653
private final EncryptRule rule;
5754

58-
private Map<String, ShardingSphereSchema> schemas;
59-
60-
private ShardingSphereSchema defaultSchema;
61-
6255
@Override
6356
public boolean isGenerateSQLToken(final SQLStatementContext sqlStatementContext) {
6457
return sqlStatementContext instanceof SelectStatementContext && containsGroupByItem((SelectStatementContext) sqlStatementContext);
@@ -79,21 +72,18 @@ private boolean containsGroupByItem(final SelectStatementContext sqlStatementCon
7972
@Override
8073
public Collection<SQLToken> generateSQLTokens(final SelectStatementContext sqlStatementContext) {
8174
Collection<SQLToken> result = new LinkedList<>();
82-
ShardingSphereSchema schema = sqlStatementContext.getTablesContext().getSchemaName().map(schemas::get).orElseGet(() -> defaultSchema);
8375
for (OrderByItem each : getGroupByItems(sqlStatementContext)) {
8476
if (each.getSegment() instanceof ColumnOrderByItemSegment) {
8577
ColumnSegment columnSegment = ((ColumnOrderByItemSegment) each.getSegment()).getColumn();
86-
Map<String, String> columnTableNames = sqlStatementContext.getTablesContext().findTableNames(Collections.singleton(columnSegment), schema);
87-
generateSQLToken(columnSegment, columnTableNames, sqlStatementContext.getDatabaseType()).ifPresent(result::add);
78+
generateSQLToken(columnSegment, sqlStatementContext.getDatabaseType()).ifPresent(result::add);
8879
}
8980
}
9081
return result;
9182
}
9283

93-
private Optional<SubstitutableColumnNameToken> generateSQLToken(final ColumnSegment columnSegment, final Map<String, String> columnTableNames, final DatabaseType databaseType) {
94-
String tableName = columnTableNames.getOrDefault(columnSegment.getExpression(), "");
95-
Optional<EncryptTable> encryptTable = rule.findEncryptTable(tableName);
96-
String columnName = columnSegment.getIdentifier().getValue();
84+
private Optional<SubstitutableColumnNameToken> generateSQLToken(final ColumnSegment columnSegment, final DatabaseType databaseType) {
85+
Optional<EncryptTable> encryptTable = rule.findEncryptTable(columnSegment.getColumnBoundInfo().getOriginalTable().getValue());
86+
String columnName = columnSegment.getColumnBoundInfo().getOriginalColumn().getValue();
9787
if (!encryptTable.isPresent() || !encryptTable.get().isEncryptColumn(columnName)) {
9888
return Optional.empty();
9989
}

features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/sql/orderby/EncryptOrderByItemSupportedCheckerTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ColumnOrderByItemSegment;
3434
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.AliasSegment;
3535
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment;
36+
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.ColumnSegmentBoundInfo;
37+
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.TableSegmentBoundInfo;
3638
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
3739
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
3840
import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
@@ -116,6 +118,8 @@ private SelectStatementContext mockSelectStatementContext(final String tableName
116118
simpleTableSegment.setAlias(new AliasSegment(0, 0, new IdentifierValue("a")));
117119
ColumnSegment columnSegment = new ColumnSegment(0, 0, new IdentifierValue("foo_col"));
118120
columnSegment.setOwner(new OwnerSegment(0, 0, new IdentifierValue("a")));
121+
columnSegment.setColumnBoundInfo(
122+
new ColumnSegmentBoundInfo(new TableSegmentBoundInfo(new IdentifierValue("foo_db"), new IdentifierValue("foo_db")), new IdentifierValue(tableName), new IdentifierValue("foo_col")));
119123
SelectStatementContext result = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS);
120124
when(result.getDatabaseType()).thenReturn(databaseType);
121125
ColumnOrderByItemSegment columnOrderByItemSegment = new ColumnOrderByItemSegment(columnSegment, OrderDirection.ASC, NullsOrderType.FIRST);

features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/checker/sql/predicate/EncryptPredicateColumnSupportedCheckerTest.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ private SQLStatementContext mockSelectStatementContextWithLike() {
8888
columnSegment.setColumnBoundInfo(new ColumnSegmentBoundInfo(new TableSegmentBoundInfo(new IdentifierValue("foo_db"), new IdentifierValue("foo_schema")), new IdentifierValue("t_user"),
8989
new IdentifierValue("user_name")));
9090
SelectStatementContext result = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS);
91-
when(result.getTablesContext().findTableNames(Collections.singleton(columnSegment), null)).thenReturn(Collections.singletonMap("user_name", "t_user"));
9291
when(result.getColumnSegments()).thenReturn(Collections.singleton(columnSegment));
9392
when(result.getWhereSegments()).thenReturn(Collections.singleton(new WhereSegment(0, 0, new BinaryOperationExpression(0, 0, columnSegment, columnSegment, "LIKE", ""))));
9493
when(result.getSubqueryContexts()).thenReturn(Collections.emptyMap());
@@ -106,7 +105,6 @@ private SQLStatementContext mockSelectStatementContextWithEqual() {
106105
columnSegment.setColumnBoundInfo(new ColumnSegmentBoundInfo(new TableSegmentBoundInfo(new IdentifierValue("foo_db"), new IdentifierValue("foo_schema")), new IdentifierValue("t_user"),
107106
new IdentifierValue("user_name")));
108107
SelectStatementContext result = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS);
109-
when(result.getTablesContext().findTableNames(Collections.singleton(columnSegment), null)).thenReturn(Collections.singletonMap("user_name", "t_user"));
110108
when(result.getColumnSegments()).thenReturn(Collections.singleton(columnSegment));
111109
when(result.getWhereSegments()).thenReturn(Collections.singleton(new WhereSegment(0, 0, new BinaryOperationExpression(0, 0, columnSegment, columnSegment, "=", ""))));
112110
when(result.getSubqueryContexts()).thenReturn(Collections.emptyMap());

features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/predicate/EncryptPredicateRightValueTokenGeneratorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,6 @@ void assertGenerateSQLTokenFromGenerateNewSQLToken() {
6363
private Collection<EncryptCondition> getEncryptConditions(final UpdateStatementContext updateStatementContext) {
6464
ShardingSphereDatabase database = new ShardingSphereDatabase("foo_db", mock(), mock(), mock(), Collections.singleton(new ShardingSphereSchema("foo_db")));
6565
return new EncryptConditionEngine(EncryptGeneratorFixtureBuilder.createEncryptRule(), database)
66-
.createEncryptConditions(updateStatementContext.getWhereSegments(), updateStatementContext.getColumnSegments(), updateStatementContext, "foo_db");
66+
.createEncryptConditions(updateStatementContext.getWhereSegments());
6767
}
6868
}

0 commit comments

Comments
 (0)