Skip to content

Commit

Permalink
[CALCITE-6874] FilterCalcMergeRule/ProjectCalcMergeRule should not me…
Browse files Browse the repository at this point in the history
…rge a Filter/Project to Calc when it contains Subquery
  • Loading branch information
NobiGo committed Mar 7, 2025
1 parent 0ff9fcf commit b7e71a6
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexProgram;
import org.apache.calcite.rex.RexProgramBuilder;
import org.apache.calcite.rex.RexUtil;
import org.apache.calcite.tools.RelBuilderFactory;

import org.immutables.value.Value;
Expand Down Expand Up @@ -105,8 +106,9 @@ public interface Config extends RelRule.Config {
default Config withOperandFor(Class<? extends Filter> filterClass,
Class<? extends Calc> calcClass) {
return withOperandSupplier(b0 ->
b0.operand(filterClass).oneInput(b1 ->
b1.operand(calcClass).anyInputs()))
b0.operand(filterClass)
.predicate(filter -> !RexUtil.SubQueryFinder.containsSubQuery(filter))
.oneInput(b1 -> b1.operand(calcClass).anyInputs()))
.as(Config.class);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.apache.calcite.rex.RexOver;
import org.apache.calcite.rex.RexProgram;
import org.apache.calcite.rex.RexProgramBuilder;
import org.apache.calcite.rex.RexUtil;
import org.apache.calcite.tools.RelBuilderFactory;
import org.apache.calcite.util.Pair;

Expand Down Expand Up @@ -120,8 +121,9 @@ public interface Config extends RelRule.Config {
default Config withOperandFor(Class<? extends Project> projectClass,
Class<? extends Calc> calcClass) {
return withOperandSupplier(b0 ->
b0.operand(projectClass).oneInput(b1 ->
b1.operand(calcClass).anyInputs()))
b0.operand(projectClass)
.predicate(project -> !RexUtil.SubQueryFinder.containsSubQuery(project))
.oneInput(b1 -> b1.operand(calcClass).anyInputs()))
.as(Config.class);
}
}
Expand Down
31 changes: 31 additions & 0 deletions core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -9711,6 +9711,37 @@ private void checkJoinAssociateRuleWithTopAlwaysTrueCondition(boolean allowAlway
.check();
}

/**
* Test case for
* <a href="https://issues.apache.org/jira/browse/CALCITE-6874">[CALCITE-6874]
* FilterCalcMergeRule/ProjectCalcMergeRule should not merge a Filter/Project to Calc
* when it contains Subquery</a>. */
@Test void testFilterCalcMergeRule() {
final String sql = "select deptno from sales.emp where\n"
+ "exists (select deptno from sales.emp where empno < 20)\n";
HepProgram program = new HepProgramBuilder()
.addRuleInstance(CoreRules.PROJECT_FILTER_TRANSPOSE)
.addRuleInstance(CoreRules.PROJECT_TO_CALC)
.build();
sql(sql)
.withPre(program)
.withRule(CoreRules.FILTER_CALC_MERGE)
.checkUnchanged();
}

@Test void testProjectCalcMergeRule() {
final String sql = "select exists (select deptno from sales.emp)\n"
+ "from (select deptno from sales.emp where empno < 20)\n";
HepProgram program = new HepProgramBuilder()
.addRuleInstance(CoreRules.PROJECT_FILTER_TRANSPOSE)
.addRuleInstance(CoreRules.FILTER_TO_CALC)
.build();
sql(sql)
.withPre(program)
.withRule(CoreRules.PROJECT_CALC_MERGE)
.checkUnchanged();
}

/**
* Test case of
* <a href="https://issues.apache.org/jira/browse/CALCITE-6850">[CALCITE-6850]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5100,6 +5100,23 @@ MyProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], C
MultiJoin(joinFilter=[true], isFullOuterJoin=[false], joinTypes=[[INNER, LEFT]], outerJoinConditions=[[NULL, =($7, $9)]], projFields=[[{0, 1, 2, 3, 4, 5, 6, 7, 8}, {0, 1}]], postJoinFilter=[>($9, 3)])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
]]>
</Resource>
</TestCase>
<TestCase name="testFilterCalcMergeRule">
<Resource name="sql">
<![CDATA[select deptno from sales.emp where
exists (select deptno from sales.emp where empno < 20)
]]>
</Resource>
<Resource name="planBefore">
<![CDATA[
LogicalFilter(condition=[EXISTS({
LogicalFilter(condition=[<($0, 20)])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
})])
LogicalCalc(expr#0..8=[{inputs}], DEPTNO=[$t7])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
</TestCase>
Expand Down Expand Up @@ -8643,6 +8660,23 @@ LogicalProject(EXPR$0=[*($0, 2)], SS0=[$1])
LogicalAggregate(group=[{}], SUM_SAL=[SUM($0)], agg#1=[$SUM0($0)])
LogicalProject(SAL=[$5])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
</TestCase>
<TestCase name="testProjectCalcMergeRule">
<Resource name="sql">
<![CDATA[select exists (select deptno from sales.emp)
from (select deptno from sales.emp where empno < 20)
]]>
</Resource>
<Resource name="planBefore">
<![CDATA[
LogicalProject(EXPR$0=[EXISTS({
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
})])
LogicalCalc(expr#0=[{inputs}], expr#1=[20], expr#2=[<($t0, $t1)], EMPNO=[$t0], $condition=[$t2])
LogicalProject(EMPNO=[$0])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
</TestCase>
Expand Down

0 comments on commit b7e71a6

Please sign in to comment.