You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@calcite.apache.org by "yanjing.wang (Jira)" <ji...@apache.org> on 2021/06/23 10:03:00 UTC
[jira] [Commented] (CALCITE-4663) And predicate in one subtree of
Join causes JoinPushTransitivePredicatesRule pulls up predicates infinitely
and StackOverflowError
[ https://issues.apache.org/jira/browse/CALCITE-4663?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17368009#comment-17368009 ]
yanjing.wang commented on CALCITE-4663:
---------------------------------------
Hi [~julianhyde], I changed the subject and the code within description helps reproduce the problem.
> And predicate in one subtree of Join causes JoinPushTransitivePredicatesRule pulls up predicates infinitely and StackOverflowError
> ----------------------------------------------------------------------------------------------------------------------------------
>
> Key: CALCITE-4663
> URL: https://issues.apache.org/jira/browse/CALCITE-4663
> Project: Calcite
> Issue Type: Bug
> Components: core
> Affects Versions: 1.26.0, 1.27.0
> Environment: jdk8
> calcite1.27.0
> Reporter: yanjing.wang
> Priority: Major
>
> the query is *select empid from hr.emps where deptno in (select deptno from hr.depts where deptno between 1000 and 2000)* and the logical plan tree after decorrelated optimization is
> LogicalProject(empid=[$0])
> LogicalJoin(condition=[=($1, $5)], joinType=[inner])
> LogicalTableScan(table=[[hr, emps]])
> LogicalAggregate(group=[\{0}])
> LogicalProject(deptno=[$0])
> LogicalFilter(condition=[*AND(>=($0, 1000), <=($0, 2000))*])
> LogicalTableScan(table=[[hr, depts]])
> the *AND* predicate behaves different with *Search* In JoinConditionBasedPredicateInference.
> We can reproduce this problem through adding a test case like SortRemoveRuleTest.
> {code:java}
> public final class JoinPushTransitivePredicatesRuleTest {
> @Test
> void conjunctionTransitive() throws Exception {
> SchemaPlus rootSchema = Frameworks.createRootSchema(true);
> SchemaPlus defSchema = rootSchema.add("hr", new HrClusteredSchema());
> FrameworkConfig config = Frameworks.newConfigBuilder()
> .parserConfig(SqlParser.Config.DEFAULT)
> .defaultSchema(defSchema)
> .traitDefs(ConventionTraitDef.INSTANCE, RelCollationTraitDef.INSTANCE)
> .build();
> String sql = "select \"empid\" from \"hr\".\"emps\" where \"deptno\" in (select \"deptno\" from \"hr\".\"depts\" where \"deptno\" between 1000 and 2000)";
> Planner planner = Frameworks.getPlanner(config);
> SqlNode parse = planner.parse(sql);
> SqlNode validate = planner.validate(parse);
> RelRoot planRoot = planner.rel(validate);
> RelNode planBefore = planRoot.rel;
> HepProgram hepProgram = HepProgram.builder()
> // .addRuleInstance(CoreRules.FILTER_REDUCE_EXPRESSIONS)
> .addRuleInstance(CoreRules.JOIN_PUSH_TRANSITIVE_PREDICATES)
> .build();
> HepPlanner hepPlanner = new HepPlanner(hepProgram);
> hepPlanner.setRoot(planBefore);
> hepPlanner.findBestExp();
> }
> }
> {code}
> {color:#ff0000}Exception in thread "main" java.lang.StackOverflowError{color}
> The culprit is that the JoinPushTransitivePredicatesRule simplify pulledUpPredicates, otherwise JoinConditionBasedPredicateInference not, so that the JoinConditionBasedPredicateInference can infer predicates indefinitely.
> Though we can add a *CoreRules.FILTER_REDUCE_EXPRESSIONS* before *CoreRules.JOIN_PUSH_TRANSITIVE_PREDICATES* as a workaround, but I think we can simplify left and right child predicates in JoinConditionBasedPredicateInference constructor and seems better.
>
> I add simplification for child predicates and StackOverflowError disappears.
> {code:java}
> leftChildPredicates = simplify.simplify(leftPredicates.accept(
> new RexPermuteInputsShuttle(leftMapping, joinRel.getInput(0))));
> rightChildPredicates = simplify.simplify(rightPredicates.accept(
> new RexPermuteInputsShuttle(rightMapping, joinRel.getInput(1))));
> {code}
>
--
This message was sent by Atlassian Jira
(v8.3.4#803005)