You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2015/09/03 00:16:23 UTC
[35/50] incubator-calcite git commit: [CALCITE-811] Extend
JoinProjectTransposeRule with option to support outer joins
[CALCITE-811] Extend JoinProjectTransposeRule with option to support outer joins
Close apache/incubator-calcite#109
Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/2376ae4a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/2376ae4a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/2376ae4a
Branch: refs/heads/branch-release
Commit: 2376ae4a876b421ee19c2b2a05a6bd1d306e442b
Parents: 5cb95e6
Author: Jesus Camacho Rodriguez <jc...@apache.org>
Authored: Mon Jul 27 19:41:36 2015 +0100
Committer: Jesus Camacho Rodriguez <jc...@apache.org>
Committed: Mon Jul 27 19:48:48 2015 +0100
----------------------------------------------------------------------
.../rel/rules/JoinProjectTransposeRule.java | 61 +++++++++++++++++---
.../apache/calcite/test/RelOptRulesTest.java | 24 ++++++++
.../org/apache/calcite/test/RelOptRulesTest.xml | 31 ++++++++++
3 files changed, 107 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2376ae4a/core/src/main/java/org/apache/calcite/rel/rules/JoinProjectTransposeRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/JoinProjectTransposeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/JoinProjectTransposeRule.java
index 2f41648..afcea6b 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/JoinProjectTransposeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/JoinProjectTransposeRule.java
@@ -75,20 +75,52 @@ public class JoinProjectTransposeRule extends RelOptRule {
operand(LogicalProject.class, any())),
"JoinProjectTransposeRule(Other-Project)");
+ public static final JoinProjectTransposeRule BOTH_PROJECT_INCLUDE_OUTER =
+ new JoinProjectTransposeRule(
+ operand(LogicalJoin.class,
+ operand(LogicalProject.class, any()),
+ operand(LogicalProject.class, any())),
+ "Join(IncludingOuter)ProjectTransposeRule(Project-Project)",
+ true, RelFactories.DEFAULT_PROJECT_FACTORY);
+
+ public static final JoinProjectTransposeRule LEFT_PROJECT_INCLUDE_OUTER =
+ new JoinProjectTransposeRule(
+ operand(LogicalJoin.class,
+ some(operand(LogicalProject.class, any()))),
+ "Join(IncludingOuter)ProjectTransposeRule(Project-Other)",
+ true, RelFactories.DEFAULT_PROJECT_FACTORY);
+
+ public static final JoinProjectTransposeRule RIGHT_PROJECT_INCLUDE_OUTER =
+ new JoinProjectTransposeRule(
+ operand(
+ LogicalJoin.class,
+ operand(RelNode.class, any()),
+ operand(LogicalProject.class, any())),
+ "Join(IncludingOuter)ProjectTransposeRule(Other-Project)",
+ true, RelFactories.DEFAULT_PROJECT_FACTORY);
+
+ private final boolean includeOuter;
private final ProjectFactory projectFactory;
//~ Constructors -----------------------------------------------------------
public JoinProjectTransposeRule(
RelOptRuleOperand operand,
String description) {
- this(operand, description, RelFactories.DEFAULT_PROJECT_FACTORY);
+ this(operand, description, false, RelFactories.DEFAULT_PROJECT_FACTORY);
}
- public JoinProjectTransposeRule(
- RelOptRuleOperand operand,
- String description, ProjectFactory pFactory) {
+ @Deprecated
+ public JoinProjectTransposeRule(RelOptRuleOperand operand,
+ String description, ProjectFactory projectFactory) {
+ this(operand, description, false, projectFactory);
+ }
+
+ public JoinProjectTransposeRule(RelOptRuleOperand operand,
+ String description, boolean includeOuter,
+ ProjectFactory projectFactory) {
super(operand, description);
- projectFactory = pFactory;
+ this.includeOuter = includeOuter;
+ this.projectFactory = projectFactory;
}
//~ Methods ----------------------------------------------------------------
@@ -103,15 +135,18 @@ public class JoinProjectTransposeRule extends RelOptRule {
RelNode leftJoinChild;
RelNode rightJoinChild;
- // see if at least one input's projection doesn't generate nulls
- if (hasLeftChild(call) && !joinType.generatesNullsOnLeft()) {
+ // If 1) the rule works on outer joins, or
+ // 2) input's projection doesn't generate nulls
+ if (hasLeftChild(call)
+ && (includeOuter || !joinType.generatesNullsOnLeft())) {
leftProj = call.rel(1);
leftJoinChild = getProjectChild(call, leftProj, true);
} else {
leftProj = null;
leftJoinChild = call.rel(1);
}
- if (hasRightChild(call) && !joinType.generatesNullsOnRight()) {
+ if (hasRightChild(call)
+ && (includeOuter || !joinType.generatesNullsOnRight())) {
rightProj = getRightChild(call);
rightJoinChild = getProjectChild(call, rightProj, false);
} else {
@@ -235,6 +270,14 @@ public class JoinProjectTransposeRule extends RelOptRule {
// finally, create the projection on top of the join
RelNode newProjRel = projectFactory.createProject(newJoinRel, newProjExprs,
joinRel.getRowType().getFieldNames());
+ // if the join was outer, we might need a cast after the
+ // projection to fix differences wrt nullability of fields
+ if (joinType != JoinRelType.INNER) {
+ RelNode newTopProjRel = RelOptUtil.createCastRel(newProjRel, joinRel.getRowType(),
+ false, projectFactory);
+ call.transformTo(newTopProjRel);
+ return;
+ }
call.transformTo(newProjRel);
}
@@ -294,7 +337,7 @@ public class JoinProjectTransposeRule extends RelOptRule {
* removed)
* @param projects Projection expressions & names to be created
*/
- private void createProjectExprs(
+ protected void createProjectExprs(
Project projRel,
RelNode joinChild,
int adjustmentAmount,
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2376ae4a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
index 1901f89..013405c 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -51,6 +51,7 @@ import org.apache.calcite.rel.rules.FilterToCalcRule;
import org.apache.calcite.rel.rules.JoinAddRedundantSemiJoinRule;
import org.apache.calcite.rel.rules.JoinCommuteRule;
import org.apache.calcite.rel.rules.JoinExtractFilterRule;
+import org.apache.calcite.rel.rules.JoinProjectTransposeRule;
import org.apache.calcite.rel.rules.JoinPushTransitivePredicatesRule;
import org.apache.calcite.rel.rules.JoinToMultiJoinRule;
import org.apache.calcite.rel.rules.JoinUnionTransposeRule;
@@ -296,6 +297,29 @@ public class RelOptRulesTest extends RelOptTestBase {
+ "right join dept c on b.deptno > 10\n");
}
+ @Test public void testJoinProjectTranspose() {
+ final HepProgram preProgram =
+ HepProgram.builder()
+ .addRuleInstance(ProjectJoinTransposeRule.INSTANCE)
+ .addRuleInstance(ProjectMergeRule.INSTANCE)
+ .build();
+ final HepProgram program =
+ HepProgram.builder()
+ .addRuleInstance(JoinProjectTransposeRule.LEFT_PROJECT_INCLUDE_OUTER)
+ .addRuleInstance(ProjectMergeRule.INSTANCE)
+ .addRuleInstance(JoinProjectTransposeRule.RIGHT_PROJECT_INCLUDE_OUTER)
+ .addRuleInstance(JoinProjectTransposeRule.LEFT_PROJECT_INCLUDE_OUTER)
+ .addRuleInstance(ProjectMergeRule.INSTANCE)
+ .build();
+ checkPlanning(tester,
+ preProgram,
+ new HepPlanner(program),
+ "select a.name\n"
+ + "from dept a\n"
+ + "left join dept b on b.deptno > 10\n"
+ + "right join dept c on b.deptno > 10\n");
+ }
+
@Test public void testSemiJoinRule() {
final HepProgram preProgram =
HepProgram.builder()
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2376ae4a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
index 04d0fe2..bd650ce 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -3255,6 +3255,37 @@ LogicalProject(NAME=[$1])
]]>
</Resource>
</TestCase>
+ <TestCase name="testJoinProjectTranspose">
+ <Resource name="sql">
+ <![CDATA[select a.name
+from dept a
+left join dept b on b.deptno > 10
+right join dept c on b.deptno > 10
+]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalProject(NAME=[$1])
+ LogicalJoin(condition=[$4], joinType=[right])
+ LogicalProject(DEPTNO=[$0], NAME=[$1], DEPTNO0=[$2], NAME0=[$3], $f4=[>($2, 10)])
+ LogicalJoin(condition=[$4], joinType=[left])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+ LogicalProject(DEPTNO=[$0], NAME=[$1], $f2=[>($0, 10)])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+LogicalProject(NAME=[$1])
+ LogicalJoin(condition=[>($2, 10)], joinType=[right])
+ LogicalJoin(condition=[>($2, 10)], joinType=[left])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+]]>
+ </Resource>
+ </TestCase>
<TestCase name="testMergeFilter">
<Resource name="sql">
<![CDATA[select name from (