[
https://issues.apache.org/jira/browse/CALCITE-2865?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Ruben Quesada Lopez updated CALCITE-2865:
-----------------------------------------
Description:
Problem can be reproduced with the following test:
{code}
@Test public void testFilterProjectTransposeRule() {
CalciteAssert.that()
.withSchema("s", new ReflectiveSchema(new JdbcTest.HrSchema()))
.query("?")
.withRel(b -> b
.scan("s", "emps")
.filter(b.equals(b.field(1), b.literal(10))) // deptno = 10
.sort(-4) // salary desc
.project(b.field(3)) // salary (**)
.filter(b.equals(b.field(0), b.literal(11500))) // salary =
11500 (**)
.build())
.returnsOrdered("salary=11500.0");
}
{code}
If we run the test with a break point at the end of
{{FilterProjectTransposeRule#onMatch}} method, we can see that, when the
project and filter tagged with (**) are transposed, the generated output
(newFilterRel) is different in terms of traitSet, depending if the copyFilter /
copyProject flags are used or not:
- copyFilter and copyProject TRUE (default)
{code}
LogicalProject.NONE.[0 DESC]
LogicalFilter.NONE.[0 DESC] // !!!
LogicalSort.NONE.[1 DESC]
{code}
- copyFilter and copyProject FALSE
{code}
LogicalProject.NONE.[0 DESC]
LogicalFilter.NONE.[1 DESC] // !!!
LogicalSort.NONE.[1 DESC]
{code}
As I see it, the default behavior seems wrong in terms of new filter's
traitSet, although the test run successfully (maybe because other rules
intervene to build the final plan?).
As suggested by [~zabetak], another possibility to reproduce this issue is with
the following test in RelOptRulesTest:
{code}
/** 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 values:
copyFilter=true, copyProject=true
new FilterProjectTransposeRule(Filter.class, Project.class,
/*copyFilter*/ false, /*copyProject*/ false, RelFactories.LOGICAL_BUILDER));
List<RelNode> results = new ArrayList<>(2);
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);
results.add(hepPlanner.findBestExp());
}
// compare LogicalFilter traitSet
assertEquals(results.get(0).getInput(0).getTraitSet(),
results.get(1).getInput(0).getTraitSet());
}
{code}
was:
Problem can be reproduced with the following test:
{code}
@Test public void testFilterProjectTransposeRule() {
CalciteAssert.that()
.withSchema("s", new ReflectiveSchema(new JdbcTest.HrSchema()))
.query("?")
.withRel(b -> b
.scan("s", "emps")
.filter(b.equals(b.field(1), b.literal(10))) // deptno = 10
.sort(-4) // salary desc
.project(b.field(3)) // salary (**)
.filter(b.equals(b.field(0), b.literal(11500))) // salary =
11500 (**)
.build())
.returnsOrdered("salary=11500.0");
}
{code}
If we run the test with a break point at the end of
{{FilterProjectTransposeRule#onMatch}} method, we can see that, when the
project and filter tagged with (**) are transposed, the generated output
(newFilterRel) is different in terms of traitSet, depending if the copyFilter /
copyProject flags are used or not:
- copyFilter and copyProject TRUE (default)
{code}
LogicalProject.NONE.[0 DESC]
LogicalFilter.NONE.[0 DESC] // !!!
LogicalSort.NONE.[1 DESC]
{code}
- copyFilter and copyProject FALSE
{code}
LogicalProject.NONE.[0 DESC]
LogicalFilter.NONE.[1 DESC] // !!!
LogicalSort.NONE.[1 DESC]
{code}
As I see it, the default behavior seems wrong in terms of new filter's
traitSet, although the test run successfully (maybe because other rules
intervene to build the final plan?).
As suggested by [~zabetak], another possibility to reproduce this issue is with
the following test in RelOptRulesTest:
{code}
/** 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 values:
copyFilter=true, copyProject=true
new FilterProjectTransposeRule(Filter.class, Project.class, false,
false, RelFactories.LOGICAL_BUILDER)); // copyFilter=false, copyProject=false
List<RelNode> results = new ArrayList<>(2);
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);
results.add(hepPlanner.findBestExp());
}
// compare LogicalFilter traitSet
assertEquals(results.get(0).getInput(0).getTraitSet(),
results.get(1).getInput(0).getTraitSet());
}
{code}
> FilterProjectTransposeRule generates wrong traitSet when copyFilter/Project
> is true
> -----------------------------------------------------------------------------------
>
> Key: CALCITE-2865
> URL: https://issues.apache.org/jira/browse/CALCITE-2865
> Project: Calcite
> Issue Type: Bug
> Affects Versions: 1.18.0
> Reporter: Ruben Quesada Lopez
> Assignee: Ruben Quesada Lopez
> Priority: Major
>
> Problem can be reproduced with the following test:
> {code}
> @Test public void testFilterProjectTransposeRule() {
> CalciteAssert.that()
> .withSchema("s", new ReflectiveSchema(new JdbcTest.HrSchema()))
> .query("?")
> .withRel(b -> b
> .scan("s", "emps")
> .filter(b.equals(b.field(1), b.literal(10))) // deptno = 10
> .sort(-4) // salary desc
> .project(b.field(3)) // salary (**)
> .filter(b.equals(b.field(0), b.literal(11500))) // salary =
> 11500 (**)
> .build())
> .returnsOrdered("salary=11500.0");
> }
> {code}
> If we run the test with a break point at the end of
> {{FilterProjectTransposeRule#onMatch}} method, we can see that, when the
> project and filter tagged with (**) are transposed, the generated output
> (newFilterRel) is different in terms of traitSet, depending if the copyFilter
> / copyProject flags are used or not:
> - copyFilter and copyProject TRUE (default)
> {code}
> LogicalProject.NONE.[0 DESC]
> LogicalFilter.NONE.[0 DESC] // !!!
> LogicalSort.NONE.[1 DESC]
> {code}
> - copyFilter and copyProject FALSE
> {code}
> LogicalProject.NONE.[0 DESC]
> LogicalFilter.NONE.[1 DESC] // !!!
> LogicalSort.NONE.[1 DESC]
> {code}
> As I see it, the default behavior seems wrong in terms of new filter's
> traitSet, although the test run successfully (maybe because other rules
> intervene to build the final plan?).
> As suggested by [~zabetak], another possibility to reproduce this issue is
> with the following test in RelOptRulesTest:
> {code}
> /** 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 values:
> copyFilter=true, copyProject=true
> new FilterProjectTransposeRule(Filter.class, Project.class,
> /*copyFilter*/ false, /*copyProject*/ false, RelFactories.LOGICAL_BUILDER));
> List<RelNode> results = new ArrayList<>(2);
> 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);
> results.add(hepPlanner.findBestExp());
> }
> // compare LogicalFilter traitSet
> assertEquals(results.get(0).getInput(0).getTraitSet(),
> results.get(1).getInput(0).getTraitSet());
> }
> {code}
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)