You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2022/06/17 12:08:04 UTC

[shardingsphere] branch master updated: Optimize sharding tables route logic when execute cursor statement (#18413)

This is an automated email from the ASF dual-hosted git repository.

zhaojinchao 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 7bfa655d427 Optimize sharding tables route logic when execute cursor statement (#18413)
7bfa655d427 is described below

commit 7bfa655d42754ec1144d26af7089962703d840e6
Author: Zhengqiang Duan <du...@apache.org>
AuthorDate: Fri Jun 17 20:07:59 2022 +0800

    Optimize sharding tables route logic when execute cursor statement (#18413)
---
 .../engine/type/ShardingRouteEngineFactory.java    | 16 +++++++-
 .../type/ShardingRouteEngineFactoryTest.java       | 47 ++++++++++++++++++++++
 2 files changed, 61 insertions(+), 2 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 0d141b0c000..77f4ae7750a 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
@@ -121,12 +121,24 @@ public final class ShardingRouteEngineFactory {
             return new ShardingIgnoreRoutingEngine();
         }
         if (sqlStatementContext instanceof CursorAvailable) {
-            return shardingRule.isAllBroadcastTables(shardingRuleTableNames) ? new ShardingUnicastRoutingEngine(sqlStatementContext, shardingRuleTableNames)
-                    : new ShardingStandardRoutingEngine(shardingRuleTableNames.iterator().next(), shardingConditions, props);
+            return getCursorRouteEngine(shardingRule, database, sqlStatementContext, shardingConditions, props, tableNames);
         }
         return new ShardingTableBroadcastRoutingEngine(database, sqlStatementContext, shardingRuleTableNames);
     }
     
+    private static ShardingRouteEngine getCursorRouteEngine(final ShardingRule shardingRule, final ShardingSphereDatabase database, final SQLStatementContext<?> sqlStatementContext,
+                                                            final ShardingConditions shardingConditions, final ConfigurationProperties props, final Collection<String> tableNames) {
+        if (shardingRule.isAllBroadcastTables(tableNames)) {
+            return new ShardingUnicastRoutingEngine(sqlStatementContext, tableNames);
+        }
+        Collection<String> logicTableNames = shardingRule.getShardingLogicTableNames(tableNames);
+        boolean allBindingTables = logicTableNames.size() > 1 && shardingRule.isAllBindingTables(database, sqlStatementContext, logicTableNames);
+        if (isShardingStandardQuery(shardingRule, logicTableNames, allBindingTables)) {
+            return new ShardingStandardRoutingEngine(getLogicTableName(shardingConditions, logicTableNames), shardingConditions, props);
+        }
+        return new ShardingIgnoreRoutingEngine();
+    }
+    
     private static ShardingRouteEngine getDALRoutingEngine(final ShardingRule shardingRule, final ShardingSphereDatabase database, final SQLStatementContext<?> sqlStatementContext) {
         SQLStatement sqlStatement = sqlStatementContext.getSqlStatement();
         if (sqlStatement instanceof MySQLUseStatement) {
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 07bd0dc0305..3cfc05ac012 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
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.sharding.route.engine.type;
 import org.apache.shardingsphere.infra.binder.segment.table.TablesContext;
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.binder.statement.dcl.GrantStatementContext;
+import org.apache.shardingsphere.infra.binder.statement.ddl.CursorStatementContext;
 import org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
 import org.apache.shardingsphere.infra.config.props.ConfigurationPropertyKey;
@@ -56,6 +57,7 @@ import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQ
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLShowDatabasesStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dcl.MySQLGrantStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLSelectStatement;
+import org.apache.shardingsphere.sql.parser.sql.dialect.statement.opengauss.ddl.OpenGaussCursorStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.dcl.OracleGrantStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.postgresql.dal.PostgreSQLSetStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.postgresql.dcl.PostgreSQLGrantStatement;
@@ -73,6 +75,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Properties;
+import java.util.stream.Collectors;
 
 import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.junit.Assert.assertThat;
@@ -366,4 +369,48 @@ public final class ShardingRouteEngineFactoryTest {
         ShardingRouteEngine actual = ShardingRouteEngineFactory.newInstance(shardingRule, database, sqlStatementContext, shardingConditions, props);
         assertThat(actual, instanceOf(ShardingIgnoreRoutingEngine.class));
     }
+    
+    @Test
+    public void assertNewInstanceForCursorStatementWithBroadcastTable() {
+        CursorStatementContext cursorStatementContext = mock(CursorStatementContext.class);
+        OpenGaussCursorStatement cursorStatement = mock(OpenGaussCursorStatement.class);
+        when(cursorStatementContext.getSqlStatement()).thenReturn(cursorStatement);
+        Collection<SimpleTableSegment> tableSegments = createSimpleTableSegments();
+        Collection<String> tableNames = tableSegments.stream().map(each -> each.getTableName().getIdentifier().getValue()).collect(Collectors.toSet());
+        when(cursorStatementContext.getAllTables()).thenReturn(tableSegments);
+        when(shardingRule.isAllBroadcastTables(tableNames)).thenReturn(true);
+        when(shardingRule.getShardingRuleTableNames(tableNames)).thenReturn(tableNames);
+        ShardingRouteEngine actual = ShardingRouteEngineFactory.newInstance(shardingRule, database, cursorStatementContext, shardingConditions, props);
+        assertThat(actual, instanceOf(ShardingUnicastRoutingEngine.class));
+    }
+    
+    @Test
+    public void assertNewInstanceForCursorStatementWithShardingTable() {
+        CursorStatementContext cursorStatementContext = mock(CursorStatementContext.class);
+        OpenGaussCursorStatement cursorStatement = mock(OpenGaussCursorStatement.class);
+        when(cursorStatementContext.getSqlStatement()).thenReturn(cursorStatement);
+        Collection<SimpleTableSegment> tableSegments = createSimpleTableSegments();
+        Collection<String> tableNames = tableSegments.stream().map(each -> each.getTableName().getIdentifier().getValue()).collect(Collectors.toSet());
+        when(cursorStatementContext.getAllTables()).thenReturn(tableSegments);
+        when(shardingRule.isAllShardingTables(tableNames)).thenReturn(true);
+        when(shardingRule.getShardingRuleTableNames(tableNames)).thenReturn(tableNames);
+        when(shardingRule.getShardingLogicTableNames(tableNames)).thenReturn(tableNames);
+        ShardingRouteEngine actual = ShardingRouteEngineFactory.newInstance(shardingRule, database, cursorStatementContext, shardingConditions, props);
+        assertThat(actual, instanceOf(ShardingStandardRoutingEngine.class));
+    }
+    
+    @Test
+    public void assertNewInstanceForCursorStatementWithSingleTable() {
+        CursorStatementContext cursorStatementContext = mock(CursorStatementContext.class);
+        OpenGaussCursorStatement cursorStatement = mock(OpenGaussCursorStatement.class);
+        when(cursorStatementContext.getSqlStatement()).thenReturn(cursorStatement);
+        Collection<SimpleTableSegment> tableSegments = createSimpleTableSegments();
+        when(cursorStatementContext.getAllTables()).thenReturn(tableSegments);
+        ShardingRouteEngine actual = ShardingRouteEngineFactory.newInstance(shardingRule, database, cursorStatementContext, shardingConditions, props);
+        assertThat(actual, instanceOf(ShardingIgnoreRoutingEngine.class));
+    }
+    
+    private Collection<SimpleTableSegment> createSimpleTableSegments() {
+        return Collections.singletonList(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
+    }
 }