This is an automated email from the ASF dual-hosted git repository.
panjuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new 2f24973 optimize route logic (#12685)
2f24973 is described below
commit 2f2497397497c8c8f090630fba5309d8551133e9
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Fri Sep 24 18:46:09 2021 +0800
optimize route logic (#12685)
---
.../engine/type/ShardingRouteEngineFactory.java | 31 +++++++---------------
.../standard/ShardingStandardRoutingEngine.java | 12 ---------
.../type/ShardingRouteEngineFactoryTest.java | 3 +--
.../statement/dml/SelectStatementContext.java | 28 +++++++++----------
.../resources/scenario/sharding/case/select.xml | 4 +--
5 files changed, 26 insertions(+), 52 deletions(-)
diff --git
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/ShardingRouteEngineFactory.java
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/ShardingRouteEngineFactory.java
index 537e752..661d11d 100644
---
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/ShardingRouteEngineFactory.java
+++
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/ShardingRouteEngineFactory.java
@@ -177,31 +177,16 @@ public final class ShardingRouteEngineFactory {
private static ShardingRouteEngine getDQLRouteEngineForShardingTable(final
ShardingRule shardingRule, final SQLStatementContext<?> sqlStatementContext,
final
ShardingConditions shardingConditions, final Collection<String> tableNames,
final ConfigurationProperties props) {
- if (isShardingStandardQuery(tableNames, shardingRule)) {
- ShardingStandardRoutingEngine result = new
ShardingStandardRoutingEngine(getLogicTableName(shardingConditions,
tableNames), shardingConditions, props);
- boolean needExecuteByCalcite =
isNeedExecuteByCalcite(sqlStatementContext, shardingConditions);
- if (!needExecuteByCalcite ||
result.route(shardingRule).isSingleRouting()) {
- return result;
- }
- }
if (isShardingFederatedQuery(sqlStatementContext, tableNames,
shardingRule, shardingConditions)) {
return new ShardingFederatedRoutingEngine(tableNames);
}
+ if (isShardingStandardQuery(tableNames, shardingRule)) {
+ return new
ShardingStandardRoutingEngine(getLogicTableName(shardingConditions,
tableNames), shardingConditions, props);
+ }
// TODO config for cartesian set
return new ShardingComplexRoutingEngine(tableNames,
shardingConditions, props);
}
- private static boolean isNeedExecuteByCalcite(final SQLStatementContext<?>
sqlStatementContext, final ShardingConditions shardingConditions) {
- if (!(sqlStatementContext instanceof SelectStatementContext)) {
- return false;
- }
- SelectStatementContext selectStatementContext =
(SelectStatementContext) sqlStatementContext;
- if (selectStatementContext.getPaginationContext().isHasPagination()) {
- return false;
- }
- return selectStatementContext.isNeedExecuteByCalcite() ||
(shardingConditions.isNeedMerge() &&
!shardingConditions.isSameShardingCondition());
- }
-
private static String getLogicTableName(final ShardingConditions
shardingConditions, final Collection<String> tableNames) {
return shardingConditions.getConditions().stream().flatMap(each ->
each.getValues().stream())
.map(ShardingConditionValue::getTableName).findFirst().orElseGet(() ->
tableNames.iterator().next());
@@ -217,12 +202,16 @@ public final class ShardingRouteEngineFactory {
return false;
}
SelectStatementContext select = (SelectStatementContext)
sqlStatementContext;
- if (isNeedExecuteByCalcite(sqlStatementContext, shardingConditions)) {
+ if (select.getPaginationContext().isHasPagination() ||
(shardingConditions.isNeedMerge() &&
shardingConditions.isSameShardingCondition())) {
+ return false;
+ }
+ if (select.isContainsSubquery() || select.isContainsHaving() ||
select.isContainsPartialDistinctAggregation()) {
return true;
}
- if ((!select.isContainsJoinQuery() && !select.isContainsSubquery()) ||
shardingRule.isAllTablesInSameDataSource(tableNames)) {
+ Collection<String> shardingTableNames =
shardingRule.getShardingLogicTableNames(tableNames);
+ if (!select.isContainsJoinQuery() ||
shardingRule.isAllTablesInSameDataSource(shardingTableNames)) {
return false;
}
- return shardingRule.isAllShardingTables(tableNames);
+ return shardingTableNames.size() > 1 &&
!shardingRule.isAllBindingTables(shardingTableNames);
}
}
diff --git
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/standard/ShardingStandardRoutingEngine.java
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/standard/ShardingStandardRoutingEngine.java
index a4d8681..37a87ab 100644
---
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/standard/ShardingStandardRoutingEngine.java
+++
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/standard/ShardingStandardRoutingEngine.java
@@ -49,7 +49,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
/**
* Sharding standard routing engine.
@@ -65,19 +64,8 @@ public final class ShardingStandardRoutingEngine implements
ShardingRouteEngine
private final Collection<Collection<DataNode>> originalDataNodes = new
LinkedList<>();
- private final Map<String, RouteContext> cachedRouteContexts = new
ConcurrentHashMap<>();
-
@Override
public RouteContext route(final ShardingRule shardingRule) {
- RouteContext result = cachedRouteContexts.get(logicTableName);
- if (null == result) {
- result = getRouteContext(shardingRule);
- }
- cachedRouteContexts.put(logicTableName, result);
- return result;
- }
-
- private RouteContext getRouteContext(final ShardingRule shardingRule) {
RouteContext result = new RouteContext();
Collection<DataNode> dataNodes = getDataNodes(shardingRule,
shardingRule.getTableRule(logicTableName));
result.getOriginalDataNodes().addAll(originalDataNodes);
diff --git
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/ShardingRouteEngineFactoryTest.java
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/ShardingRouteEngineFactoryTest.java
index a90340d..20ccfbb 100644
---
a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/ShardingRouteEngineFactoryTest.java
+++
b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-core/src/test/java/org/apache/shardingsphere/sharding/route/engine/type/ShardingRouteEngineFactoryTest.java
@@ -294,10 +294,9 @@ public final class ShardingRouteEngineFactoryTest {
SelectStatementContext sqlStatementContext =
mock(SelectStatementContext.class, RETURNS_DEEP_STUBS);
tableNames.add("t_order");
when(sqlStatementContext.getTablesContext().getTableNames()).thenReturn(tableNames);
- when(sqlStatementContext.isNeedExecuteByCalcite()).thenReturn(false);
+ when(sqlStatementContext.isContainsSubquery()).thenReturn(true);
ShardingRule shardingRule = mock(ShardingRule.class,
RETURNS_DEEP_STUBS);
when(shardingRule.getShardingRuleTableNames(tableNames)).thenReturn(tableNames);
- when(shardingRule.isAllShardingTables(tableNames)).thenReturn(true);
when(shardingRule.getTableRule("t_order").getActualDatasourceNames()).thenReturn(Arrays.asList("ds_0",
"ds_1"));
when(shardingConditions.isNeedMerge()).thenReturn(true);
when(shardingConditions.isSameShardingCondition()).thenReturn(false);
diff --git
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
index 5cf18cd..02204ee 100644
---
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
+++
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
@@ -42,7 +42,6 @@ import
org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
import
org.apache.shardingsphere.sql.parser.sql.common.extractor.TableExtractor;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubquerySegment;
-import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.AggregationProjectionSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.ColumnOrderByItemSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.ExpressionOrderByItemSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.IndexOrderByItemSegment;
@@ -79,8 +78,6 @@ public final class SelectStatementContext extends
CommonSQLStatementContext<Sele
private final Collection<SubquerySegment> subquerySegments;
- private final boolean needExecuteByCalcite;
-
private final String schemaName;
public SelectStatementContext(final Map<String, ShardingSphereMetaData>
metaDataMap, final List<Object> parameters, final SelectStatement sqlStatement,
final String defaultSchemaName) {
@@ -93,12 +90,7 @@ public final class SelectStatementContext extends
CommonSQLStatementContext<Sele
.createProjectionsContext(getSqlStatement().getFrom(),
getSqlStatement().getProjections(), groupByContext, orderByContext);
paginationContext = new
PaginationContextEngine().createPaginationContext(sqlStatement,
projectionsContext, parameters);
subquerySegments =
SubqueryExtractUtil.getSubquerySegments(getSqlStatement());
- needExecuteByCalcite = checkNeedExecuteByCalcite(subquerySegments);
- this.schemaName = defaultSchemaName;
- }
-
- private boolean checkNeedExecuteByCalcite(final
Collection<SubquerySegment> subquerySegments) {
- return isContainsHaving() ||
isContainsSubqueryAggregation(subquerySegments) ||
isContainsPartialDistinctAggregation();
+ schemaName = defaultSchemaName;
}
private ShardingSphereSchema getSchema(final Map<String,
ShardingSphereMetaData> metaDataMap, final String defaultSchemaName) {
@@ -110,10 +102,6 @@ public final class SelectStatementContext extends
CommonSQLStatementContext<Sele
return metaData.getSchema();
}
- private boolean isContainsSubqueryAggregation(final
Collection<SubquerySegment> subquerySegments) {
- return subquerySegments.stream().flatMap(each ->
each.getSelect().getProjections().getProjections().stream()).anyMatch(each ->
each instanceof AggregationProjectionSegment);
- }
-
/**
* Judge whether contains join query or not.
*
@@ -132,11 +120,21 @@ public final class SelectStatementContext extends
CommonSQLStatementContext<Sele
return !subquerySegments.isEmpty();
}
- private boolean isContainsHaving() {
+ /**
+ * Judge whether contains having or not.
+ *
+ * @return whether contains having or not
+ */
+ public boolean isContainsHaving() {
return getSqlStatement().getHaving().isPresent();
}
- private boolean isContainsPartialDistinctAggregation() {
+ /**
+ * Judge whether contains partial distinct aggregation.
+ *
+ * @return whether contains partial distinct aggregation
+ */
+ public boolean isContainsPartialDistinctAggregation() {
Collection<Projection> aggregationProjections =
projectionsContext.getProjections().stream().filter(each -> each instanceof
AggregationProjection).collect(Collectors.toList());
Collection<AggregationDistinctProjection>
aggregationDistinctProjections =
projectionsContext.getAggregationDistinctProjections();
return aggregationProjections.size() > 1 &&
aggregationDistinctProjections.size() > 0 && aggregationProjections.size() !=
aggregationDistinctProjections.size();
diff --git
a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/sharding/case/select.xml
b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/sharding/case/select.xml
index d3e4b39..37b91d2 100644
---
a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/sharding/case/select.xml
+++
b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/sharding/case/select.xml
@@ -34,7 +34,7 @@
<rewrite-assertion id="select_with_sum_fun">
<input sql="SELECT SUM(DISTINCT account_id), SUM(account_id) FROM
t_account WHERE account_id = 100" />
- <output sql="SELECT SUM(DISTINCT account_id), SUM(account_id) FROM
t_account_0 WHERE account_id = 100" />
+ <output sql="SELECT SUM(DISTINCT account_id), SUM(account_id) FROM
t_account WHERE account_id = 100" />
</rewrite-assertion>
<rewrite-assertion id="select_with_avg_fun">
@@ -80,7 +80,7 @@
<rewrite-assertion id="select_with_subquery_in_projection_and_where"
db-type="MySQL">
<input sql="SELECT (select id from t_account limit 1) as myid FROM
(select b.account_id from (select t_account.account_id from t_account) b where
b.account_id=?) a WHERE account_id >= (select account_id from t_account limit
1)" parameters="100"/>
- <output sql="SELECT (select id from t_account_0 limit 1) as myid FROM
(select b.account_id from (select t_account_0.account_id from t_account_0) b
where b.account_id=?) a WHERE account_id >= (select account_id from t_account_0
limit 1)" parameters="100"/>
+ <output sql="SELECT (select id from t_account limit 1) as myid FROM
(select b.account_id from (select t_account.account_id from t_account) b where
b.account_id=?) a WHERE account_id >= (select account_id from t_account limit
1)" parameters="100"/>
</rewrite-assertion>
<rewrite-assertion id="select_with_subquery_only_in_projection"
db-type="MySQL">