You're correct, my mistake. Now I unwrapped this drill-specific class and converted the *LogicalAggregate* to *JdbcAggregate* my self. But the unparsed SQL is still using a subquery.
Drill seems to use a custom build of Calcite v.1.4. The difference between the *implement* method of JdbcAggregate in v1.4 and the master branch is considerably different. Thank you. *---------------------* *Muhammad Gelbana* http://www.linkedin.com/in/mgelbana On Thu, Jun 1, 2017 at 5:31 PM, Julian Hyde <[email protected]> wrote: > There is already a rule that does this: JdbcRules.JdbcAggregateRule. > > I don’t know what DrillCalciteSqlAggFunctionWrapper is; it seems > Drill-specific. > > > On Jun 1, 2017, at 4:20 AM, Muhammad Gelbana <[email protected]> > wrote: > > > > > > The following query > > *SELECT COUNT(**CNTRn**) FROM incorta.SLS.CNTR* > > > > Is translated to the following > > *SELECT COUNT("**CNTRn**") AS "EXPR$0"* > > *FROM (SELECT "**CNTRn**" FROM "**SLS**"."**CNTR**") AS "t"* > > > > But I want to pushdown the whole aggregation so the output query would be > > *SELECT COUNT("**CNTRn**") FROM "**SLS**"."**CNTR**"* > > > > To do so, I wrote a rule that matches *LogicalAggregate* with input > > *JdbcProject*, and transformed the *LogicalAggregate* to a > *JdbcAggregate* > > node with it's input being the *JdbcProject*. > > > > public void onMatch(RelOptRuleCall call) { > >> LogicalAggregate aggregate = call.rel(0); > >> RelNode input = ((HepRelVertex) aggregate.getInput()). > getCurrentRel(); > >> JdbcAggregate newAggregate; > >> try { > >> newAggregate = new JdbcRules.JdbcAggregate( > aggregate.getCluster(), > >> aggregate.getTraitSet().replace(this.outConvention), *input*, > >> aggregate.indicator, aggregate.getGroupSet(), aggregate.getGroupSets(), > >> aggregate.getAggCallList()); > >> call.transformTo(newAggregate); > >> } catch (InvalidRelException e) { > >> e.printStackTrace(); > >> } > >> } > > > > > > But that threw the following exception because the aggregation class type > > of the aggregate call is of type *DrillCalciteSqlAggFunctionWrapper* > while > > *JdbcRules.AGG_FUNCS* (i.e. *ImmutableList*) doesn't contain this type > > (Check *org.apache.calcite.adapter.jdbc.JdbcRules.JdbcAggregate. > canImplement(SqlAggFunction, > > SqlDialect)* for details) > > > > org.apache.calcite.rel.InvalidRelException: cannot implement aggregate > >> function COUNT > >> at > >> org.apache.calcite.adapter.jdbc.JdbcRules$JdbcAggregate.< > init>(JdbcRules.java:710) > > > > > > So I tried providing a different aggregate call list *manually*: > > > > public void onMatch(RelOptRuleCall call) { > >> LogicalAggregate aggregate = call.rel(0); > >> RelNode input = ((HepRelVertex) aggregate.getInput()). > getCurrentRel(); > >> JdbcAggregate newAggregate; > >> try { > >> AggregateCall agg = aggregate.getAggCallList().get(0); > >> AggregateCall newAgg = > >> AggregateCall.create(SqlStdOperatorTable.COUNT, agg.isDistinct(), > >> agg.getArgList(), agg.filterArg, agg.type, agg.name); > >> List<AggregateCall> *sqlAggCallList* = Arrays.asList(newAgg); > >> newAggregate = new JdbcRules.JdbcAggregate( > aggregate.getCluster(), > >> aggregate.getTraitSet().replace(this.outConvention), input, > >> aggregate.indicator, aggregate.getGroupSet(), aggregate.getGroupSets(), > >> *sqlAggCallList*); > >> call.transformTo(newAggregate); > >> } catch (InvalidRelException e) { > >> e.printStackTrace(); > >> } > >> } > > > > > > And this output the following query > > *SELECT COUNT("**CNTRn**") AS "EXPR$0"* > > *FROM (SELECT "**CNTRn**" FROM "**SLS**"."**CNTR**") AS "t"* > > > > But this isn't the syntax I was hoping for because the datasource I'm > using > > doesn't support subqueries. > > > > Again, this is what I'm aiming for > > *SELECT COUNT("**CNTRn**") FROM "**SLS**"."**CNTR**"* > > > > *---------------------* > > *Muhammad Gelbana* > > http://www.linkedin.com/in/mgelbana > >
