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/10/19 09:11:00 UTC

git commit: [OPTIQ-434] FilterAggregateTransposeRule loses conditions that cannot be pushed

Repository: incubator-optiq
Updated Branches:
  refs/heads/master 99c7ff96b -> 44c72c32c


[OPTIQ-434] FilterAggregateTransposeRule loses conditions that cannot be pushed


Project: http://git-wip-us.apache.org/repos/asf/incubator-optiq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-optiq/commit/44c72c32
Tree: http://git-wip-us.apache.org/repos/asf/incubator-optiq/tree/44c72c32
Diff: http://git-wip-us.apache.org/repos/asf/incubator-optiq/diff/44c72c32

Branch: refs/heads/master
Commit: 44c72c32cbb4c47ed8b6e33db5dc2c353d250bf4
Parents: 99c7ff9
Author: Pengcheng Xiong <px...@hortonworks.com>
Authored: Sat Oct 18 23:49:35 2014 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Sat Oct 18 23:49:35 2014 -0700

----------------------------------------------------------------------
 .../rel/rules/FilterAggregateTransposeRule.java | 19 +++++------
 .../java/org/eigenbase/relopt/RelOptUtil.java   | 34 +++++++++++++++++---
 .../org/eigenbase/test/RelOptRulesTest.java     | 11 +++++++
 .../org/eigenbase/test/RelOptRulesTest.xml      | 33 ++++++++++++++++++-
 4 files changed, 82 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/44c72c32/core/src/main/java/org/eigenbase/rel/rules/FilterAggregateTransposeRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/FilterAggregateTransposeRule.java b/core/src/main/java/org/eigenbase/rel/rules/FilterAggregateTransposeRule.java
index 0ff4b58..a0f3b67 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/FilterAggregateTransposeRule.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/FilterAggregateTransposeRule.java
@@ -81,6 +81,7 @@ public class FilterAggregateTransposeRule extends RelOptRule {
         aggRel.getRowType().getFieldList();
     final int[] adjustments = new int[origFields.size()];
     final List<RexNode> pushedConditions = Lists.newArrayList();
+    final List<RexNode> remainingConditions = Lists.newArrayList();
 
     for (RexNode condition : conditions) {
       BitSet rCols = RelOptUtil.InputFinder.bits(condition);
@@ -90,19 +91,19 @@ public class FilterAggregateTransposeRule extends RelOptRule {
                 new RelOptUtil.RexInputConverter(rexBuilder, origFields,
                     aggRel.getInput(0).getRowType().getFieldList(),
                     adjustments)));
+      } else {
+        remainingConditions.add(condition);
       }
     }
 
-    final RexNode pushedCondition = RexUtil.composeConjunction(rexBuilder,
-        pushedConditions, true);
-
-    if (pushedCondition != null) {
-      RelNode newFilterRel = filterFactory.createFilter(aggRel.getInput(0),
-          pushedCondition);
-      RelNode newAggRel = aggRel.copy(aggRel.getTraitSet(),
-          ImmutableList.of(newFilterRel));
-      call.transformTo(newAggRel);
+    RelNode rel = RelOptUtil.createFilter(aggRel.getInput(0), pushedConditions,
+        filterFactory);
+    if (rel == aggRel.getInput(0)) {
+      return;
     }
+    rel = aggRel.copy(aggRel.getTraitSet(), ImmutableList.of(rel));
+    rel = RelOptUtil.createFilter(rel, remainingConditions, filterFactory);
+    call.transformTo(rel);
   }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/44c72c32/core/src/main/java/org/eigenbase/relopt/RelOptUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/relopt/RelOptUtil.java b/core/src/main/java/org/eigenbase/relopt/RelOptUtil.java
index d5ceaa0..9034b7c 100644
--- a/core/src/main/java/org/eigenbase/relopt/RelOptUtil.java
+++ b/core/src/main/java/org/eigenbase/relopt/RelOptUtil.java
@@ -267,7 +267,8 @@ public abstract class RelOptUtil {
           RexUtil.composeConjunction(
               cluster.getRexBuilder(), conditions, true);
 
-      ret = createFilter(ret, conditionExp);
+      ret = createFilter(ret, conditionExp,
+          RelFactories.DEFAULT_FILTER_FACTORY);
     }
 
     if (extraExpr != null) {
@@ -451,20 +452,43 @@ public abstract class RelOptUtil {
    * @return Relational expression
    */
   public static RelNode createFilter(RelNode child, RexNode condition) {
-    return new FilterRel(child.getCluster(), child, condition);
+    return createFilter(child, condition, RelFactories.DEFAULT_FILTER_FACTORY);
   }
 
-  /** Creates a filter, or returns the original relational expression if the
+  /**
+   * Creates a relational expression which filters according to a given
+   * condition, returning the same fields as its input.
+   *
+   * @param child     Child relational expression
+   * @param condition Condition
+   * @param filterFactory Filter factory
+   * @return Relational expression
+   */
+  public static RelNode createFilter(RelNode child, RexNode condition,
+      RelFactories.FilterFactory filterFactory) {
+    return filterFactory.createFilter(child, condition);
+  }
+
+  /** Creates a filter, using the default filter factory,
+   * or returns the original relational expression if the
    * condition is trivial. */
   public static RelNode createFilter(RelNode child,
       Iterable<? extends RexNode> conditions) {
+    return createFilter(child, conditions, RelFactories.DEFAULT_FILTER_FACTORY);
+  }
+
+  /** Creates a filter, or returns the original relational expression if the
+   * condition is trivial. */
+  public static RelNode createFilter(RelNode child,
+      Iterable<? extends RexNode> conditions,
+      RelFactories.FilterFactory filterFactory) {
     final RelOptCluster cluster = child.getCluster();
     final RexNode condition =
         RexUtil.composeConjunction(cluster.getRexBuilder(), conditions, true);
     if (condition == null) {
       return child;
     } else {
-      return createFilter(child, condition);
+      return createFilter(child, condition, filterFactory);
     }
   }
 
@@ -519,7 +543,7 @@ public abstract class RelOptUtil {
       return rel;
     }
 
-    return createFilter(rel, condition);
+    return createFilter(rel, condition, RelFactories.DEFAULT_FILTER_FACTORY);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/44c72c32/core/src/test/java/org/eigenbase/test/RelOptRulesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/eigenbase/test/RelOptRulesTest.java b/core/src/test/java/org/eigenbase/test/RelOptRulesTest.java
index 93659b7..0a03528 100644
--- a/core/src/test/java/org/eigenbase/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/eigenbase/test/RelOptRulesTest.java
@@ -173,6 +173,17 @@ public class RelOptRulesTest extends RelOptTestBase {
         + " where dname = 'Charlie'");
   }
 
+  /** Test case for
+   * <a href="https://issues.apache.org/jira/browse/OPTIQ-434">[OPTIQ-434],
+   * FilterAggregateTransposeRule loses conditions that cannot be pushed</a>. */
+  @Test public void testPushFilterPastAggTwo() {
+    checkPlanning(FilterAggregateTransposeRule.INSTANCE,
+        "select dept1.c1 from (\n"
+        + "  select dept.name as c1, count(*) as c2\n"
+        + "  from dept where dept.name > 'b' group by dept.name) dept1\n"
+        + "where dept1.c1 > 'c' and (dept1.c2 > 30 or dept1.c1 < 'z')");
+  }
+
   @Test public void testSemiJoinRule() {
     final HepProgram preProgram =
         HepProgram.builder()

http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/44c72c32/core/src/test/resources/org/eigenbase/test/RelOptRulesTest.xml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/eigenbase/test/RelOptRulesTest.xml b/core/src/test/resources/org/eigenbase/test/RelOptRulesTest.xml
index 015c361..7f4d8bf 100644
--- a/core/src/test/resources/org/eigenbase/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/eigenbase/test/RelOptRulesTest.xml
@@ -110,7 +110,9 @@ ProjectRel(EXPR$0=[1])
     </TestCase>
     <TestCase name="testPushFilterThroughSemiJoin">
         <Resource name="sql">
-            <![CDATA[select * from (select * from dept where dept.deptno in (select emp.deptno from emp))R where R.deptno <=10 ]]>
+            <![CDATA[select * from (select * from dept where dept.deptno in (
+  select emp.deptno from emp
+  ))R where R.deptno <=10 ]]>
         </Resource>
         <Resource name="planBefore">
             <![CDATA[
@@ -2353,4 +2355,33 @@ MultiJoinRel(joinFilter=[true], isFullOuterJoin=[false], joinTypes=[[RIGHT, INNE
 ]]>
         </Resource>
     </TestCase>
+    <TestCase name="testPushFilterPastAggTwo">
+        <Resource name="sql">
+            <![CDATA[select dept1.c1 from (
+  select dept.name as c1, count(*) as c2
+  from dept where dept.name > 'b' group by dept.name) dept1
+where dept1.c1 > 'c' and (dept1.c2 > 30 or dept1.c1 < 'z')]]>
+        </Resource>
+        <Resource name="planBefore">
+            <![CDATA[
+ProjectRel(C1=[$0])
+  FilterRel(condition=[AND(>($0, 'c'), OR(>($1, 30), <($0, 'z')))])
+    AggregateRel(group=[{0}], C2=[COUNT()])
+      ProjectRel(C1=[$1])
+        FilterRel(condition=[>($1, 'b')])
+          TableAccessRel(table=[[CATALOG, SALES, DEPT]])
+]]>
+        </Resource>
+        <Resource name="planAfter">
+            <![CDATA[
+ProjectRel(C1=[$0])
+  FilterRel(condition=[OR(>($1, 30), <($0, 'z'))])
+    AggregateRel(group=[{0}], C2=[COUNT()])
+      FilterRel(condition=[>($0, 'c')])
+        ProjectRel(C1=[$1])
+          FilterRel(condition=[>($1, 'b')])
+            TableAccessRel(table=[[CATALOG, SALES, DEPT]])
+]]>
+        </Resource>
+    </TestCase>
 </Root>