This is an automated email from the ASF dual-hosted git repository. zabetak pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/master by this push: new 8982925 [CALCITE-2865] FilterProjectTransposeRule generates wrong traitSet when copyFilter/Project is true (Ruben Quesada Lopez) 8982925 is described below commit 89829252689477bfeb305071285edcde1b4a3048 Author: rubenada <rube...@gmail.com> AuthorDate: Fri Mar 1 09:50:24 2019 +0100 [CALCITE-2865] FilterProjectTransposeRule generates wrong traitSet when copyFilter/Project is true (Ruben Quesada Lopez) --- .../rel/rules/FilterProjectTransposeRule.java | 15 +++++++-- .../org/apache/calcite/test/RelOptRulesTest.java | 38 ++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/apache/calcite/rel/rules/FilterProjectTransposeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/FilterProjectTransposeRule.java index 4dc14dd..3592375 100644 --- a/core/src/main/java/org/apache/calcite/rel/rules/FilterProjectTransposeRule.java +++ b/core/src/main/java/org/apache/calcite/rel/rules/FilterProjectTransposeRule.java @@ -21,6 +21,9 @@ import org.apache.calcite.plan.RelOptRule; import org.apache.calcite.plan.RelOptRuleCall; import org.apache.calcite.plan.RelOptRuleOperand; import org.apache.calcite.plan.RelOptUtil; +import org.apache.calcite.plan.RelTraitSet; +import org.apache.calcite.rel.RelCollationTraitDef; +import org.apache.calcite.rel.RelDistributionTraitDef; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.core.Filter; import org.apache.calcite.rel.core.Project; @@ -35,6 +38,7 @@ import org.apache.calcite.tools.RelBuilder; import org.apache.calcite.tools.RelBuilderFactory; import org.apache.calcite.util.Util; +import java.util.Collections; import java.util.function.Predicate; /** @@ -155,8 +159,15 @@ public class FilterProjectTransposeRule extends RelOptRule { final RelBuilder relBuilder = call.builder(); RelNode newFilterRel; if (copyFilter) { - newFilterRel = filter.copy(filter.getTraitSet(), project.getInput(), - simplifyFilterCondition(newCondition, call)); + final RelNode input = project.getInput(); + final RelTraitSet traitSet = filter.getTraitSet() + .replaceIfs(RelCollationTraitDef.INSTANCE, + () -> Collections.singletonList( + input.getTraitSet().getTrait(RelCollationTraitDef.INSTANCE))) + .replaceIfs(RelDistributionTraitDef.INSTANCE, + () -> Collections.singletonList( + input.getTraitSet().getTrait(RelDistributionTraitDef.INSTANCE))); + newFilterRel = filter.copy(traitSet, input, simplifyFilterCondition(newCondition, call)); } else { newFilterRel = relBuilder.push(project.getInput()).filter(newCondition).build(); 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 5c7a18e..1885d9d 100644 --- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java +++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java @@ -29,6 +29,7 @@ import org.apache.calcite.plan.hep.HepPlanner; import org.apache.calcite.plan.hep.HepProgram; import org.apache.calcite.plan.hep.HepProgramBuilder; import org.apache.calcite.prepare.Prepare; +import org.apache.calcite.rel.RelCollation; import org.apache.calcite.rel.RelCollationTraitDef; import org.apache.calcite.rel.RelCollations; import org.apache.calcite.rel.RelDistributions; @@ -135,6 +136,7 @@ import org.apache.calcite.util.ImmutableBitSet; import com.google.common.collect.ImmutableList; +import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; @@ -256,6 +258,42 @@ public class RelOptRulesTest extends RelOptTestBase { .check(); } + /** Test case for + * <a href="https://issues.apache.org/jira/browse/CALCITE-2865">[CALCITE-2865] + * FilterProjectTransposeRule generates wrong traitSet when copyFilter/Project is true</a>. */ + @Test public void testFilterProjectTransposeRule() { + List<RelOptRule> rules = Arrays.asList( + FilterProjectTransposeRule.INSTANCE, // default: copyFilter=true, copyProject=true + new FilterProjectTransposeRule(Filter.class, Project.class, + false, false, RelFactories.LOGICAL_BUILDER)); + + for (RelOptRule rule : rules) { + RelBuilder b = RelBuilder.create(RelBuilderTest.config().build()); + RelNode in = b + .scan("EMP") + .sort(-4) // salary desc + .project(b.field(3)) // salary + .filter(b.equals(b.field(0), b.literal(11500))) // salary = 11500 + .build(); + HepProgram program = new HepProgramBuilder() + .addRuleInstance(rule) + .build(); + HepPlanner hepPlanner = new HepPlanner(program); + hepPlanner.setRoot(in); + RelNode result = hepPlanner.findBestExp(); + + // Verify LogicalFilter traitSet (must be [3 DESC]) + RelNode filter = result.getInput(0); + RelCollation collation = filter.getTraitSet().getTrait(RelCollationTraitDef.INSTANCE); + Assert.assertNotNull(collation); + List<RelFieldCollation> fieldCollations = collation.getFieldCollations(); + Assert.assertEquals(1, fieldCollations.size()); + RelFieldCollation fieldCollation = fieldCollations.get(0); + Assert.assertEquals(3, fieldCollation.getFieldIndex()); + Assert.assertEquals(RelFieldCollation.Direction.DESCENDING, fieldCollation.getDirection()); + } + } + @Test public void testReduceOrCaseWhen() { HepProgram preProgram = new HepProgramBuilder() .build();