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 2014/12/17 21:45:11 UTC

incubator-calcite git commit: [CALCITE-513] Support for grouping sets in AggregateProjectMergeRule (Jesus Camacho Rodriguez)

Repository: incubator-calcite
Updated Branches:
  refs/heads/master 615a3c629 -> 2b3581923


[CALCITE-513] Support for grouping sets in AggregateProjectMergeRule (Jesus Camacho Rodriguez)

Close apache/incubator-calcite#29


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

Branch: refs/heads/master
Commit: 2b35819237e35cf93688527f7cb7f44998a77125
Parents: 615a3c6
Author: Jesus Camacho Rodriguez <jc...@hortonworks.com>
Authored: Wed Dec 10 17:07:17 2014 +0100
Committer: Julian Hyde <jh...@apache.org>
Committed: Wed Dec 17 12:06:08 2014 -0800

----------------------------------------------------------------------
 .../rel/rules/AggregateProjectMergeRule.java    | 33 +++++++++++++++++---
 .../apache/calcite/test/RelOptRulesTest.java    | 12 +++++++
 .../org/apache/calcite/test/RelOptRulesTest.xml | 27 ++++++++++++++++
 3 files changed, 67 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2b358192/core/src/main/java/org/apache/calcite/rel/rules/AggregateProjectMergeRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AggregateProjectMergeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AggregateProjectMergeRule.java
index ebb882a..f017ec6 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/AggregateProjectMergeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/AggregateProjectMergeRule.java
@@ -51,7 +51,7 @@ public class AggregateProjectMergeRule extends RelOptRule {
   /** Private constructor. */
   private AggregateProjectMergeRule() {
     super(
-        operand(Aggregate.class, null, Aggregate.IS_SIMPLE,
+        operand(Aggregate.class,
             operand(Project.class, any())));
   }
 
@@ -77,6 +77,23 @@ public class AggregateProjectMergeRule extends RelOptRule {
       }
     }
 
+    final ImmutableBitSet newGroupSet = ImmutableBitSet.of(newKeys);
+
+    ImmutableList<ImmutableBitSet> newGroupingSets = null;
+    if (aggregate.indicator) {
+      ImmutableList.Builder<ImmutableBitSet> newGroupingSetsBuilder =
+              ImmutableList.builder();
+      for (ImmutableBitSet groupingSet: aggregate.getGroupSets()) {
+        final ImmutableBitSet.Builder newGroupingSet =
+                ImmutableBitSet.builder();
+        for (int c : groupingSet) {
+          newGroupingSet.set(newKeys.get(c));
+        }
+        newGroupingSetsBuilder.add(newGroupingSet.build());
+      }
+      newGroupingSets = newGroupingSetsBuilder.build();
+    }
+
     final ImmutableList.Builder<AggregateCall> aggCalls =
         ImmutableList.builder();
     for (AggregateCall aggregateCall : aggregate.getAggCallList()) {
@@ -93,10 +110,10 @@ public class AggregateProjectMergeRule extends RelOptRule {
       aggCalls.add(aggregateCall.copy(newArgs.build()));
     }
 
-    final ImmutableBitSet newGroupSet = ImmutableBitSet.of(newKeys);
     final Aggregate newAggregate =
-        aggregate.copy(aggregate.getTraitSet(), project.getInput(), false,
-            newGroupSet, null, aggCalls.build());
+        aggregate.copy(aggregate.getTraitSet(), project.getInput(),
+            aggregate.indicator, newGroupSet, newGroupingSets,
+            aggCalls.build());
 
     // Add a project if the group set is not in the same order or
     // contains duplicates.
@@ -106,7 +123,13 @@ public class AggregateProjectMergeRule extends RelOptRule {
       for (int newKey : newKeys) {
         posList.add(newGroupSet.indexOf(newKey));
       }
-      for (int i = newAggregate.getGroupSet().cardinality();
+      if (aggregate.indicator) {
+        for (int newKey : newKeys) {
+          posList.add(aggregate.getGroupCount() + newGroupSet.indexOf(newKey));
+        }
+      }
+      for (int i = newAggregate.getGroupCount()
+                   + newAggregate.getIndicatorCount();
            i < newAggregate.getRowType().getFieldCount(); i++) {
         posList.add(i);
       }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2b358192/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 9459a67..f1db459 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -126,6 +126,7 @@ public class RelOptRulesTest extends RelOptTestBase {
     return DiffRepository.lookup(RelOptRulesTest.class);
   }
 
+
   @Test public void testUnionToDistinctRule() {
     checkPlanning(UnionToDistinctRule.INSTANCE,
         "select * from dept union select * from dept");
@@ -1054,6 +1055,17 @@ public class RelOptRulesTest extends RelOptTestBase {
             + "group by x, y");
   }
 
+  @Test public void testAggregateGroupingSetsProjectMerge() throws Exception {
+    HepProgram program = new HepProgramBuilder()
+        .addRuleInstance(AggregateProjectMergeRule.INSTANCE)
+        .build();
+    checkPlanning(program,
+        "select x, sum(z), y from (\n"
+            + "  select deptno as x, empno as y, sal as z, sal * 2 as zz\n"
+            + "  from emp)\n"
+            + "group by rollup(x, y)");
+  }
+
   public void transitiveInference() throws Exception {
     final DiffRepository diffRepos = getDiffRepos();
     String sql = diffRepos.expand(null, "${sql}");

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/2b358192/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 f80de19..1f20cc4 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -2685,6 +2685,33 @@ LogicalProject(X=[$0], EXPR$1=[$2], Y=[$1])
 ]]>
         </Resource>
     </TestCase>
+    <TestCase name="testAggregateGroupingSetsProjectMerge">
+        <Resource name="sql">
+            <![CDATA[select x, sum(z), y from (
+  select deptno as x, empno as y, sal as z, sal * 2 as zz
+  from emp)
+group by rollup(x, y)]]>
+        </Resource>
+        <Resource name="planBefore">
+            <![CDATA[
+LogicalProject(X=[$0], EXPR$1=[$4], Y=[$1])
+  LogicalProject(X=[CASE($2, null, $0)], Y=[CASE($3, null, $1)], i$X=[$2], i$Y=[$3], EXPR$1=[$4])
+    LogicalAggregate(group=[{0, 1}], groups=[[{0, 1}, {0}, {}]], indicator=[true], EXPR$1=[SUM($2)])
+      LogicalProject(X=[$0], Y=[$1], Z=[$2])
+        LogicalProject(X=[$7], Y=[$0], Z=[$5], ZZ=[*($5, 2)])
+          LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+        </Resource>
+        <Resource name="planAfter">
+            <![CDATA[
+LogicalProject(X=[$0], EXPR$1=[$4], Y=[$1])
+  LogicalProject(X=[CASE($2, null, $0)], Y=[CASE($3, null, $1)], i$X=[$2], i$Y=[$3], EXPR$1=[$4])
+    LogicalProject($f0=[$1], $f1=[$0], $f2=[$3], $f3=[$2], $f4=[$4])
+      LogicalAggregate(group=[{0, 7}], groups=[[{0, 7}, {7}, {}]], indicator=[true], EXPR$1=[SUM($5)])
+        LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+        </Resource>
+    </TestCase>
     <TestCase name="testPushFilterWithRank">
         <Resource name="sql">
             <![CDATA[select e1.ename, r