calcite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jh...@apache.org
Subject calcite git commit: [CALCITE-939] Variant of SortUnionTransposeRule for order-preserving Union (Maryann Xue)
Date Wed, 28 Oct 2015 00:29:26 GMT
Repository: calcite
Updated Branches:
  refs/heads/master d02305eaf -> 1a491b7f9


[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/master
Commit: 1a491b7f9fbe8ae2f2a88b2fe40945f0fe526cbc
Parents: d02305e
Author: maryannxue <wei.xue@intel.com>
Authored: Tue Oct 27 16:20:54 2015 -0700
Committer: Julian Hyde <jhyde@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>


Mime
View raw message