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/09/16 00:14:33 UTC
git commit: [OPTIQ-409] PushFilterPastProjectRule should not push
filters past windowed aggregates
Repository: incubator-optiq
Updated Branches:
refs/heads/master 0184cc575 -> d0b284908
[OPTIQ-409] PushFilterPastProjectRule should not push filters past windowed aggregates
Project: http://git-wip-us.apache.org/repos/asf/incubator-optiq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-optiq/commit/d0b28490
Tree: http://git-wip-us.apache.org/repos/asf/incubator-optiq/tree/d0b28490
Diff: http://git-wip-us.apache.org/repos/asf/incubator-optiq/diff/d0b28490
Branch: refs/heads/master
Commit: d0b284908d1047ac9ef59ff8760d939b144ca607
Parents: 0184cc5
Author: Harish Butani <hb...@hortonworks.com>
Authored: Mon Sep 15 14:21:54 2014 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon Sep 15 14:42:54 2014 -0700
----------------------------------------------------------------------
.../rel/rules/PushFilterPastProjectRule.java | 14 +++++-
.../org/eigenbase/test/RelOptRulesTest.java | 22 +++++++++
.../org/eigenbase/test/RelOptRulesTest.xml | 48 ++++++++++++++++++++
3 files changed, 82 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/d0b28490/core/src/main/java/org/eigenbase/rel/rules/PushFilterPastProjectRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/eigenbase/rel/rules/PushFilterPastProjectRule.java b/core/src/main/java/org/eigenbase/rel/rules/PushFilterPastProjectRule.java
index 659d781..2e07d23 100644
--- a/core/src/main/java/org/eigenbase/rel/rules/PushFilterPastProjectRule.java
+++ b/core/src/main/java/org/eigenbase/rel/rules/PushFilterPastProjectRule.java
@@ -50,11 +50,11 @@ public class PushFilterPastProjectRule extends RelOptRule {
public PushFilterPastProjectRule(
Class<? extends FilterRelBase> filterClass,
RelFactories.FilterFactory filterFactory,
- Class<? extends ProjectRelBase> projectRelBaseClass,
+ Class<? extends ProjectRelBase> projectClass,
RelFactories.ProjectFactory projectFactory) {
super(
operand(filterClass,
- operand(projectRelBaseClass, any())));
+ operand(projectClass, any())));
this.filterFactory = filterFactory;
this.projectFactory = projectFactory;
}
@@ -66,6 +66,16 @@ public class PushFilterPastProjectRule extends RelOptRule {
final FilterRelBase filterRel = call.rel(0);
final ProjectRelBase projRel = call.rel(1);
+ if (RexOver.containsOver(projRel.getProjects(), null)) {
+ // In general a filter cannot be pushed below a windowing calculation.
+ // Applying the filter before the aggregation function changes
+ // the results of the windowing invocation.
+ //
+ // When the filter is on the PARTITION BY expression of the OVER clause
+ // it can be pushed down. For now we don't support this.
+ return;
+ }
+
// convert the filter to one that references the child of the project
RexNode newCondition =
RelOptUtil.pushFilterPastProject(filterRel.getCondition(), projRel);
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/d0b28490/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 31a9906..b6bc208 100644
--- a/core/src/test/java/org/eigenbase/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/eigenbase/test/RelOptRulesTest.java
@@ -1001,6 +1001,28 @@ public class RelOptRulesTest extends RelOptTestBase {
@Test public void testTransitiveInferenceComplexPredicate() throws Exception {
transitiveInference();
}
+
+ @Test public void testPushFilterWithRank() throws Exception {
+ HepProgram program = new HepProgramBuilder().addRuleInstance(
+ PushFilterPastProjectRule.INSTANCE).build();
+ checkPlanning(program, "select e1.ename, r\n"
+ + "from (\n"
+ + " select ename, "
+ + " rank() over(partition by deptno order by sal) as r "
+ + " from emp) e1\n"
+ + "where r < 2");
+ }
+
+ @Test public void testPushFilterWithRankExpr() throws Exception {
+ HepProgram program = new HepProgramBuilder().addRuleInstance(
+ PushFilterPastProjectRule.INSTANCE).build();
+ checkPlanning(program, "select e1.ename, r\n"
+ + "from (\n"
+ + " select ename,\n"
+ + " rank() over(partition by deptno order by sal) + 1 as r "
+ + " from emp) e1\n"
+ + "where r < 2");
+ }
}
// End RelOptRulesTest.java
http://git-wip-us.apache.org/repos/asf/incubator-optiq/blob/d0b28490/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 e96dfb1..07eeb68 100644
--- a/core/src/test/resources/org/eigenbase/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/eigenbase/test/RelOptRulesTest.xml
@@ -2158,4 +2158,52 @@ ProjectRel(X=[$0], EXPR$1=[$2], Y=[$1])
]]>
</Resource>
</TestCase>
+ <TestCase name="testPushFilterWithRank">
+ <Resource name="sql">
+ <![CDATA[select e1.ename, r
+from (select ename, rank() over(partition by deptno order by sal) as r from emp) e1
+where r < 2
+]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+ProjectRel(ENAME=[$0], R=[$1])
+ FilterRel(condition=[<($1, 2)])
+ ProjectRel(ENAME=[$1], R=[RANK() OVER (PARTITION BY $7 ORDER BY $5 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)])
+ TableAccessRel(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+ProjectRel(ENAME=[$0], R=[$1])
+ FilterRel(condition=[<($1, 2)])
+ ProjectRel(ENAME=[$1], R=[RANK() OVER (PARTITION BY $7 ORDER BY $5 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)])
+ TableAccessRel(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ </TestCase>
+ <TestCase name="testPushFilterWithRankExpr">
+ <Resource name="sql">
+ <![CDATA[select e1.ename, r
+from (select ename, rank() over(partition by deptno order by sal) as r + 1 from emp) e1
+where r < 2
+]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+ProjectRel(ENAME=[$0], R=[$1])
+ FilterRel(condition=[<($1, 2)])
+ ProjectRel(ENAME=[$1], R=[+(RANK() OVER (PARTITION BY $7 ORDER BY $5 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 1)])
+ TableAccessRel(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+ProjectRel(ENAME=[$0], R=[$1])
+ FilterRel(condition=[<($1, 2)])
+ ProjectRel(ENAME=[$1], R=[+(RANK() OVER (PARTITION BY $7 ORDER BY $5 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 1)])
+ TableAccessRel(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ </TestCase>
</Root>