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 <morningman....@gmail.com> 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: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org