[ 
https://issues.apache.org/jira/browse/CALCITE-1434?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Arun Mahadevan updated CALCITE-1434:
------------------------------------
    Description: 
We have an interface like below which we want to expose to users for writing 
aggregate functions.

{noformat}
public interface UDAF<A, V, R> {
    A init();
    A add(A aggregate, V val);
    R result(A aggregate);
}
{noformat}


Internally we create an instance of AggregateFunctionImpl and register the 
Function in SchemaPlus. However this doesn't work for example if we have an 
implementation like below,

{noformat}
public class MySum implements UDAF<Number, Number, Number> {
    @Override
    public Number init() {...}
    @Override
    public Number add(Number aggregate, Number val) {...}
    @Override
    public Number result(Number aggregate) {...}
}
{noformat}

We get an Exception "java.lang.RuntimeException: In user-defined aggregate 
class 'x.y.z.$MySum', first parameter to 'add' method must be the accumulator 
(the return type of the 'init' method)"

This happens because the ReflectiveFunctionBase.findMethod is trying to look 
for a method name "init" and it get a method with a different signature (that 
returns Object) instead of the actual method defined in MySum. This happens to 
be a 'bridge' method inserted by java.

In findMethod, the bridge methods can be skipped while looking for the method 
by name. 

  was:
We have an interface like below which we want to expose to users for writing 
aggregate functions.

public interface UDAF<A, V, R> {
    A init();
    A add(A aggregate, V val);
    R result(A aggregate);
}

Internally we create an instance of AggregateFunctionImpl and register the 
Function in SchemaPlus. However this doesn't work for example if we have an 
implementation like below,

public class MySum implements UDAF<Number, Number, Number> {
    @Override
    public Number init() {...}
    @Override
    public Number add(Number aggregate, Number val) {...}
    @Override
    public Number result(Number aggregate) {...}
}

We get an Exception "java.lang.RuntimeException: In user-defined aggregate 
class 'x.y.z.$MySum', first parameter to 'add' method must be the accumulator 
(the return type of the 'init' method)"

This happens because the ReflectiveFunctionBase.findMethod is trying to look 
for a method name "init" and it get a method with a different signature (that 
returns Object) instead of the actual method defined in MySum. This happens to 
be a 'bridge' method inserted by java.

In findMethod, the bridge methods can be skipped while looking for the method 
by name. 


> AggregateFunctionImpl doesnt work if the class implements a generic interface
> -----------------------------------------------------------------------------
>
>                 Key: CALCITE-1434
>                 URL: https://issues.apache.org/jira/browse/CALCITE-1434
>             Project: Calcite
>          Issue Type: Bug
>            Reporter: Arun Mahadevan
>            Assignee: Julian Hyde
>
> We have an interface like below which we want to expose to users for writing 
> aggregate functions.
> {noformat}
> public interface UDAF<A, V, R> {
>     A init();
>     A add(A aggregate, V val);
>     R result(A aggregate);
> }
> {noformat}
> Internally we create an instance of AggregateFunctionImpl and register the 
> Function in SchemaPlus. However this doesn't work for example if we have an 
> implementation like below,
> {noformat}
> public class MySum implements UDAF<Number, Number, Number> {
>     @Override
>     public Number init() {...}
>     @Override
>     public Number add(Number aggregate, Number val) {...}
>     @Override
>     public Number result(Number aggregate) {...}
> }
> {noformat}
> We get an Exception "java.lang.RuntimeException: In user-defined aggregate 
> class 'x.y.z.$MySum', first parameter to 'add' method must be the accumulator 
> (the return type of the 'init' method)"
> This happens because the ReflectiveFunctionBase.findMethod is trying to look 
> for a method name "init" and it get a method with a different signature (that 
> returns Object) instead of the actual method defined in MySum. This happens 
> to be a 'bridge' method inserted by java.
> In findMethod, the bridge methods can be skipped while looking for the method 
> by name. 



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to