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

Rick Hillegas updated DERBY-672:
--------------------------------

    Attachment: derby-672-02-ac-nonDistinct.diff

Attaching derby-672-02-ac-nonDistinct.diff. This patch adds bind() and 
execute() support for non-distinct user-defined aggregates. I am running 
regression tests now.

With this patch you can invoke user-defined aggregates in simple queries. These 
include both scalar and grouped results. So, for instance, the following script 
now runs correctly:

create derby aggregate mode for int external name 
'org.apache.derbyTesting.functionTests.tests.lang.ModeAggregate';
create table mode_inputs( a int, b int );
insert into mode_inputs( a, b ) values ( 1, 1 ), ( 1, 2 ), ( 1, 2 ), ( 1, 2 ), 
( 2, 3 ), ( 2, 3 ), ( 2, 4 );
select mode( b ) from mode_inputs;
select a, mode( b ) from mode_inputs group by a;

Support is NOT included for DISTINCT invocations of user-defined aggregates nor 
for user-defined aggregates in HAVING clauses.

On 2012-07-18 Knut wondered whether we would support parameterized aggregates, 
e.g., with elegant syntax like the following:

    create derby aggregate int_mode for int external name 
'GenericMode<Integer>'; 

Unfortunately, I have not been able to make this work. That is because type 
erasure makes it impossible to instantiate the aggregate via Class.forName(). 
The following sample code demonstrates the problem:

public  class   z
{
    public  static  void    main( String[] args ) throws Exception
    {
        // raises a ClassNotFoundException
        Class.forName( "java.util.ArrayList<String>" );
    }
}

Your thoughts about how to work around this limitation are welcome. In the 
meantime, the following less elegant syntax will work:

public  class   GenericMode<V extends Comparable<V>>    implements  
Aggregator<V,V,GenericMode<V>>
{
    public  static  final   class   IntMode extends GenericMode<Integer> {}

   ...
}

    create derby aggregate intMode for int external name 'GenericMode$IntMode';


Touches the following files:

-----------------

A       java/engine/org/apache/derby/agg
A       java/engine/org/apache/derby/agg/Aggregator.java
A       java/engine/org/apache/derby/agg/build.xml
M       tools/javadoc/publishedapi.ant
M       java/engine/build.xml

Adds this interface to the public api. This is the interface which users 
implement in order to create a user-defined aggregate.

-----------------

M       java/engine/org/apache/derby/impl/services/reflect/DatabaseClasses.java
A       
java/engine/org/apache/derby/impl/services/reflect/Java5ClassFactory.java
M       
java/engine/org/apache/derby/impl/services/reflect/ReflectClassesJava2.java
M       java/engine/org/apache/derby/impl/services/build.xml
M       java/engine/org/apache/derby/modules.properties
M       java/engine/org/apache/derby/iapi/services/build.xml
A       
java/engine/org/apache/derby/iapi/services/loader/Java5ClassInspector.java
M       java/engine/org/apache/derby/iapi/services/loader/ClassInspector.java

Adds a new implementation of the ClassFactory module, for use on JVMs which 
support generics. Adds the following new method to ClassInspector:

        /**
         * Given an implementation of a parameterized class/interface, return
     * the actual concrete types of the parameters. Types are returned in the
     * order that they are declared by the parameterized class/interface.
     * So for instance, if the parameterized class is Map<K,V> and the
     * implementation is HashMap<Integer,String>, then the return value is
     * [ Integer.class, String.class ]. This method raises an exception if the
     * JVM does not support generics. May return null if type resolution fails.
         */
        public Class[] getGenericParameterTypes( Class parameterizedType, Class 
implementation )
        throws StandardException;

On CDC/FP this method raises an exception. On Java 5 and higher, this resolves 
the types of the generic variables. Fortunately, this type resolution is 
possible via the reflection classes. Unfortunately, getting at this information 
is far from straightforward.

-----------------

M       java/engine/org/apache/derby/catalog/types/AggregateAliasInfo.java

Added some accessors to this metadata descriptor.

-----------------

M       java/engine/org/apache/derby/impl/sql/compile/MethodCallNode.java
M       java/engine/org/apache/derby/impl/sql/compile/AggregateNode.java
M       java/engine/org/apache/derby/impl/sql/compile/JavaToSQLValueNode.java
A       
java/engine/org/apache/derby/impl/sql/compile/UserAggregateDefinition.java
M       java/engine/org/apache/derby/impl/sql/compile/JavaValueNode.java
M       java/engine/org/apache/derby/impl/sql/compile/AggregateDefinition.java
M       java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java

Bind-time logic for handling non-distinct user-defined aggregates in the SELECT 
list. These are the highlights:

1) JavaToSQLValueNode.bindExpression() and 
StaticMethodCallNode.bindExpression() cooperate to check whether the invocation 
of a single-arg function is actually the invocation of a user-defined aggregate.

2) If so, StaticMethodCallNode.bindExpression() returns an AggregateNode 
wrapping a UserAggregateDefinition.

3) UserAggregateDefinition calls ClassInspector.getGenericParameterTypes() in 
order to resolve the user-defined aggregate's types. It is expected that the 
actual types will correspond to the declared types under the same rules which 
map SQL routines args to Java method args.

-----------------

M       java/engine/org/apache/derby/iapi/sql/execute/ExecAggregator.java
M       java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java
M       java/engine/org/apache/derby/iapi/reference/ClassName.java
M       java/engine/org/apache/derby/impl/sql/execute/GenericAggregator.java
M       java/engine/org/apache/derby/impl/sql/execute/CountAggregator.java
M       java/engine/org/apache/derby/impl/sql/execute/MaxMinAggregator.java
A       java/engine/org/apache/derby/impl/sql/execute/UserDefinedAggregator.java
M       java/engine/org/apache/derby/impl/sql/execute/OrderableAggregator.java
M       tools/jar/extraDBMSclasses.properties

Execution logic for invoking user-defined aggregates. Some additional 
parameters were added to the ExecAggregator.setup() method. The guts of the 
execution logic are in UserDefinedAggregator, a new implementation of 
ExecAggregator.

-----------------

M       java/engine/org/apache/derby/loc/messages.xml
M       java/shared/org/apache/derby/shared/common/reference/SQLState.java
M       java/shared/org/apache/derby/shared/common/reference/MessageId.java

New error messages.

-----------------

A       
java/testing/org/apache/derbyTesting/functionTests/tests/lang/GenericMode.java
A       
java/testing/org/apache/derbyTesting/functionTests/tests/lang/ModeAggregate.java
M       
java/testing/org/apache/derbyTesting/functionTests/tests/lang/UserDefinedAggregatesTest.java
M       java/testing/org/apache/derbyTesting/functionTests/tests/lang/build.xml
M       
java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java

Tests for this functionality. Includes tests for scalar and grouped 
user-defined aggregates. Includes tests for user-defined aggregates which 
extend generic implementations. These tests do not run on small devices.

-----------------

M       
java/testing/org/apache/derbyTesting/functionTests/tests/lang/UngroupedAggregatesNegativeTest.java

Added a test case for CDC/FP, verifying that we raise a reasonable error if 
someone tries to execute a user-defined aggregate on a small device.

                
> Re-enable user defined aggregates
> ---------------------------------
>
>                 Key: DERBY-672
>                 URL: https://issues.apache.org/jira/browse/DERBY-672
>             Project: Derby
>          Issue Type: Improvement
>          Components: SQL
>            Reporter: Rick Hillegas
>            Assignee: Rick Hillegas
>         Attachments: derby-672-01-aa-ddl.diff, 
> derby-672-02-ac-nonDistinct.diff, UserDefinedAggregates.html, 
> UserDefinedAggregates.html
>
>
> Nicolas Dufour in an email thread titled "functions and list" started on 
> November 2, 2005 requests the ability to create user defined aggregates.
> This functionality used to be in Cloudscape. It was disabled presumably 
> because it was considered non-standard. However, most of the machinery needed 
> for this feature is still in the code. We should re-enable user defined 
> aggregates after we agree on acceptable syntax.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to