[ https://issues.apache.org/jira/browse/CALCITE-6432?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
ASF GitHub Bot updated CALCITE-6432: ------------------------------------ Labels: pull-request-available (was: ) > Infinite loop for JoinPushTransitivePredicatesRule when there are multiple > project expressions reference the same input field > ----------------------------------------------------------------------------------------------------------------------------- > > Key: CALCITE-6432 > URL: https://issues.apache.org/jira/browse/CALCITE-6432 > Project: Calcite > Issue Type: Improvement > Components: core > Reporter: asdfgh19 > Assignee: asdfgh19 > Priority: Minor > Labels: pull-request-available > Attachments: 1.png, 2.png > > > Below is a newly created test case that is stuck in an infinite loop. > {code:java} > @Test void testProjectPredicatePull() { > final String sql = "select e.ename, d.dname\n" > + "from (select ename, deptno from emp where deptno = 10) e\n" > + "join (select name dname, deptno, * from dept) d\n" > + "on e.deptno = d.deptno"; > final HepProgram program = new HepProgramBuilder() > .addRuleCollection( > ImmutableList.of(CoreRules.FILTER_PROJECT_TRANSPOSE, > CoreRules.JOIN_PUSH_TRANSITIVE_PREDICATES)) > .build(); > sql(sql).withProgram(program).check(); > } {code} > !1.png|width=563,height=192! > From the figure above, we can see the process of this infinite loop: > # JOIN_PUSH_TRANSITIVE_PREDICATES infers DEPTNO = 10 from the left side of > the Join > # JOIN_PUSH_TRANSITIVE_PREDICATES creates a new Filter DEPTNO = 10 on the > right side of the Join > # FILTER_PROJECT_TRANSPOSE pushes this newly created Filter past the Project > # JOIN_PUSH_TRANSITIVE_PREDICATES infers DEPTNO = 10 from the left side of > the Join and infers {color:#FF0000}DEPTNO0 = 10{color} from the right side of > the Join,Note that it is DEPTNO0, not DEPTNO > # So, JOIN_PUSH_TRANSITIVE_PREDICATES creates a new Filter DEPTNO = 10 and > put it to the right side of the Join again. And then the process keeps > repeating. > The reason is that when RelMdPredicates infers predicates for a project, > and the project has multiple expressions referencing the same input field, > for example, DEPT=$0 DEPT0=$0, and the input predicate is $0=10, the inferred > result is DEPT0=10, which means that the predicates related to other > expressions with the same input field (DEPT=10) are lost, leaving only the > last one. > > Below is the test case from RelOptRulesTest and its planAfter. > {code:java} > @Test void testJoinPushTransitivePredicatesRule2() { > final String sql = "select n1.SAL\n" > + "from EMPNULLABLES_20 n1\n" > + "where n1.SAL IN (\n" > + " select n2.SAL\n" > + " from EMPNULLABLES_20 n2\n" > + " where n1.SAL = n2.SAL or n1.SAL = 4)"; > sql(sql).withDecorrelate(true) > .withExpand(true) > .withRule(CoreRules.FILTER_INTO_JOIN, > CoreRules.JOIN_CONDITION_PUSH, > CoreRules.JOIN_PUSH_TRANSITIVE_PREDICATES) > .check(); > }{code} > !2.png|width=563,height=175! > In the case where the left side of the Join already has an identical > predicate (>($5, 1000)), JOIN_PUSH_TRANSITIVE_PREDICATES infers a new > predicate (LogicalFilter(condition=[>($5, 1000)])) from the right side of the > Join and puts it on the left side of the Join. This is because the Project on > the left side of the Join has SAL=[$5], SAL0=[$5], and > JOIN_PUSH_TRANSITIVE_PREDICATES fails to find this predicate, so it creates a > new one. > If we add a new rule CoreRules.FILTER_PROJECT_TRANSPOSE to this test case > and modify it slightly, it will also fall into an infinite loop. > {code:java} > @Test void testJoinPushTransitivePredicatesRule2() { > final String sql = "select n1.SAL\n" > + "from EMPNULLABLES_20 n1\n" > + "where n1.SAL IN (\n" > + " select n2.SAL\n" > + " from EMPNULLABLES_20 n2\n" > + " where n1.SAL = n2.SAL or n1.SAL = 4)"; > final HepProgram program = new HepProgramBuilder() > .addRuleCollection( > ImmutableList.of(CoreRules.FILTER_INTO_JOIN, > CoreRules.FILTER_PROJECT_TRANSPOSE, > CoreRules.JOIN_CONDITION_PUSH, > CoreRules.JOIN_PUSH_TRANSITIVE_PREDICATES)) > .build(); > sql(sql).withDecorrelate(true) > .withExpand(true) > .withProgram(program) > .check(); > } {code} -- This message was sent by Atlassian Jira (v8.20.10#820010)