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 1f565ceae9..dee9d933c6 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 getConjuncts(List tupleIds) { List 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 c192d18327..dccd979a23 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