Skip to content

Commit 583e73f

Browse files
committed
[CALCITE-7373] FILTER_INTO_JOIN should not push Filter into a join when the Filter contains non-deterministic function
1 parent 17af184 commit 583e73f

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

core/src/main/java/org/apache/calcite/rel/rules/FilterJoinRule.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,15 @@ protected FilterJoinRule(C config) {
7272

7373
protected void perform(RelOptRuleCall call, @Nullable Filter filter,
7474
Join join) {
75+
// Skip non-deterministic filter condition
76+
if (filter != null && !RexUtil.isDeterministic(filter.getCondition())) {
77+
return;
78+
}
79+
// Skip non-deterministic join condition
80+
if (!RexUtil.isDeterministic(join.getCondition())) {
81+
return;
82+
}
83+
7584
List<RexNode> joinFilters =
7685
RelOptUtil.conjunctions(join.getCondition());
7786
final List<RexNode> origJoinFilters = ImmutableList.copyOf(joinFilters);

core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2187,6 +2187,33 @@ private void checkSemiOrAntiJoinProjectTranspose(JoinRelType type) {
21872187
assertTrue(join.getHints().contains(noHashJoinHint));
21882188
}
21892189

2190+
/** Test case for
2191+
* <a href="https://issues.apache.org/jira/browse/CALCITE-7373">[CALCITE-7373]
2192+
* FILTER_INTO_JOIN should not push Filter into a join
2193+
* when the Filter contains non-deterministic function</a>. */
2194+
@Test void testPushFilterThroughJoinWithNonDeterministic() {
2195+
final String sql = "select * from (\n"
2196+
+ " select * from dept inner join\n"
2197+
+ " emp on dept.deptno = emp.deptno) R\n"
2198+
+ "where 0.9 <= rand()";
2199+
sql(sql)
2200+
.withRule(CoreRules.FILTER_PROJECT_TRANSPOSE,
2201+
CoreRules.FILTER_INTO_JOIN,
2202+
CoreRules.JOIN_CONDITION_PUSH)
2203+
.check();
2204+
}
2205+
2206+
@Test void testPushJoinConditionWithNonDeterministic() {
2207+
final String sql = "select * from (\n"
2208+
+ " select * from dept inner join\n"
2209+
+ " emp on dept.deptno = emp.deptno and emp.mgr <= rand()) R\n";
2210+
sql(sql)
2211+
.withRule(CoreRules.FILTER_PROJECT_TRANSPOSE,
2212+
CoreRules.FILTER_INTO_JOIN,
2213+
CoreRules.JOIN_CONDITION_PUSH)
2214+
.checkUnchanged();
2215+
}
2216+
21902217
/** Test case for
21912218
* <a href="https://issues.apache.org/jira/browse/CALCITE-438">[CALCITE-438]
21922219
* Push predicates through SemiJoin</a>. */

core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14228,6 +14228,34 @@ LogicalProject(DNAME=[$1])
1422814228
LogicalTableScan(table=[[scott, DEPT]])
1422914229
LogicalFilter(condition=[=($5, 100)])
1423014230
LogicalTableScan(table=[[scott, EMP]])
14231+
]]>
14232+
</Resource>
14233+
</TestCase>
14234+
<TestCase name="testPushFilterThroughJoinWithNonDeterministic">
14235+
<Resource name="sql">
14236+
<![CDATA[select * from (
14237+
select * from dept inner join
14238+
emp on dept.deptno = emp.deptno) R
14239+
where 0.9 <= rand()]]>
14240+
</Resource>
14241+
<Resource name="planBefore">
14242+
<![CDATA[
14243+
LogicalProject(DEPTNO=[$0], NAME=[$1], EMPNO=[$2], ENAME=[$3], JOB=[$4], MGR=[$5], HIREDATE=[$6], SAL=[$7], COMM=[$8], DEPTNO0=[$9], SLACKER=[$10])
14244+
LogicalFilter(condition=[<=(CAST(0.9:DECIMAL(2, 1)):DOUBLE NOT NULL, RAND())])
14245+
LogicalProject(DEPTNO=[$0], NAME=[$1], EMPNO=[$2], ENAME=[$3], JOB=[$4], MGR=[$5], HIREDATE=[$6], SAL=[$7], COMM=[$8], DEPTNO0=[$9], SLACKER=[$10])
14246+
LogicalJoin(condition=[=($0, $9)], joinType=[inner])
14247+
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
14248+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
14249+
]]>
14250+
</Resource>
14251+
<Resource name="planAfter">
14252+
<![CDATA[
14253+
LogicalProject(DEPTNO=[$0], NAME=[$1], EMPNO=[$2], ENAME=[$3], JOB=[$4], MGR=[$5], HIREDATE=[$6], SAL=[$7], COMM=[$8], DEPTNO0=[$9], SLACKER=[$10])
14254+
LogicalProject(DEPTNO=[$0], NAME=[$1], EMPNO=[$2], ENAME=[$3], JOB=[$4], MGR=[$5], HIREDATE=[$6], SAL=[$7], COMM=[$8], DEPTNO0=[$9], SLACKER=[$10])
14255+
LogicalFilter(condition=[<=(CAST(0.9:DECIMAL(2, 1)):DOUBLE NOT NULL, RAND())])
14256+
LogicalJoin(condition=[=($0, $9)], joinType=[inner])
14257+
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
14258+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
1423114259
]]>
1423214260
</Resource>
1423314261
</TestCase>
@@ -14337,6 +14365,22 @@ LogicalProject(DEPTNO=[$0], DEPTNO0=[$9])
1433714365
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
1433814366
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f9=[*($7, 2)])
1433914367
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
14368+
]]>
14369+
</Resource>
14370+
</TestCase>
14371+
<TestCase name="testPushJoinConditionWithNonDeterministic">
14372+
<Resource name="sql">
14373+
<![CDATA[select * from (
14374+
select * from dept inner join
14375+
emp on dept.deptno = emp.deptno and emp.mgr <= rand()) R
14376+
]]>
14377+
</Resource>
14378+
<Resource name="planBefore">
14379+
<![CDATA[
14380+
LogicalProject(DEPTNO=[$0], NAME=[$1], EMPNO=[$2], ENAME=[$3], JOB=[$4], MGR=[$5], HIREDATE=[$6], SAL=[$7], COMM=[$8], DEPTNO0=[$9], SLACKER=[$10])
14381+
LogicalJoin(condition=[AND(=($0, $9), <=(CAST($5):DOUBLE, RAND()))], joinType=[inner])
14382+
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
14383+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
1434014384
]]>
1434114385
</Resource>
1434214386
</TestCase>

0 commit comments

Comments
 (0)