Skip to content

Commit

Permalink
fix join condition.
Browse files Browse the repository at this point in the history
  • Loading branch information
shuo.cs committed Mar 25, 2020
1 parent ffcfb92 commit b9a7fb5
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
2 changes: 1 addition & 1 deletion core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
Expand Up @@ -3722,7 +3722,7 @@ private static RexNode pushDownEqualJoinConditions(
}
}
if (!list.equals(call.getOperands())) {
return call.clone(call.getType(), list);
return builder.makeCall(call.getOperator(), list);
}
return call;
case OR:
Expand Down
56 changes: 56 additions & 0 deletions core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
Expand Up @@ -557,6 +557,62 @@ protected DiffRepository getDiffRepos() {
SqlToRelTestBase.assertValid(output);
}

@Test public void testPushSemiJoinConditions() {
final RelBuilder relBuilder = RelBuilder.create(RelBuilderTest.config().build());
RelNode left = relBuilder.scan("EMP")
.project(
relBuilder.field("DEPTNO"),
relBuilder.field("ENAME"))
.build();
RelNode right = relBuilder.scan("DEPT")
.project(
relBuilder.field("DEPTNO"),
relBuilder.field("DNAME"))
.build();

relBuilder.push(left).push(right);

RexInputRef ref1 = relBuilder.field(2, 0, "DEPTNO");
RexInputRef ref2 = relBuilder.field(2, 1, "DEPTNO");
RexInputRef ref3 = relBuilder.field(2, 0, "ENAME");
RexInputRef ref4 = relBuilder.field(2, 1, "DNAME");

// ref1 IS NOT DISTINCT FROM ref2
RexCall cond1 = (RexCall) relBuilder.call(
SqlStdOperatorTable.OR,
relBuilder.call(SqlStdOperatorTable.EQUALS, ref1, ref2),
relBuilder.call(SqlStdOperatorTable.AND,
relBuilder.call(SqlStdOperatorTable.IS_NULL, ref1),
relBuilder.call(SqlStdOperatorTable.IS_NULL, ref2)));

// ref3 IS NOT DISTINCT FROM ref4
RexCall cond2 = (RexCall) relBuilder.call(
SqlStdOperatorTable.OR,
relBuilder.call(SqlStdOperatorTable.EQUALS, ref3, ref4),
relBuilder.call(SqlStdOperatorTable.AND,
relBuilder.call(SqlStdOperatorTable.IS_NULL, ref3),
relBuilder.call(SqlStdOperatorTable.IS_NULL, ref4)));

RexNode cond = relBuilder.call(SqlStdOperatorTable.AND, cond1, cond2);
RelNode relNode = relBuilder.semiJoin(cond)
.project(relBuilder.field(0))
.build();

HepProgram program = new HepProgramBuilder()
.addRuleInstance(JoinPushExpressionsRule.INSTANCE)
.addRuleInstance(SemiJoinProjectTransposeRule.INSTANCE)
.build();

HepPlanner hepPlanner = new HepPlanner(program);
hepPlanner.setRoot(relNode);
RelNode output = hepPlanner.findBestExp();

final String planAfter = NL + RelOptUtil.toString(output);
final DiffRepository diffRepos = getDiffRepos();
diffRepos.assertEquals("planAfter", "${planAfter}", planAfter);
SqlToRelTestBase.assertValid(output);
}

@Test public void testFullOuterJoinSimplificationToLeftOuter() {
final String sql = "select 1 from sales.dept d full outer join sales.emp e\n"
+ "on d.deptno = e.deptno\n"
Expand Down
Expand Up @@ -6754,6 +6754,18 @@ LogicalProject(EMPNO=[$0])
LogicalJoin(condition=[AND(IS NOT DISTINCT FROM($7, $8), >($0, 20))], joinType=[semi])
LogicalTableScan(table=[[scott, EMP]])
LogicalTableScan(table=[[scott, DEPT]])
]]>
</Resource>
</TestCase>
<TestCase name="testPushSemiJoinConditions">
<Resource name="planAfter">
<![CDATA[
LogicalProject(DEPTNO=[$0])
LogicalProject(DEPTNO=[$7], ENAME=[$1])
LogicalJoin(condition=[AND(IS NOT DISTINCT FROM($7, $8), IS NOT DISTINCT FROM($1, $9))], joinType=[semi])
LogicalTableScan(table=[[scott, EMP]])
LogicalProject(DEPTNO=[$0], DNAME=[$1])
LogicalTableScan(table=[[scott, DEPT]])
]]>
</Resource>
</TestCase>
Expand Down

0 comments on commit b9a7fb5

Please sign in to comment.