This is an automated email from the ASF dual-hosted git repository.
morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-doris.git
The following commit(s) were added to refs/heads/master by this push:
new ca36dc6 [Bug] Fix bug that push down logic error on semi join (#3481)
ca36dc6 is described below
commit ca36dc697f0fb0fd25085cf4f01db215848ae87a
Author: Mingyu Chen <[email protected]>
AuthorDate: Thu May 7 09:30:30 2020 +0800
[Bug] Fix bug that push down logic error on semi join (#3481)
For SQL like:
```
select * from
join1 left semi join join2
on join1.id = join2.id and join2.id > 1;
```
the predicate `join2.id > 1` can not be pushed down to table join1.
---
.../java/org/apache/doris/analysis/Analyzer.java | 8 ++--
.../org/apache/doris/planner/QueryPlanTest.java | 55 ++++++++++++++++++++++
2 files changed, 60 insertions(+), 3 deletions(-)
diff --git a/fe/src/main/java/org/apache/doris/analysis/Analyzer.java
b/fe/src/main/java/org/apache/doris/analysis/Analyzer.java
index 1f565ce..dee9d93 100644
--- a/fe/src/main/java/org/apache/doris/analysis/Analyzer.java
+++ b/fe/src/main/java/org/apache/doris/analysis/Analyzer.java
@@ -956,8 +956,9 @@ public class Analyzer {
/**
- * Return all registered conjuncts that are fully bound by
- * given list of tuple ids, the eqJoinConjuncts and inclOjConjuncts is
excluded.
+ * Return all registered conjuncts that are fully bound by given list of
tuple ids.
+ * the eqJoinConjuncts and sjClauseByConjunct is excluded.
+ * This method is used get conjuncts which may be able to pushed down to
scan node.
*/
public List<Expr> getConjuncts(List<TupleId> tupleIds) {
List<Expr> result = Lists.newArrayList();
@@ -968,8 +969,9 @@ public class Analyzer {
for (Expr e : globalState.conjuncts.values()) {
if (e.isBoundByTupleIds(tupleIds)
&& !e.isAuxExpr()
- && !eqJoinConjunctIds.contains(e.getId())
+ && !eqJoinConjunctIds.contains(e.getId()) // to exclude
to conjuncts like (A.id = B.id)
&& !globalState.ojClauseByConjunct.containsKey(e.getId())
+ && !globalState.sjClauseByConjunct.containsKey(e.getId())
&& canEvalPredicate(tupleIds, e)) {
result.add(e);
}
diff --git a/fe/src/test/java/org/apache/doris/planner/QueryPlanTest.java
b/fe/src/test/java/org/apache/doris/planner/QueryPlanTest.java
index c192d18..dccd979 100644
--- a/fe/src/test/java/org/apache/doris/planner/QueryPlanTest.java
+++ b/fe/src/test/java/org/apache/doris/planner/QueryPlanTest.java
@@ -655,6 +655,61 @@ public class QueryPlanTest {
System.out.println(explainString);
Assert.assertTrue(explainString.contains("PREDICATES: `join1`.`id` >
1"));
Assert.assertTrue(explainString.contains("PREDICATES: `join2`.`id` >
1"));
+
+ // test anti join, right table join predicate, only push to right table
+ sql = "select *\n from join1\n" +
+ "left anti join join2 on join1.id = join2.id\n" +
+ "and join2.id > 1;";
+ explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext,
"explain " + sql);
+ System.out.println(explainString);
+ Assert.assertTrue(explainString.contains("PREDICATES: `join2`.`id` >
1"));
+ Assert.assertFalse(explainString.contains("PREDICATES: `join1`.`id` >
1"));
+
+ // test semi join, right table join predicate, only push to right table
+ sql = "select *\n from join1\n" +
+ "left semi join join2 on join1.id = join2.id\n" +
+ "and join2.id > 1;";
+ explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext,
"explain " + sql);
+ System.out.println(explainString);
+ Assert.assertTrue(explainString.contains("PREDICATES: `join2`.`id` >
1"));
+ Assert.assertFalse(explainString.contains("PREDICATES: `join1`.`id` >
1"));
+
+ // test anti join, left table join predicate, left table couldn't push
down
+ sql = "select *\n from join1\n" +
+ "left anti join join2 on join1.id = join2.id\n" +
+ "and join1.id > 1;";
+ explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext,
"explain " + sql);
+ System.out.println(explainString);
+ Assert.assertTrue(explainString.contains("other join predicates:
`join1`.`id` > 1"));
+ Assert.assertFalse(explainString.contains("PREDICATES: `join1`.`id` >
1"));
+
+ // test semi join, left table join predicate, only push to left table
+ sql = "select *\n from join1\n" +
+ "left semi join join2 on join1.id = join2.id\n" +
+ "and join1.id > 1;";
+ explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext,
"explain " + sql);
+ System.out.println(explainString);
+ Assert.assertTrue(explainString.contains("PREDICATES: `join1`.`id` >
1"));
+
+ // test anti join, left table where predicate, only push to left table
+ sql = "select join1.id\n" +
+ "from join1\n" +
+ "left anti join join2 on join1.id = join2.id\n" +
+ "where join1.id > 1;";
+ explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext,
"explain " + sql);
+ System.out.println(explainString);
+ Assert.assertTrue(explainString.contains("PREDICATES: `join1`.`id` >
1"));
+ Assert.assertFalse(explainString.contains("PREDICATES: `join2`.`id` >
1"));
+
+ // test semi join, left table where predicate, only push to left table
+ sql = "select join1.id\n" +
+ "from join1\n" +
+ "left semi join join2 on join1.id = join2.id\n" +
+ "where join1.id > 1;";
+ explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext,
"explain " + sql);
+ System.out.println(explainString);
+ Assert.assertTrue(explainString.contains("PREDICATES: `join1`.`id` >
1"));
+ Assert.assertFalse(explainString.contains("PREDICATES: `join2`.`id` >
1"));
}
@Test
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]