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 2018/05/24 22:39:25 UTC

calcite git commit: [CALCITE-873] Add a planner rule, SortRemoveConstantKeysRule, that removes constant keys from Sort (Atri Sharma)

Repository: calcite
Updated Branches:
  refs/heads/master 2a79e837b -> a0928af70


[CALCITE-873] Add a planner rule, SortRemoveConstantKeysRule, that removes constant keys from Sort (Atri Sharma)

Close apache/calcite#485


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

Branch: refs/heads/master
Commit: a0928af70e923171b077c1b7a3fa4553dd2ce4ee
Parents: 2a79e83
Author: Atri Sharma <at...@gmail.com>
Authored: Tue Jun 27 23:07:21 2017 +0530
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu May 24 13:28:55 2018 -0700

----------------------------------------------------------------------
 .../calcite/prepare/CalcitePrepareImpl.java     |  2 +
 .../rel/rules/SortRemoveConstantKeysRule.java   | 86 ++++++++++++++++++++
 .../apache/calcite/test/RelOptRulesTest.java    | 25 ++++++
 .../org/apache/calcite/test/RelOptRulesTest.xml | 60 +++++++++++++-
 4 files changed, 171 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/a0928af7/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java b/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
index 8f2bdff..9b772be 100644
--- a/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
+++ b/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
@@ -94,6 +94,7 @@ import org.apache.calcite.rel.rules.ProjectWindowTransposeRule;
 import org.apache.calcite.rel.rules.ReduceExpressionsRule;
 import org.apache.calcite.rel.rules.SortJoinTransposeRule;
 import org.apache.calcite.rel.rules.SortProjectTransposeRule;
+import org.apache.calcite.rel.rules.SortRemoveConstantKeysRule;
 import org.apache.calcite.rel.rules.SortUnionTransposeRule;
 import org.apache.calcite.rel.rules.TableScanRule;
 import org.apache.calcite.rel.rules.ValuesReduceRule;
@@ -239,6 +240,7 @@ public class CalcitePrepareImpl implements CalcitePrepare {
           JoinPushThroughJoinRule.LEFT,
           SortProjectTransposeRule.INSTANCE,
           SortJoinTransposeRule.INSTANCE,
+          SortRemoveConstantKeysRule.INSTANCE,
           SortUnionTransposeRule.INSTANCE);
 
   private static final List<RelOptRule> CONSTANT_REDUCTION_RULES =

http://git-wip-us.apache.org/repos/asf/calcite/blob/a0928af7/core/src/main/java/org/apache/calcite/rel/rules/SortRemoveConstantKeysRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/SortRemoveConstantKeysRule.java b/core/src/main/java/org/apache/calcite/rel/rules/SortRemoveConstantKeysRule.java
new file mode 100644
index 0000000..f2a4f47
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/rel/rules/SortRemoveConstantKeysRule.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.rel.rules;
+
+import org.apache.calcite.plan.RelOptPredicateList;
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.rel.RelCollationTraitDef;
+import org.apache.calcite.rel.RelCollations;
+import org.apache.calcite.rel.RelFieldCollation;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.RelFactories;
+import org.apache.calcite.rel.core.Sort;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rex.RexBuilder;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Planner rule that removes keys from a
+ * a {@link org.apache.calcite.rel.core.Sort} if those keys are known to be
+ * constant, or removes the entire Sort if all keys are constant.
+ *
+ * <p>Requires {@link RelCollationTraitDef}.
+ */
+public class SortRemoveConstantKeysRule extends RelOptRule {
+  public static final SortRemoveConstantKeysRule INSTANCE =
+      new SortRemoveConstantKeysRule();
+
+  private SortRemoveConstantKeysRule() {
+    super(
+        operand(Sort.class, any()),
+        RelFactories.LOGICAL_BUILDER, "SortRemoveConstantKeysRule");
+  }
+
+  @Override public void onMatch(RelOptRuleCall call) {
+    final Sort sort = call.rel(0);
+    final RelMetadataQuery mq = call.getMetadataQuery();
+    final RelNode input = sort.getInput();
+    final RelOptPredicateList predicates = mq.getPulledUpPredicates(input);
+    if (predicates == null) {
+      return;
+    }
+
+    final RexBuilder rexBuilder = sort.getCluster().getRexBuilder();
+    final List<RelFieldCollation> collationsList =
+        sort.getCollation().getFieldCollations().stream()
+            .filter(fc ->
+                !predicates.constantMap.containsKey(
+                    rexBuilder.makeInputRef(input, fc.getFieldIndex())))
+            .collect(Collectors.toList());
+
+    if (collationsList.size() == sort.collation.getFieldCollations().size()) {
+      return;
+    }
+
+    // No active collations. Remove the sort completely
+    if (collationsList.isEmpty() && sort.offset == null && sort.fetch == null) {
+      call.transformTo(input);
+      call.getPlanner().setImportance(sort, 0.0);
+      return;
+    }
+
+    final Sort result =
+        sort.copy(sort.getTraitSet(), input, RelCollations.of(collationsList));
+    call.transformTo(result);
+    call.getPlanner().setImportance(sort, 0.0);
+  }
+}
+
+// End SortRemoveConstantKeysRule.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/a0928af7/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 182b26e..1ab37c2 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -93,6 +93,7 @@ import org.apache.calcite.rel.rules.SemiJoinRemoveRule;
 import org.apache.calcite.rel.rules.SemiJoinRule;
 import org.apache.calcite.rel.rules.SortJoinTransposeRule;
 import org.apache.calcite.rel.rules.SortProjectTransposeRule;
+import org.apache.calcite.rel.rules.SortRemoveConstantKeysRule;
 import org.apache.calcite.rel.rules.SortUnionTransposeRule;
 import org.apache.calcite.rel.rules.SubQueryRemoveRule;
 import org.apache.calcite.rel.rules.TableScanRule;
@@ -538,6 +539,30 @@ public class RelOptRulesTest extends RelOptTestBase {
     checkPlanning(program, sql);
   }
 
+  @Test public void testSortRemovalAllKeysConstant() {
+    final HepProgram program = new HepProgramBuilder()
+        .addRuleInstance(SortRemoveConstantKeysRule.INSTANCE)
+        .build();
+    final String sql = "select count(*) as c\n"
+        + "from sales.emp\n"
+        + "where deptno = 10\n"
+        + "group by deptno, sal\n"
+        + "order by deptno desc nulls last";
+    sql(sql).with(program).check();
+  }
+
+  @Test public void testSortRemovalOneKeyConstant() {
+    final HepProgram program = new HepProgramBuilder()
+        .addRuleInstance(SortRemoveConstantKeysRule.INSTANCE)
+        .build();
+    final String sql = "select count(*) as c\n"
+        + "from sales.emp\n"
+        + "where deptno = 10\n"
+        + "group by deptno, sal\n"
+        + "order by deptno, sal desc nulls first";
+    sql(sql).with(program).check();
+  }
+
   @Test public void testSemiJoinRuleExists() {
     final HepProgram preProgram =
         HepProgram.builder()

http://git-wip-us.apache.org/repos/asf/calcite/blob/a0928af7/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 7754b5c..272b0e6 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -6003,8 +6003,7 @@ from sales.emp as A
 join (select mgr, sal, max(hiredate) as hiredate1,
     sum(comm) as comm1 from sales.emp group by mgr, sal) as B
 on A.sal=B.sal
-group by A.job, B.mgr, A.deptno
-]]>
+group by A.job, B.mgr, A.deptno]]>
         </Resource>
         <Resource name="planBefore">
             <![CDATA[
@@ -7564,6 +7563,63 @@ LogicalProject(EMPNO=[10], ENAME=[$1], JOB=[$2], MGR=[null], HIREDATE=[$4], SAL=
 ]]>
         </Resource>
     </TestCase>
+    <TestCase name="testSortRemovalAllKeysConstant">
+        <Resource name="sql">
+            <![CDATA[select count(*) as c
+from sales.emp
+where deptno = 10
+group by deptno, sal
+order by deptno desc nulls last]]>
+        </Resource>
+        <Resource name="planBefore">
+            <![CDATA[
+LogicalSort(sort0=[$1], dir0=[DESC-nulls-last])
+  LogicalProject(C=[$2], DEPTNO=[$0])
+    LogicalAggregate(group=[{0, 1}], C=[COUNT()])
+      LogicalProject(DEPTNO=[$7], SAL=[$5])
+        LogicalFilter(condition=[=($7, 10)])
+          LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+        </Resource>
+        <Resource name="planAfter">
+            <![CDATA[
+LogicalProject(C=[$2], DEPTNO=[$0])
+  LogicalAggregate(group=[{0, 1}], C=[COUNT()])
+    LogicalProject(DEPTNO=[$7], SAL=[$5])
+      LogicalFilter(condition=[=($7, 10)])
+        LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+        </Resource>
+    </TestCase>
+    <TestCase name="testSortRemovalOneKeyConstant">
+        <Resource name="sql">
+            <![CDATA[select count(*) as c
+from sales.emp
+where deptno = 10
+group by deptno, sal
+order by deptno, sal desc nulls first]]>
+        </Resource>
+        <Resource name="planBefore">
+            <![CDATA[
+LogicalSort(sort0=[$1], sort1=[$2], dir0=[ASC], dir1=[DESC])
+  LogicalProject(C=[$2], DEPTNO=[$0], SAL=[$1])
+    LogicalAggregate(group=[{0, 1}], C=[COUNT()])
+      LogicalProject(DEPTNO=[$7], SAL=[$5])
+        LogicalFilter(condition=[=($7, 10)])
+          LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+        </Resource>
+        <Resource name="planAfter">
+            <![CDATA[
+LogicalSort(sort0=[$2], dir0=[DESC])
+  LogicalProject(C=[$2], DEPTNO=[$0], SAL=[$1])
+    LogicalAggregate(group=[{0, 1}], C=[COUNT()])
+      LogicalProject(DEPTNO=[$7], SAL=[$5])
+        LogicalFilter(condition=[=($7, 10)])
+          LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+        </Resource>
+    </TestCase>
     <TestCase name="testSortUnionTranspose2">
         <Resource name="sql">
             <![CDATA[select a.name from dept a