Skip to content

Commit d2f7f9c

Browse files
Address comments and add tests
1 parent 71bf25f commit d2f7f9c

3 files changed

Lines changed: 138 additions & 2 deletions

File tree

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@
3434
import java.util.Map;
3535

3636
/**
37-
* AggregateExtractLiteralAggRule gets rid of the LITERAL_AGG into most databases can handle.
37+
* Rule transforms an {@link org.apache.calcite.rel.core.Aggregate} containing
38+
* {@code LITERAL_AGG} aggregate function into an {@code Aggregate} that still
39+
* performs "group by" on the relevant groups, while placing a {@code Project}
40+
* RelNode on top that returns the literal value.
3841
*/
3942
@Value.Enclosing
4043
public class AggregateExtractLiteralAggRule
@@ -121,7 +124,6 @@ protected AggregateExtractLiteralAggRule(Config config) {
121124
@Value.Immutable
122125
public interface Config extends RelRule.Config {
123126
Config DEFAULT = ImmutableAggregateExtractLiteralAggRule.Config.of()
124-
.withRelBuilderFactory(RelBuilder.proto())
125127
.withOperandSupplier(b0 ->
126128
b0.operand(Aggregate.class).anyInputs());
127129

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11413,4 +11413,47 @@ private void checkLoptOptimizeJoinRule(LoptOptimizeJoinRule rule) {
1141311413
})
1141411414
.check();
1141511415
}
11416+
11417+
/** Test case of
11418+
* <a href="https://issues.apache.org/jira/browse/CALCITE-7242">[CALCITE-7242]
11419+
* Implement a rule to eliminate LITERAL_AGG so that other databases can handle it</a>. */
11420+
@Test void testAggregateExtractLiteralAggRule1() {
11421+
final String sql = "select deptno, name = ANY (\n"
11422+
+ " select mgr from emp)\n"
11423+
+ "from dept";
11424+
sql(sql)
11425+
.withSubQueryRules()
11426+
.withLateDecorrelate(true)
11427+
.withAfter((fixture, rel) -> {
11428+
final HepProgram program = HepProgram.builder()
11429+
.addRuleInstance(CoreRules.AGGREGATE_EXTRACT_LITERAL_AGG)
11430+
.build();
11431+
final HepPlanner hep = new HepPlanner(program);
11432+
hep.setRoot(rel);
11433+
return hep.findBestExp();
11434+
})
11435+
.check();
11436+
}
11437+
11438+
/** Test case of
11439+
* <a href="https://issues.apache.org/jira/browse/CALCITE-7242">[CALCITE-7242]
11440+
* Implement a rule to eliminate LITERAL_AGG so that other databases can handle it</a>. */
11441+
@Test void testAggregateExtractLiteralAggRule2() {
11442+
final String sql = "select empno\n"
11443+
+ "from sales.emp\n"
11444+
+ "where deptno in (select deptno from sales.emp where empno < 20)\n"
11445+
+ "or emp.sal < 100";
11446+
sql(sql)
11447+
.withSubQueryRules()
11448+
.withLateDecorrelate(true)
11449+
.withAfter((fixture, rel) -> {
11450+
final HepProgram program = HepProgram.builder()
11451+
.addRuleInstance(CoreRules.AGGREGATE_EXTRACT_LITERAL_AGG)
11452+
.build();
11453+
final HepPlanner hep = new HepPlanner(program);
11454+
hep.setRoot(rel);
11455+
return hep.findBestExp();
11456+
})
11457+
.check();
11458+
}
1141611459
}

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

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,97 @@ LogicalProject(HIREDATE=[$1])
216216
LogicalProject(MGR=[$3])
217217
LogicalFilter(condition=[AND(IS NULL($3), =($4, CURRENT_TIMESTAMP))])
218218
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
219+
]]>
220+
</Resource>
221+
</TestCase>
222+
<TestCase name="testAggregateExtractLiteralAggRule1">
223+
<Resource name="sql">
224+
<![CDATA[select deptno, name = ANY (
225+
select mgr from emp)
226+
from dept]]>
227+
</Resource>
228+
<Resource name="planBefore">
229+
<![CDATA[
230+
LogicalProject(DEPTNO=[$0], EXPR$1=[IN($1, {
231+
LogicalProject(MGR=[$3])
232+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
233+
})])
234+
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
235+
]]>
236+
</Resource>
237+
<Resource name="planMid">
238+
<![CDATA[
239+
LogicalProject(DEPTNO=[$0], EXPR$1=[OR(AND(IS NOT NULL($5), <>($2, 0)), AND(<($3, $2), null, <>($2, 0), IS NULL($5)))])
240+
LogicalJoin(condition=[=($1, $4)], joinType=[left])
241+
LogicalJoin(condition=[true], joinType=[inner])
242+
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
243+
LogicalAggregate(group=[{}], c=[COUNT()], ck=[COUNT($0)])
244+
LogicalProject(MGR=[$3])
245+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
246+
LogicalAggregate(group=[{0}], i=[LITERAL_AGG(true)])
247+
LogicalProject(MGR=[$3])
248+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
249+
]]>
250+
</Resource>
251+
<Resource name="planAfter">
252+
<![CDATA[
253+
LogicalProject(DEPTNO=[$0], EXPR$1=[OR(AND(IS NOT NULL($5), <>($2, 0)), AND(<($3, $2), null, <>($2, 0), IS NULL($5)))])
254+
LogicalJoin(condition=[=($1, $4)], joinType=[left])
255+
LogicalJoin(condition=[true], joinType=[inner])
256+
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
257+
LogicalAggregate(group=[{}], c=[COUNT()], ck=[COUNT($0)])
258+
LogicalProject(MGR=[$3])
259+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
260+
LogicalProject(MGR=[$0], $f1=[true])
261+
LogicalAggregate(group=[{0}])
262+
LogicalProject(MGR=[$3])
263+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
264+
]]>
265+
</Resource>
266+
</TestCase>
267+
<TestCase name="testAggregateExtractLiteralAggRule2">
268+
<Resource name="sql">
269+
<![CDATA[select empno
270+
from sales.emp
271+
where deptno in (select deptno from sales.emp where empno < 20)
272+
or emp.sal < 100]]>
273+
</Resource>
274+
<Resource name="planBefore">
275+
<![CDATA[
276+
LogicalProject(EMPNO=[$0])
277+
LogicalFilter(condition=[OR(IN($7, {
278+
LogicalProject(DEPTNO=[$7])
279+
LogicalFilter(condition=[<($0, 20)])
280+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
281+
}), <($5, 100))])
282+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
283+
]]>
284+
</Resource>
285+
<Resource name="planMid">
286+
<![CDATA[
287+
LogicalProject(EMPNO=[$0])
288+
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
289+
LogicalFilter(condition=[OR(IS NOT NULL($10), <($5, 100))])
290+
LogicalJoin(condition=[=($7, $9)], joinType=[left])
291+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
292+
LogicalAggregate(group=[{0}], i=[LITERAL_AGG(true)])
293+
LogicalProject(DEPTNO=[$7])
294+
LogicalFilter(condition=[<($0, 20)])
295+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
296+
]]>
297+
</Resource>
298+
<Resource name="planAfter">
299+
<![CDATA[
300+
LogicalProject(EMPNO=[$0])
301+
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
302+
LogicalFilter(condition=[OR(IS NOT NULL($10), <($5, 100))])
303+
LogicalJoin(condition=[=($7, $9)], joinType=[left])
304+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
305+
LogicalProject(DEPTNO=[$0], $f1=[true])
306+
LogicalAggregate(group=[{0}])
307+
LogicalProject(DEPTNO=[$7])
308+
LogicalFilter(condition=[<($0, 20)])
309+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
219310
]]>
220311
</Resource>
221312
</TestCase>

0 commit comments

Comments
 (0)