From cf91c7062a6f99e65a0f4c2f5786f260f669bf70 Mon Sep 17 00:00:00 2001 From: kangkaisen Date: Sun, 20 Sep 2020 20:57:50 +0800 Subject: [PATCH] [SQL][Bug]Fix join Predicate transitivity bug (#4629) --- .../doris/planner/SingleNodePlanner.java | 5 ++++ .../apache/doris/planner/QueryPlanTest.java | 23 ++++++------------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java b/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java index 7621b9120f..69ae7fc07d 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java +++ b/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java @@ -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)); diff --git a/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java b/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java index b66823e41f..ffc0860b1f 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java @@ -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")); }