Skip to content

Commit 25f57be

Browse files
Address comments and add tests
1 parent 466ebea commit 25f57be

File tree

3 files changed

+137
-3
lines changed

3 files changed

+137
-3
lines changed

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: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11973,4 +11973,45 @@ private void checkLoptOptimizeJoinRule(LoptOptimizeJoinRule rule) {
1197311973
.check();
1197411974
}
1197511975

11976-
}
11976+
/** Test case of
11977+
* <a href="https://issues.apache.org/jira/browse/CALCITE-7242">[CALCITE-7242]
11978+
* Implement a rule to eliminate LITERAL_AGG so that other databases can handle it</a>. */
11979+
@Test void testAggregateExtractLiteralAggRule1() {final String sql = "select deptno, name = ANY (\n"
11980+
+ " select mgr from emp)\n"
11981+
+ "from dept";
11982+
sql(sql)
11983+
.withSubQueryRules()
11984+
.withLateDecorrelate(true)
11985+
.withAfter((fixture, rel) -> {
11986+
final HepProgram program = HepProgram.builder()
11987+
.addRuleInstance(CoreRules.AGGREGATE_EXTRACT_LITERAL_AGG)
11988+
.build();
11989+
final HepPlanner hep = new HepPlanner(program);
11990+
hep.setRoot(rel);
11991+
return hep.findBestExp();
11992+
})
11993+
.check();
11994+
}
11995+
11996+
/** Test case of
11997+
* <a href="https://issues.apache.org/jira/browse/CALCITE-7242">[CALCITE-7242]
11998+
* Implement a rule to eliminate LITERAL_AGG so that other databases can handle it</a>. */
11999+
@Test void testAggregateExtractLiteralAggRule2() {
12000+
final String sql = "select empno\n"
12001+
+ "from sales.emp\n"
12002+
+ "where deptno in (select deptno from sales.emp where empno < 20)\n"
12003+
+ "or emp.sal < 100";
12004+
sql(sql)
12005+
.withSubQueryRules()
12006+
.withLateDecorrelate(true)
12007+
.withAfter((fixture, rel) -> {
12008+
final HepProgram program = HepProgram.builder()
12009+
.addRuleInstance(CoreRules.AGGREGATE_EXTRACT_LITERAL_AGG)
12010+
.build();
12011+
final HepPlanner hep = new HepPlanner(program);
12012+
hep.setRoot(rel);
12013+
return hep.findBestExp();
12014+
})
12015+
.check();
12016+
}
12017+
}

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

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,97 @@ LogicalProject(HIREDATE=[$1])
229229
LogicalProject(MGR=[$3])
230230
LogicalFilter(condition=[AND(IS NULL($3), =($4, CURRENT_TIMESTAMP))])
231231
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
232+
]]>
233+
</Resource>
234+
</TestCase>
235+
<TestCase name="testAggregateExtractLiteralAggRule1">
236+
<Resource name="sql">
237+
<![CDATA[select deptno, name = ANY (
238+
select mgr from emp)
239+
from dept]]>
240+
</Resource>
241+
<Resource name="planBefore">
242+
<![CDATA[
243+
LogicalProject(DEPTNO=[$0], EXPR$1=[IN($1, {
244+
LogicalProject(MGR=[$3])
245+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
246+
})])
247+
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
248+
]]>
249+
</Resource>
250+
<Resource name="planMid">
251+
<![CDATA[
252+
LogicalProject(DEPTNO=[$0], EXPR$1=[OR(AND(IS NOT NULL($5), <>($2, 0)), AND(<($3, $2), null, <>($2, 0), IS NULL($5)))])
253+
LogicalJoin(condition=[=($1, $4)], joinType=[left])
254+
LogicalJoin(condition=[true], joinType=[inner])
255+
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
256+
LogicalAggregate(group=[{}], c=[COUNT()], ck=[COUNT($0)])
257+
LogicalProject(MGR=[$3])
258+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
259+
LogicalAggregate(group=[{0}], i=[LITERAL_AGG(true)])
260+
LogicalProject(MGR=[$3])
261+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
262+
]]>
263+
</Resource>
264+
<Resource name="planAfter">
265+
<![CDATA[
266+
LogicalProject(DEPTNO=[$0], EXPR$1=[OR(AND(IS NOT NULL($5), <>($2, 0)), AND(<($3, $2), null, <>($2, 0), IS NULL($5)))])
267+
LogicalJoin(condition=[=($1, $4)], joinType=[left])
268+
LogicalJoin(condition=[true], joinType=[inner])
269+
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
270+
LogicalAggregate(group=[{}], c=[COUNT()], ck=[COUNT($0)])
271+
LogicalProject(MGR=[$3])
272+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
273+
LogicalProject(MGR=[$0], $f1=[true])
274+
LogicalAggregate(group=[{0}])
275+
LogicalProject(MGR=[$3])
276+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
277+
]]>
278+
</Resource>
279+
</TestCase>
280+
<TestCase name="testAggregateExtractLiteralAggRule2">
281+
<Resource name="sql">
282+
<![CDATA[select empno
283+
from sales.emp
284+
where deptno in (select deptno from sales.emp where empno < 20)
285+
or emp.sal < 100]]>
286+
</Resource>
287+
<Resource name="planBefore">
288+
<![CDATA[
289+
LogicalProject(EMPNO=[$0])
290+
LogicalFilter(condition=[OR(IN($7, {
291+
LogicalProject(DEPTNO=[$7])
292+
LogicalFilter(condition=[<($0, 20)])
293+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
294+
}), <($5, 100))])
295+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
296+
]]>
297+
</Resource>
298+
<Resource name="planMid">
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+
LogicalAggregate(group=[{0}], i=[LITERAL_AGG(true)])
306+
LogicalProject(DEPTNO=[$7])
307+
LogicalFilter(condition=[<($0, 20)])
308+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
309+
]]>
310+
</Resource>
311+
<Resource name="planAfter">
312+
<![CDATA[
313+
LogicalProject(EMPNO=[$0])
314+
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
315+
LogicalFilter(condition=[OR(IS NOT NULL($10), <($5, 100))])
316+
LogicalJoin(condition=[=($7, $9)], joinType=[left])
317+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
318+
LogicalProject(DEPTNO=[$0], $f1=[true])
319+
LogicalAggregate(group=[{0}])
320+
LogicalProject(DEPTNO=[$7])
321+
LogicalFilter(condition=[<($0, 20)])
322+
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
232323
]]>
233324
</Resource>
234325
</TestCase>

0 commit comments

Comments
 (0)