diff --git a/itests/src/test/resources/testconfiguration.properties b/itests/src/test/resources/testconfiguration.properties index 8c4d9b7de7..7aad679fc3 100644 --- a/itests/src/test/resources/testconfiguration.properties +++ b/itests/src/test/resources/testconfiguration.properties @@ -767,6 +767,7 @@ minillaplocal.query.files=\ tez_union_multiinsert.q,\ tez_vector_dynpart_hashjoin_1.q,\ tez_vector_dynpart_hashjoin_2.q,\ + transitive_not_null.q,\ truncate_external_force.q,\ uber_reduce.q,\ udaf_collect_set_2.q,\ diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveJoinAddNotNullRule.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveJoinAddNotNullRule.java index 9711625016..e4bd29515d 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveJoinAddNotNullRule.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveJoinAddNotNullRule.java @@ -26,7 +26,6 @@ import org.apache.calcite.plan.RelOptRuleCall; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.core.Join; -import org.apache.calcite.rel.core.JoinRelType; import org.apache.calcite.rel.core.RelFactories; import org.apache.calcite.rel.core.RelFactories.FilterFactory; import org.apache.calcite.rex.RexBuilder; @@ -76,14 +75,31 @@ public void onMatch(RelOptRuleCall call) { HiveRulesRegistry registry = call.getPlanner().getContext().unwrap(HiveRulesRegistry.class); assert registry != null; - if (join.getJoinType() != JoinRelType.INNER) { - return; - } if (join.getCondition().isAlwaysTrue()) { return; } + boolean genPredOnLeftSide=false, genPredOnRightSide=false; + + switch(join.getJoinType()) { + case INNER: + genPredOnLeftSide = true; + genPredOnRightSide = true; + break; + case LEFT: + genPredOnLeftSide = false; + genPredOnRightSide = true; + break; + case RIGHT: + genPredOnLeftSide = true; + genPredOnRightSide = false; + break; + default: + genPredOnLeftSide = false; + genPredOnRightSide = false; + } + JoinPredicateInfo joinPredInfo; try { joinPredInfo = HiveCalciteUtil.JoinPredicateInfo.constructJoinPredicateInfo(join); @@ -102,26 +118,43 @@ public void onMatch(RelOptRuleCall call) { final RelOptCluster cluster = join.getCluster(); final RexBuilder rexBuilder = join.getCluster().getRexBuilder(); + + RexNode newLeftPredicate = null, newRightPredicate = null; + // generate predicate on left side Set leftPushedPredicates = Sets.newHashSet(registry.getPushedPredicates(join, 0)); - final List newLeftConditions = getNotNullConditions(cluster, - rexBuilder, leftJoinExprsList, leftPushedPredicates); + if(genPredOnLeftSide) { + List newLeftConditions = getNotNullConditions(cluster, + rexBuilder, leftJoinExprsList, leftPushedPredicates); + newLeftPredicate = RexUtil.composeConjunction(rexBuilder, newLeftConditions, false); + } + + // generate predicate on right side Set rightPushedPredicates = Sets.newHashSet(registry.getPushedPredicates(join, 1)); - final List newRightConditions = getNotNullConditions(cluster, - rexBuilder, rightJoinExprsList, rightPushedPredicates); + if (genPredOnRightSide) { + List newRightConditions = getNotNullConditions(cluster, + rexBuilder, rightJoinExprsList, rightPushedPredicates); + newRightPredicate = RexUtil.composeConjunction(rexBuilder, newRightConditions, false); + } - // Nothing will be added to the expression - RexNode newLeftPredicate = RexUtil.composeConjunction(rexBuilder, newLeftConditions, false); - RexNode newRightPredicate = RexUtil.composeConjunction(rexBuilder, newRightConditions, false); - if (newLeftPredicate.isAlwaysTrue() && newRightPredicate.isAlwaysTrue()) { - return; + boolean isNewLeftPredicateAlwaysTrue = false, isNewRightPredAlwaysTrue = false; + + if (newLeftPredicate != null && newLeftPredicate.isAlwaysTrue()){ + isNewLeftPredicateAlwaysTrue = true; + } + if (newRightPredicate != null && newRightPredicate.isAlwaysTrue()){ + isNewRightPredAlwaysTrue = true; } - if (!newLeftPredicate.isAlwaysTrue()) { + if(isNewLeftPredicateAlwaysTrue && isNewRightPredAlwaysTrue) { + return ; + } + + if (!isNewLeftPredicateAlwaysTrue && newLeftPredicate != null){ RelNode curr = lChild; lChild = filterFactory.createFilter(lChild, newLeftPredicate); call.getPlanner().onCopy(curr, lChild); } - if (!newRightPredicate.isAlwaysTrue()) { + if (!isNewRightPredAlwaysTrue && newRightPredicate != null) { RelNode curr = rChild; rChild = filterFactory.createFilter(rChild, newRightPredicate); call.getPlanner().onCopy(curr, rChild); @@ -152,5 +185,4 @@ public void onMatch(RelOptRuleCall call) { } return newConditions; } - -} +} \ No newline at end of file diff --git a/ql/src/test/queries/clientpositive/transitive_not_null.q b/ql/src/test/queries/clientpositive/transitive_not_null.q new file mode 100644 index 0000000000..e5fb710e23 --- /dev/null +++ b/ql/src/test/queries/clientpositive/transitive_not_null.q @@ -0,0 +1,53 @@ +create table tbl_1(i1 int, j1 int); +insert into tbl_1 values(1,2),(1,null), (null, 200), (45,68); +create table tbl_2(i2 int, j2 int); +insert into tbl_2 values(1,2),(1,null), (null, 200), (45,68); + +-- simple join +explain cbo select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2; +select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2; + +explain cbo select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2; +select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2; + +explain cbo select * from tbl_1 full outer join tbl_2 on tbl_1.i1 = tbl_2.i2; +select * from tbl_1 full outer join tbl_2 on tbl_1.i1 = tbl_2.i2; + +-- conjunction +explain cbo select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1=tbl_2.j2; +select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1=tbl_2.j2; + +explain cbo select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1=tbl_2.j2; +select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1=tbl_2.j2; + +-- equi + non-equi +explain cbo select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1>tbl_2.j2; +select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1>tbl_2.j2; + +explain cbo select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1>tbl_2.j2; +select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1>tbl_2.j2; + +explain cbo SELECT t0.col0, t0.col1 +FROM + ( + SELECT i1 as col0, j1 as col1 FROM tbl_1 + ) AS t0 + LEFT JOIN + ( + SELECT i2 as col0, j2 as col1 FROM tbl_2 + ) AS t1 +ON t0.col0 = t1.col0 AND t0.col1 = t1.col1; + +SELECT t0.col0, t0.col1 +FROM + ( + SELECT i1 as col0, j1 as col1 FROM tbl_1 + ) AS t0 + LEFT JOIN + ( + SELECT i2 as col0, j2 as col1 FROM tbl_2 + ) AS t1 +ON t0.col0 = t1.col0 AND t0.col1 = t1.col1; + +DROP TABLE tbl_1; +DROP TABLE tbl_2; diff --git a/ql/src/test/results/clientpositive/llap/transitive_not_null.q.out b/ql/src/test/results/clientpositive/llap/transitive_not_null.q.out new file mode 100644 index 0000000000..a0089ac631 --- /dev/null +++ b/ql/src/test/results/clientpositive/llap/transitive_not_null.q.out @@ -0,0 +1,351 @@ +PREHOOK: query: create table tbl_1(i1 int, j1 int) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@tbl_1 +POSTHOOK: query: create table tbl_1(i1 int, j1 int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@tbl_1 +PREHOOK: query: insert into tbl_1 values(1,2),(1,null), (null, 200), (45,68) +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +PREHOOK: Output: default@tbl_1 +POSTHOOK: query: insert into tbl_1 values(1,2),(1,null), (null, 200), (45,68) +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +POSTHOOK: Output: default@tbl_1 +POSTHOOK: Lineage: tbl_1.i1 SCRIPT [] +POSTHOOK: Lineage: tbl_1.j1 SCRIPT [] +PREHOOK: query: create table tbl_2(i2 int, j2 int) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@tbl_2 +POSTHOOK: query: create table tbl_2(i2 int, j2 int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@tbl_2 +PREHOOK: query: insert into tbl_2 values(1,2),(1,null), (null, 200), (45,68) +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +PREHOOK: Output: default@tbl_2 +POSTHOOK: query: insert into tbl_2 values(1,2),(1,null), (null, 200), (45,68) +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +POSTHOOK: Output: default@tbl_2 +POSTHOOK: Lineage: tbl_2.i2 SCRIPT [] +POSTHOOK: Lineage: tbl_2.j2 SCRIPT [] +PREHOOK: query: explain cbo select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2 +PREHOOK: type: QUERY +PREHOOK: Input: default@tbl_1 +PREHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +POSTHOOK: query: explain cbo select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@tbl_1 +POSTHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +CBO PLAN: +HiveJoin(condition=[=($0, $2)], joinType=[left], algorithm=[none], cost=[not available]) + HiveProject(i1=[$0], j1=[$1]) + HiveTableScan(table=[[default, tbl_1]], table:alias=[tbl_1]) + HiveProject(i2=[$0], j2=[$1]) + HiveFilter(condition=[IS NOT NULL($0)]) + HiveTableScan(table=[[default, tbl_2]], table:alias=[tbl_2]) + +PREHOOK: query: select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2 +PREHOOK: type: QUERY +PREHOOK: Input: default@tbl_1 +PREHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +POSTHOOK: query: select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@tbl_1 +POSTHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +NULL 200 NULL NULL +1 2 1 2 +1 2 1 NULL +1 NULL 1 2 +1 NULL 1 NULL +45 68 45 68 +PREHOOK: query: explain cbo select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2 +PREHOOK: type: QUERY +PREHOOK: Input: default@tbl_1 +PREHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +POSTHOOK: query: explain cbo select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@tbl_1 +POSTHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +CBO PLAN: +HiveJoin(condition=[=($0, $2)], joinType=[right], algorithm=[none], cost=[not available]) + HiveProject(i1=[$0], j1=[$1]) + HiveFilter(condition=[IS NOT NULL($0)]) + HiveTableScan(table=[[default, tbl_1]], table:alias=[tbl_1]) + HiveProject(i2=[$0], j2=[$1]) + HiveTableScan(table=[[default, tbl_2]], table:alias=[tbl_2]) + +PREHOOK: query: select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2 +PREHOOK: type: QUERY +PREHOOK: Input: default@tbl_1 +PREHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +POSTHOOK: query: select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@tbl_1 +POSTHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +NULL NULL NULL 200 +1 2 1 2 +1 2 1 NULL +1 NULL 1 2 +1 NULL 1 NULL +45 68 45 68 +PREHOOK: query: explain cbo select * from tbl_1 full outer join tbl_2 on tbl_1.i1 = tbl_2.i2 +PREHOOK: type: QUERY +PREHOOK: Input: default@tbl_1 +PREHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +POSTHOOK: query: explain cbo select * from tbl_1 full outer join tbl_2 on tbl_1.i1 = tbl_2.i2 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@tbl_1 +POSTHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +CBO PLAN: +HiveJoin(condition=[=($0, $2)], joinType=[full], algorithm=[none], cost=[not available]) + HiveProject(i1=[$0], j1=[$1]) + HiveTableScan(table=[[default, tbl_1]], table:alias=[tbl_1]) + HiveProject(i2=[$0], j2=[$1]) + HiveTableScan(table=[[default, tbl_2]], table:alias=[tbl_2]) + +PREHOOK: query: select * from tbl_1 full outer join tbl_2 on tbl_1.i1 = tbl_2.i2 +PREHOOK: type: QUERY +PREHOOK: Input: default@tbl_1 +PREHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +POSTHOOK: query: select * from tbl_1 full outer join tbl_2 on tbl_1.i1 = tbl_2.i2 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@tbl_1 +POSTHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +NULL NULL NULL 200 +NULL 200 NULL NULL +1 2 1 2 +1 2 1 NULL +1 NULL 1 2 +1 NULL 1 NULL +45 68 45 68 +PREHOOK: query: explain cbo select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1=tbl_2.j2 +PREHOOK: type: QUERY +PREHOOK: Input: default@tbl_1 +PREHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +POSTHOOK: query: explain cbo select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1=tbl_2.j2 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@tbl_1 +POSTHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +CBO PLAN: +HiveJoin(condition=[AND(=($0, $2), =($1, $3))], joinType=[left], algorithm=[none], cost=[not available]) + HiveProject(i1=[$0], j1=[$1]) + HiveTableScan(table=[[default, tbl_1]], table:alias=[tbl_1]) + HiveProject(i2=[$0], j2=[$1]) + HiveFilter(condition=[AND(IS NOT NULL($0), IS NOT NULL($1))]) + HiveTableScan(table=[[default, tbl_2]], table:alias=[tbl_2]) + +PREHOOK: query: select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1=tbl_2.j2 +PREHOOK: type: QUERY +PREHOOK: Input: default@tbl_1 +PREHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +POSTHOOK: query: select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1=tbl_2.j2 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@tbl_1 +POSTHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +NULL 200 NULL NULL +1 NULL NULL NULL +1 2 1 2 +45 68 45 68 +PREHOOK: query: explain cbo select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1=tbl_2.j2 +PREHOOK: type: QUERY +PREHOOK: Input: default@tbl_1 +PREHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +POSTHOOK: query: explain cbo select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1=tbl_2.j2 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@tbl_1 +POSTHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +CBO PLAN: +HiveJoin(condition=[AND(=($0, $2), =($1, $3))], joinType=[right], algorithm=[none], cost=[not available]) + HiveProject(i1=[$0], j1=[$1]) + HiveFilter(condition=[AND(IS NOT NULL($0), IS NOT NULL($1))]) + HiveTableScan(table=[[default, tbl_1]], table:alias=[tbl_1]) + HiveProject(i2=[$0], j2=[$1]) + HiveTableScan(table=[[default, tbl_2]], table:alias=[tbl_2]) + +PREHOOK: query: select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1=tbl_2.j2 +PREHOOK: type: QUERY +PREHOOK: Input: default@tbl_1 +PREHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +POSTHOOK: query: select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1=tbl_2.j2 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@tbl_1 +POSTHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +NULL NULL NULL 200 +NULL NULL 1 NULL +1 2 1 2 +45 68 45 68 +PREHOOK: query: explain cbo select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1>tbl_2.j2 +PREHOOK: type: QUERY +PREHOOK: Input: default@tbl_1 +PREHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +POSTHOOK: query: explain cbo select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1>tbl_2.j2 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@tbl_1 +POSTHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +CBO PLAN: +HiveJoin(condition=[AND(=($0, $2), >($1, $3))], joinType=[left], algorithm=[none], cost=[not available]) + HiveProject(i1=[$0], j1=[$1]) + HiveTableScan(table=[[default, tbl_1]], table:alias=[tbl_1]) + HiveProject(i2=[$0], j2=[$1]) + HiveFilter(condition=[IS NOT NULL($0)]) + HiveTableScan(table=[[default, tbl_2]], table:alias=[tbl_2]) + +PREHOOK: query: select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1>tbl_2.j2 +PREHOOK: type: QUERY +PREHOOK: Input: default@tbl_1 +PREHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +POSTHOOK: query: select * from tbl_1 left join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1>tbl_2.j2 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@tbl_1 +POSTHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +NULL 200 NULL NULL +1 2 NULL NULL +1 NULL NULL NULL +45 68 NULL NULL +PREHOOK: query: explain cbo select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1>tbl_2.j2 +PREHOOK: type: QUERY +PREHOOK: Input: default@tbl_1 +PREHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +POSTHOOK: query: explain cbo select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1>tbl_2.j2 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@tbl_1 +POSTHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +CBO PLAN: +HiveJoin(condition=[AND(=($0, $2), >($1, $3))], joinType=[right], algorithm=[none], cost=[not available]) + HiveProject(i1=[$0], j1=[$1]) + HiveFilter(condition=[IS NOT NULL($0)]) + HiveTableScan(table=[[default, tbl_1]], table:alias=[tbl_1]) + HiveProject(i2=[$0], j2=[$1]) + HiveTableScan(table=[[default, tbl_2]], table:alias=[tbl_2]) + +PREHOOK: query: select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1>tbl_2.j2 +PREHOOK: type: QUERY +PREHOOK: Input: default@tbl_1 +PREHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +POSTHOOK: query: select * from tbl_1 right join tbl_2 on tbl_1.i1 = tbl_2.i2 AND tbl_1.j1>tbl_2.j2 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@tbl_1 +POSTHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +NULL NULL NULL 200 +NULL NULL 1 2 +NULL NULL 1 NULL +NULL NULL 45 68 +PREHOOK: query: explain cbo SELECT t0.col0, t0.col1 +FROM + ( + SELECT i1 as col0, j1 as col1 FROM tbl_1 + ) AS t0 + LEFT JOIN + ( + SELECT i2 as col0, j2 as col1 FROM tbl_2 + ) AS t1 +ON t0.col0 = t1.col0 AND t0.col1 = t1.col1 +PREHOOK: type: QUERY +PREHOOK: Input: default@tbl_1 +PREHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +POSTHOOK: query: explain cbo SELECT t0.col0, t0.col1 +FROM + ( + SELECT i1 as col0, j1 as col1 FROM tbl_1 + ) AS t0 + LEFT JOIN + ( + SELECT i2 as col0, j2 as col1 FROM tbl_2 + ) AS t1 +ON t0.col0 = t1.col0 AND t0.col1 = t1.col1 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@tbl_1 +POSTHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +CBO PLAN: +HiveProject(col0=[$0], col1=[$1]) + HiveJoin(condition=[AND(=($0, $2), =($1, $3))], joinType=[left], algorithm=[none], cost=[not available]) + HiveProject(i1=[$0], j1=[$1]) + HiveTableScan(table=[[default, tbl_1]], table:alias=[tbl_1]) + HiveProject(i2=[$0], j2=[$1]) + HiveFilter(condition=[AND(IS NOT NULL($0), IS NOT NULL($1))]) + HiveTableScan(table=[[default, tbl_2]], table:alias=[tbl_2]) + +PREHOOK: query: SELECT t0.col0, t0.col1 +FROM + ( + SELECT i1 as col0, j1 as col1 FROM tbl_1 + ) AS t0 + LEFT JOIN + ( + SELECT i2 as col0, j2 as col1 FROM tbl_2 + ) AS t1 +ON t0.col0 = t1.col0 AND t0.col1 = t1.col1 +PREHOOK: type: QUERY +PREHOOK: Input: default@tbl_1 +PREHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +POSTHOOK: query: SELECT t0.col0, t0.col1 +FROM + ( + SELECT i1 as col0, j1 as col1 FROM tbl_1 + ) AS t0 + LEFT JOIN + ( + SELECT i2 as col0, j2 as col1 FROM tbl_2 + ) AS t1 +ON t0.col0 = t1.col0 AND t0.col1 = t1.col1 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@tbl_1 +POSTHOOK: Input: default@tbl_2 +#### A masked pattern was here #### +NULL 200 +1 NULL +1 2 +45 68 +PREHOOK: query: DROP TABLE tbl_1 +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@tbl_1 +PREHOOK: Output: default@tbl_1 +POSTHOOK: query: DROP TABLE tbl_1 +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@tbl_1 +POSTHOOK: Output: default@tbl_1 +PREHOOK: query: DROP TABLE tbl_2 +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@tbl_2 +PREHOOK: Output: default@tbl_2 +POSTHOOK: query: DROP TABLE tbl_2 +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@tbl_2 +POSTHOOK: Output: default@tbl_2