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

totalo 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 d6873cfdd95 Fix wrong route result when execute `SELECT 
LAST_INSERT_ID() AS id;` statement (#17943)
d6873cfdd95 is described below

commit d6873cfdd95116ddedef68ba6e421905189dd6dd
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Wed May 25 18:32:55 2022 +0800

    Fix wrong route result when execute `SELECT LAST_INSERT_ID() AS id;` 
statement (#17943)
    
    * Fix wrong route result when execute `SELECT LAST_INSERT_ID() AS id;` 
statement
    
    * fix unit test
---
 .../impl/ReadwriteSplittingDataSourceRouter.java      | 19 ++++++++++++++-----
 .../route/ReadwriteSplittingSQLRouterTest.java        |  3 ++-
 .../segment/select/projection/ProjectionsContext.java | 14 ++++++++++++++
 .../select/projection/ProjectionsContextTest.java     |  9 +++++++++
 .../metadata/rule/ShardingSphereRuleMetaDataTest.java |  2 +-
 5 files changed, 40 insertions(+), 7 deletions(-)

diff --git 
a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/impl/ReadwriteSplittingDataSourceRouter.java
 
b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/impl/ReadwriteSplittingDataSourceRouter.java
index d9042bb8fcc..61f95f070b9 100644
--- 
a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/impl/ReadwriteSplittingDataSourceRouter.java
+++ 
b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/impl/ReadwriteSplittingDataSourceRouter.java
@@ -20,12 +20,13 @@ package 
org.apache.shardingsphere.readwritesplitting.route.impl;
 import lombok.RequiredArgsConstructor;
 import 
org.apache.shardingsphere.infra.binder.statement.CommonSQLStatementContext;
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
+import 
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
 import org.apache.shardingsphere.infra.hint.HintManager;
-import org.apache.shardingsphere.transaction.TransactionHolder;
 import 
org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingDataSourceRule;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.handler.dml.SelectStatementHandler;
+import org.apache.shardingsphere.transaction.TransactionHolder;
 
 /**
  * Data source router for readwrite-splitting.
@@ -52,15 +53,23 @@ public final class ReadwriteSplittingDataSourceRouter {
     }
     
     private boolean isPrimaryRoute(final SQLStatementContext<?> 
sqlStatementContext) {
-        SQLStatement sqlStatement = sqlStatementContext.getSqlStatement();
-        return containsLockSegment(sqlStatement) || !(sqlStatement instanceof 
SelectStatement) || isHintWriteRouteOnly(sqlStatementContext) || 
TransactionHolder.isTransaction();
+        return isWriteRouteStatement(sqlStatementContext) || 
isHintWriteRouteOnly(sqlStatementContext) || TransactionHolder.isTransaction();
     }
     
-    private boolean isHintWriteRouteOnly(final SQLStatementContext<?> 
sqlStatementContext) {
-        return HintManager.isWriteRouteOnly() || (sqlStatementContext 
instanceof CommonSQLStatementContext && ((CommonSQLStatementContext<?>) 
sqlStatementContext).isHintWriteRouteOnly());
+    private boolean isWriteRouteStatement(final SQLStatementContext<?> 
sqlStatementContext) {
+        SQLStatement sqlStatement = sqlStatementContext.getSqlStatement();
+        return containsLockSegment(sqlStatement) || 
containsLastInsertIdProjection(sqlStatementContext) || !(sqlStatement 
instanceof SelectStatement);
     }
     
     private boolean containsLockSegment(final SQLStatement sqlStatement) {
         return sqlStatement instanceof SelectStatement && 
SelectStatementHandler.getLockSegment((SelectStatement) 
sqlStatement).isPresent();
     }
+    
+    private boolean containsLastInsertIdProjection(final 
SQLStatementContext<?> sqlStatementContext) {
+        return sqlStatementContext instanceof SelectStatementContext && 
((SelectStatementContext) 
sqlStatementContext).getProjectionsContext().isContainsLastInsertIdProjection();
+    }
+    
+    private boolean isHintWriteRouteOnly(final SQLStatementContext<?> 
sqlStatementContext) {
+        return HintManager.isWriteRouteOnly() || (sqlStatementContext 
instanceof CommonSQLStatementContext && ((CommonSQLStatementContext<?>) 
sqlStatementContext).isHintWriteRouteOnly());
+    }
 }
diff --git 
a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouterTest.java
 
b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouterTest.java
index 98e875c850c..690191db390 100644
--- 
a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouterTest.java
+++ 
b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingSQLRouterTest.java
@@ -216,9 +216,10 @@ public final class ReadwriteSplittingSQLRouterTest {
     @Test
     public void assertSqlHintRouteWriteOnly() {
         SelectStatement statement = mock(SelectStatement.class);
-        CommonSQLStatementContext<SelectStatement> sqlStatementContext = 
mock(SelectStatementContext.class);
+        SelectStatementContext sqlStatementContext = 
mock(SelectStatementContext.class, RETURNS_DEEP_STUBS);
         when(sqlStatementContext.getSqlStatement()).thenReturn(statement);
         when(sqlStatementContext.isHintWriteRouteOnly()).thenReturn(true);
+        
when(sqlStatementContext.getProjectionsContext().isContainsLastInsertIdProjection()).thenReturn(false);
         LogicSQL logicSQL = new LogicSQL(sqlStatementContext, "", 
Collections.emptyList());
         ShardingSphereRuleMetaData ruleMetaData = new 
ShardingSphereRuleMetaData(Collections.emptyList(), 
Collections.singleton(rule));
         ShardingSphereDatabase database = new 
ShardingSphereDatabase(DefaultDatabase.LOGIC_NAME,
diff --git 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/ProjectionsContext.java
 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/ProjectionsContext.java
index 26f2fb08d7c..97784c192e6 100644
--- 
a/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/ProjectionsContext.java
+++ 
b/shardingsphere-infra/shardingsphere-infra-binder/src/main/java/org/apache/shardingsphere/infra/binder/segment/select/projection/ProjectionsContext.java
@@ -38,6 +38,8 @@ import java.util.Optional;
 @ToString
 public final class ProjectionsContext {
     
+    private static final String LAST_INSERT_ID_FUNCTION_EXPRESSION = 
"LAST_INSERT_ID()";
+    
     private final int startIndex;
     
     private final int stopIndex;
@@ -50,6 +52,8 @@ public final class ProjectionsContext {
     
     private final List<Projection> expandProjections;
     
+    private final boolean containsLastInsertIdProjection;
+    
     public ProjectionsContext(final int startIndex, final int stopIndex, final 
boolean distinctRow, final Collection<Projection> projections) {
         this.startIndex = startIndex;
         this.stopIndex = stopIndex;
@@ -57,6 +61,7 @@ public final class ProjectionsContext {
         this.projections = projections;
         aggregationDistinctProjections = 
createAggregationDistinctProjections();
         expandProjections = expandProjections();
+        containsLastInsertIdProjection = 
isContainsLastInsertIdProjection(projections);
     }
     
     private Collection<AggregationDistinctProjection> 
createAggregationDistinctProjections() {
@@ -145,4 +150,13 @@ public final class ProjectionsContext {
         }
         return result;
     }
+    
+    private boolean isContainsLastInsertIdProjection(final 
Collection<Projection> projections) {
+        for (Projection each : projections) {
+            if 
(LAST_INSERT_ID_FUNCTION_EXPRESSION.equalsIgnoreCase(SQLUtil.getExactlyExpression(each.getExpression())))
 {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git 
a/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/select/projection/ProjectionsContextTest.java
 
b/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/select/projection/ProjectionsContextTest.java
index 15943835a13..bff10479e63 100644
--- 
a/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/select/projection/ProjectionsContextTest.java
+++ 
b/shardingsphere-infra/shardingsphere-infra-binder/src/test/java/org/apache/shardingsphere/infra/binder/segment/select/projection/ProjectionsContextTest.java
@@ -21,6 +21,7 @@ import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.Agg
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.AggregationProjection;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.DerivedProjection;
+import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ExpressionProjection;
 import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ShorthandProjection;
 import org.apache.shardingsphere.infra.database.type.DatabaseType;
 import 
org.apache.shardingsphere.sql.parser.sql.common.constant.AggregationType;
@@ -145,4 +146,12 @@ public final class ProjectionsContextTest {
         assertThat(actual.getExpandProjections().get(1), 
is(columnProjection2));
         assertThat(actual.getExpandProjections().get(2), 
is(columnProjection3));
     }
+    
+    @Test
+    public void assertIsContainsLastInsertIdProjection() {
+        ProjectionsContext lastInsertIdProjection = new ProjectionsContext(0, 
0, false, Collections.singletonList(new 
ExpressionProjection("LAST_INSERT_ID()", "id")));
+        assertTrue(lastInsertIdProjection.isContainsLastInsertIdProjection());
+        ProjectionsContext maxProjection = new ProjectionsContext(0, 0, false, 
Collections.singletonList(new ExpressionProjection("MAX(id)", "max")));
+        assertFalse(maxProjection.isContainsLastInsertIdProjection());
+    }
 }
diff --git 
a/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/metadata/rule/ShardingSphereRuleMetaDataTest.java
 
b/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/metadata/rule/ShardingSphereRuleMetaDataTest.java
index 8d573a576d8..61633c368ad 100644
--- 
a/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/metadata/rule/ShardingSphereRuleMetaDataTest.java
+++ 
b/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/metadata/rule/ShardingSphereRuleMetaDataTest.java
@@ -44,7 +44,7 @@ public final class ShardingSphereRuleMetaDataTest {
     public void assertFindRuleConfigurations() {
         
assertThat(ruleMetaData.findRuleConfigurations(ShardingSphereRuleConfigurationFixture.class).size(),
 is(1));
     }
-
+    
     @Test
     public void assertFindSingleRuleConfiguration() {
         
assertTrue(ruleMetaData.findSingleRuleConfiguration(ShardingSphereRuleConfigurationFixture.class).isPresent());

Reply via email to