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 2020/09/18 03:17:02 UTC
[shardingsphere] branch master updated: Fix shadow value in literal
expression (#7486)
This is an automated email from the ASF dual-hosted git repository.
zhyee 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 17d1375 Fix shadow value in literal expression (#7486)
17d1375 is described below
commit 17d137566799fe2f51a2173c97a7cdbf9e66ea6b
Author: Yanick.xia <me...@qq.com>
AuthorDate: Fri Sep 18 11:16:42 2020 +0800
Fix shadow value in literal expression (#7486)
* Fix shadow value in literal expression
* Add more unit test
Co-authored-by: yanick.xia <ya...@daocloud.io>
---
.../application-shadow-databases.properties | 3 +-
.../impl/PreparedShadowDataSourceJudgeEngine.java | 13 ++++---
.../impl/PreparedShadowDataSourceRouterTest.java | 43 ++++++++++++++++++++++
.../statement/ShadowPreparedStatementTest.java | 14 +++++++
4 files changed, 67 insertions(+), 6 deletions(-)
diff --git a/examples/shardingsphere-jdbc-example/other-feature-example/shadow-example/shadow-spring-boot-example/src/main/resources/application-shadow-databases.properties b/examples/shardingsphere-jdbc-example/other-feature-example/shadow-example/shadow-spring-boot-example/src/main/resources/application-shadow-databases.properties
index 8226d15..4360c90 100644
--- a/examples/shardingsphere-jdbc-example/other-feature-example/shadow-example/shadow-spring-boot-example/src/main/resources/application-shadow-databases.properties
+++ b/examples/shardingsphere-jdbc-example/other-feature-example/shadow-example/shadow-spring-boot-example/src/main/resources/application-shadow-databases.properties
@@ -27,4 +27,5 @@ spring.shardingsphere.datasource.ds.jdbc-url=jdbc:mysql://localhost:3306/demo_ds
spring.shardingsphere.datasource.shadow_ds.jdbc-url=jdbc:mysql://localhost:3306/shadow_demo_ds?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.rules.shadow.column=shadow
-spring.shardingsphere.rules.shadow.shadow-mappings.ds=shadow_ds
+spring.shardingsphere.rules.shadow.sourceDataSourceNames=ds
+spring.shardingsphere.rules.shadow.shadowDataSourceNames=shadow_ds
diff --git a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-route/src/main/java/org/apache/shardingsphere/shadow/route/engine/judge/impl/PreparedShadowDataSourceJudgeEngine.java b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-route/src/main/java/org/apache/shardingsphere/shadow/route/engine/judge/impl/PreparedShadowDataSourceJudgeEngine.java
index 44e01ae..11f7431 100644
--- a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-route/src/main/java/org/apache/shardingsphere/shadow/route/engine/judge/impl/PreparedShadowDataSourceJudgeEngine.java
+++ b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-route/src/main/java/org/apache/shardingsphere/shadow/route/engine/judge/impl/PreparedShadowDataSourceJudgeEngine.java
@@ -19,15 +19,16 @@ package org.apache.shardingsphere.shadow.route.engine.judge.impl;
import com.google.common.base.Preconditions;
import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.shadow.route.engine.judge.ShadowDataSourceJudgeEngine;
import org.apache.shardingsphere.shadow.route.engine.judge.util.ShadowValueJudgeUtil;
import org.apache.shardingsphere.shadow.rule.ShadowRule;
-import org.apache.shardingsphere.shadow.route.engine.judge.ShadowDataSourceJudgeEngine;
import org.apache.shardingsphere.sql.parser.binder.statement.SQLStatementContext;
import org.apache.shardingsphere.sql.parser.binder.statement.dml.InsertStatementContext;
import org.apache.shardingsphere.sql.parser.binder.type.WhereAvailable;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.AndPredicate;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.WhereSegment;
@@ -98,11 +99,13 @@ public final class PreparedShadowDataSourceJudgeEngine implements ShadowDataSour
}
if (column.getIdentifier().getValue().equals(shadowRule.getColumn())) {
Preconditions.checkArgument(each instanceof BinaryOperationExpression, "must be BinaryOperationExpression");
- if (!(right instanceof ParameterMarkerExpressionSegment)) {
- continue;
+ if (right instanceof LiteralExpressionSegment) {
+ return ShadowValueJudgeUtil.isShadowValue(((LiteralExpressionSegment) right).getLiterals());
+ }
+ if (right instanceof ParameterMarkerExpressionSegment) {
+ int parameterMarkerIndex = ((ParameterMarkerExpressionSegment) right).getParameterMarkerIndex();
+ return ShadowValueJudgeUtil.isShadowValue(parameters.get(parameterMarkerIndex));
}
- int parameterMarkerIndex = ((ParameterMarkerExpressionSegment) right).getParameterMarkerIndex();
- return ShadowValueJudgeUtil.isShadowValue(parameters.get(parameterMarkerIndex));
}
}
return false;
diff --git a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-route/src/test/java/org/apache/shardingsphere/shadow/route/engine/judge/impl/PreparedShadowDataSourceRouterTest.java b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-route/src/test/java/org/apache/shardingsphere/shadow/route/engine/judge/impl/PreparedShadowDataSourceRouterTest.java
index 0271c3c..48663e8 100644
--- a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-route/src/test/java/org/apache/shardingsphere/shadow/route/engine/judge/impl/PreparedShadowDataSourceRouterTest.java
+++ b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-route/src/test/java/org/apache/shardingsphere/shadow/route/engine/judge/impl/PreparedShadowDataSourceRouterTest.java
@@ -21,10 +21,16 @@ import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration;
import org.apache.shardingsphere.shadow.rule.ShadowRule;
import org.apache.shardingsphere.sql.parser.binder.metadata.schema.SchemaMetaData;
import org.apache.shardingsphere.sql.parser.binder.statement.dml.InsertStatementContext;
+import org.apache.shardingsphere.sql.parser.binder.statement.dml.SelectStatementContext;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.InsertColumnsSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.WhereSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.InsertStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLInsertStatement;
import org.junit.Test;
@@ -53,4 +59,41 @@ public final class PreparedShadowDataSourceRouterTest {
PreparedShadowDataSourceJudgeEngine preparedShadowDataSourceRouter = new PreparedShadowDataSourceJudgeEngine(shadowRule, insertStatementContext, Arrays.asList(1, "Tom", true));
assertTrue("should be shadow", preparedShadowDataSourceRouter.isShadow());
}
+
+ @Test
+ public void isShadowSQLInLiteralExpression() {
+ SchemaMetaData schemaMetaData = mock(SchemaMetaData.class);
+ when(schemaMetaData.getAllColumnNames("tbl")).thenReturn(Arrays.asList("id", "name", "shadow"));
+ ShadowRuleConfiguration shadowRuleConfiguration = new ShadowRuleConfiguration("shadow", Collections.singletonList("ds"), Collections.singletonList("shadow_ds"));
+ ShadowRule shadowRule = new ShadowRule(shadowRuleConfiguration);
+
+ PreparedShadowDataSourceJudgeEngine preparedShadowDataSourceRouter = new PreparedShadowDataSourceJudgeEngine(shadowRule, selectStatementContext(), Arrays.asList(1, "Tom", true));
+ assertTrue("should be shadow", preparedShadowDataSourceRouter.isShadow());
+ }
+
+ private SelectStatementContext selectStatementContext() {
+ BinaryOperationExpression left = new BinaryOperationExpression();
+ left.setLeft(new ColumnSegment(0, 0, new IdentifierValue("id")));
+ left.setRight(new ParameterMarkerExpressionSegment(0, 0, 0));
+ left.setText("id=?");
+ left.setOperator("=");
+
+ BinaryOperationExpression right = new BinaryOperationExpression();
+ right.setLeft(new ColumnSegment(0, 0, new IdentifierValue("shadow")));
+ right.setRight(new LiteralExpressionSegment(45, 48, "true"));
+ right.setText("shadow=true");
+ right.setOperator("=");
+
+ BinaryOperationExpression binaryOperationExpression = new BinaryOperationExpression();
+ binaryOperationExpression.setLeft(left);
+ binaryOperationExpression.setRight(right);
+ binaryOperationExpression.setOperator("and");
+ binaryOperationExpression.setText("id=? and shadow=true");
+
+ WhereSegment whereSegment = new WhereSegment(0, 0, binaryOperationExpression);
+ SelectStatement selectStatement = new SelectStatement();
+ selectStatement.setWhere(whereSegment);
+
+ return new SelectStatementContext(selectStatement, null, null, null, null);
+ }
}
diff --git a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShadowPreparedStatementTest.java b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShadowPreparedStatementTest.java
index 3bb67ff..7ecbd8c 100644
--- a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShadowPreparedStatementTest.java
+++ b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShadowPreparedStatementTest.java
@@ -51,6 +51,8 @@ public final class ShadowPreparedStatementTest extends AbstractShardingSphereDat
private static final String SHADOW_UPDATE_SQL = "UPDATE t_encrypt SET cipher_pwd = ? WHERE id = ? AND shadow = ?";
+ private static final String SHADOW_UPDATE_SQL_WITH_CONDITION = "UPDATE t_encrypt SET cipher_pwd = ? WHERE id = ? AND shadow = true";
+
@Test
public void assertInsertWithExecute() throws SQLException {
try (PreparedStatement statement = getShadowDataSource().getConnection().prepareStatement(INSERT_SQL)) {
@@ -121,6 +123,18 @@ public final class ShadowPreparedStatementTest extends AbstractShardingSphereDat
assertResultSet(true, 99, 1, "cipher_pwd");
}
+ @Test
+ public void assertShadowUpdateConditionWithExecuteUpdate() throws SQLException {
+ int result;
+ try (PreparedStatement statement = getShadowDataSource().getConnection().prepareStatement(SHADOW_UPDATE_SQL_WITH_CONDITION)) {
+ statement.setString(1, "cipher_pwd");
+ statement.setInt(2, 99);
+ result = statement.executeUpdate();
+ }
+ assertThat(result, is(1));
+ assertResultSet(true, 99, 1, "cipher_pwd");
+ }
+
private void assertResultSet(final boolean isShadow, final int resultSetCount, final Object cipherPwd) throws SQLException {
Map<String, DataSource> dataMaps = getDATABASE_TYPE_MAP().get(DatabaseTypes.getActualDatabaseType("H2"));
DataSource dataSource = isShadow ? dataMaps.get("jdbc_1") : dataMaps.get("jdbc_0");