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

Mime
View raw message