db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Rick Hillegas (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (DERBY-672) Re-enable user defined aggregates
Date Tue, 28 Aug 2012 20:13:08 GMT

     [ 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

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,
> 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

View raw message