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 <m.gelb...@gmail.com> 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

Reply via email to