This is an automated email from the ASF dual-hosted git repository.
duanzhengqiang 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 86196a9 #11397 fix bug of wrong route result (#11690)
86196a9 is described below
commit 86196a92a314a0dc4e4a1acbebbd72221f4f3c0b
Author: LiaoWenxing <[email protected]>
AuthorDate: Tue Aug 10 13:57:22 2021 +0800
#11397 fix bug of wrong route result (#11690)
---
.../parser/sql/common/util/ExpressionBuilder.java | 41 +++++++++++++++++-----
.../sql/common/util/ExpressionBuilderTest.java | 23 ++++++++++++
.../resources/scenario/sharding/case/select.xml | 6 ++++
3 files changed, 62 insertions(+), 8 deletions(-)
diff --git
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/ExpressionBuilder.java
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/ExpressionBuilder.java
index 9dba409..d446224 100644
---
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/ExpressionBuilder.java
+++
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/ExpressionBuilder.java
@@ -23,7 +23,8 @@ import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOp
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.AndPredicate;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.OrPredicateSegment;
-
+import java.util.Collection;
+import java.util.LinkedList;
import java.util.Optional;
/**
@@ -50,13 +51,7 @@ public final class ExpressionBuilder {
result.getAndPredicates().addAll(leftBuilder.extractAndPredicates().getAndPredicates());
result.getAndPredicates().addAll(rightBuilder.extractAndPredicates().getAndPredicates());
} else if (logicalOperator.isPresent() && LogicalOperator.AND ==
logicalOperator.get()) {
- ExpressionBuilder leftBuilder = new
ExpressionBuilder(((BinaryOperationExpression) expression).getLeft());
- ExpressionBuilder rightBuilder = new
ExpressionBuilder(((BinaryOperationExpression) expression).getRight());
- for (AndPredicate eachLeft :
leftBuilder.extractAndPredicates().getAndPredicates()) {
- for (AndPredicate eachRight :
rightBuilder.extractAndPredicates().getAndPredicates()) {
-
result.getAndPredicates().add(createAndPredicate(eachLeft, eachRight));
- }
- }
+ result.getAndPredicates().addAll(createAndPredicates());
} else {
AndPredicate andPredicate = new AndPredicate();
andPredicate.getPredicates().add(expression);
@@ -76,4 +71,34 @@ public final class ExpressionBuilder {
result.getPredicates().addAll(right.getPredicates());
return result;
}
+
+ private Collection<AndPredicate> createAndPredicates() {
+ Collection<AndPredicate> result = new LinkedList<>();
+ ExpressionBuilder leftBuilder = new
ExpressionBuilder(((BinaryOperationExpression) expression).getLeft());
+ ExpressionBuilder rightBuilder = new
ExpressionBuilder(((BinaryOperationExpression) expression).getRight());
+ ExpressionSegment leftExpression = ((BinaryOperationExpression)
expression).getLeft();
+ if (leftExpression instanceof BinaryOperationExpression) {
+ String leftOp = ((BinaryOperationExpression)
leftExpression).getOperator();
+ Optional<LogicalOperator> logicLeftOp =
LogicalOperator.valueFrom(leftOp);
+ if (logicLeftOp.isPresent() && LogicalOperator.OR ==
logicLeftOp.get()) {
+ ExpressionBuilder beforeOrBuilder = new
ExpressionBuilder(((BinaryOperationExpression) leftExpression).getLeft());
+ ExpressionBuilder afterOrBuilder = new
ExpressionBuilder(((BinaryOperationExpression) leftExpression).getRight());
+
result.addAll(beforeOrBuilder.extractAndPredicates().getAndPredicates());
+ result.addAll(createResultCollection(afterOrBuilder,
rightBuilder));
+ return result;
+ }
+ }
+ result.addAll(createResultCollection(leftBuilder, rightBuilder));
+ return result;
+ }
+
+ private Collection<AndPredicate> createResultCollection(final
ExpressionBuilder leftBuilder, final ExpressionBuilder rightBuilder) {
+ Collection<AndPredicate> result = new LinkedList<>();
+ for (AndPredicate eachLeft :
leftBuilder.extractAndPredicates().getAndPredicates()) {
+ for (AndPredicate eachRight :
rightBuilder.extractAndPredicates().getAndPredicates()) {
+ result.add(createAndPredicate(eachLeft, eachRight));
+ }
+ }
+ return result;
+ }
}
diff --git
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/util/ExpressionBuilderTest.java
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/util/ExpressionBuilderTest.java
index 1c2e6a0..2f7316b 100644
---
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/util/ExpressionBuilderTest.java
+++
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/util/ExpressionBuilderTest.java
@@ -82,4 +82,27 @@ public final class ExpressionBuilderTest {
assertThat(andPredicate2.getPredicates().iterator().next(),
is(expressionSegment2));
}
+
+ @Test
+ public void assertExtractAndPredicatesOrAndCondition() {
+ ColumnSegment columnSegment1 = new ColumnSegment(28, 33, new
IdentifierValue("status"));
+ ParameterMarkerExpressionSegment parameterMarkerExpressionSegment1 =
new ParameterMarkerExpressionSegment(35, 35, 0);
+ ExpressionSegment expressionSegment1 = new
BinaryOperationExpression(28, 39, columnSegment1,
parameterMarkerExpressionSegment1, "=", "status=?");
+ ColumnSegment columnSegment2 = new ColumnSegment(40, 45, new
IdentifierValue("status"));
+ ParameterMarkerExpressionSegment parameterMarkerExpressionSegment2 =
new ParameterMarkerExpressionSegment(47, 47, 1);
+ ExpressionSegment expressionSegment2 = new
BinaryOperationExpression(40, 47, columnSegment2,
parameterMarkerExpressionSegment2, "=", "status=?");
+ BinaryOperationExpression expressionOr = new
BinaryOperationExpression(28, 47, expressionSegment1, expressionSegment2, "OR",
"status=? OR status=?");
+ ColumnSegment columnSegment3 = new ColumnSegment(53, 57, new
IdentifierValue("count"));
+ ParameterMarkerExpressionSegment parameterMarkerExpressionSegment3 =
new ParameterMarkerExpressionSegment(59, 59, 2);
+ ExpressionSegment expressionSegment3 = new
BinaryOperationExpression(53, 59, columnSegment3,
parameterMarkerExpressionSegment3, "=", "count=?");
+ BinaryOperationExpression expression = new
BinaryOperationExpression(28, 59, expressionOr, expressionSegment3, "AND",
"status=? OR status=? AND count=?");
+ ExpressionBuilder expressionBuilder = new
ExpressionBuilder(expression);
+ OrPredicateSegment result = expressionBuilder.extractAndPredicates();
+ Iterator<AndPredicate> andPredicateIterator =
result.getAndPredicates().iterator();
+ AndPredicate andPredicate1 = andPredicateIterator.next();
+ AndPredicate andPredicate2 = andPredicateIterator.next();
+ assertThat(result.getAndPredicates().size(), is(2));
+ assertThat(andPredicate1.getPredicates().size(), is(1));
+ assertThat(andPredicate2.getPredicates().size(), is(2));
+ }
}
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 ebde0f0..c59a811 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
@@ -486,4 +486,10 @@
<input sql="SELECT * FROM t_user JOIN t_user_extend ON t_user.id =
t_user_extend.user_id WHERE t_user_extend.user_id = ?" parameters="1"/>
<output sql="SELECT * FROM t_user_1 JOIN t_user_extend_1 ON
t_user_1.id = t_user_extend_1.user_id WHERE t_user_extend_1.user_id = ?"
parameters="1"/>
</rewrite-assertion>
+
+ <rewrite-assertion id="select_with_or_and_condition">
+ <input sql="SELECT * FROM t_account WHERE amount=? OR amount=? AND
account_id=?" parameters="1, 2, 3"/>
+ <output sql="SELECT * FROM t_account_0 WHERE amount=? OR amount=? AND
account_id=?" parameters="1, 2, 3"/>
+ <output sql="SELECT * FROM t_account_1 WHERE amount=? OR amount=? AND
account_id=?" parameters="1, 2, 3"/>
+ </rewrite-assertion>
</rewrite-assertions>