[SQL][Bug]Fix join Predicate transitivity bug (#4629)

This commit is contained in:
kangkaisen
2020-09-20 20:57:50 +08:00
committed by GitHub
parent 2a637f848d
commit cf91c7062a
2 changed files with 12 additions and 16 deletions

View File

@ -1421,6 +1421,11 @@ public class SingleNodePlanner {
SlotRef leftSlot = eqJoinPredicate.getChild(0).unwrapSlotRef();
SlotRef rightSlot = eqJoinPredicate.getChild(1).unwrapSlotRef();
// ensure the type is match
if (!leftSlot.getDesc().getType().matchesType(rightSlot.getDesc().getType())) {
continue;
}
// example: t1.id = t2.id and t1.id = 1 => t2.id =1
if (otherSlot.isBound(leftSlot.getSlotId()) && rightSlot.isBound(tupleId)) {
pushDownConjuncts.add(rewritePredicate(analyzer, conjunct, rightSlot));

View File

@ -673,7 +673,6 @@ public class QueryPlanTest {
"left join join2 on join1.id = join2.id\n" +
"where join1.id > 1;";
String explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "explain " + sql);
System.out.println(explainString);
Assert.assertTrue(explainString.contains("PREDICATES: `join2`.`id` > 1"));
Assert.assertTrue(explainString.contains("PREDICATES: `join1`.`id` > 1"));
@ -683,7 +682,6 @@ public class QueryPlanTest {
"left join join2 on join1.id = join2.id\n" +
"where join1.id in (2);";
explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "explain " + sql);
System.out.println(explainString);
Assert.assertTrue(explainString.contains("PREDICATES: `join2`.`id` IN (2)"));
Assert.assertTrue(explainString.contains("PREDICATES: `join1`.`id` IN (2)"));
@ -693,7 +691,6 @@ public class QueryPlanTest {
"left join join2 on join1.id = join2.id\n" +
"where join1.id BETWEEN 1 AND 2;";
explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "explain " + sql);
System.out.println(explainString);
Assert.assertTrue(explainString.contains("PREDICATES: `join1`.`id` >= 1, `join1`.`id` <= 2"));
Assert.assertTrue(explainString.contains("PREDICATES: `join2`.`id` >= 1, `join2`.`id` <= 2"));
@ -702,7 +699,6 @@ public class QueryPlanTest {
"left 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"));
@ -713,7 +709,6 @@ public class QueryPlanTest {
"left join join2 on join1.id = join2.id\n" +
"where join2.id > 1;";
explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "explain " + sql);
System.out.println(explainString);
Assert.assertTrue(explainString.contains("PREDICATES: `join1`.`id` > 1"));
Assert.assertFalse(explainString.contains("other join predicates: `join2`.`id` > 1"));
@ -722,7 +717,6 @@ public class QueryPlanTest {
"left 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"));
@ -731,7 +725,6 @@ public class QueryPlanTest {
"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.assertTrue(explainString.contains("PREDICATES: `join2`.`id` > 1"));
@ -740,7 +733,6 @@ public class QueryPlanTest {
"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"));
Assert.assertTrue(explainString.contains("PREDICATES: `join2`.`id` > 1"));
@ -749,7 +741,6 @@ public class QueryPlanTest {
"join join2 on join1.id = join2.id\n" +
"where join2.id > 1;";
explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "explain " + sql);
System.out.println(explainString);
Assert.assertTrue(explainString.contains("PREDICATES: `join1`.`id` > 1"));
Assert.assertTrue(explainString.contains("PREDICATES: `join2`.`id` > 1"));
@ -758,16 +749,21 @@ public class QueryPlanTest {
"join join2 on join1.id = join2.id\n" +
"and 1 < join2.id;";
explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "explain " + sql);
System.out.println(explainString);
Assert.assertTrue(explainString.contains("PREDICATES: `join1`.`id` > 1"));
Assert.assertTrue(explainString.contains("PREDICATES: `join2`.`id` > 1"));
sql = "select *\n from join1\n" +
"join join2 on join1.id = join2.value\n" +
"and join2.value in ('abc');";
explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "explain " + sql);
Assert.assertFalse(explainString.contains("'abc' is not a number"));
Assert.assertFalse(explainString.contains("`join1`.`value` IN ('abc')"));
// 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"));
@ -776,7 +772,6 @@ public class QueryPlanTest {
"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"));
@ -785,7 +780,6 @@ public class QueryPlanTest {
"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"));
@ -794,7 +788,6 @@ public class QueryPlanTest {
"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
@ -803,7 +796,6 @@ public class QueryPlanTest {
"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"));
@ -813,7 +805,6 @@ public class QueryPlanTest {
"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"));
}