[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.
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user