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());