You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jc...@apache.org on 2015/11/11 13:25:32 UTC
[26/50] [abbrv] calcite git commit: [CALCITE-939] Variant of
SortUnionTransposeRule for order-preserving Union (Maryann Xue)
[CALCITE-939] Variant of SortUnionTransposeRule for order-preserving Union (Maryann Xue)
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/1a491b7f
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/1a491b7f
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/1a491b7f
Branch: refs/heads/branch-release
Commit: 1a491b7f9fbe8ae2f2a88b2fe40945f0fe526cbc
Parents: d02305e
Author: maryannxue <we...@intel.com>
Authored: Tue Oct 27 16:20:54 2015 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Tue Oct 27 16:20:54 2015 -0700
----------------------------------------------------------------------
.../rel/rules/SortUnionTransposeRule.java | 54 ++++++++++++++++----
.../apache/calcite/test/RelOptRulesTest.java | 16 ++++++
.../org/apache/calcite/test/RelOptRulesTest.xml | 33 ++++++++++++
3 files changed, 93 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/1a491b7f/core/src/main/java/org/apache/calcite/rel/rules/SortUnionTransposeRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/SortUnionTransposeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/SortUnionTransposeRule.java
index a403ffd..b195e3f 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/SortUnionTransposeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/SortUnionTransposeRule.java
@@ -19,9 +19,11 @@ package org.apache.calcite.rel.rules;
import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelOptRuleCall;
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.core.Union;
import org.apache.calcite.rel.metadata.RelMdUtil;
+import org.apache.calcite.tools.RelBuilderFactory;
import java.util.ArrayList;
import java.util.List;
@@ -32,29 +34,61 @@ import java.util.List;
*
*/
public class SortUnionTransposeRule extends RelOptRule {
- public static final SortUnionTransposeRule INSTANCE = new SortUnionTransposeRule();
+
+ /** Rule instance for Union implementation that does not preserve the
+ * ordering of its inputs. Thus, it makes no sense to match this rule
+ * if the Sort does not have a limit, i.e., {@link Sort#fetch} is null. */
+ public static final SortUnionTransposeRule INSTANCE = new SortUnionTransposeRule(false);
+
+ /** Rule instance for Union implementation that preserves the ordering
+ * of its inputs. It is still worth applying this rule even if the Sort
+ * does not have a limit, for the merge of already sorted inputs that
+ * the Union can do is usually cheap. */
+ public static final SortUnionTransposeRule MATCH_NULL_FETCH = new SortUnionTransposeRule(true);
+
+ /** Whether to match a Sort whose {@link Sort#fetch} is null. Generally
+ * this only makes sense if the Union preserves order (and merges). */
+ private final boolean matchNullFetch;
// ~ Constructors -----------------------------------------------------------
+ private SortUnionTransposeRule(boolean matchNullFetch) {
+ this(Sort.class, Union.class, matchNullFetch, RelFactories.LOGICAL_BUILDER,
+ "SortUnionTransposeRule:default");
+ }
+
/**
* Creates a SortUnionTransposeRule.
*/
- private SortUnionTransposeRule() {
- super(operand(Sort.class, operand(Union.class, any())));
+ public SortUnionTransposeRule(
+ Class<? extends Sort> sortClass,
+ Class<? extends Union> unionClass,
+ boolean matchNullFetch,
+ RelBuilderFactory relBuilderFactory,
+ String description) {
+ super(
+ operand(sortClass,
+ operand(unionClass, any())),
+ relBuilderFactory, description);
+ this.matchNullFetch = matchNullFetch;
}
// ~ Methods ----------------------------------------------------------------
+ @Override public boolean matches(RelOptRuleCall call) {
+ final Sort sort = call.rel(0);
+ final Union union = call.rel(1);
+ // We only apply this rule if Union.all is true and Sort.offset is null.
+ // There is a flag indicating if this rule should be applied when
+ // Sort.fetch is null.
+ return union.all
+ && sort.offset == null
+ && (matchNullFetch || sort.fetch != null);
+ }
+
public void onMatch(RelOptRuleCall call) {
final Sort sort = call.rel(0);
final Union union = call.rel(1);
- // It is not valid to apply the rule if
- // Union.all is false;
- // or Sort.offset is not null
- // or Sort.fetch is null.
- if (!union.all || sort.offset != null || sort.fetch == null) {
- return;
- }
List<RelNode> inputs = new ArrayList<>();
// Thus we use 'ret' as a flag to identify if we have finished pushing the
// sort past a union.
http://git-wip-us.apache.org/repos/asf/calcite/blob/1a491b7f/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 53c3f63..244871d 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -395,6 +395,22 @@ public class RelOptRulesTest extends RelOptTestBase {
checkPlanning(program, sql);
}
+ /** Test case for
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-889">[CALCITE-889]
+ * Implement SortUnionTransposeRule</a>. */
+ @Test public void testSortUnionTranspose2() {
+ final HepProgram program =
+ HepProgram.builder()
+ .addRuleInstance(ProjectSetOpTransposeRule.INSTANCE)
+ .addRuleInstance(SortUnionTransposeRule.MATCH_NULL_FETCH)
+ .build();
+ final String sql = "select a.name from dept a\n"
+ + "union all\n"
+ + "select b.name from dept b\n"
+ + "order by name";
+ checkPlanning(program, sql);
+ }
+
@Test public void testSemiJoinRule() {
final HepProgram preProgram =
HepProgram.builder()
http://git-wip-us.apache.org/repos/asf/calcite/blob/1a491b7f/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 b1be89c..06e70f7 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -4263,4 +4263,37 @@ LogicalProject(EMPNO=[10], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$
]]>
</Resource>
</TestCase>
+ <TestCase name="testSortUnionTranspose2">
+ <Resource name="sql">
+ <![CDATA[select a.name from dept a
+union all
+select b.name from dept b
+order by name]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalSort(sort0=[$0], dir0=[ASC])
+ LogicalProject(NAME=[$0])
+ LogicalUnion(all=[true])
+ LogicalProject(NAME=[$1])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+ LogicalProject(NAME=[$1])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+LogicalSort(sort0=[$0], dir0=[ASC])
+ LogicalUnion(all=[true])
+ LogicalSort(sort0=[$0], dir0=[ASC])
+ LogicalProject(NAME=[$0])
+ LogicalProject(NAME=[$1])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+ LogicalSort(sort0=[$0], dir0=[ASC])
+ LogicalProject(NAME=[$0])
+ LogicalProject(NAME=[$1])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+]]>
+ </Resource>
+ </TestCase>
</Root>