This is an automated email from the ASF dual-hosted git repository. chengzhang 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 01dfad96dc0 Adjust single, encrypt and broadcast order and simply broadcast sql router (#33839) 01dfad96dc0 is described below commit 01dfad96dc07f93462183edbe837ab72453bc6e9 Author: Zhengqiang Duan <duanzhengqi...@apache.org> AuthorDate: Fri Nov 29 18:22:12 2024 +0800 Adjust single, encrypt and broadcast order and simply broadcast sql router (#33839) * Adjust single, encrypt and broadcast order and simply broadcast sql router * revert some dev config * fix unit test * fix unit test * modify e2e case --- .../broadcast/constant/BroadcastOrder.java | 2 +- .../broadcast/route/BroadcastSQLRouter.java | 130 ++------------------ .../route/engine/BroadcastRouteEngineFactory.java | 71 +++-------- .../route/engine/type/BroadcastRouteEngine.java | 3 +- .../BroadcastDatabaseBroadcastRouteEngine.java | 7 +- .../BroadcastInstanceBroadcastRouteEngine.java | 50 -------- .../BroadcastTableBroadcastRouteEngine.java | 9 +- .../type/ignore/BroadcastIgnoreRouteEngine.java | 33 ----- .../type/unicast/BroadcastUnicastRouteEngine.java | 7 +- .../broadcast/rule/BroadcastRule.java | 17 ++- .../broadcast/route/BroadcastSQLRouterTest.java | 64 +--------- .../engine/BroadcastRouteEngineFactoryTest.java | 100 +++------------ .../BroadcastDatabaseBroadcastRouteEngineTest.java | 2 +- .../BroadcastInstanceBroadcastRouteEngineTest.java | 52 -------- .../BroadcastTableBroadcastRouteEngineTest.java | 8 +- .../ignore/BroadcastIgnoreRouteEngineTest.java | 35 ------ .../unicast/BroadcastUnicastRouteEngineTest.java | 4 +- .../broadcast/rule/BroadcastRuleTest.java | 4 +- .../encrypt/constant/EncryptOrder.java | 2 +- .../standard/assertion/ShardingRouteAssert.java | 12 +- .../single/constant/SingleOrder.java | 2 +- .../single/route/SingleSQLRouter.java | 45 +++++-- .../single/route/engine/SingleRouteEngine.java | 111 ++++++++++++++++- .../route/engine/SingleRouteEngineFactory.java | 47 ------- .../engine/standard/SingleStandardRouteEngine.java | 136 --------------------- .../single/route/SingleSQLRouterTest.java | 14 +-- .../route/engine/SingleRouteEngineFactoryTest.java | 42 ------- ...eEngineTest.java => SingleRouteEngineTest.java} | 18 +-- .../resources/cases/dql/e2e-dql-select-join.xml | 10 ++ .../scenario/sharding/case/ddl/create-table.xml | 21 +++- 30 files changed, 276 insertions(+), 782 deletions(-) diff --git a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/constant/BroadcastOrder.java b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/constant/BroadcastOrder.java index 4745ee15c62..d2b240abd45 100644 --- a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/constant/BroadcastOrder.java +++ b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/constant/BroadcastOrder.java @@ -29,5 +29,5 @@ public final class BroadcastOrder { /** * Broadcast order. */ - public static final int ORDER = 5; + public static final int ORDER = 15; } diff --git a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/BroadcastSQLRouter.java b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/BroadcastSQLRouter.java index 7b44e74d57d..e9926f0b89b 100644 --- a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/BroadcastSQLRouter.java +++ b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/BroadcastSQLRouter.java @@ -19,148 +19,32 @@ package org.apache.shardingsphere.broadcast.route; import org.apache.shardingsphere.broadcast.constant.BroadcastOrder; import org.apache.shardingsphere.broadcast.route.engine.BroadcastRouteEngineFactory; -import org.apache.shardingsphere.broadcast.route.engine.type.broadcast.BroadcastDatabaseBroadcastRouteEngine; -import org.apache.shardingsphere.broadcast.route.engine.type.broadcast.BroadcastInstanceBroadcastRouteEngine; import org.apache.shardingsphere.broadcast.rule.BroadcastRule; import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation; -import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; -import org.apache.shardingsphere.infra.binder.context.statement.ddl.CloseStatementContext; -import org.apache.shardingsphere.infra.binder.context.type.CursorAvailable; -import org.apache.shardingsphere.infra.binder.context.type.IndexAvailable; -import org.apache.shardingsphere.infra.binder.context.type.TableAvailable; import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; import org.apache.shardingsphere.infra.route.context.RouteContext; -import org.apache.shardingsphere.infra.route.context.RouteMapper; -import org.apache.shardingsphere.infra.route.context.RouteUnit; -import org.apache.shardingsphere.infra.route.type.DecorateSQLRouter; import org.apache.shardingsphere.infra.route.type.EntranceSQLRouter; import org.apache.shardingsphere.infra.route.type.TableSQLRouter; import org.apache.shardingsphere.infra.session.query.QueryContext; -import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment; -import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement; -import org.apache.shardingsphere.sql.parser.statement.core.statement.dal.DALStatement; -import org.apache.shardingsphere.sql.parser.statement.core.statement.dcl.DCLStatement; -import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.AlterFunctionStatement; -import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.AlterProcedureStatement; -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.CreateProcedureStatement; -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.DropProcedureStatement; -import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DropTablespaceStatement; -import org.apache.shardingsphere.sql.parser.statement.core.statement.tcl.TCLStatement; -import org.apache.shardingsphere.sql.parser.statement.mysql.dal.MySQLCreateResourceGroupStatement; -import org.apache.shardingsphere.sql.parser.statement.mysql.dal.MySQLSetResourceGroupStatement; import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashSet; /** * Broadcast SQL router. */ @HighFrequencyInvocation -public final class BroadcastSQLRouter implements EntranceSQLRouter<BroadcastRule>, DecorateSQLRouter<BroadcastRule>, TableSQLRouter<BroadcastRule> { +public final class BroadcastSQLRouter implements EntranceSQLRouter<BroadcastRule>, TableSQLRouter<BroadcastRule> { @Override - public RouteContext createRouteContext(final QueryContext queryContext, final RuleMetaData globalRuleMetaData, - final ShardingSphereDatabase database, final BroadcastRule rule, final Collection<String> tableNames, final ConfigurationProperties props) { - return BroadcastRouteEngineFactory.newInstance(rule, database, queryContext).route(new RouteContext(), rule); - } - - @Override - public void decorateRouteContext(final RouteContext routeContext, final QueryContext queryContext, - final ShardingSphereDatabase database, final BroadcastRule rule, final Collection<String> tableNames, final ConfigurationProperties props) { - SQLStatementContext sqlStatementContext = queryContext.getSqlStatementContext(); - SQLStatement sqlStatement = sqlStatementContext.getSqlStatement(); - if (sqlStatement instanceof TCLStatement) { - decorateRouteContextWhenTCLStatement(routeContext, rule); - } else if (sqlStatement instanceof DDLStatement) { - decorateRouteContextWhenDDLStatement(routeContext, queryContext, database, rule); - } else if (sqlStatement instanceof DALStatement && isResourceGroupStatement(sqlStatement)) { - doInstanceBroadcastRoute(routeContext, database, rule); - } else if (sqlStatement instanceof DCLStatement && !isDCLForSingleTable(queryContext.getSqlStatementContext())) { - doInstanceBroadcastRoute(routeContext, database, rule); - } - } - - private void decorateRouteContextWhenTCLStatement(final RouteContext routeContext, final BroadcastRule rule) { - doDatabaseBroadcastRoute(routeContext, rule); - } - - private void decorateRouteContextWhenDDLStatement(final RouteContext routeContext, final QueryContext queryContext, final ShardingSphereDatabase database, final BroadcastRule rule) { - SQLStatementContext sqlStatementContext = queryContext.getSqlStatementContext(); - if (sqlStatementContext instanceof CursorAvailable) { - if (sqlStatementContext instanceof CloseStatementContext && ((CloseStatementContext) sqlStatementContext).getSqlStatement().isCloseAll()) { - doDatabaseBroadcastRoute(routeContext, rule); - } - return; - } - if (sqlStatementContext instanceof IndexAvailable && !routeContext.getRouteUnits().isEmpty()) { - putAllBroadcastTables(routeContext, rule, sqlStatementContext); - } - SQLStatement sqlStatement = sqlStatementContext.getSqlStatement(); - boolean functionStatement = sqlStatement instanceof CreateFunctionStatement || sqlStatement instanceof AlterFunctionStatement || sqlStatement instanceof DropFunctionStatement; - boolean procedureStatement = sqlStatement instanceof CreateProcedureStatement || sqlStatement instanceof AlterProcedureStatement || sqlStatement instanceof DropProcedureStatement; - if (functionStatement || procedureStatement) { - doDatabaseBroadcastRoute(routeContext, rule); - return; - } - // TODO BEGIN extract db route logic to common database router, eg: DCL in instance route @duanzhengqiang - if (sqlStatement instanceof CreateTablespaceStatement || sqlStatement instanceof AlterTablespaceStatement || sqlStatement instanceof DropTablespaceStatement) { - doInstanceBroadcastRoute(routeContext, database, rule); + public RouteContext createRouteContext(final QueryContext queryContext, final RuleMetaData globalRuleMetaData, final ShardingSphereDatabase database, + final BroadcastRule rule, final Collection<String> tableNames, final ConfigurationProperties props) { + Collection<String> broadcastTableNames = rule.getBroadcastTableNames(tableNames); + if (broadcastTableNames.isEmpty()) { + return new RouteContext(); } - // TODO END extract db route logic to common database router, eg: DCL in instance route - Collection<String> tableNames = sqlStatementContext instanceof TableAvailable ? getTableNames((TableAvailable) sqlStatementContext) : Collections.emptyList(); - if (rule.isAllBroadcastTables(tableNames)) { - doInstanceBroadcastRoute(routeContext, database, rule); - } - } - - private Collection<String> getTableNames(final TableAvailable sqlStatementContext) { - Collection<SimpleTableSegment> tableSegments = sqlStatementContext.getTablesContext().getSimpleTables(); - Collection<String> result = new LinkedHashSet<>(tableSegments.size()); - for (SimpleTableSegment each : tableSegments) { - result.add(each.getTableName().getIdentifier().getValue()); - } - return result; - } - - private void putAllBroadcastTables(final RouteContext routeContext, final BroadcastRule rule, final SQLStatementContext sqlStatementContext) { - Collection<String> tableNames = sqlStatementContext instanceof TableAvailable ? ((TableAvailable) sqlStatementContext).getTablesContext().getTableNames() : Collections.emptyList(); - for (String each : rule.filterBroadcastTableNames(tableNames)) { - for (RouteUnit routeUnit : routeContext.getRouteUnits()) { - routeUnit.getTableMappers().add(new RouteMapper(each, each)); - } - } - } - - private boolean isResourceGroupStatement(final SQLStatement sqlStatement) { - // TODO add dropResourceGroupStatement, alterResourceGroupStatement - return sqlStatement instanceof MySQLCreateResourceGroupStatement || sqlStatement instanceof MySQLSetResourceGroupStatement; - } - - private boolean isDCLForSingleTable(final SQLStatementContext sqlStatementContext) { - if (sqlStatementContext instanceof TableAvailable) { - TableAvailable tableSegmentsAvailable = (TableAvailable) sqlStatementContext; - return 1 == tableSegmentsAvailable.getTablesContext().getSimpleTables().size() - && !"*".equals(tableSegmentsAvailable.getTablesContext().getSimpleTables().iterator().next().getTableName().getIdentifier().getValue()); - } - return false; - } - - private void doDatabaseBroadcastRoute(final RouteContext routeContext, final BroadcastRule rule) { - routeContext.getRouteUnits().clear(); - routeContext.getRouteUnits().addAll(new BroadcastDatabaseBroadcastRouteEngine().route(new RouteContext(), rule).getRouteUnits()); - } - - private void doInstanceBroadcastRoute(final RouteContext routeContext, final ShardingSphereDatabase database, final BroadcastRule rule) { - routeContext.getRouteUnits().clear(); - routeContext.getRouteUnits().addAll(new BroadcastInstanceBroadcastRouteEngine(database.getResourceMetaData()).route(new RouteContext(), rule).getRouteUnits()); + return BroadcastRouteEngineFactory.newInstance(queryContext, broadcastTableNames).route(rule); } @Override diff --git a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/BroadcastRouteEngineFactory.java b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/BroadcastRouteEngineFactory.java index 6237e1e0b4c..887f45e5ee6 100644 --- a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/BroadcastRouteEngineFactory.java +++ b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/BroadcastRouteEngineFactory.java @@ -22,16 +22,10 @@ import lombok.NoArgsConstructor; import org.apache.shardingsphere.broadcast.route.engine.type.BroadcastRouteEngine; import org.apache.shardingsphere.broadcast.route.engine.type.broadcast.BroadcastDatabaseBroadcastRouteEngine; import org.apache.shardingsphere.broadcast.route.engine.type.broadcast.BroadcastTableBroadcastRouteEngine; -import org.apache.shardingsphere.broadcast.route.engine.type.ignore.BroadcastIgnoreRouteEngine; import org.apache.shardingsphere.broadcast.route.engine.type.unicast.BroadcastUnicastRouteEngine; -import org.apache.shardingsphere.broadcast.rule.BroadcastRule; import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation; -import org.apache.shardingsphere.infra.binder.context.extractor.SQLStatementContextExtractor; import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; -import org.apache.shardingsphere.infra.binder.context.statement.ddl.CloseStatementContext; import org.apache.shardingsphere.infra.binder.context.type.CursorAvailable; -import org.apache.shardingsphere.infra.binder.context.type.TableAvailable; -import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.session.connection.ConnectionContext; import org.apache.shardingsphere.infra.session.query.QueryContext; import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement; @@ -39,7 +33,6 @@ import org.apache.shardingsphere.sql.parser.statement.core.statement.dal.DALStat import org.apache.shardingsphere.sql.parser.statement.core.statement.dcl.DCLStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DDLStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.SelectStatement; -import org.apache.shardingsphere.sql.parser.statement.core.statement.tcl.TCLStatement; import java.util.Collection; @@ -53,70 +46,42 @@ public final class BroadcastRouteEngineFactory { /** * Create new instance of broadcast routing engine. * - * @param rule broadcast rule - * @param database database * @param queryContext query context + * @param broadcastTableNames broadcast table names * @return broadcast route engine */ - public static BroadcastRouteEngine newInstance(final BroadcastRule rule, final ShardingSphereDatabase database, final QueryContext queryContext) { + public static BroadcastRouteEngine newInstance(final QueryContext queryContext, final Collection<String> broadcastTableNames) { SQLStatementContext sqlStatementContext = queryContext.getSqlStatementContext(); SQLStatement sqlStatement = sqlStatementContext.getSqlStatement(); - if (sqlStatement instanceof TCLStatement) { - return new BroadcastDatabaseBroadcastRouteEngine(); - } if (sqlStatement instanceof DDLStatement) { - return sqlStatementContext instanceof CursorAvailable - ? getCursorRouteEngine(rule, sqlStatementContext, queryContext.getConnectionContext()) - : getDDLRouteEngine(rule, database, sqlStatementContext); - } - if (!(sqlStatementContext instanceof TableAvailable)) { - return new BroadcastIgnoreRouteEngine(); - } - Collection<String> tableNames = ((TableAvailable) sqlStatementContext).getTablesContext().getTableNames(); - if (tableNames.isEmpty()) { - return new BroadcastIgnoreRouteEngine(); + return getDDLRouteEngine(queryContext, broadcastTableNames, sqlStatementContext); } if (sqlStatement instanceof DALStatement) { - return getDALRouteEngine(rule, tableNames); + return getDALRouteEngine(broadcastTableNames); } if (sqlStatement instanceof DCLStatement) { - return getDCLRouteEngine(rule, tableNames); - } - return getDMLRouteEngine(rule, sqlStatementContext, queryContext.getConnectionContext(), tableNames); - } - - private static BroadcastRouteEngine getCursorRouteEngine(final BroadcastRule rule, final SQLStatementContext sqlStatementContext, final ConnectionContext connectionContext) { - if (sqlStatementContext instanceof CloseStatementContext && ((CloseStatementContext) sqlStatementContext).getSqlStatement().isCloseAll()) { - return new BroadcastDatabaseBroadcastRouteEngine(); + return getDCLRouteEngine(broadcastTableNames); } - if (sqlStatementContext instanceof TableAvailable) { - Collection<String> tableNames = ((TableAvailable) sqlStatementContext).getTablesContext().getTableNames(); - return rule.isAllBroadcastTables(tableNames) ? new BroadcastUnicastRouteEngine(sqlStatementContext, tableNames, connectionContext) : new BroadcastIgnoreRouteEngine(); - } - return new BroadcastIgnoreRouteEngine(); + return getDMLRouteEngine(sqlStatementContext, queryContext.getConnectionContext(), broadcastTableNames); } - private static BroadcastRouteEngine getDDLRouteEngine(final BroadcastRule rule, final ShardingSphereDatabase database, final SQLStatementContext sqlStatementContext) { - Collection<String> tableNames = SQLStatementContextExtractor.getTableNames(database, sqlStatementContext); - return rule.isAllBroadcastTables(tableNames) ? new BroadcastTableBroadcastRouteEngine(tableNames) : new BroadcastIgnoreRouteEngine(); + private static BroadcastRouteEngine getDDLRouteEngine(final QueryContext queryContext, final Collection<String> broadcastTableNames, final SQLStatementContext sqlStatementContext) { + return sqlStatementContext instanceof CursorAvailable + ? new BroadcastUnicastRouteEngine(sqlStatementContext, broadcastTableNames, queryContext.getConnectionContext()) + : new BroadcastTableBroadcastRouteEngine(broadcastTableNames); } - private static BroadcastRouteEngine getDALRouteEngine(final BroadcastRule rule, final Collection<String> tableNames) { - return new BroadcastTableBroadcastRouteEngine(rule.filterBroadcastTableNames(tableNames)); + private static BroadcastRouteEngine getDALRouteEngine(final Collection<String> broadcastTableNames) { + return new BroadcastTableBroadcastRouteEngine(broadcastTableNames); } - private static BroadcastRouteEngine getDCLRouteEngine(final BroadcastRule rule, final Collection<String> tableNames) { - Collection<String> broadcastTableNames = rule.filterBroadcastTableNames(tableNames); - return broadcastTableNames.isEmpty() ? new BroadcastIgnoreRouteEngine() : new BroadcastTableBroadcastRouteEngine(broadcastTableNames); + private static BroadcastRouteEngine getDCLRouteEngine(final Collection<String> broadcastTableNames) { + return new BroadcastTableBroadcastRouteEngine(broadcastTableNames); } - private static BroadcastRouteEngine getDMLRouteEngine(final BroadcastRule rule, final SQLStatementContext sqlStatementContext, - final ConnectionContext connectionContext, final Collection<String> tableNames) { - if (rule.isAllBroadcastTables(tableNames)) { - return sqlStatementContext.getSqlStatement() instanceof SelectStatement - ? new BroadcastUnicastRouteEngine(sqlStatementContext, tableNames, connectionContext) - : new BroadcastDatabaseBroadcastRouteEngine(); - } - return new BroadcastIgnoreRouteEngine(); + private static BroadcastRouteEngine getDMLRouteEngine(final SQLStatementContext sqlStatementContext, final ConnectionContext connectionContext, final Collection<String> broadcastTableNames) { + return sqlStatementContext.getSqlStatement() instanceof SelectStatement + ? new BroadcastUnicastRouteEngine(sqlStatementContext, broadcastTableNames, connectionContext) + : new BroadcastDatabaseBroadcastRouteEngine(); } } diff --git a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/BroadcastRouteEngine.java b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/BroadcastRouteEngine.java index 76e493fbb64..0825f9ffceb 100644 --- a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/BroadcastRouteEngine.java +++ b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/BroadcastRouteEngine.java @@ -28,9 +28,8 @@ public interface BroadcastRouteEngine { /** * Route. * - * @param routeContext route context * @param broadcastRule broadcast rule * @return route context */ - RouteContext route(RouteContext routeContext, BroadcastRule broadcastRule); + RouteContext route(BroadcastRule broadcastRule); } diff --git a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastDatabaseBroadcastRouteEngine.java b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastDatabaseBroadcastRouteEngine.java index 9269f64e419..03a49f52475 100644 --- a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastDatabaseBroadcastRouteEngine.java +++ b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastDatabaseBroadcastRouteEngine.java @@ -33,10 +33,11 @@ import java.util.Collections; public final class BroadcastDatabaseBroadcastRouteEngine implements BroadcastRouteEngine { @Override - public RouteContext route(final RouteContext routeContext, final BroadcastRule rule) { + public RouteContext route(final BroadcastRule rule) { + RouteContext result = new RouteContext(); for (String each : rule.getDataSourceNames()) { - routeContext.getRouteUnits().add(new RouteUnit(new RouteMapper(each, each), Collections.emptyList())); + result.getRouteUnits().add(new RouteUnit(new RouteMapper(each, each), Collections.emptyList())); } - return routeContext; + return result; } } diff --git a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastInstanceBroadcastRouteEngine.java b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastInstanceBroadcastRouteEngine.java deleted file mode 100644 index 3cb9ae7af77..00000000000 --- a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastInstanceBroadcastRouteEngine.java +++ /dev/null @@ -1,50 +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.broadcast.route.engine.type.broadcast; - -import lombok.RequiredArgsConstructor; -import org.apache.shardingsphere.broadcast.route.engine.type.BroadcastRouteEngine; -import org.apache.shardingsphere.broadcast.rule.BroadcastRule; -import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation; -import org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData; -import org.apache.shardingsphere.infra.route.context.RouteContext; -import org.apache.shardingsphere.infra.route.context.RouteMapper; -import org.apache.shardingsphere.infra.route.context.RouteUnit; - -import java.util.Collections; - -/** - * Broadcast route engine for database instance. - */ -@HighFrequencyInvocation -@RequiredArgsConstructor -public final class BroadcastInstanceBroadcastRouteEngine implements BroadcastRouteEngine { - - private final ResourceMetaData resourceMetaData; - - @Override - public RouteContext route(final RouteContext routeContext, final BroadcastRule rule) { - RouteContext result = new RouteContext(); - for (String each : rule.getDataSourceNames()) { - if (resourceMetaData.getAllInstanceDataSourceNames().contains(each)) { - result.getRouteUnits().add(new RouteUnit(new RouteMapper(each, each), Collections.emptyList())); - } - } - return result; - } -} diff --git a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastTableBroadcastRouteEngine.java b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastTableBroadcastRouteEngine.java index 98d59ee2068..a24b7169d1a 100644 --- a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastTableBroadcastRouteEngine.java +++ b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastTableBroadcastRouteEngine.java @@ -39,11 +39,12 @@ public final class BroadcastTableBroadcastRouteEngine implements BroadcastRouteE private final Collection<String> broadcastTableNames; @Override - public RouteContext route(final RouteContext routeContext, final BroadcastRule rule) { - Collection<String> logicTableNames = rule.filterBroadcastTableNames(broadcastTableNames); + public RouteContext route(final BroadcastRule rule) { + RouteContext result = new RouteContext(); + Collection<String> logicTableNames = rule.getBroadcastTableNames(broadcastTableNames); RouteContext toBeAddedRouteContext = logicTableNames.isEmpty() ? getRouteContext(rule) : getRouteContext(rule, logicTableNames); - routeContext.getRouteUnits().addAll(toBeAddedRouteContext.getRouteUnits()); - return routeContext; + result.getRouteUnits().addAll(toBeAddedRouteContext.getRouteUnits()); + return result; } private RouteContext getRouteContext(final BroadcastRule rule) { diff --git a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/ignore/BroadcastIgnoreRouteEngine.java b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/ignore/BroadcastIgnoreRouteEngine.java deleted file mode 100644 index 4dc1a749507..00000000000 --- a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/ignore/BroadcastIgnoreRouteEngine.java +++ /dev/null @@ -1,33 +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.broadcast.route.engine.type.ignore; - -import org.apache.shardingsphere.broadcast.route.engine.type.BroadcastRouteEngine; -import org.apache.shardingsphere.broadcast.rule.BroadcastRule; -import org.apache.shardingsphere.infra.route.context.RouteContext; - -/** - * Broadcast ignore route engine. - */ -public final class BroadcastIgnoreRouteEngine implements BroadcastRouteEngine { - - @Override - public RouteContext route(final RouteContext routeContext, final BroadcastRule rule) { - return routeContext; - } -} diff --git a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/unicast/BroadcastUnicastRouteEngine.java b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/unicast/BroadcastUnicastRouteEngine.java index 444116de5a0..aa4472cc34f 100644 --- a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/unicast/BroadcastUnicastRouteEngine.java +++ b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/route/engine/type/unicast/BroadcastUnicastRouteEngine.java @@ -49,10 +49,11 @@ public final class BroadcastUnicastRouteEngine implements BroadcastRouteEngine { private final ConnectionContext connectionContext; @Override - public RouteContext route(final RouteContext routeContext, final BroadcastRule rule) { + public RouteContext route(final BroadcastRule rule) { + RouteContext result = new RouteContext(); RouteMapper dataSourceMapper = getDataSourceRouteMapper(rule.getDataSourceNames()); - routeContext.getRouteUnits().add(new RouteUnit(dataSourceMapper, createTableRouteMappers())); - return routeContext; + result.getRouteUnits().add(new RouteUnit(dataSourceMapper, createTableRouteMappers())); + return result; } private RouteMapper getDataSourceRouteMapper(final Collection<String> dataSourceNames) { diff --git a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/rule/BroadcastRule.java b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/rule/BroadcastRule.java index d40ab1e88fe..64431426ac0 100644 --- a/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/rule/BroadcastRule.java +++ b/features/broadcast/core/src/main/java/org/apache/shardingsphere/broadcast/rule/BroadcastRule.java @@ -34,7 +34,6 @@ import java.util.LinkedList; import java.util.Map; import java.util.Map.Entry; import java.util.Optional; -import java.util.stream.Collectors; /** * Broadcast rule. @@ -85,13 +84,19 @@ public final class BroadcastRule implements DatabaseRule { } /** - * Filter broadcast table names. + * Get broadcast table names. * - * @param logicTableNames to be filtered logic table names - * @return filtered broadcast table names + * @param logicTableNames all logic table names + * @return broadcast table names */ - public Collection<String> filterBroadcastTableNames(final Collection<String> logicTableNames) { - return logicTableNames.stream().filter(tables::contains).collect(Collectors.toSet()); + public Collection<String> getBroadcastTableNames(final Collection<String> logicTableNames) { + Collection<String> result = new CaseInsensitiveSet<>(); + for (String each : logicTableNames) { + if (tables.contains(each)) { + result.add(each); + } + } + return result; } /** diff --git a/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/BroadcastSQLRouterTest.java b/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/BroadcastSQLRouterTest.java index 26ce3cc15a2..27407ce4115 100644 --- a/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/BroadcastSQLRouterTest.java +++ b/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/BroadcastSQLRouterTest.java @@ -17,48 +17,24 @@ package org.apache.shardingsphere.broadcast.route; -import com.google.common.collect.Lists; -import org.apache.shardingsphere.broadcast.config.BroadcastRuleConfiguration; import org.apache.shardingsphere.broadcast.route.engine.BroadcastRouteEngineFactory; import org.apache.shardingsphere.broadcast.route.engine.type.BroadcastRouteEngine; import org.apache.shardingsphere.broadcast.rule.BroadcastRule; -import org.apache.shardingsphere.infra.binder.context.statement.ddl.CreateTableStatementContext; import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; -import org.apache.shardingsphere.infra.database.core.DefaultDatabase; -import org.apache.shardingsphere.infra.hint.HintValueContext; -import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; -import org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit; import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; import org.apache.shardingsphere.infra.route.SQLRouter; -import org.apache.shardingsphere.infra.route.context.RouteContext; -import org.apache.shardingsphere.infra.route.context.RouteMapper; -import org.apache.shardingsphere.infra.route.context.RouteUnit; -import org.apache.shardingsphere.infra.session.connection.ConnectionContext; import org.apache.shardingsphere.infra.session.query.QueryContext; import org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPILoader; -import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment; -import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment; -import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateTableStatement; -import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue; -import org.apache.shardingsphere.sql.parser.statement.mysql.ddl.MySQLCreateTableStatement; -import org.apache.shardingsphere.test.fixture.jdbc.MockedDataSource; import org.apache.shardingsphere.test.mock.AutoMockExtension; import org.apache.shardingsphere.test.mock.StaticMockSettings; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Optional; import java.util.Properties; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -71,47 +47,15 @@ class BroadcastSQLRouterTest { void assertCreateRouteContext() { QueryContext queryContext = mock(QueryContext.class); BroadcastRule rule = mock(BroadcastRule.class); + when(rule.getBroadcastTableNames(Collections.singleton("t_config"))).thenReturn(Collections.singleton("t_config")); ShardingSphereDatabase database = mock(ShardingSphereDatabase.class); BroadcastRouteEngine routeEngine = mock(BroadcastRouteEngine.class); - when(BroadcastRouteEngineFactory.newInstance(rule, database, queryContext)).thenReturn(routeEngine); - getSQLRouter(rule).createRouteContext(queryContext, mock(RuleMetaData.class), database, rule, Collections.emptyList(), new ConfigurationProperties(new Properties())); - verify(routeEngine).route(any(), eq(rule)); - } - - @Test - void assertDecorateBroadcastRouteContextWithSingleDataSource() { - BroadcastRuleConfiguration currentConfig = mock(BroadcastRuleConfiguration.class); - when(currentConfig.getTables()).thenReturn(Collections.singleton("t_order")); - BroadcastRule rule = new BroadcastRule(currentConfig, Collections.singletonMap("foo_ds", new MockedDataSource()), Collections.emptyList()); - RouteContext routeContext = new RouteContext(); - routeContext.getRouteUnits().add(new RouteUnit(new RouteMapper("foo_ds", "foo_ds"), Lists.newArrayList())); - BroadcastSQLRouter sqlRouter = getSQLRouter(rule); - sqlRouter.decorateRouteContext(routeContext, createQueryContext(), mockSingleDatabase(), rule, Collections.emptyList(), new ConfigurationProperties(new Properties())); - Iterator<String> routedDataSourceNames = routeContext.getActualDataSourceNames().iterator(); - assertThat(routedDataSourceNames.next(), is("foo_ds")); + when(BroadcastRouteEngineFactory.newInstance(queryContext, Collections.singleton("t_config"))).thenReturn(routeEngine); + getSQLRouter(rule).createRouteContext(queryContext, mock(RuleMetaData.class), database, rule, Collections.singleton("t_config"), new ConfigurationProperties(new Properties())); + verify(routeEngine).route(eq(rule)); } private BroadcastSQLRouter getSQLRouter(final BroadcastRule rule) { return (BroadcastSQLRouter) OrderedSPILoader.getServices(SQLRouter.class, Collections.singleton(rule)).get(rule); } - - private ShardingSphereDatabase mockSingleDatabase() { - ShardingSphereDatabase result = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS); - when(result.getResourceMetaData().getStorageUnits()).thenReturn(Collections.singletonMap("foo_ds", mock(StorageUnit.class))); - when(result.getResourceMetaData().getAllInstanceDataSourceNames()).thenReturn(Collections.singletonList("foo_ds")); - return result; - } - - private QueryContext createQueryContext() { - CreateTableStatement createTableStatement = new MySQLCreateTableStatement(false); - createTableStatement.setTable(new SimpleTableSegment(new TableNameSegment(1, 2, new IdentifierValue("t_order")))); - return new QueryContext(new CreateTableStatementContext(createTableStatement, DefaultDatabase.LOGIC_NAME), "CREATE TABLE", new LinkedList<>(), new HintValueContext(), - mockConnectionContext(), mock(ShardingSphereMetaData.class)); - } - - private ConnectionContext mockConnectionContext() { - ConnectionContext result = mock(ConnectionContext.class); - when(result.getCurrentDatabaseName()).thenReturn(Optional.of(DefaultDatabase.LOGIC_NAME)); - return result; - } } diff --git a/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/BroadcastRouteEngineFactoryTest.java b/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/BroadcastRouteEngineFactoryTest.java index f88f78184dc..ca641d5dc2b 100644 --- a/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/BroadcastRouteEngineFactoryTest.java +++ b/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/BroadcastRouteEngineFactoryTest.java @@ -19,14 +19,12 @@ package org.apache.shardingsphere.broadcast.route.engine; import org.apache.shardingsphere.broadcast.route.engine.type.broadcast.BroadcastDatabaseBroadcastRouteEngine; import org.apache.shardingsphere.broadcast.route.engine.type.broadcast.BroadcastTableBroadcastRouteEngine; -import org.apache.shardingsphere.broadcast.route.engine.type.ignore.BroadcastIgnoreRouteEngine; import org.apache.shardingsphere.broadcast.route.engine.type.unicast.BroadcastUnicastRouteEngine; import org.apache.shardingsphere.broadcast.rule.BroadcastRule; import org.apache.shardingsphere.infra.binder.context.extractor.SQLStatementContextExtractor; import org.apache.shardingsphere.infra.binder.context.segment.table.TablesContext; import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; import org.apache.shardingsphere.infra.binder.context.statement.ddl.CloseStatementContext; -import org.apache.shardingsphere.infra.binder.context.type.CursorAvailable; import org.apache.shardingsphere.infra.binder.context.type.TableAvailable; import org.apache.shardingsphere.infra.database.core.type.DatabaseType; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; @@ -34,11 +32,9 @@ import org.apache.shardingsphere.infra.session.query.QueryContext; import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment; -import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.dal.DALStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.dcl.DCLStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DDLStatement; -import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.DMLStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.SelectStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.UpdateStatement; import org.apache.shardingsphere.sql.parser.statement.core.statement.tcl.TCLStatement; @@ -78,45 +74,22 @@ class BroadcastRouteEngineFactoryTest { @BeforeEach void setUp() { - when(rule.filterBroadcastTableNames(Collections.singleton("foo_tbl"))).thenReturn(Collections.singleton("foo_tbl")); + when(rule.getBroadcastTableNames(Collections.singleton("foo_tbl"))).thenReturn(Collections.singleton("foo_tbl")); when(rule.isAllBroadcastTables(Collections.singleton("foo_tbl"))).thenReturn(true); } @Test void assertNewInstanceWithTCLStatement() { when(queryContext.getSqlStatementContext().getSqlStatement()).thenReturn(mock(TCLStatement.class)); - assertThat(BroadcastRouteEngineFactory.newInstance(rule, database, queryContext), instanceOf(BroadcastDatabaseBroadcastRouteEngine.class)); - } - - @Test - void assertNewInstanceWithCloseStatementContextAndCloseAll() { - CloseStatementContext sqlStatementContext = mock(CloseStatementContext.class, RETURNS_DEEP_STUBS); - when(sqlStatementContext.getSqlStatement().isCloseAll()).thenReturn(true); - when(queryContext.getSqlStatementContext()).thenReturn(sqlStatementContext); - assertThat(BroadcastRouteEngineFactory.newInstance(rule, database, queryContext), instanceOf(BroadcastDatabaseBroadcastRouteEngine.class)); - } - - @Test - void assertNewInstanceWithCursorAvailableAndIsNotAllBroadcastTables() { - CloseStatementContext sqlStatementContext = mock(CloseStatementContext.class, RETURNS_DEEP_STUBS); - when(queryContext.getSqlStatementContext()).thenReturn(sqlStatementContext); - assertThat(BroadcastRouteEngineFactory.newInstance(rule, database, queryContext), instanceOf(BroadcastIgnoreRouteEngine.class)); + assertThat(BroadcastRouteEngineFactory.newInstance(queryContext, Collections.emptyList()), instanceOf(BroadcastDatabaseBroadcastRouteEngine.class)); } @Test void assertNewInstanceWithCursorAvailableAndIsAllBroadcastTables() { CloseStatementContext sqlStatementContext = mock(CloseStatementContext.class, RETURNS_DEEP_STUBS); - when(sqlStatementContext.getTablesContext()).thenReturn(createTablesContext("foo_tbl")); - when(queryContext.getSqlStatementContext()).thenReturn(sqlStatementContext); - assertThat(BroadcastRouteEngineFactory.newInstance(rule, database, queryContext), instanceOf(BroadcastUnicastRouteEngine.class)); - } - - @Test - void assertNewInstanceWithCursorAvailableAndNotTableAvailable() { - SQLStatementContext sqlStatementContext = mock(SQLStatementContext.class, withSettings().extraInterfaces(CursorAvailable.class)); - when(sqlStatementContext.getSqlStatement()).thenReturn(mock(DDLStatement.class)); + when(sqlStatementContext.getTablesContext()).thenReturn(createTablesContext()); when(queryContext.getSqlStatementContext()).thenReturn(sqlStatementContext); - assertThat(BroadcastRouteEngineFactory.newInstance(rule, database, queryContext), instanceOf(BroadcastIgnoreRouteEngine.class)); + assertThat(BroadcastRouteEngineFactory.newInstance(queryContext, Collections.emptyList()), instanceOf(BroadcastUnicastRouteEngine.class)); } @Test @@ -125,92 +98,47 @@ class BroadcastRouteEngineFactoryTest { when(sqlStatementContext.getSqlStatement()).thenReturn(mock(DDLStatement.class)); when(queryContext.getSqlStatementContext()).thenReturn(sqlStatementContext); when(SQLStatementContextExtractor.getTableNames(database, sqlStatementContext)).thenReturn(Collections.singleton("foo_tbl")); - assertThat(BroadcastRouteEngineFactory.newInstance(rule, database, queryContext), instanceOf(BroadcastTableBroadcastRouteEngine.class)); - } - - @Test - void assertNewInstanceWithDDLStatementAndIsNotAllBroadcastTables() { - SQLStatementContext sqlStatementContext = mock(SQLStatementContext.class); - when(sqlStatementContext.getSqlStatement()).thenReturn(mock(DDLStatement.class)); - when(queryContext.getSqlStatementContext()).thenReturn(sqlStatementContext); - assertThat(BroadcastRouteEngineFactory.newInstance(rule, database, queryContext), instanceOf(BroadcastIgnoreRouteEngine.class)); - } - - @Test - void assertNewInstanceWithoutTableAvailableStatement() { - when(queryContext.getSqlStatementContext().getSqlStatement()).thenReturn(mock(SQLStatement.class)); - assertThat(BroadcastRouteEngineFactory.newInstance(rule, database, queryContext), instanceOf(BroadcastIgnoreRouteEngine.class)); - } - - @Test - void assertNewInstanceWithEmptyTables() { - SQLStatementContext sqlStatementContext = mock(SQLStatementContext.class, withSettings().extraInterfaces(TableAvailable.class)); - when(((TableAvailable) sqlStatementContext).getTablesContext()).thenReturn(createTablesContext()); - when(queryContext.getSqlStatementContext()).thenReturn(sqlStatementContext); - assertThat(BroadcastRouteEngineFactory.newInstance(rule, database, queryContext), instanceOf(BroadcastIgnoreRouteEngine.class)); + assertThat(BroadcastRouteEngineFactory.newInstance(queryContext, Collections.emptyList()), instanceOf(BroadcastTableBroadcastRouteEngine.class)); } @Test void assertNewInstanceWithDALStatement() { SQLStatementContext sqlStatementContext = mock(SQLStatementContext.class, withSettings().extraInterfaces(TableAvailable.class)); - when(((TableAvailable) sqlStatementContext).getTablesContext()).thenReturn(createTablesContext("foo_tbl")); + when(((TableAvailable) sqlStatementContext).getTablesContext()).thenReturn(createTablesContext()); when(sqlStatementContext.getSqlStatement()).thenReturn(mock(DALStatement.class)); when(queryContext.getSqlStatementContext()).thenReturn(sqlStatementContext); - assertThat(BroadcastRouteEngineFactory.newInstance(rule, database, queryContext), instanceOf(BroadcastTableBroadcastRouteEngine.class)); - } - - @Test - void assertNewInstanceWithDCLStatementWithoutBroadcastTables() { - SQLStatementContext sqlStatementContext = mock(SQLStatementContext.class, withSettings().extraInterfaces(TableAvailable.class)); - when(((TableAvailable) sqlStatementContext).getTablesContext()).thenReturn(createTablesContext("bar_tbl")); - when(sqlStatementContext.getSqlStatement()).thenReturn(mock(DCLStatement.class)); - when(queryContext.getSqlStatementContext()).thenReturn(sqlStatementContext); - assertThat(BroadcastRouteEngineFactory.newInstance(rule, database, queryContext), instanceOf(BroadcastIgnoreRouteEngine.class)); + assertThat(BroadcastRouteEngineFactory.newInstance(queryContext, Collections.emptyList()), instanceOf(BroadcastTableBroadcastRouteEngine.class)); } @Test void assertNewInstanceWithDCLStatementWithBroadcastTables() { SQLStatementContext sqlStatementContext = mock(SQLStatementContext.class, withSettings().extraInterfaces(TableAvailable.class)); - when(((TableAvailable) sqlStatementContext).getTablesContext()).thenReturn(createTablesContext("foo_tbl")); + when(((TableAvailable) sqlStatementContext).getTablesContext()).thenReturn(createTablesContext()); when(sqlStatementContext.getSqlStatement()).thenReturn(mock(DCLStatement.class)); when(queryContext.getSqlStatementContext()).thenReturn(sqlStatementContext); - assertThat(BroadcastRouteEngineFactory.newInstance(rule, database, queryContext), instanceOf(BroadcastTableBroadcastRouteEngine.class)); - } - - @Test - void assertNewInstanceWithDMLStatementAndIsNotAllBroadcastTables() { - SQLStatementContext sqlStatementContext = mock(SQLStatementContext.class, withSettings().extraInterfaces(TableAvailable.class)); - when(((TableAvailable) sqlStatementContext).getTablesContext()).thenReturn(createTablesContext("bar_tbl")); - when(sqlStatementContext.getSqlStatement()).thenReturn(mock(DMLStatement.class)); - when(queryContext.getSqlStatementContext()).thenReturn(sqlStatementContext); - assertThat(BroadcastRouteEngineFactory.newInstance(rule, database, queryContext), instanceOf(BroadcastIgnoreRouteEngine.class)); + assertThat(BroadcastRouteEngineFactory.newInstance(queryContext, Collections.emptyList()), instanceOf(BroadcastTableBroadcastRouteEngine.class)); } @Test void assertNewInstanceWithSelectStatementAndIsAllBroadcastTables() { SQLStatementContext sqlStatementContext = mock(SQLStatementContext.class, withSettings().extraInterfaces(TableAvailable.class)); - when(((TableAvailable) sqlStatementContext).getTablesContext()).thenReturn(createTablesContext("foo_tbl")); + when(((TableAvailable) sqlStatementContext).getTablesContext()).thenReturn(createTablesContext()); when(sqlStatementContext.getSqlStatement()).thenReturn(mock(SelectStatement.class)); when(queryContext.getSqlStatementContext()).thenReturn(sqlStatementContext); - assertThat(BroadcastRouteEngineFactory.newInstance(rule, database, queryContext), instanceOf(BroadcastUnicastRouteEngine.class)); + assertThat(BroadcastRouteEngineFactory.newInstance(queryContext, Collections.emptyList()), instanceOf(BroadcastUnicastRouteEngine.class)); } @Test void assertNewInstanceWithUpdateStatementAndIsAllBroadcastTables() { SQLStatementContext sqlStatementContext = mock(SQLStatementContext.class, withSettings().extraInterfaces(TableAvailable.class)); - when(((TableAvailable) sqlStatementContext).getTablesContext()).thenReturn(createTablesContext("foo_tbl")); + when(((TableAvailable) sqlStatementContext).getTablesContext()).thenReturn(createTablesContext()); when(sqlStatementContext.getSqlStatement()).thenReturn(mock(UpdateStatement.class)); when(queryContext.getSqlStatementContext()).thenReturn(sqlStatementContext); - assertThat(BroadcastRouteEngineFactory.newInstance(rule, database, queryContext), instanceOf(BroadcastDatabaseBroadcastRouteEngine.class)); + assertThat(BroadcastRouteEngineFactory.newInstance(queryContext, Collections.emptyList()), instanceOf(BroadcastDatabaseBroadcastRouteEngine.class)); } private TablesContext createTablesContext() { DatabaseType databaseType = TypedSPILoader.getService(DatabaseType.class, "FIXTURE"); - return new TablesContext(Collections.emptyList(), databaseType, null); - } - - private TablesContext createTablesContext(final String tableName) { - DatabaseType databaseType = TypedSPILoader.getService(DatabaseType.class, "FIXTURE"); - return new TablesContext(Collections.singleton(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue(tableName)))), databaseType, null); + return new TablesContext(Collections.singleton(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("foo_tbl")))), databaseType, null); } } diff --git a/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastDatabaseBroadcastRouteEngineTest.java b/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastDatabaseBroadcastRouteEngineTest.java index 23572825334..66c7c488495 100644 --- a/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastDatabaseBroadcastRouteEngineTest.java +++ b/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastDatabaseBroadcastRouteEngineTest.java @@ -37,7 +37,7 @@ class BroadcastDatabaseBroadcastRouteEngineTest { BroadcastRule rule = mock(BroadcastRule.class); when(rule.getDataSourceNames()).thenReturn(Arrays.asList("ds_0", "ds_1")); BroadcastDatabaseBroadcastRouteEngine engine = new BroadcastDatabaseBroadcastRouteEngine(); - RouteContext routeContext = engine.route(new RouteContext(), rule); + RouteContext routeContext = engine.route(rule); assertThat(routeContext.getRouteUnits().size(), is(2)); Iterator<RouteUnit> iterator = routeContext.getRouteUnits().iterator(); assertDataSourceRouteMapper(iterator.next(), "ds_0"); diff --git a/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastInstanceBroadcastRouteEngineTest.java b/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastInstanceBroadcastRouteEngineTest.java deleted file mode 100644 index 1b6e5ca87d4..00000000000 --- a/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastInstanceBroadcastRouteEngineTest.java +++ /dev/null @@ -1,52 +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.broadcast.route.engine.type.broadcast; - -import org.apache.shardingsphere.broadcast.rule.BroadcastRule; -import org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData; -import org.apache.shardingsphere.infra.route.context.RouteContext; -import org.apache.shardingsphere.infra.route.context.RouteUnit; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.Collections; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -class BroadcastInstanceBroadcastRouteEngineTest { - - @Test - void assertRoute() { - ResourceMetaData resourceMetaData = mock(ResourceMetaData.class); - when(resourceMetaData.getAllInstanceDataSourceNames()).thenReturn(Collections.singleton("ds_0")); - BroadcastInstanceBroadcastRouteEngine engine = new BroadcastInstanceBroadcastRouteEngine(resourceMetaData); - BroadcastRule rule = mock(BroadcastRule.class); - when(rule.getDataSourceNames()).thenReturn(Arrays.asList("ds_0", "ds_1")); - RouteContext routeContext = engine.route(new RouteContext(), rule); - assertThat(routeContext.getRouteUnits().size(), is(1)); - assertDataSourceRouteMapper(routeContext.getRouteUnits().iterator().next(), "ds_0"); - } - - private void assertDataSourceRouteMapper(final RouteUnit routeUnit, final String expected) { - assertThat(routeUnit.getDataSourceMapper().getLogicName(), is(expected)); - assertThat(routeUnit.getDataSourceMapper().getActualName(), is(expected)); - } -} diff --git a/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastTableBroadcastRouteEngineTest.java b/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastTableBroadcastRouteEngineTest.java index f3a11136f1f..b2095f60deb 100644 --- a/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastTableBroadcastRouteEngineTest.java +++ b/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/broadcast/BroadcastTableBroadcastRouteEngineTest.java @@ -42,8 +42,8 @@ class BroadcastTableBroadcastRouteEngineTest { BroadcastTableBroadcastRouteEngine engine = new BroadcastTableBroadcastRouteEngine(broadcastRuleTableNames); BroadcastRule rule = mock(BroadcastRule.class); when(rule.getDataSourceNames()).thenReturn(Arrays.asList("ds_0", "ds_1")); - when(rule.filterBroadcastTableNames(any())).thenReturn(Collections.singleton("t_address")); - RouteContext routeContext = engine.route(new RouteContext(), rule); + when(rule.getBroadcastTableNames(any())).thenReturn(Collections.singleton("t_address")); + RouteContext routeContext = engine.route(rule); assertThat(routeContext.getRouteUnits().size(), is(2)); Iterator<RouteUnit> iterator = routeContext.getRouteUnits().iterator(); assertRouteMapper(iterator.next(), "ds_0", "t_address"); @@ -56,8 +56,8 @@ class BroadcastTableBroadcastRouteEngineTest { BroadcastTableBroadcastRouteEngine engine = new BroadcastTableBroadcastRouteEngine(broadcastRuleTableNames); BroadcastRule rule = mock(BroadcastRule.class); when(rule.getDataSourceNames()).thenReturn(Arrays.asList("ds_0", "ds_1")); - when(rule.filterBroadcastTableNames(any())).thenReturn(Collections.emptyList()); - RouteContext routeContext = engine.route(new RouteContext(), rule); + when(rule.getBroadcastTableNames(any())).thenReturn(Collections.emptyList()); + RouteContext routeContext = engine.route(rule); assertThat(routeContext.getRouteUnits().size(), is(2)); Iterator<RouteUnit> iterator = routeContext.getRouteUnits().iterator(); assertRouteMapper(iterator.next(), "ds_0", ""); diff --git a/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/ignore/BroadcastIgnoreRouteEngineTest.java b/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/ignore/BroadcastIgnoreRouteEngineTest.java deleted file mode 100644 index 6bb667aa832..00000000000 --- a/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/ignore/BroadcastIgnoreRouteEngineTest.java +++ /dev/null @@ -1,35 +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.broadcast.route.engine.type.ignore; - -import org.apache.shardingsphere.broadcast.rule.BroadcastRule; -import org.apache.shardingsphere.infra.route.context.RouteContext; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; - -class BroadcastIgnoreRouteEngineTest { - - @Test - void assertRoute() { - BroadcastIgnoreRouteEngine engine = new BroadcastIgnoreRouteEngine(); - RouteContext routeContext = engine.route(new RouteContext(), mock(BroadcastRule.class)); - assertTrue(routeContext.getRouteUnits().isEmpty()); - } -} diff --git a/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/unicast/BroadcastUnicastRouteEngineTest.java b/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/unicast/BroadcastUnicastRouteEngineTest.java index 18a815a0c1e..f35175c1a60 100644 --- a/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/unicast/BroadcastUnicastRouteEngineTest.java +++ b/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/route/engine/type/unicast/BroadcastUnicastRouteEngineTest.java @@ -93,7 +93,7 @@ class BroadcastUnicastRouteEngineTest { @SafeVarargs private final void assertRoute(final SQLStatementContext sqlStatementContext, final Matcher<String>... matchers) { BroadcastUnicastRouteEngine engine = new BroadcastUnicastRouteEngine(sqlStatementContext, Collections.singleton("foo_tbl"), connectionContext); - RouteContext actual = engine.route(new RouteContext(), rule); + RouteContext actual = engine.route(rule); assertThat(actual.getRouteUnits().size(), is(1)); RouteMapper actualDataSourceRouteMapper = actual.getRouteUnits().iterator().next().getDataSourceMapper(); assertThat(actualDataSourceRouteMapper.getLogicName(), anyOf(matchers)); @@ -111,7 +111,7 @@ class BroadcastUnicastRouteEngineTest { @Test void assertRouteWithEmptyTables() { BroadcastUnicastRouteEngine engine = new BroadcastUnicastRouteEngine(mock(SQLStatementContext.class), Collections.emptyList(), connectionContext); - RouteContext actual = engine.route(new RouteContext(), rule); + RouteContext actual = engine.route(rule); assertThat(actual.getRouteUnits().size(), is(1)); Collection<RouteMapper> actualTableRouteMappers = actual.getRouteUnits().iterator().next().getTableMappers(); assertTrue(actualTableRouteMappers.isEmpty()); diff --git a/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/rule/BroadcastRuleTest.java b/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/rule/BroadcastRuleTest.java index 19a604ef2c4..95a1383b95b 100644 --- a/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/rule/BroadcastRuleTest.java +++ b/features/broadcast/core/src/test/java/org/apache/shardingsphere/broadcast/rule/BroadcastRuleTest.java @@ -67,9 +67,9 @@ class BroadcastRuleTest { } @Test - void assertFilterBroadcastTableNames() { + void assertGetBroadcastTableNames() { BroadcastRule rule = new BroadcastRule(new BroadcastRuleConfiguration(Collections.singleton("foo_tbl")), Collections.emptyMap(), Collections.emptyList()); - assertThat(rule.filterBroadcastTableNames(Arrays.asList("foo_tbl", "bar_tbl")), is(Collections.singleton("foo_tbl"))); + assertThat(rule.getBroadcastTableNames(Arrays.asList("foo_tbl", "bar_tbl")), is(Collections.singleton("foo_tbl"))); } @Test diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/constant/EncryptOrder.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/constant/EncryptOrder.java index dbbf4f28117..649d5d672d4 100644 --- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/constant/EncryptOrder.java +++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/constant/EncryptOrder.java @@ -29,5 +29,5 @@ public final class EncryptOrder { /** * Encrypt order. */ - public static final int ORDER = 15; + public static final int ORDER = 10; } diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/standard/assertion/ShardingRouteAssert.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/standard/assertion/ShardingRouteAssert.java index 4d6e8a3774a..2699dc95554 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/standard/assertion/ShardingRouteAssert.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/standard/assertion/ShardingRouteAssert.java @@ -35,6 +35,8 @@ import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSp import org.apache.shardingsphere.infra.parser.sql.SQLStatementParserEngine; import org.apache.shardingsphere.infra.route.context.RouteContext; import org.apache.shardingsphere.infra.route.engine.SQLRouteEngine; +import org.apache.shardingsphere.infra.rule.ShardingSphereRule; +import org.apache.shardingsphere.infra.rule.attribute.table.TableMapperRuleAttribute; import org.apache.shardingsphere.infra.session.connection.ConnectionContext; import org.apache.shardingsphere.infra.session.query.QueryContext; import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; @@ -50,10 +52,12 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Properties; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * Sharding route assert. @@ -74,16 +78,20 @@ public final class ShardingRouteAssert { SingleRule singleRule = ShardingRouteEngineFixtureBuilder.createSingleRule(Collections.singleton(shardingRule)); TimestampServiceRule timestampServiceRule = ShardingRouteEngineFixtureBuilder.createTimeServiceRule(); Map<String, ShardingSphereSchema> schemas = buildSchemas(); - ConfigurationProperties props = new ConfigurationProperties(new Properties()); SQLStatementParserEngine sqlStatementParserEngine = new SQLStatementParserEngine(databaseType, new CacheOption(2000, 65535L), new CacheOption(128, 1024L)); - RuleMetaData ruleMetaData = new RuleMetaData(Arrays.asList(shardingRule, singleRule, timestampServiceRule)); + ShardingSphereRule broadcastRule = mock(ShardingSphereRule.class, RETURNS_DEEP_STUBS); + TableMapperRuleAttribute ruleAttribute = mock(TableMapperRuleAttribute.class); + when(ruleAttribute.getDistributedTableNames()).thenReturn(Collections.singleton("t_product")); + when(broadcastRule.getAttributes().findAttribute(TableMapperRuleAttribute.class)).thenReturn(Optional.of(ruleAttribute)); + RuleMetaData ruleMetaData = new RuleMetaData(Arrays.asList(shardingRule, broadcastRule, singleRule, timestampServiceRule)); ShardingSphereDatabase database = new ShardingSphereDatabase(DefaultDatabase.LOGIC_NAME, databaseType, mock(ResourceMetaData.class, RETURNS_DEEP_STUBS), ruleMetaData, schemas); ShardingSphereMetaData metaData = createShardingSphereMetaData(database); SQLStatementContext sqlStatementContext = new SQLBindEngine(metaData, DefaultDatabase.LOGIC_NAME, new HintValueContext()).bind(sqlStatementParserEngine.parse(sql, false), params); ConnectionContext connectionContext = new ConnectionContext(Collections::emptySet); connectionContext.setCurrentDatabaseName(DefaultDatabase.LOGIC_NAME); QueryContext queryContext = new QueryContext(sqlStatementContext, sql, params, new HintValueContext(), connectionContext, metaData); + ConfigurationProperties props = new ConfigurationProperties(new Properties()); return new SQLRouteEngine(Arrays.asList(shardingRule, singleRule), props).route(queryContext, mock(RuleMetaData.class), database); } diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/constant/SingleOrder.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/constant/SingleOrder.java index b11706fa32c..69d9cbd4a47 100644 --- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/constant/SingleOrder.java +++ b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/constant/SingleOrder.java @@ -29,5 +29,5 @@ public final class SingleOrder { /** * Single order. */ - public static final int ORDER = 10; + public static final int ORDER = 5; } diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/SingleSQLRouter.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/SingleSQLRouter.java index e7fd34700a0..24523813990 100644 --- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/SingleSQLRouter.java +++ b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/SingleSQLRouter.java @@ -17,6 +17,7 @@ package org.apache.shardingsphere.single.route; +import com.cedarsoftware.util.CaseInsensitiveSet; import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation; import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; import org.apache.shardingsphere.infra.binder.context.type.TableAvailable; @@ -30,11 +31,11 @@ import org.apache.shardingsphere.infra.route.context.RouteUnit; import org.apache.shardingsphere.infra.route.type.DecorateSQLRouter; import org.apache.shardingsphere.infra.route.type.EntranceSQLRouter; import org.apache.shardingsphere.infra.route.type.TableSQLRouter; +import org.apache.shardingsphere.infra.rule.attribute.table.TableMapperRuleAttribute; import org.apache.shardingsphere.infra.session.query.QueryContext; import org.apache.shardingsphere.single.constant.SingleOrder; -import org.apache.shardingsphere.single.route.engine.SingleRouteEngineFactory; +import org.apache.shardingsphere.single.route.engine.SingleRouteEngine; import org.apache.shardingsphere.single.rule.SingleRule; -import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateTableStatement; import java.util.Collection; import java.util.Collections; @@ -52,19 +53,24 @@ public final class SingleSQLRouter implements EntranceSQLRouter<SingleRule>, Dec if (1 == database.getResourceMetaData().getStorageUnits().size()) { return createSingleDataSourceRouteContext(rule, database, queryContext); } - RouteContext result = new RouteContext(); - Collection<QualifiedTable> singleTables = getSingleTables(database, rule, result, queryContext.getSqlStatementContext()); - SingleRouteEngineFactory.newInstance(singleTables, queryContext.getSqlStatementContext().getSqlStatement(), queryContext.getHintValueContext()) - .ifPresent(optional -> optional.route(result, rule)); - return result; + SQLStatementContext sqlStatementContext = queryContext.getSqlStatementContext(); + RouteContext routeContext = new RouteContext(); + Collection<QualifiedTable> singleTables = getSingleTables(database, rule, sqlStatementContext); + if (singleTables.isEmpty()) { + return routeContext; + } + return new SingleRouteEngine(singleTables, sqlStatementContext.getSqlStatement(), queryContext.getHintValueContext()).route(routeContext, rule); } @Override public void decorateRouteContext(final RouteContext routeContext, final QueryContext queryContext, final ShardingSphereDatabase database, final SingleRule rule, final Collection<String> tableNames, final ConfigurationProperties props) { - Collection<QualifiedTable> singleTables = getSingleTables(database, rule, routeContext, queryContext.getSqlStatementContext()); - SingleRouteEngineFactory.newInstance(singleTables, queryContext.getSqlStatementContext().getSqlStatement(), queryContext.getHintValueContext()) - .ifPresent(optional -> optional.route(routeContext, rule)); + SQLStatementContext sqlStatementContext = queryContext.getSqlStatementContext(); + Collection<QualifiedTable> singleTables = getSingleTables(database, rule, sqlStatementContext); + if (singleTables.isEmpty()) { + return; + } + new SingleRouteEngine(singleTables, sqlStatementContext.getSqlStatement(), queryContext.getHintValueContext()).route(routeContext, rule); } private RouteContext createSingleDataSourceRouteContext(final SingleRule rule, final ShardingSphereDatabase database, final QueryContext queryContext) { @@ -86,9 +92,24 @@ public final class SingleSQLRouter implements EntranceSQLRouter<SingleRule>, Dec return result; } - private Collection<QualifiedTable> getSingleTables(final ShardingSphereDatabase database, final SingleRule rule, final RouteContext routeContext, final SQLStatementContext sqlStatementContext) { + private Collection<QualifiedTable> getSingleTables(final ShardingSphereDatabase database, final SingleRule rule, final SQLStatementContext sqlStatementContext) { Collection<QualifiedTable> qualifiedTables = rule.getQualifiedTables(sqlStatementContext, database); - return routeContext.getRouteUnits().isEmpty() && sqlStatementContext.getSqlStatement() instanceof CreateTableStatement ? qualifiedTables : rule.getSingleTables(qualifiedTables); + Collection<String> distributedTableNames = getDistributedTableNames(database); + Collection<QualifiedTable> result = new LinkedList<>(); + for (QualifiedTable each : qualifiedTables) { + if (!distributedTableNames.contains(each.getTableName())) { + result.add(each); + } + } + return result; + } + + private Collection<String> getDistributedTableNames(final ShardingSphereDatabase database) { + Collection<String> result = new CaseInsensitiveSet<>(); + for (TableMapperRuleAttribute each : database.getRuleMetaData().getAttributes(TableMapperRuleAttribute.class)) { + result.addAll(each.getDistributedTableNames()); + } + return result; } @Override diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngine.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngine.java index 64de553484a..4223fbc364a 100644 --- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngine.java +++ b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngine.java @@ -17,19 +17,126 @@ package org.apache.shardingsphere.single.route.engine; +import lombok.RequiredArgsConstructor; +import org.apache.shardingsphere.infra.datanode.DataNode; +import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions; +import org.apache.shardingsphere.infra.exception.dialect.exception.syntax.table.TableExistsException; +import org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException; +import org.apache.shardingsphere.infra.hint.HintValueContext; +import org.apache.shardingsphere.infra.metadata.database.schema.QualifiedTable; import org.apache.shardingsphere.infra.route.context.RouteContext; +import org.apache.shardingsphere.infra.route.context.RouteMapper; +import org.apache.shardingsphere.infra.route.context.RouteUnit; +import org.apache.shardingsphere.infra.rule.attribute.datanode.MutableDataNodeRuleAttribute; +import org.apache.shardingsphere.single.exception.SingleTableNotFoundException; import org.apache.shardingsphere.single.rule.SingleRule; +import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement; +import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateTableStatement; +import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DDLStatement; +import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.SelectStatement; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; /** * Single route engine. */ -public interface SingleRouteEngine { +@RequiredArgsConstructor +public final class SingleRouteEngine { + + private final Collection<QualifiedTable> singleTables; + + private final SQLStatement sqlStatement; + + private final HintValueContext hintValueContext; /** * Route. * * @param routeContext route context * @param singleRule single rule + * @return route context */ - void route(RouteContext routeContext, SingleRule singleRule); + public RouteContext route(final RouteContext routeContext, final SingleRule singleRule) { + if (routeContext.getRouteUnits().isEmpty() || sqlStatement instanceof SelectStatement) { + routeStatement(routeContext, singleRule); + } else { + RouteContext newRouteContext = new RouteContext(); + routeStatement(newRouteContext, singleRule); + combineRouteContext(routeContext, newRouteContext); + } + return routeContext; + } + + private void routeStatement(final RouteContext routeContext, final SingleRule rule) { + if (sqlStatement instanceof DDLStatement) { + routeDDLStatement(routeContext, rule); + } else { + boolean allTablesInSameComputeNode = rule.isAllTablesInSameComputeNode(getDataNodes(routeContext), singleTables); + ShardingSpherePreconditions.checkState(allTablesInSameComputeNode, () -> new UnsupportedSQLOperationException("all tables must be in the same compute node")); + fillRouteContext(rule, routeContext, singleTables); + } + } + + private Collection<DataNode> getDataNodes(final RouteContext routeContext) { + Collection<DataNode> result = new LinkedList<>(); + for (Collection<DataNode> each : routeContext.getOriginalDataNodes()) { + result.addAll(each); + } + return result; + } + + private void routeDDLStatement(final RouteContext routeContext, final SingleRule rule) { + if (sqlStatement instanceof CreateTableStatement) { + QualifiedTable table = singleTables.iterator().next(); + Optional<DataNode> dataNode = rule.getAttributes().getAttribute(MutableDataNodeRuleAttribute.class).findTableDataNode(table.getSchemaName(), table.getTableName()); + boolean containsIfNotExists = ((CreateTableStatement) sqlStatement).isIfNotExists(); + if (dataNode.isPresent()) { + routeDDLStatementWithExistTable(routeContext, containsIfNotExists, dataNode.get(), table); + } else { + String dataSourceName = rule.assignNewDataSourceName(); + routeContext.getRouteUnits().add(new RouteUnit(new RouteMapper(dataSourceName, dataSourceName), Collections.singleton(new RouteMapper(table.getTableName(), table.getTableName())))); + } + } else { + fillRouteContext(rule, routeContext, singleTables); + } + } + + private void routeDDLStatementWithExistTable(final RouteContext routeContext, final boolean containsIfNotExists, final DataNode dataNode, final QualifiedTable table) { + if (containsIfNotExists || hintValueContext.isSkipMetadataValidate()) { + String dataSourceName = dataNode.getDataSourceName(); + routeContext.getRouteUnits() + .add(new RouteUnit(new RouteMapper(dataSourceName, dataSourceName), Collections.singleton(new RouteMapper(table.getTableName(), table.getTableName())))); + } else { + throw new TableExistsException(table.getTableName()); + } + } + + private void fillRouteContext(final SingleRule singleRule, final RouteContext routeContext, final Collection<QualifiedTable> logicTables) { + for (QualifiedTable each : logicTables) { + String tableName = each.getTableName(); + DataNode dataNode = singleRule.getAttributes().getAttribute(MutableDataNodeRuleAttribute.class).findTableDataNode(each.getSchemaName(), tableName) + .orElseThrow(() -> new SingleTableNotFoundException(tableName)); + String dataSource = dataNode.getDataSourceName(); + routeContext.putRouteUnit(new RouteMapper(dataSource, dataSource), Collections.singletonList(new RouteMapper(tableName, tableName))); + } + } + + private void combineRouteContext(final RouteContext routeContext, final RouteContext newRouteContext) { + Map<String, RouteUnit> dataSourceRouteUnits = getDataSourceRouteUnits(newRouteContext); + routeContext.getRouteUnits().removeIf(each -> !dataSourceRouteUnits.containsKey(each.getDataSourceMapper().getLogicName())); + for (Entry<String, RouteUnit> entry : dataSourceRouteUnits.entrySet()) { + routeContext.putRouteUnit(entry.getValue().getDataSourceMapper(), entry.getValue().getTableMappers()); + } + } + + private Map<String, RouteUnit> getDataSourceRouteUnits(final RouteContext newRouteContext) { + return newRouteContext.getRouteUnits().stream().collect(Collectors.toMap(each -> each.getDataSourceMapper().getLogicName(), Function.identity())); + } } diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngineFactory.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngineFactory.java deleted file mode 100644 index cb8dd5bc3b5..00000000000 --- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngineFactory.java +++ /dev/null @@ -1,47 +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.single.route.engine; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.apache.shardingsphere.infra.hint.HintValueContext; -import org.apache.shardingsphere.infra.metadata.database.schema.QualifiedTable; -import org.apache.shardingsphere.single.route.engine.standard.SingleStandardRouteEngine; -import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement; - -import java.util.Collection; -import java.util.Optional; - -/** - * Single route engine factory. - */ -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public final class SingleRouteEngineFactory { - - /** - * Create new instance of single route engine. - * - * @param singleTables single tables - * @param sqlStatement SQL statement - * @param hintValueContext hint value context - * @return created instance - */ - public static Optional<SingleRouteEngine> newInstance(final Collection<QualifiedTable> singleTables, final SQLStatement sqlStatement, final HintValueContext hintValueContext) { - return singleTables.isEmpty() ? Optional.empty() : Optional.of(new SingleStandardRouteEngine(singleTables, sqlStatement, hintValueContext)); - } -} diff --git a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/engine/standard/SingleStandardRouteEngine.java b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/engine/standard/SingleStandardRouteEngine.java deleted file mode 100644 index 02ea6cfef44..00000000000 --- a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/route/engine/standard/SingleStandardRouteEngine.java +++ /dev/null @@ -1,136 +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.single.route.engine.standard; - -import lombok.RequiredArgsConstructor; -import org.apache.shardingsphere.infra.datanode.DataNode; -import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions; -import org.apache.shardingsphere.infra.exception.dialect.exception.syntax.table.TableExistsException; -import org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException; -import org.apache.shardingsphere.infra.hint.HintValueContext; -import org.apache.shardingsphere.infra.metadata.database.schema.QualifiedTable; -import org.apache.shardingsphere.infra.route.context.RouteContext; -import org.apache.shardingsphere.infra.route.context.RouteMapper; -import org.apache.shardingsphere.infra.route.context.RouteUnit; -import org.apache.shardingsphere.infra.rule.attribute.datanode.MutableDataNodeRuleAttribute; -import org.apache.shardingsphere.single.exception.SingleTableNotFoundException; -import org.apache.shardingsphere.single.route.engine.SingleRouteEngine; -import org.apache.shardingsphere.single.rule.SingleRule; -import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement; -import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.CreateTableStatement; -import org.apache.shardingsphere.sql.parser.statement.core.statement.ddl.DDLStatement; -import org.apache.shardingsphere.sql.parser.statement.core.statement.dml.SelectStatement; - -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedList; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** - * Single standard route engine. - */ -@RequiredArgsConstructor -public final class SingleStandardRouteEngine implements SingleRouteEngine { - - private final Collection<QualifiedTable> singleTables; - - private final SQLStatement sqlStatement; - - private final HintValueContext hintValueContext; - - @Override - public void route(final RouteContext routeContext, final SingleRule singleRule) { - if (routeContext.getRouteUnits().isEmpty() || sqlStatement instanceof SelectStatement) { - routeStatement(routeContext, singleRule); - } else { - RouteContext newRouteContext = new RouteContext(); - routeStatement(newRouteContext, singleRule); - combineRouteContext(routeContext, newRouteContext); - } - } - - private void routeStatement(final RouteContext routeContext, final SingleRule rule) { - if (sqlStatement instanceof DDLStatement) { - routeDDLStatement(routeContext, rule); - } else { - boolean allTablesInSameComputeNode = rule.isAllTablesInSameComputeNode(getDataNodes(routeContext), singleTables); - ShardingSpherePreconditions.checkState(allTablesInSameComputeNode, () -> new UnsupportedSQLOperationException("all tables must be in the same compute node")); - fillRouteContext(rule, routeContext, singleTables); - } - } - - private Collection<DataNode> getDataNodes(final RouteContext routeContext) { - Collection<DataNode> result = new LinkedList<>(); - for (Collection<DataNode> each : routeContext.getOriginalDataNodes()) { - result.addAll(each); - } - return result; - } - - private void routeDDLStatement(final RouteContext routeContext, final SingleRule rule) { - if (sqlStatement instanceof CreateTableStatement) { - QualifiedTable table = singleTables.iterator().next(); - Optional<DataNode> dataNode = rule.getAttributes().getAttribute(MutableDataNodeRuleAttribute.class).findTableDataNode(table.getSchemaName(), table.getTableName()); - boolean containsIfNotExists = ((CreateTableStatement) sqlStatement).isIfNotExists(); - if (dataNode.isPresent()) { - routeDDLStatementWithExistTable(routeContext, containsIfNotExists, dataNode.get(), table); - } else { - String dataSourceName = rule.assignNewDataSourceName(); - routeContext.getRouteUnits().add(new RouteUnit(new RouteMapper(dataSourceName, dataSourceName), Collections.singleton(new RouteMapper(table.getTableName(), table.getTableName())))); - } - } else { - fillRouteContext(rule, routeContext, singleTables); - } - } - - private void routeDDLStatementWithExistTable(final RouteContext routeContext, final boolean containsIfNotExists, final DataNode dataNode, final QualifiedTable table) { - if (containsIfNotExists || hintValueContext.isSkipMetadataValidate()) { - String dataSourceName = dataNode.getDataSourceName(); - routeContext.getRouteUnits() - .add(new RouteUnit(new RouteMapper(dataSourceName, dataSourceName), Collections.singleton(new RouteMapper(table.getTableName(), table.getTableName())))); - } else { - throw new TableExistsException(table.getTableName()); - } - } - - private void fillRouteContext(final SingleRule singleRule, final RouteContext routeContext, final Collection<QualifiedTable> logicTables) { - for (QualifiedTable each : logicTables) { - String tableName = each.getTableName(); - DataNode dataNode = singleRule.getAttributes().getAttribute(MutableDataNodeRuleAttribute.class).findTableDataNode(each.getSchemaName(), tableName) - .orElseThrow(() -> new SingleTableNotFoundException(tableName)); - String dataSource = dataNode.getDataSourceName(); - routeContext.putRouteUnit(new RouteMapper(dataSource, dataSource), Collections.singletonList(new RouteMapper(tableName, tableName))); - } - } - - private void combineRouteContext(final RouteContext routeContext, final RouteContext newRouteContext) { - Map<String, RouteUnit> dataSourceRouteUnits = getDataSourceRouteUnits(newRouteContext); - routeContext.getRouteUnits().removeIf(each -> !dataSourceRouteUnits.containsKey(each.getDataSourceMapper().getLogicName())); - for (Entry<String, RouteUnit> entry : dataSourceRouteUnits.entrySet()) { - routeContext.putRouteUnit(entry.getValue().getDataSourceMapper(), entry.getValue().getTableMappers()); - } - } - - private Map<String, RouteUnit> getDataSourceRouteUnits(final RouteContext newRouteContext) { - return newRouteContext.getRouteUnits().stream().collect(Collectors.toMap(each -> each.getDataSourceMapper().getLogicName(), Function.identity())); - } -} diff --git a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/SingleSQLRouterTest.java b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/SingleSQLRouterTest.java index fa0beb370a4..41dd0a61f90 100644 --- a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/SingleSQLRouterTest.java +++ b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/SingleSQLRouterTest.java @@ -58,7 +58,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -69,6 +68,7 @@ import java.util.Properties; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; @@ -197,7 +197,8 @@ class SingleSQLRouterTest { ShardingSphereDatabase database = new ShardingSphereDatabase(DefaultDatabase.LOGIC_NAME, mock(DatabaseType.class), mock(ResourceMetaData.class, RETURNS_DEEP_STUBS), new RuleMetaData(Collections.singleton(rule)), Collections.emptyMap()); sqlRouter.decorateRouteContext(routeContext, createQueryContext(), database, rule, Collections.singletonList("t_order"), new ConfigurationProperties(new Properties())); - assertThat(routeContext.getActualDataSourceNames(), is(new HashSet<>(Arrays.asList("write_ds", "readwrite_ds")))); + assertThat(routeContext.getActualDataSourceNames().size(), is(1)); + assertTrue(Arrays.asList("write_ds", "readwrite_ds").contains(routeContext.getActualDataSourceNames().iterator().next())); } @Test @@ -207,11 +208,10 @@ class SingleSQLRouterTest { routeContext.getRouteUnits().add(new RouteUnit(new RouteMapper("ds_0", "ds_0"), Collections.emptyList())); routeContext.getRouteUnits().add(new RouteUnit(new RouteMapper("ds_1", "ds_1"), Collections.emptyList())); SingleSQLRouter sqlRouter = (SingleSQLRouter) OrderedSPILoader.getServices(SQLRouter.class, Collections.singleton(rule)).get(rule); - sqlRouter.decorateRouteContext( - routeContext, createQueryContext(), mockDatabaseWithMultipleResources(), rule, Collections.singletonList("t_order"), new ConfigurationProperties(new Properties())); - Iterator<String> routedDataSourceNames = routeContext.getActualDataSourceNames().iterator(); - assertThat(routedDataSourceNames.next(), is("ds_1")); - assertThat(routedDataSourceNames.next(), is("ds_0")); + sqlRouter.decorateRouteContext(routeContext, createQueryContext(), mockDatabaseWithMultipleResources(), rule, Collections.singletonList("t_order"), + new ConfigurationProperties(new Properties())); + assertThat(routeContext.getActualDataSourceNames().size(), is(1)); + assertTrue(Arrays.asList("ds_0", "ds_1").contains(routeContext.getActualDataSourceNames().iterator().next())); } private QueryContext createQueryContext() { diff --git a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngineFactoryTest.java b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngineFactoryTest.java deleted file mode 100644 index d81bb51ccf9..00000000000 --- a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/SingleRouteEngineFactoryTest.java +++ /dev/null @@ -1,42 +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.single.route.engine; - -import org.apache.shardingsphere.infra.hint.HintValueContext; -import org.apache.shardingsphere.infra.metadata.database.schema.QualifiedTable; -import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement; -import org.junit.jupiter.api.Test; - -import java.util.Collections; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; - -class SingleRouteEngineFactoryTest { - - @Test - void assertNewInstanceWithNotEmptySingleTables() { - assertTrue(SingleRouteEngineFactory.newInstance(Collections.singleton(new QualifiedTable("demo_ds", "t_order")), mock(SQLStatement.class), mock(HintValueContext.class)).isPresent()); - } - - @Test - void assertNewInstanceWithEmptySingleTableNameAndOtherStatement() { - assertFalse(SingleRouteEngineFactory.newInstance(Collections.emptyList(), mock(SQLStatement.class), mock(HintValueContext.class)).isPresent()); - } -} diff --git a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/engine/SingleStandardRouteEngineTest.java b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/engine/SingleRouteEngineTest.java similarity index 89% rename from kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/engine/SingleStandardRouteEngineTest.java rename to kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/engine/SingleRouteEngineTest.java index 4f52e8efe31..14751984b2d 100644 --- a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/engine/SingleStandardRouteEngineTest.java +++ b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/route/engine/engine/SingleRouteEngineTest.java @@ -30,7 +30,7 @@ import org.apache.shardingsphere.infra.rule.attribute.datanode.MutableDataNodeRu import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes; import org.apache.shardingsphere.infra.rule.attribute.datanode.DataNodeRuleAttribute; import org.apache.shardingsphere.single.config.SingleRuleConfiguration; -import org.apache.shardingsphere.single.route.engine.standard.SingleStandardRouteEngine; +import org.apache.shardingsphere.single.route.engine.SingleRouteEngine; import org.apache.shardingsphere.single.rule.SingleRule; import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment; import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment; @@ -61,11 +61,11 @@ import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -class SingleStandardRouteEngineTest { +class SingleRouteEngineTest { @Test void assertRouteInSameDataSource() throws SQLException { - SingleStandardRouteEngine engine = new SingleStandardRouteEngine(mockQualifiedTables(), null, mock(HintValueContext.class)); + SingleRouteEngine engine = new SingleRouteEngine(mockQualifiedTables(), null, mock(HintValueContext.class)); SingleRule singleRule = new SingleRule(new SingleRuleConfiguration(), DefaultDatabase.LOGIC_NAME, new MySQLDatabaseType(), createDataSourceMap(), Collections.emptyList()); singleRule.getAttributes().getAttribute(DataNodeRuleAttribute.class).getAllDataNodes().put("t_order", Collections.singleton(mockDataNode("t_order"))); singleRule.getAttributes().getAttribute(DataNodeRuleAttribute.class).getAllDataNodes().put("t_order_item", Collections.singleton(mockDataNode("t_order_item"))); @@ -96,7 +96,7 @@ class SingleStandardRouteEngineTest { @Test void assertRouteWithoutSingleRule() throws SQLException { - SingleStandardRouteEngine engine = new SingleStandardRouteEngine(mockQualifiedTables(), new MySQLCreateTableStatement(false), mock(HintValueContext.class)); + SingleRouteEngine engine = new SingleRouteEngine(mockQualifiedTables(), new MySQLCreateTableStatement(false), mock(HintValueContext.class)); SingleRule singleRule = new SingleRule(new SingleRuleConfiguration(), DefaultDatabase.LOGIC_NAME, new MySQLDatabaseType(), createDataSourceMap(), Collections.emptyList()); RouteContext routeContext = new RouteContext(); engine.route(routeContext, singleRule); @@ -111,7 +111,7 @@ class SingleStandardRouteEngineTest { @Test void assertRouteWithDefaultSingleRule() throws SQLException { - SingleStandardRouteEngine engine = new SingleStandardRouteEngine(mockQualifiedTables(), new MySQLCreateTableStatement(false), mock(HintValueContext.class)); + SingleRouteEngine engine = new SingleRouteEngine(mockQualifiedTables(), new MySQLCreateTableStatement(false), mock(HintValueContext.class)); SingleRule singleRule = new SingleRule(new SingleRuleConfiguration(Collections.emptyList(), "ds_0"), DefaultDatabase.LOGIC_NAME, new MySQLDatabaseType(), createDataSourceMap(), Collections.emptyList()); RouteContext routeContext = new RouteContext(); @@ -137,15 +137,15 @@ class SingleStandardRouteEngineTest { @Test void assertRouteDuplicateSingleTable() { - SingleStandardRouteEngine engine = - new SingleStandardRouteEngine(Collections.singleton(new QualifiedTable(DefaultDatabase.LOGIC_NAME, "t_order")), mockStatement(false), mock(HintValueContext.class)); + SingleRouteEngine engine = + new SingleRouteEngine(Collections.singleton(new QualifiedTable(DefaultDatabase.LOGIC_NAME, "t_order")), mockStatement(false), mock(HintValueContext.class)); assertThrows(TableExistsException.class, () -> engine.route(new RouteContext(), mockSingleRule())); } @Test void assertRouteIfNotExistsDuplicateSingleTable() { - SingleStandardRouteEngine engine = - new SingleStandardRouteEngine(Collections.singleton(new QualifiedTable(DefaultDatabase.LOGIC_NAME, "t_order")), mockStatement(true), mock(HintValueContext.class)); + SingleRouteEngine engine = + new SingleRouteEngine(Collections.singleton(new QualifiedTable(DefaultDatabase.LOGIC_NAME, "t_order")), mockStatement(true), mock(HintValueContext.class)); assertDoesNotThrow(() -> engine.route(new RouteContext(), mockSingleRule())); } diff --git a/test/e2e/sql/src/test/resources/cases/dql/e2e-dql-select-join.xml b/test/e2e/sql/src/test/resources/cases/dql/e2e-dql-select-join.xml index 6a6da2083b0..952981fc24d 100644 --- a/test/e2e/sql/src/test/resources/cases/dql/e2e-dql-select-join.xml +++ b/test/e2e/sql/src/test/resources/cases/dql/e2e-dql-select-join.xml @@ -87,6 +87,16 @@ <test-case sql="SELECT i.* FROM t_order o JOIN t_order_item i USING(order_id) WHERE o.order_id = ?" db-types="MySQL,PostgreSQL" scenario-types="tbl,dbtbl_with_readwrite_splitting,readwrite_splitting"> <assertion parameters="1000:int" expected-data-source-name="read_dataset" /> </test-case> + + <!-- Test single, broadcast and sharding join begin --> + <test-case sql="SELECT * FROM t_product p INNER JOIN t_product_category c ON p.category_id = c.category_id WHERE p.product_id = ?" scenario-types="db,dbtbl_with_readwrite_splitting"> + <assertion parameters="1:int" expected-data-source-name="read_dataset" /> + </test-case> + + <test-case sql="SELECT * FROM t_product_category c INNER JOIN t_order_item i ON c.category_id = i.product_id WHERE i.product_id = ?" scenario-types="db,dbtbl_with_readwrite_splitting"> + <assertion parameters="1:int" expected-data-source-name="read_dataset" /> + </test-case> + <!-- Test single, broadcast and sharding join end --> <test-case sql="SELECT * FROM t_order o NATURAL JOIN t_merchant m WHERE o.user_id = ? ORDER BY o.order_id" db-types="MySQL,PostgreSQL,openGauss" scenario-types="db_tbl_sql_federation"> <assertion parameters="10:int" expected-data-source-name="read_dataset" /> diff --git a/test/it/rewriter/src/test/resources/scenario/sharding/case/ddl/create-table.xml b/test/it/rewriter/src/test/resources/scenario/sharding/case/ddl/create-table.xml index 842faf0edb1..c2772527943 100644 --- a/test/it/rewriter/src/test/resources/scenario/sharding/case/ddl/create-table.xml +++ b/test/it/rewriter/src/test/resources/scenario/sharding/case/ddl/create-table.xml @@ -21,68 +21,83 @@ <input sql="CREATE TABLE t_order_new(order_id INT PRIMARY KEY, CONSTRAINT t_order_new_fk FOREIGN KEY (order_id) REFERENCES t_order_item (order_id))" /> <output sql="CREATE TABLE t_order_new_0(order_id INT PRIMARY KEY, CONSTRAINT t_order_new_fk_t_order_new_0 FOREIGN KEY (order_id) REFERENCES t_order_item_0 (order_id))" /> </rewrite-assertion> + <rewrite-assertion id="create_table_with_single_data_node_unbinding_table_with_add_foreign_constraint" db-types="MySQL,PostgreSQL,openGauss"> <input sql="CREATE TABLE t_order_new(order_id INT PRIMARY KEY, CONSTRAINT t_order_new_fk FOREIGN KEY (order_id) REFERENCES t_order_extend (order_id))" /> <output sql="CREATE TABLE t_order_new_0(order_id INT PRIMARY KEY, CONSTRAINT t_order_new_fk_t_order_new_0 FOREIGN KEY (order_id) REFERENCES t_order_extend_0 (order_id))" /> </rewrite-assertion> + <rewrite-assertion id="create_table_with_multi_data_node_and_single_data_node_table_with_add_foreign_constraint" db-types="MySQL,PostgreSQL,openGauss"> <input sql="CREATE TABLE t_account_detail_new(order_id INT PRIMARY KEY, CONSTRAINT t_account_fk FOREIGN KEY (account_id) REFERENCES t_order_new (account_id))" /> <output sql="CREATE TABLE t_account_detail_new_0(order_id INT PRIMARY KEY, CONSTRAINT t_account_fk_t_account_detail_new_0 FOREIGN KEY (account_id) REFERENCES t_order_new_0 (account_id))" /> <output sql="CREATE TABLE t_account_detail_new_1(order_id INT PRIMARY KEY, CONSTRAINT t_account_fk_t_account_detail_new_1 FOREIGN KEY (account_id) REFERENCES t_order_new_0 (account_id))" /> </rewrite-assertion> + <rewrite-assertion id="create_table_with_multi_data_node_binding_table_with_add_foreign_constraint" db-types="MySQL,PostgreSQL,openGauss"> <input sql="CREATE TABLE t_account_detail_new(order_id INT PRIMARY KEY, CONSTRAINT t_account_fk FOREIGN KEY (account_id) REFERENCES t_account_detail_new (account_id))" /> <output sql="CREATE TABLE t_account_detail_new_0(order_id INT PRIMARY KEY, CONSTRAINT t_account_fk_t_account_detail_new_0 FOREIGN KEY (account_id) REFERENCES t_account_detail_new_0 (account_id))" /> <output sql="CREATE TABLE t_account_detail_new_1(order_id INT PRIMARY KEY, CONSTRAINT t_account_fk_t_account_detail_new_1 FOREIGN KEY (account_id) REFERENCES t_account_detail_new_1 (account_id))" /> </rewrite-assertion> + <rewrite-assertion id="create_table_with_single_data_node_and_broadcast_table_with_add_foreign_constraint" db-types="MySQL,PostgreSQL,openGauss"> <input sql="CREATE TABLE t_order_new(order_id INT PRIMARY KEY, CONSTRAINT t_order_new_fk FOREIGN KEY (order_id) REFERENCES t_config_new (order_id))" /> <output sql="CREATE TABLE t_order_new_0(order_id INT PRIMARY KEY, CONSTRAINT t_order_new_fk_t_order_new_0 FOREIGN KEY (order_id) REFERENCES t_config_new (order_id))" /> </rewrite-assertion> + <rewrite-assertion id="create_table_with_multi_data_node_and_broadcast_table_with_add_foreign_constraint" db-types="MySQL,PostgreSQL,openGauss"> <input sql="CREATE TABLE t_account_detail_new(order_id INT PRIMARY KEY, CONSTRAINT t_account_fk FOREIGN KEY (account_id) REFERENCES t_config_new (account_id))" /> <output sql="CREATE TABLE t_account_detail_new_0(order_id INT PRIMARY KEY, CONSTRAINT t_account_fk_t_account_detail_new_0 FOREIGN KEY (account_id) REFERENCES t_config_new (account_id))" /> <output sql="CREATE TABLE t_account_detail_new_1(order_id INT PRIMARY KEY, CONSTRAINT t_account_fk_t_account_detail_new_1 FOREIGN KEY (account_id) REFERENCES t_config_new (account_id))" /> </rewrite-assertion> + <rewrite-assertion id="create_table_with_single_data_node_and_single_table_with_add_foreign_constraint" db-types="MySQL,PostgreSQL,openGauss"> <input sql="CREATE TABLE t_order_new(order_id INT PRIMARY KEY, CONSTRAINT t_order_new_fk FOREIGN KEY (order_id) REFERENCES t_single_new (order_id))" /> <output sql="CREATE TABLE t_order_new_0(order_id INT PRIMARY KEY, CONSTRAINT t_order_new_fk_t_order_new_0 FOREIGN KEY (order_id) REFERENCES t_single_new (order_id))" /> </rewrite-assertion> + <rewrite-assertion id="create_table_with_multi_data_node_and_single_table_with_add_foreign_constraint" db-types="MySQL,PostgreSQL,openGauss"> <input sql="CREATE TABLE t_account_detail_new(order_id INT PRIMARY KEY, CONSTRAINT t_account_fk FOREIGN KEY (account_id) REFERENCES t_single_new (account_id))" /> <output sql="CREATE TABLE t_account_detail_new_0(order_id INT PRIMARY KEY, CONSTRAINT t_account_fk_t_account_detail_new_0 FOREIGN KEY (account_id) REFERENCES t_single_new (account_id))" /> <output sql="CREATE TABLE t_account_detail_new_1(order_id INT PRIMARY KEY, CONSTRAINT t_account_fk_t_account_detail_new_1 FOREIGN KEY (account_id) REFERENCES t_single_new (account_id))" /> </rewrite-assertion> + <rewrite-assertion id="create_table_with_broadcast_and_single_data_node_table_with_add_foreign_constraint" db-types="MySQL,PostgreSQL,openGauss"> <input sql="CREATE TABLE t_config_new(order_id INT PRIMARY KEY, CONSTRAINT t_config_new_fk FOREIGN KEY (order_id) REFERENCES t_order_new (order_id))" /> - <output sql="CREATE TABLE t_config_new(order_id INT PRIMARY KEY, CONSTRAINT t_config_new_fk_t_config_new FOREIGN KEY (order_id) REFERENCES t_order_new_0 (order_id))" /> + <output sql="CREATE TABLE t_config_new(order_id INT PRIMARY KEY, CONSTRAINT t_config_new_fk FOREIGN KEY (order_id) REFERENCES t_order_new_0 (order_id))" /> </rewrite-assertion> + <rewrite-assertion id="create_table_with_broadcast_table_with_add_foreign_constraint" db-types="MySQL,PostgreSQL,openGauss"> <input sql="CREATE TABLE t_config_new(order_id INT PRIMARY KEY, CONSTRAINT t_config_new_fk FOREIGN KEY (order_id) REFERENCES t_order_new_type (order_id))" /> <output sql="CREATE TABLE t_config_new(order_id INT PRIMARY KEY, CONSTRAINT t_config_new_fk FOREIGN KEY (order_id) REFERENCES t_order_new_type (order_id))" /> </rewrite-assertion> + <rewrite-assertion id="create_table_with_broadcast_and_single_table_with_add_foreign_constraint" db-types="MySQL,PostgreSQL,openGauss"> <input sql="CREATE TABLE t_config_new(order_id INT PRIMARY KEY, CONSTRAINT t_config_new_fk FOREIGN KEY (order_id) REFERENCES t_single_new (order_id))" /> <output sql="CREATE TABLE t_config_new(order_id INT PRIMARY KEY, CONSTRAINT t_config_new_fk FOREIGN KEY (order_id) REFERENCES t_single_new (order_id))" /> </rewrite-assertion> - <rewrite-assertion id="create_table_with_single_and_single_data_node_table_with_add_foreign_constraint" db-types="MySQL,PostgreSQL,openGauss"> + + <!--<rewrite-assertion id="create_table_with_single_and_single_data_node_table_with_add_foreign_constraint" db-types="MySQL,PostgreSQL,openGauss"> <input sql="CREATE TABLE t_single_new(order_id INT PRIMARY KEY, CONSTRAINT t_single_new_fk FOREIGN KEY (order_id) REFERENCES t_order_new (order_id))" /> <output sql="CREATE TABLE t_single_new(order_id INT PRIMARY KEY, CONSTRAINT t_single_new_fk FOREIGN KEY (order_id) REFERENCES t_order_new_0 (order_id))" /> - </rewrite-assertion> + </rewrite-assertion>--> + <!-- TODO fix me #26299 --> <!-- <rewrite-assertion id="create_table_with_single_and_broadcast_table_with_add_foreign_constraint" db-types="MySQL,PostgreSQL,openGauss">--> <!-- <input sql="CREATE TABLE t_single_new(order_id INT PRIMARY KEY, CONSTRAINT t_single_new_fk FOREIGN KEY (order_id) REFERENCES t_config_new (order_id))" />--> <!-- <output sql="CREATE TABLE t_single_new(order_id INT PRIMARY KEY, CONSTRAINT t_single_new_fk FOREIGN KEY (order_id) REFERENCES t_config_new (order_id))" />--> <!-- </rewrite-assertion>--> + <rewrite-assertion id="create_table_with_single_table_with_add_foreign_constraint" db-types="MySQL,PostgreSQL,openGauss"> <input sql="CREATE TABLE t_single_new(order_id INT PRIMARY KEY, CONSTRAINT t_single_new_fk FOREIGN KEY (order_id) REFERENCES t_single_extend (order_id))" /> <output sql="CREATE TABLE t_single_new(order_id INT PRIMARY KEY, CONSTRAINT t_single_new_fk FOREIGN KEY (order_id) REFERENCES t_single_extend (order_id))" /> </rewrite-assertion> + <rewrite-assertion id="create_table_with_multi_data_node_with_storage_parameter" db-types="openGauss"> <input sql="CREATE TABLE t_account_detail_new (order_id INT,account_id INT) WITH (FILLFACTOR = 80, ORIENTATION=ROW)" /> <output sql="CREATE TABLE t_account_detail_new_0 (order_id INT,account_id INT) WITH (FILLFACTOR = 80, ORIENTATION=ROW)" /> <output sql="CREATE TABLE t_account_detail_new_1 (order_id INT,account_id INT) WITH (FILLFACTOR = 80, ORIENTATION=ROW)" /> </rewrite-assertion> + <rewrite-assertion id="create_view_with_sharding_table" db-types="MySQL,PostgreSQL,openGauss"> <input sql="CREATE VIEW t_account_view AS SELECT account_id, amount FROM t_account WHERE status = 'OK'" /> <output sql="CREATE VIEW t_account_view_0 AS SELECT account_id, amount FROM t_account_0 WHERE status = 'OK'" />