Skip to content

Commit

Permalink
Move tableless route in single to TablelessRouteEngineFactory and ref…
Browse files Browse the repository at this point in the history
…actor single validator (apache#33830)

* Move tableless route in single to TablelessRouteEngineFactory and refactor single validator

* fix unit test
  • Loading branch information
strongduanmu authored Nov 27, 2024
1 parent 6813dfe commit 4d30358
Show file tree
Hide file tree
Showing 32 changed files with 269 additions and 333 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext;
import org.apache.shardingsphere.infra.checker.SupportedSQLChecker;
import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ColumnOrderByItemSegment;
Expand Down Expand Up @@ -60,10 +61,10 @@ private boolean containsOrderByItem(final SelectStatementContext sqlStatementCon
}

@Override
public void check(final EncryptRule rule, final ShardingSphereSchema schema, final SelectStatementContext sqlStatementContext) {
public void check(final EncryptRule rule, final ShardingSphereDatabase database, final ShardingSphereSchema currentSchema, final SelectStatementContext sqlStatementContext) {
for (OrderByItem each : getOrderByItems(sqlStatementContext)) {
if (each.getSegment() instanceof ColumnOrderByItemSegment) {
checkColumnOrderByItem(rule, schema, sqlStatementContext, ((ColumnOrderByItemSegment) each.getSegment()).getColumn());
checkColumnOrderByItem(rule, currentSchema, sqlStatementContext, ((ColumnOrderByItemSegment) each.getSegment()).getColumn());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@
import org.apache.shardingsphere.infra.checker.SupportedSQLChecker;
import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
import org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
import org.apache.shardingsphere.sql.parser.statement.core.extractor.ExpressionExtractor;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.BinaryOperationExpression;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.AndPredicate;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.predicate.WhereSegment;
import org.apache.shardingsphere.sql.parser.statement.core.extractor.ExpressionExtractor;

import java.util.Collection;
import java.util.Map;
Expand All @@ -54,12 +55,12 @@ public boolean isCheck(final SQLStatementContext sqlStatementContext) {
}

@Override
public void check(final EncryptRule rule, final ShardingSphereSchema schema, final SQLStatementContext sqlStatementContext) {
public void check(final EncryptRule rule, final ShardingSphereDatabase database, final ShardingSphereSchema currentSchema, final SQLStatementContext sqlStatementContext) {
Collection<SelectStatementContext> allSubqueryContexts = SQLStatementContextExtractor.getAllSubqueryContexts(sqlStatementContext);
Collection<BinaryOperationExpression> joinConditions = SQLStatementContextExtractor.getJoinConditions((WhereAvailable) sqlStatementContext, allSubqueryContexts);
ShardingSpherePreconditions.checkState(JoinConditionsEncryptorComparator.isSame(joinConditions, rule),
() -> new UnsupportedSQLOperationException("Can not use different encryptor in join condition"));
check(rule, schema, (WhereAvailable) sqlStatementContext);
check(rule, currentSchema, (WhereAvailable) sqlStatementContext);
}

private void check(final EncryptRule rule, final ShardingSphereSchema schema, final WhereAvailable sqlStatementContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.binder.context.statement.dml.InsertStatementContext;
import org.apache.shardingsphere.infra.checker.SupportedSQLChecker;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;

/**
Expand All @@ -36,7 +37,7 @@ public boolean isCheck(final SQLStatementContext sqlStatementContext) {
}

@Override
public void check(final EncryptRule rule, final ShardingSphereSchema schema, final InsertStatementContext sqlStatementContext) {
new EncryptSelectProjectionSupportedChecker().check(rule, schema, sqlStatementContext.getInsertSelectContext().getSelectStatementContext());
public void check(final EncryptRule rule, final ShardingSphereDatabase database, final ShardingSphereSchema currentSchema, final InsertStatementContext sqlStatementContext) {
new EncryptSelectProjectionSupportedChecker().check(rule, database, currentSchema, sqlStatementContext.getInsertSelectContext().getSelectStatementContext());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.apache.shardingsphere.infra.checker.SupportedSQLChecker;
import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
import org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.combine.CombineSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment;
Expand All @@ -48,7 +49,7 @@ public boolean isCheck(final SQLStatementContext sqlStatementContext) {
}

@Override
public void check(final EncryptRule rule, final ShardingSphereSchema schema, final SelectStatementContext sqlStatementContext) {
public void check(final EncryptRule rule, final ShardingSphereDatabase database, final ShardingSphereSchema currentSchema, final SelectStatementContext sqlStatementContext) {
checkSelectStatementContext(rule, sqlStatementContext);
for (SelectStatementContext each : sqlStatementContext.getSubqueryContexts().values()) {
checkSelectStatementContext(rule, each);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.apache.shardingsphere.infra.database.core.DefaultDatabase;
import org.apache.shardingsphere.infra.database.core.metadata.database.enums.NullsOrderType;
import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
import org.apache.shardingsphere.sql.parser.statement.core.enums.OrderDirection;
Expand Down Expand Up @@ -95,12 +96,13 @@ void assertIsCheckWithSubQueryOrderBy() {
@Test
void assertCheckFailed() {
assertThrows(UnsupportedEncryptSQLException.class,
() -> new EncryptOrderByItemSupportedChecker().check(mockEncryptRule(), mock(ShardingSphereSchema.class), mockSelectStatementContext("foo_tbl")));
() -> new EncryptOrderByItemSupportedChecker().check(mockEncryptRule(), mock(ShardingSphereDatabase.class), mock(ShardingSphereSchema.class), mockSelectStatementContext("foo_tbl")));
}

@Test
void assertCheckSuccess() {
assertDoesNotThrow(() -> new EncryptOrderByItemSupportedChecker().check(mockEncryptRule(), mock(ShardingSphereSchema.class), mockSelectStatementContext("bar_tbl")));
assertDoesNotThrow(
() -> new EncryptOrderByItemSupportedChecker().check(mockEncryptRule(), mock(ShardingSphereDatabase.class), mock(ShardingSphereSchema.class), mockSelectStatementContext("bar_tbl")));
}

private EncryptRule mockEncryptRule() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void assertIsCheckWithNotEmptyWhereSegments() {
@Test
void assertCheckWithDifferentEncryptorsInJoinCondition() {
assertThrows(UnsupportedSQLOperationException.class, () -> new EncryptPredicateColumnSupportedChecker()
.check(EncryptGeneratorFixtureBuilder.createEncryptRule(), null, mockSelectStatementContextWithDifferentEncryptorsInJoinCondition()));
.check(EncryptGeneratorFixtureBuilder.createEncryptRule(), null, null, mockSelectStatementContextWithDifferentEncryptorsInJoinCondition()));
}

private SQLStatementContext mockSelectStatementContextWithDifferentEncryptorsInJoinCondition() {
Expand All @@ -80,7 +80,7 @@ private SQLStatementContext mockSelectStatementContextWithDifferentEncryptorsInJ
@Test
void assertCheckWithNotMatchedLikeQueryEncryptor() {
assertThrows(MissingMatchedEncryptQueryAlgorithmException.class, () -> new EncryptPredicateColumnSupportedChecker()
.check(EncryptGeneratorFixtureBuilder.createEncryptRule(), null, mockSelectStatementContextWithLike()));
.check(EncryptGeneratorFixtureBuilder.createEncryptRule(), null, null, mockSelectStatementContextWithLike()));
}

private SQLStatementContext mockSelectStatementContextWithLike() {
Expand All @@ -98,7 +98,7 @@ private SQLStatementContext mockSelectStatementContextWithLike() {

@Test
void assertCheckSuccess() {
assertDoesNotThrow(() -> new EncryptPredicateColumnSupportedChecker().check(EncryptGeneratorFixtureBuilder.createEncryptRule(), null, mockSelectStatementContextWithEqual()));
assertDoesNotThrow(() -> new EncryptPredicateColumnSupportedChecker().check(EncryptGeneratorFixtureBuilder.createEncryptRule(), null, null, mockSelectStatementContextWithEqual()));
}

private SQLStatementContext mockSelectStatementContextWithEqual() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.apache.shardingsphere.infra.binder.context.segment.insert.values.InsertSelectContext;
import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.binder.context.statement.dml.InsertStatementContext;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -55,6 +56,7 @@ void assertIsCheckWithInsertSelect() {
@Test
void assertCheckSuccess() {
assertDoesNotThrow(
() -> new EncryptInsertSelectProjectionSupportedChecker().check(mock(EncryptRule.class), mock(ShardingSphereSchema.class), mock(InsertStatementContext.class, RETURNS_DEEP_STUBS)));
() -> new EncryptInsertSelectProjectionSupportedChecker().check(mock(EncryptRule.class), mock(ShardingSphereDatabase.class), mock(ShardingSphereSchema.class),
mock(InsertStatementContext.class, RETURNS_DEEP_STUBS)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,19 @@ void assertCheckWhenShorthandExpandContainsSubqueryTable() {
SelectStatementContext sqlStatementContext = mock(SelectStatementContext.class, RETURNS_DEEP_STUBS);
when(sqlStatementContext.containsTableSubquery()).thenReturn(true);
when(sqlStatementContext.getSqlStatement().getProjections().getProjections()).thenReturn(Collections.singleton(new ShorthandProjectionSegment(0, 0)));
assertThrows(UnsupportedSQLOperationException.class, () -> new EncryptSelectProjectionSupportedChecker().check(mock(EncryptRule.class, RETURNS_DEEP_STUBS), null, sqlStatementContext));
assertThrows(UnsupportedSQLOperationException.class, () -> new EncryptSelectProjectionSupportedChecker().check(mock(EncryptRule.class, RETURNS_DEEP_STUBS), null, null, sqlStatementContext));
}

@Test
void assertCheckWhenCombineStatementContainsEncryptColumn() {
SelectStatementContext sqlStatementContext = mockSelectStatementContext();
assertThrows(UnsupportedSQLOperationException.class, () -> new EncryptSelectProjectionSupportedChecker().check(mock(EncryptRule.class, RETURNS_DEEP_STUBS), null, sqlStatementContext));
assertThrows(UnsupportedSQLOperationException.class, () -> new EncryptSelectProjectionSupportedChecker().check(mock(EncryptRule.class, RETURNS_DEEP_STUBS), null, null, sqlStatementContext));
}

@Test
void assertCheckSuccess() {
SelectStatementContext sqlStatementContext = mockSelectStatementContext();
assertDoesNotThrow(() -> new EncryptSelectProjectionSupportedChecker().check(mockEncryptRule(), null, sqlStatementContext));
assertDoesNotThrow(() -> new EncryptSelectProjectionSupportedChecker().check(mockEncryptRule(), null, null, sqlStatementContext));
}

private SelectStatementContext mockSelectStatementContext() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.binder.context.type.TableAvailable;
import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
import org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPILoader;
Expand All @@ -38,23 +39,22 @@ public final class SupportedSQLCheckEngine {
*
* @param rules rules
* @param sqlStatementContext to be checked SQL statement context
* @param schemas schemas
* @param databaseName database name
* @param database database
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public void checkSQL(final Collection<ShardingSphereRule> rules, final SQLStatementContext sqlStatementContext, final Map<String, ShardingSphereSchema> schemas, final String databaseName) {
ShardingSphereSchema schema = getSchema(sqlStatementContext, schemas, databaseName);
public void checkSQL(final Collection<ShardingSphereRule> rules, final SQLStatementContext sqlStatementContext, final ShardingSphereDatabase database) {
ShardingSphereSchema currentSchema = getCurrentSchema(sqlStatementContext, database.getSchemas(), database.getName());
for (Entry<ShardingSphereRule, SupportedSQLCheckersBuilder> entry : OrderedSPILoader.getServices(SupportedSQLCheckersBuilder.class, rules).entrySet()) {
Collection<SupportedSQLChecker> checkers = entry.getValue().getSupportedSQLCheckers();
for (SupportedSQLChecker each : checkers) {
if (each.isCheck(sqlStatementContext)) {
each.check(entry.getKey(), schema, sqlStatementContext);
each.check(entry.getKey(), database, currentSchema, sqlStatementContext);
}
}
}
}

private ShardingSphereSchema getSchema(final SQLStatementContext sqlStatementContext, final Map<String, ShardingSphereSchema> schemas, final String databaseName) {
private ShardingSphereSchema getCurrentSchema(final SQLStatementContext sqlStatementContext, final Map<String, ShardingSphereSchema> schemas, final String databaseName) {
ShardingSphereSchema defaultSchema = schemas.get(new DatabaseTypeRegistry(sqlStatementContext.getDatabaseType()).getDefaultSchemaName(databaseName));
return sqlStatementContext instanceof TableAvailable ? ((TableAvailable) sqlStatementContext).getTablesContext().getSchemaName().map(schemas::get).orElse(defaultSchema) : defaultSchema;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package org.apache.shardingsphere.infra.checker;

import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
import org.apache.shardingsphere.infra.rule.ShardingSphereRule;

Expand All @@ -41,8 +42,9 @@ public interface SupportedSQLChecker<T extends SQLStatementContext, R extends Sh
* Check SQL.
*
* @param rule rule
* @param schema schema
* @param database database
* @param currentSchema current schema
* @param sqlStatementContext to be checked SQL statement context
*/
void check(R rule, ShardingSphereSchema schema, T sqlStatementContext);
void check(R rule, ShardingSphereDatabase database, ShardingSphereSchema currentSchema, T sqlStatementContext);
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public ExecutionContext generateExecutionContext(final QueryContext queryContext

private void check(final QueryContext queryContext) {
ShardingSphereDatabase database = queryContext.getUsedDatabase();
new SupportedSQLCheckEngine().checkSQL(database.getRuleMetaData().getRules(), queryContext.getSqlStatementContext(), database.getSchemas(), database.getName());
new SupportedSQLCheckEngine().checkSQL(database.getRuleMetaData().getRules(), queryContext.getSqlStatementContext(), database);
}

private RouteContext route(final QueryContext queryContext, final RuleMetaData globalRuleMetaData, final ConfigurationProperties props) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,14 @@
import org.apache.shardingsphere.sql.parser.statement.core.statement.dal.ShowTableStatusStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.dal.ShowTablesStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.AlterFunctionStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.AlterSchemaStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.AlterTablespaceStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateFunctionStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateSchemaStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateTablespaceStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DDLStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DropFunctionStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DropSchemaStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DropTablespaceStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.tcl.TCLStatement;

Expand Down Expand Up @@ -97,13 +100,20 @@ private static TablelessRouteEngine getDDLRouteEngine(final SQLStatementContext
return getCursorRouteEngine(sqlStatementContext);
}
SQLStatement sqlStatement = sqlStatementContext.getSqlStatement();
boolean functionStatement = sqlStatement instanceof CreateFunctionStatement || sqlStatement instanceof AlterFunctionStatement || sqlStatement instanceof DropFunctionStatement;
if (functionStatement) {
if (isFunctionDDLStatement(sqlStatement) || isSchemaDDLStatement(sqlStatement)) {
return new DataSourceBroadcastRouteEngine();
}
return new IgnoreRouteEngine();
}

private static boolean isFunctionDDLStatement(final SQLStatement sqlStatement) {
return sqlStatement instanceof CreateFunctionStatement || sqlStatement instanceof AlterFunctionStatement || sqlStatement instanceof DropFunctionStatement;
}

private static boolean isSchemaDDLStatement(final SQLStatement sqlStatement) {
return sqlStatement instanceof CreateSchemaStatement || sqlStatement instanceof AlterSchemaStatement || sqlStatement instanceof DropSchemaStatement;
}

private static TablelessRouteEngine getCursorRouteEngine(final SQLStatementContext sqlStatementContext) {
if (sqlStatementContext instanceof CloseStatementContext && ((CloseStatementContext) sqlStatementContext).getSqlStatement().isCloseAll()) {
return new DataSourceBroadcastRouteEngine();
Expand Down
Loading

0 comments on commit 4d30358

Please sign in to comment.