Repository: calcite
Updated Branches:
  refs/heads/master bdaa485ee -> 7cdf4d04b


[CALCITE-1850] Extend UnionMergeRule to deal with more than 2 branches 
(Pengcheng Xiong)


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/db95f5ba
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/db95f5ba
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/db95f5ba

Branch: refs/heads/master
Commit: db95f5ba8247a5c00039719e246d6ee27f04d6cf
Parents: bdaa485
Author: Pengcheng Xiong <[email protected]>
Authored: Tue Jun 20 09:30:46 2017 +0100
Committer: Jesus Camacho Rodriguez <[email protected]>
Committed: Tue Jun 20 10:58:48 2017 +0100

----------------------------------------------------------------------
 .../calcite/rel/rules/UnionMergeRule.java       |  5 +-
 .../apache/calcite/test/RelOptRulesTest.java    | 26 +++++++++
 .../org/apache/calcite/test/RelOptRulesTest.xml | 56 ++++++++++++++++++++
 3 files changed, 86 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/db95f5ba/core/src/main/java/org/apache/calcite/rel/rules/UnionMergeRule.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/calcite/rel/rules/UnionMergeRule.java 
b/core/src/main/java/org/apache/calcite/rel/rules/UnionMergeRule.java
index 71865b3..39bb474 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/UnionMergeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/UnionMergeRule.java
@@ -116,9 +116,12 @@ public class UnionMergeRule extends RelOptRule {
     // the top set-op.
     final RelBuilder relBuilder = call.builder();
     if (setOpClass.isInstance(call.rel(2))) {
-      assert topOp.getInputs().size() == 2;
       relBuilder.push(topOp.getInput(0));
       relBuilder.pushAll(bottomOp.getInputs());
+      // topOp.getInputs().size() may be more than 2
+      for (int index = 2; index < topOp.getInputs().size(); index++) {
+        relBuilder.push(topOp.getInput(index));
+      }
     } else {
       relBuilder.pushAll(bottomOp.getInputs());
       relBuilder.pushAll(Util.skip(topOp.getInputs()));

http://git-wip-us.apache.org/repos/asf/calcite/blob/db95f5ba/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 eb209e5..891ea10 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -1074,6 +1074,32 @@ public class RelOptRulesTest extends RelOptTestBase {
             + "where deptno = 10\n");
   }
 
+  /** Tests to see if the final branch of union is missed */
+  @Test
+  public void testUnionMergeRule() throws Exception {
+    HepProgram program = new HepProgramBuilder()
+            .addRuleInstance(ProjectSetOpTransposeRule.INSTANCE)
+            .addRuleInstance(ProjectRemoveRule.INSTANCE)
+            .addRuleInstance(UnionMergeRule.INSTANCE)
+            .build();
+
+    checkPlanning(program,
+            "select * from (\n"
+                    + "select * from (\n"
+                    + "  select name, deptno from dept\n"
+                    + "  union all\n"
+                    + "  select name, deptno from\n"
+                    + "  (\n"
+                    + "    select name, deptno, count(1) from dept group by 
name, deptno\n"
+                    + "    union all\n"
+                    + "    select name, deptno, count(1) from dept group by 
name, deptno\n"
+                    + "  ) subq\n"
+                    + ") a\n"
+                    + "union all\n"
+                    + "select name, deptno from dept\n"
+                    + ") aa\n");
+  }
+
   /** Tests that a filters is combined are combined if they are identical,
    * even if one of them originates in an ON clause of a JOIN. */
   @Test public void testMergeJoinFilter() throws Exception {

http://git-wip-us.apache.org/repos/asf/calcite/blob/db95f5ba/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 a042dbd..90f43f2 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -150,6 +150,62 @@ LogicalUnion(all=[false])
 ]]>
         </Resource>
     </TestCase>
+    <TestCase name="testUnionMergeRule">
+        <Resource name="sql">
+            <![CDATA[select * from (
+select * from (
+  select name, deptno from dept
+  union all
+  select name, deptno from
+  (
+    select name, deptno, count(1) from dept group by name, deptno
+    union all
+    select name, deptno, count(1) from dept group by name, deptno
+  ) subq
+) a
+union all
+select name, deptno from dept
+) aa
+]]>
+        </Resource>
+        <Resource name="planAfter">
+            <![CDATA[
+LogicalUnion(all=[true])
+  LogicalProject(NAME=[$1], DEPTNO=[$0])
+    LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+  LogicalProject(NAME=[$0], DEPTNO=[$1])
+    LogicalAggregate(group=[{0, 1}], EXPR$2=[COUNT()])
+      LogicalProject(NAME=[$1], DEPTNO=[$0], $f2=[1])
+        LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+  LogicalProject(NAME=[$0], DEPTNO=[$1])
+    LogicalAggregate(group=[{0, 1}], EXPR$2=[COUNT()])
+      LogicalProject(NAME=[$1], DEPTNO=[$0], $f2=[1])
+        LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+  LogicalProject(NAME=[$1], DEPTNO=[$0])
+    LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+]]>
+        </Resource>
+        <Resource name="planBefore">
+            <![CDATA[
+LogicalProject(NAME=[$0], DEPTNO=[$1])
+  LogicalUnion(all=[true])
+    LogicalProject(NAME=[$0], DEPTNO=[$1])
+      LogicalUnion(all=[true])
+        LogicalProject(NAME=[$1], DEPTNO=[$0])
+          LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+        LogicalProject(NAME=[$0], DEPTNO=[$1])
+          LogicalUnion(all=[true])
+            LogicalAggregate(group=[{0, 1}], EXPR$2=[COUNT()])
+              LogicalProject(NAME=[$1], DEPTNO=[$0], $f2=[1])
+                LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+            LogicalAggregate(group=[{0, 1}], EXPR$2=[COUNT()])
+              LogicalProject(NAME=[$1], DEPTNO=[$0], $f2=[1])
+                LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+    LogicalProject(NAME=[$1], DEPTNO=[$0])
+      LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+]]>
+        </Resource>
+    </TestCase>
     <TestCase name="testExtractJoinFilterRule">
         <Resource name="sql">
             <![CDATA[select 1 from emp inner join dept on 
emp.deptno=dept.deptno]]>

Reply via email to