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