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>