db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhille...@apache.org
Subject svn commit: r1378639 [1/2] - in /db/derby/code/trunk: java/engine/ java/engine/org/apache/derby/ java/engine/org/apache/derby/agg/ java/engine/org/apache/derby/catalog/types/ java/engine/org/apache/derby/iapi/reference/ java/engine/org/apache/derby/iap...
Date Wed, 29 Aug 2012 16:52:59 GMT
Author: rhillegas
Date: Wed Aug 29 16:52:58 2012
New Revision: 1378639

URL: http://svn.apache.org/viewvc?rev=1378639&view=rev
Log:
DERBY-672: Wire in bind and execute logic for non-distinct user-defined aggregates in the SELECT list.

Added:
    db/derby/code/trunk/java/engine/org/apache/derby/agg/
    db/derby/code/trunk/java/engine/org/apache/derby/agg/Aggregator.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/agg/build.xml   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/loader/Java5ClassInspector.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/Java5ClassFactory.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UserAggregateDefinition.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UserDefinedAggregator.java   (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GenericMode.java   (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ModeAggregate.java   (with props)
Modified:
    db/derby/code/trunk/java/engine/build.xml
    db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/AggregateAliasInfo.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/ClassName.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/build.xml
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/loader/ClassInspector.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecAggregator.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/build.xml
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/DatabaseClasses.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/ReflectClassesJava2.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/AggregateDefinition.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/AggregateNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/JavaToSQLValueNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/JavaValueNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MethodCallNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CountAggregator.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericAggregator.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/MaxMinAggregator.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/OrderableAggregator.java
    db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
    db/derby/code/trunk/java/engine/org/apache/derby/modules.properties
    db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/MessageId.java
    db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UngroupedAggregatesNegativeTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UserDefinedAggregatesTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/build.xml
    db/derby/code/trunk/tools/jar/extraDBMSclasses.properties
    db/derby/code/trunk/tools/javadoc/publishedapi.ant

Modified: db/derby/code/trunk/java/engine/build.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/build.xml?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/build.xml (original)
+++ db/derby/code/trunk/java/engine/build.xml Wed Aug 29 16:52:58 2012
@@ -61,6 +61,7 @@
     <ant dir="${derby.engine.dir}/database"/>
 
     <ant dir="${derby.engine.dir}/vti"/>
+    <ant dir="${derby.engine.dir}/agg"/>
     <ant dir="${derby.engine.dir}/impl"/>
     <ant dir="${derby.engine.dir}/jdbc"/>
     <ant dir="${derby.engine.dir}/osgi"/>

Added: db/derby/code/trunk/java/engine/org/apache/derby/agg/Aggregator.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/agg/Aggregator.java?rev=1378639&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/agg/Aggregator.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/agg/Aggregator.java Wed Aug 29 16:52:58 2012
@@ -0,0 +1,52 @@
+/*
+
+   Derby - Class org.apache.derby.agg.Aggregator
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.derby.agg;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * Behavior of a user-defined Derby aggregator. Aggregates values
+ * of type V and returns a result of type R. In addition to the methods
+ * in the interface, implementing classes must have a 0-arg public
+ * constructor.
+ * </p>
+ */
+public interface Aggregator<V,R,A extends Aggregator<V,R,A>>    extends Serializable
+{
+    /** Initialize the Aggregator */
+    public void init();
+
+    /** Accumulate the next scalar value */
+    public  void    accumulate( V value );
+
+    /**
+     * For merging another partial result into this Aggregator.
+     * This lets the SQL interpreter divide the incoming rows into
+     * subsets, aggregating each subset in isolation, and then merging
+     * the partial results together.
+     */
+    public  void    merge( A otherAggregator );
+
+    /** Return the result scalar value */
+    public  R   terminate();
+}
+

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/agg/Aggregator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/engine/org/apache/derby/agg/build.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/agg/build.xml?rev=1378639&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/agg/build.xml (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/agg/build.xml Wed Aug 29 16:52:58 2012
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<project default="agg" basedir="../../../../../..">
+
+<!-- Set Properties -->
+  <!-- User settings -->
+  <property file="${user.home}/ant.properties"/>
+  <!-- Set property lib dir -->
+  <property name="properties.dir" value="tools/ant/properties"/>
+  <!-- Significant dirs -->
+  <property file="${properties.dir}/dirs.properties"/>
+  <!-- Compiler settings -->
+<property file="${properties.dir}/defaultcompiler.properties"/> 
+  <property file="${properties.dir}/${build.compiler}.properties"/>
+  <!-- Compile-time classpath properties files -->
+  <property file="${properties.dir}/extrapath.properties"/>
+  <property file="${properties.dir}/compilepath.properties"/>
+
+<!-- Targets -->
+  <target name="agg" depends="compile_agg"/>
+
+  <target name="compile_agg">
+
+    <javac
+      source="1.5"
+      target="1.5"
+      bootclasspath="${empty}"
+      nowarn="on"
+      debug="${debug}"
+      depend="${depend}"
+      deprecation="${deprecation}"
+      optimize="${optimize}"
+      proceed="${proceed}"
+      verbose="${verbose}"
+      srcdir="${derby.engine.src.dir}"
+      destdir="${out.dir}">
+      <classpath>
+        <pathelement path="${java15compile.classpath}"/>
+      </classpath>
+      <include name="${derby.dir}/agg/*.java"/>
+    </javac>
+
+  </target>
+
+</project>
+

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/agg/build.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/AggregateAliasInfo.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/AggregateAliasInfo.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/AggregateAliasInfo.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/AggregateAliasInfo.java Wed Aug 29 16:52:58 2012
@@ -85,6 +85,15 @@ public class AggregateAliasInfo implemen
 
     ///////////////////////////////////////////////////////////////////////////////////
     //
+    // ACCESSORS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+	public TypeDescriptor   getForType() { return _forType; }
+    public TypeDescriptor   getReturnType() { return _returnType; }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
     // Formatable BEHAVIOR
     //
     ///////////////////////////////////////////////////////////////////////////////////

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/ClassName.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/ClassName.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/ClassName.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/ClassName.java Wed Aug 29 16:52:58 2012
@@ -112,6 +112,7 @@ public interface ClassName
 	String SumAggregator = "org.apache.derby.impl.sql.execute.SumAggregator";
 	String CountAggregator = "org.apache.derby.impl.sql.execute.CountAggregator";
 	String AvgAggregator = "org.apache.derby.impl.sql.execute.AvgAggregator";
+	String UserDefinedAggregator = "org.apache.derby.impl.sql.execute.UserDefinedAggregator";
 
 	String ExecutionFactory = "org.apache.derby.iapi.sql.execute.ExecutionFactory";
 	String LanguageFactory ="org.apache.derby.iapi.sql.LanguageFactory";

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/build.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/build.xml?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/build.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/build.xml Wed Aug 29 16:52:58 2012
@@ -34,7 +34,7 @@
 
 <!-- Targets -->
 
-  <target name="compile" depends="compile_crypto"/>
+  <target name="compile" depends="compile_crypto,java5"/>
 
   <target name="compile_iapi_services_jsr169">
     <javac
@@ -56,10 +56,32 @@
       <include name="${derby.dir}/iapi/services/**"/>
       <exclude name="${derby.dir}/iapi/services/crypto/**"/>
       <exclude name="${derby.dir}/iapi/services/io/**"/>
+      <exclude name="${derby.dir}/iapi/services/loader/Java5*"/>
     </javac>
     <ant dir="${derby.engine.dir}/iapi/services/io"/>
   </target>
 
+  <target name="java5">
+    <javac
+      source="1.5"
+      target="1.5"
+      bootclasspath="${empty}"
+      nowarn="on"
+      debug="${debug}"
+      depend="${depend}"
+      deprecation="${deprecation}"
+      optimize="${optimize}"
+      proceed="${proceed}"
+      verbose="${verbose}"
+      srcdir="${derby.engine.src.dir}"
+      destdir="${out.dir}">
+      <classpath>
+        <pathelement path="${java15compile.classpath}"/>
+      </classpath>
+      <include name="${derby.dir}/iapi/services/loader/Java5*"/>
+    </javac>
+  </target>
+
   <target name="compile_crypto" depends="compile_iapi_services_jsr169">
     <ant dir="${derby.engine.dir}/iapi/services/crypto" target="compile_crypto"/>
   </target>

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java Wed Aug 29 16:52:58 2012
@@ -375,7 +375,7 @@ String[] TwoByte = {
         /* 320 */       "org.apache.derby.impl.sql.catalog.CoreDDFinderClassInfo",             // InstanceGetter
         /* 321 */       null,
         /* 322 */       null,
-        /* 323 */       null,
+        /* 323 */       "org.apache.derby.impl.sql.execute.UserDefinedAggregator",
         /* 324 */       null,
         /* 325 */       "org.apache.derby.impl.sql.catalog.CoreDDFinderClassInfo",             // InstanceGetter
         /* 326 */       "org.apache.derby.catalog.types.DefaultInfoImpl",

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/loader/ClassInspector.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/loader/ClassInspector.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/loader/ClassInspector.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/loader/ClassInspector.java Wed Aug 29 16:52:58 2012
@@ -35,7 +35,7 @@ import java.lang.reflect.*;
 	e.g. int, COM.foo.Myclass, int[], java.lang.Object[]. That is java internal
 	class names as defined in the class file format are not understood.
 */
-public final class ClassInspector
+public class ClassInspector
 {
 	private static final String[] primTypeNames =
 		{"boolean", "byte", "char", "short", "int", "long", "float", "double"};
@@ -484,6 +484,21 @@ public final class 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&lt;K,V&gt; and the
+     * implementation is HashMap&lt;Integer,String&gt;, 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
+	{
+		throw StandardException.newException( SQLState.VM_LEVEL_TOO_LOW, "Java 5" );
+    }
+    
+	/**
 	 * Get the parameter types for a method described by a Member as a String[].
 	 *
 	 * @param method	A Member describing a method

Added: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/loader/Java5ClassInspector.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/loader/Java5ClassInspector.java?rev=1378639&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/loader/Java5ClassInspector.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/loader/Java5ClassInspector.java Wed Aug 29 16:52:58 2012
@@ -0,0 +1,215 @@
+/*
+
+   Derby - Class org.apache.derby.iapi.services.loader.Java5ClassInspector
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derby.iapi.services.loader;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.reference.SQLState;
+
+/**
+ * A ClassInspector for JVMs which support the language features introduced
+ * by Java 5, including generics.
+*/
+public class Java5ClassInspector extends ClassInspector
+{
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTANTS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // STATE
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTRUCTOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+	/**
+		DO NOT USE! use the method in ClassFactory.
+	*/
+	public Java5ClassInspector( ClassFactory cf ) { super( cf ); }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // BEHAVIOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    @Override
+    public Class[] getGenericParameterTypes( Class parameterizedType, Class implementation )
+        throws StandardException
+	{
+        // construct the inheritance chain stretching from the parameterized type
+        // down to the concrete implemention
+        ArrayList<Class<?>>    chain = getTypeChain( parameterizedType, implementation );
+
+        // walk the chain, filling in a map of generic types to their resolved types
+        HashMap<Type,Type>  resolvedTypes = getResolvedTypes( chain );
+
+        // compose the resolved types together in order to compute the actual
+        // classes which are plugged into the variables of the parameterized type
+        ArrayList<Class<?>>    parameterTypes = getParameterTypes( parameterizedType, resolvedTypes );
+
+        // turn the list into an array
+        if ( parameterTypes == null ) { return null; }
+
+        Class[] result = new Class[ parameterTypes.size() ];
+        parameterTypes.toArray( result );
+
+        return result;
+    }
+
+    /**
+     * Construct an inheritance chain of types stretching from a supertype down
+     * to a concrete implementation.
+     */
+    private ArrayList<Class<?>>    getTypeChain( Class<?> chainEnd, Class<?> start )
+    {
+        ArrayList<Class<?>>    result = null;
+        
+        if ( start == null ) { return null; }
+        if ( !chainEnd.isAssignableFrom(  start ) ) { return null; }
+
+        if ( start == chainEnd )    { result = new ArrayList<Class<?>>(); }
+        if ( result == null )
+        {
+            result = getTypeChain( chainEnd, start.getSuperclass() );
+        
+            if ( result == null )
+            {
+                for ( Class<?> iface : start.getInterfaces() )
+                {
+                    result = getTypeChain( chainEnd, iface );
+                    if ( result != null ) { break; }
+                }
+            }
+        }
+
+        if ( result != null ) { result.add( start ); }
+
+        return result;
+    }
+
+    /**
+     * Given an inheritance chain of types, stretching from a superclass down
+     * to a terminal concrete class, construct a map of generic types to their
+     * resolved types.
+     */
+    private HashMap<Type,Type>  getResolvedTypes( ArrayList<Class<?>> chain )
+    {
+        if ( chain ==  null ) { return null; }
+        
+        HashMap<Type,Type>  resolvedTypes = new HashMap<Type,Type>();
+
+        for ( Class<?> klass : chain )
+        {
+            addResolvedTypes( resolvedTypes, klass.getGenericSuperclass() );
+
+            for ( Type iface : klass.getGenericInterfaces() )
+            {
+                addResolvedTypes( resolvedTypes, iface );
+            }
+        }
+
+        return resolvedTypes;
+    }
+
+    /**
+     * Given a generic type, add its parameter types to an evolving
+     * map of resolved types. Some of the resolved types may be
+     * generic type variables which will need further resolution from
+     * other generic types.
+     */
+    private void    addResolvedTypes
+        ( HashMap<Type,Type> resolvedTypes, Type genericType )
+    {
+        if ( genericType == null ) { return; }
+
+        if ( genericType instanceof ParameterizedType )
+        {
+            ParameterizedType   pt = (ParameterizedType) genericType;
+            Class       rawType = (Class) pt.getRawType();
+            
+            Type[] actualTypeArguments = pt.getActualTypeArguments();
+            TypeVariable[] typeParameters = rawType.getTypeParameters();
+            for (int i = 0; i < actualTypeArguments.length; i++)
+            {
+                resolvedTypes.put(typeParameters[i], actualTypeArguments[i]);
+            }
+        }
+    }
+
+    /**
+     * Given a map of resolved types, compose them together in order
+     * to resolve the actual concrete types that are plugged into the
+     * parameterized type.
+     */
+    private ArrayList<Class<?>>    getParameterTypes
+        ( Class<?> parameterizedType, HashMap<Type,Type> resolvedTypes )
+    {
+        if ( resolvedTypes == null ) { return null; }
+        
+        Type[] actualTypeArguments = parameterizedType.getTypeParameters();
+
+        ArrayList<Class<?>> result = new ArrayList<Class<?>>();
+        
+        // resolve types by composing type variables.
+        for (Type baseType: actualTypeArguments)
+        {
+            while ( resolvedTypes.containsKey( baseType ) )
+            {
+                baseType = resolvedTypes.get(baseType);
+            }
+            
+            result.add( getClass( baseType ) );
+        }
+        
+        return result;
+    }
+
+    /**
+     * Get the underlying class for a type, or null if the type is a variable type.
+     */
+    private Class<?> getClass( Type type )
+    {
+        if ( type instanceof Class ) { return (Class) type; }
+        else if (type instanceof ParameterizedType)
+        {
+            return getClass( ((ParameterizedType) type).getRawType() );
+        }
+        else { return null; }
+    }
+
+}
+

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/loader/Java5ClassInspector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecAggregator.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecAggregator.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecAggregator.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecAggregator.java Wed Aug 29 16:52:58 2012
@@ -21,9 +21,11 @@
 
 package org.apache.derby.iapi.sql.execute;
 
+import org.apache.derby.iapi.types.DataTypeDescriptor;
 import org.apache.derby.iapi.types.DataValueDescriptor;
 import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.services.io.Formatable;
+import org.apache.derby.iapi.services.loader.ClassFactory;
 
 /**
  * An ExecAggregator is the interface that execution uses
@@ -50,8 +52,12 @@ public interface ExecAggregator extends 
 {
 	/**
 	    Set's up the aggregate for processing.
+
+        @param  classFactory Database-specific class factory.
+        @param  aggregateName   For builtin aggregates, this is a SQL aggregate name like MAX. For user-defined aggregates, this is the name of the user-written class which implements org.apache.derby.agg.Aggregator.
+        @param  returnDataType  The type returned by the getResult() method.
 	 */
-	public void setup(String aggregateName);
+	public void setup(ClassFactory classFactory, String aggregateName, DataTypeDescriptor returnDataType );
 
 	/**
 	 * Iteratively accumulates the addend into the aggregator.

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/build.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/build.xml?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/build.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/build.xml Wed Aug 29 16:52:58 2012
@@ -52,6 +52,7 @@
         <pathelement path="${compile.classpath}"/>
       </classpath>
       <include name="${derby.dir}/impl/services/**"/>
+      <exclude name="${derby.dir}/impl/services/reflect/Java5*"/>
       <exclude name="${derby.dir}/impl/services/jce/**"/>
       <exclude name="${derby.dir}/impl/services/locks/Concurrent*.java"/>
       <exclude name="${derby.dir}/impl/services/cache/Concurrent*.java"/>
@@ -80,6 +81,7 @@
      <classpath>
        <pathelement path="${java15compile.classpath}"/>
      </classpath>
+     <include name="${derby.dir}/impl/services/reflect/Java5*"/>
      <include name="${derby.dir}/impl/services/locks/Concurrent*.java"/>
      <include name="${derby.dir}/impl/services/cache/Concurrent*.java"/>
      <include name="${derby.dir}/impl/services/cache/CacheEntry.java"/>

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/DatabaseClasses.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/DatabaseClasses.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/DatabaseClasses.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/DatabaseClasses.java Wed Aug 29 16:52:58 2012
@@ -107,7 +107,7 @@ abstract class DatabaseClasses
 		throws StandardException
 	{
 
-		classInspector = new ClassInspector(this);
+		classInspector = makeClassInspector( this );
 
 		//
 		//The ClassFactory runs per service (database) mode (booted as a service module after AccessFactory).
@@ -136,6 +136,15 @@ abstract class DatabaseClasses
 			applicationLoader.close();
 	}
 
+    /**
+     * For creating the class inspector. On Java 5 and higher, we have a more
+     * capable class inspector.
+     */
+    protected   ClassInspector  makeClassInspector( DatabaseClasses dc )
+    {
+        return new ClassInspector( dc );
+    }
+
 	/*
 	**	Public methods of ClassFactory
 	*/

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/Java5ClassFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/Java5ClassFactory.java?rev=1378639&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/Java5ClassFactory.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/Java5ClassFactory.java Wed Aug 29 16:52:58 2012
@@ -0,0 +1,56 @@
+/*
+
+   Derby - Class org.apache.derby.impl.services.reflect.Java5ClassFactory
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derby.impl.services.reflect;
+
+import org.apache.derby.iapi.services.loader.ClassInspector;
+import org.apache.derby.iapi.services.loader.Java5ClassInspector;
+
+/**
+ * ClassFactory for Java 5 and higher.
+ */
+public class Java5ClassFactory extends ReflectClassesJava2
+{
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTANTS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // STATE
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // BEHAVIOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    @Override
+    protected   ClassInspector  makeClassInspector( DatabaseClasses dc )
+    {
+        return new Java5ClassInspector( dc );
+    }
+
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/Java5ClassFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/ReflectClassesJava2.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/ReflectClassesJava2.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/ReflectClassesJava2.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/reflect/ReflectClassesJava2.java Wed Aug 29 16:52:58 2012
@@ -26,7 +26,7 @@ import org.apache.derby.iapi.util.ByteAr
 	Relfect loader with Privileged block for Java 2 security. 
 */
 
-public final class ReflectClassesJava2 extends DatabaseClasses
+public class ReflectClassesJava2 extends DatabaseClasses
 	implements java.security.PrivilegedAction
 {
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/AggregateDefinition.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/AggregateDefinition.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/AggregateDefinition.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/AggregateDefinition.java Wed Aug 29 16:52:58 2012
@@ -23,6 +23,7 @@ package	org.apache.derby.impl.sql.compil
 
 import java.sql.SQLException;
 
+import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.types.DataTypeDescriptor;
 
 /**
@@ -81,6 +82,7 @@ interface AggregateDefinition
 	 * @see org.apache.derby.catalog.TypeDescriptor
 	 *
 	 */
-	public	DataTypeDescriptor getAggregator(DataTypeDescriptor inputType,
-							StringBuffer aggregatorClassName);
+	public	DataTypeDescriptor getAggregator
+        ( DataTypeDescriptor inputType, StringBuffer aggregatorClassName )
+        throws StandardException;
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/AggregateNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/AggregateNode.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/AggregateNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/AggregateNode.java Wed Aug 29 16:52:58 2012
@@ -108,16 +108,15 @@ public class AggregateNode extends Unary
 		super.init(operand);
 		this.aggregateName = (String) aggregateName;
 
-		if (uadClass instanceof String)
+		if (uadClass instanceof AggregateDefinition)
 		{
-			this.aggregateDefinitionClassName = (String) uadClass;
+			this.uad = (AggregateDefinition) uadClass;
+			this.aggregateDefinitionClass = uad.getClass();
 			this.distinct = ((Boolean) distinct).booleanValue();
 		}
 		else
 		{
 			this.aggregateDefinitionClass = (Class) uadClass;
-			this.aggregateDefinitionClassName =
-										aggregateDefinitionClass.getName();
 
 			// Distinct is meaningless for min and max
 			if (!aggregateDefinitionClass.equals(MaxMinAggregateDefinition.class))
@@ -125,6 +124,8 @@ public class AggregateNode extends Unary
 				this.distinct = ((Boolean) distinct).booleanValue();
 			}
 		}
+        
+        this.aggregateDefinitionClassName = aggregateDefinitionClass.getName();
 	}
 
 	/**
@@ -391,63 +392,65 @@ public class AggregateNode extends Unary
 	*/
 	private void instantiateAggDef() throws StandardException
 	{
-		Class theClass = aggregateDefinitionClass;
-
-		// get the class
-		if (theClass == null)
-		{
-			String aggClassName = aggregateDefinitionClassName;
-			verifyClassExist(aggClassName);
-
-			try
-			{
-				theClass = classInspector.getClass(aggClassName);
-			}
-			catch (Throwable t)
-			{
-				throw StandardException.unexpectedUserException(t);
-			}
-		}
-
-		// get an instance
-		Object instance = null;
-		try
-		{
-			instance = theClass.newInstance();
-		}
-		catch (Throwable t)
-		{
-			throw StandardException.unexpectedUserException(t);
-		}
-
-		if (!(instance instanceof AggregateDefinition))
-		{
-			throw StandardException.newException(SQLState.LANG_INVALID_USER_AGGREGATE_DEFINITION2, aggregateDefinitionClassName);
-		}
-
-		if (instance instanceof MaxMinAggregateDefinition)
-		{
-			MaxMinAggregateDefinition temp = (MaxMinAggregateDefinition)instance;
-			if (aggregateName.equals("MAX"))
-				temp.setMaxOrMin(true);
-			else
-				temp.setMaxOrMin(false);
-		}
-
-		if (instance instanceof SumAvgAggregateDefinition)
-		{
-			SumAvgAggregateDefinition temp1 = (SumAvgAggregateDefinition)instance;
-			if (aggregateName.equals("SUM"))
-				temp1.setSumOrAvg(true);
-			else
-				temp1.setSumOrAvg(false);
-		}
+        if ( uad == null )
+        {
+            Class theClass = aggregateDefinitionClass;
+
+            // get the class
+            if (theClass == null)
+            {
+                String aggClassName = aggregateDefinitionClassName;
+                verifyClassExist(aggClassName);
+
+                try
+                {
+                    theClass = classInspector.getClass(aggClassName);
+                }
+                catch (Throwable t)
+                {
+                    throw StandardException.unexpectedUserException(t);
+                }
+            }
+
+            // get an instance
+            Object instance = null;
+            try
+            {
+                instance = theClass.newInstance();
+            }
+            catch (Throwable t)
+            {
+                throw StandardException.unexpectedUserException(t);
+            }
+
+            if (!(instance instanceof AggregateDefinition))
+            {
+                throw StandardException.newException(SQLState.LANG_INVALID_USER_AGGREGATE_DEFINITION2, aggregateDefinitionClassName);
+            }
+
+            if (instance instanceof MaxMinAggregateDefinition)
+            {
+                MaxMinAggregateDefinition temp = (MaxMinAggregateDefinition)instance;
+                if (aggregateName.equals("MAX"))
+                    temp.setMaxOrMin(true);
+                else
+                    temp.setMaxOrMin(false);
+            }
+
+            if (instance instanceof SumAvgAggregateDefinition)
+            {
+                SumAvgAggregateDefinition temp1 = (SumAvgAggregateDefinition)instance;
+                if (aggregateName.equals("SUM"))
+                    temp1.setSumOrAvg(true);
+                else
+                    temp1.setSumOrAvg(false);
+            }
 
-		this.uad = (AggregateDefinition)instance;
+            this.uad = (AggregateDefinition)instance;
+        }
 	
 		setOperator(aggregateName);
 		setMethodName(aggregateDefinitionClassName);
-
 	}
 
 	/**

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/JavaToSQLValueNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/JavaToSQLValueNode.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/JavaToSQLValueNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/JavaToSQLValueNode.java Wed Aug 29 16:52:58 2012
@@ -236,6 +236,16 @@ public class JavaToSQLValueNode extends 
 		/* Bind the expression under us */
 		javaNode = javaNode.bindExpression(fromList, subqueryList, aggregateVector);
 
+        if ( javaNode instanceof StaticMethodCallNode )
+        {
+            AggregateNode   agg = ((StaticMethodCallNode) javaNode).getResolvedAggregate();
+
+            if ( agg != null )
+            {
+                return agg.bindExpression( fromList, subqueryList, aggregateVector );
+            }
+        }
+
 		DataTypeDescriptor dts = javaNode.getDataType();
 		if (dts == null)
 		{

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/JavaValueNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/JavaValueNode.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/JavaValueNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/JavaValueNode.java Wed Aug 29 16:52:58 2012
@@ -179,7 +179,7 @@ abstract class JavaValueNode extends Que
 	  *	@return	the corresponding compilation type id
 	  *
 	  */
-	public	TypeId	mapToTypeID( JSQLType jsqlType )
+	public	static  TypeId	mapToTypeID( JSQLType jsqlType )
         throws StandardException
 	{
 		DataTypeDescriptor	dts = jsqlType.getSQLType();

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MethodCallNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MethodCallNode.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MethodCallNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MethodCallNode.java Wed Aug 29 16:52:58 2012
@@ -39,6 +39,7 @@ import org.apache.derby.iapi.sql.compile
 import org.apache.derby.iapi.types.DataTypeDescriptor;
 
 import org.apache.derby.iapi.sql.compile.TypeCompiler;
+import org.apache.derby.iapi.sql.compile.TypeCompilerFactory;
 import org.apache.derby.catalog.TypeDescriptor;
 
 import org.apache.derby.catalog.types.TypeDescriptorImpl;
@@ -1041,7 +1042,9 @@ abstract class MethodCallNode extends Ja
 		int		count = signature.length;
 		String	parmTypeNames[] = new String[ count ];
 
-		for ( int i = 0; i < count; i++ ) { parmTypeNames[i] = getObjectTypeName( signature[ i ] ); }
+        TypeCompilerFactory tcf = (routineInfo == null ) ? null : getCompilerContext().getTypeCompilerFactory();
+
+		for ( int i = 0; i < count; i++ ) { parmTypeNames[i] = getObjectTypeName( signature[ i ], tcf ); }
 
 		return parmTypeNames;
 	}
@@ -1077,7 +1080,7 @@ abstract class MethodCallNode extends Ja
 		return isParam;
 	}
 
-	private	String	getObjectTypeName( JSQLType jsqlType )
+	static  String	getObjectTypeName( JSQLType jsqlType, TypeCompilerFactory tcf )
 		throws StandardException
 	{
 		if ( jsqlType != null )
@@ -1102,9 +1105,8 @@ abstract class MethodCallNode extends Ja
 						case java.sql.Types.BIGINT:
 						case java.sql.Types.REAL:
 						case java.sql.Types.DOUBLE:
-							if (routineInfo != null) {
-								TypeCompiler tc = getTypeCompiler(ctid);
-								return tc.getCorrespondingPrimitiveTypeName();
+							if (tcf != null) {
+								return tcf.getTypeCompiler( ctid ).getCorrespondingPrimitiveTypeName();
 							}
 							// fall through
 						default:

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java Wed Aug 29 16:52:58 2012
@@ -129,6 +129,8 @@ public class StaticMethodCallNode extend
 
 	AliasDescriptor	ad;
 
+    private AggregateNode   resolvedAggregate;
+
 
 	/**
 	 * Intializer for a NonStaticMethodCallNode
@@ -148,6 +150,11 @@ public class StaticMethodCallNode extend
 		this.javaClassName = (String) javaClassName;
 	}
 
+    /**
+     * Get the aggregate, if any, which this method call resolves to.
+     */
+    public  AggregateNode   getResolvedAggregate() { return resolvedAggregate; }
+    
 	/**
 	 * Bind this expression.  This means binding the sub-expressions,
 	 * as well as figuring out what the return type is for this expression.
@@ -195,6 +202,21 @@ public class StaticMethodCallNode extend
             // is set to the name of the routine (procedureName.getTableName()).
 			resolveRoutine(fromList, subqueryList, aggregateVector, sd);
 
+            if ( (ad != null) && (ad.getAliasType() == AliasInfo.ALIAS_TYPE_AGGREGATE_AS_CHAR) )
+            {
+                resolvedAggregate = (AggregateNode) getNodeFactory().getNode
+                    (
+                     C_NodeTypes.AGGREGATE_NODE,
+                     ((SQLToJavaValueNode) methodParms[ 0 ]).getSQLValueNode(),
+                     new UserAggregateDefinition( ad ), 
+                     Boolean.FALSE,
+                     ad.getJavaClassName(),
+                     getContextManager()
+                     );
+
+                return this;
+            }
+
 			if (ad == null && noSchema && !forCallStatement)
 			{
 				// Resolve to a built-in SYSFUN function but only
@@ -660,10 +682,41 @@ public class StaticMethodCallNode extend
 
 			break;
 		}
-}
+        }
+
+        if ( ad == null )
+        {
+            resolveAggregate( fromList, subqueryList, aggregateVector, sd );
+        }
 	}
 
 	/**
+	 * Resolve a user-defined aggregate.
+     *
+	 * @param fromList
+	 * @param subqueryList
+	 * @param aggregateVector
+	 * @param sd
+	 * @throws StandardException
+	 */
+	private void resolveAggregate
+        (FromList fromList, SubqueryList subqueryList, Vector aggregateVector, SchemaDescriptor sd)
+        throws StandardException
+    {
+        // aggregates have only 1 argument
+        if ( methodParms.length != 1 ) { return; }
+        
+		java.util.List list = getDataDictionary().getRoutineList
+            ( sd.getUUID().toString(), methodName, AliasInfo.ALIAS_NAME_SPACE_AGGREGATE_AS_CHAR );
+
+        for ( int i = 0; i < list.size(); i++ )
+        {
+            ad = (AliasDescriptor) list.get( i );
+            break;
+        }
+    }
+    
+	/**
 	 * Add code to set up the SQL session context for a stored
 	 * procedure or function which needs a nested SQL session
 	 * context (only needed for those which can contain SQL).

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UserAggregateDefinition.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UserAggregateDefinition.java?rev=1378639&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UserAggregateDefinition.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UserAggregateDefinition.java Wed Aug 29 16:52:58 2012
@@ -0,0 +1,202 @@
+/*
+
+   Derby - Class org.apache.derby.impl.sql.compile.UserAggregateDefinition
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derby.impl.sql.compile;
+
+import java.lang.reflect.Method;
+
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
+import org.apache.derby.iapi.reference.SQLState;
+import org.apache.derby.iapi.services.context.ContextService;
+import org.apache.derby.iapi.services.loader.ClassFactory;
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+import org.apache.derby.catalog.TypeDescriptor;
+import org.apache.derby.catalog.types.AggregateAliasInfo;
+import org.apache.derby.iapi.types.TypeId;
+import org.apache.derby.iapi.types.JSQLType;
+import org.apache.derby.iapi.types.DataTypeDescriptor;
+
+import org.apache.derby.iapi.sql.compile.TypeCompiler;
+import org.apache.derby.iapi.sql.compile.TypeCompilerFactory;
+
+import org.apache.derby.iapi.sql.compile.CompilerContext;
+import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;
+
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.reference.ClassName;
+
+/**
+ * Definition for user-defined aggregates.
+ *
+ */
+public class UserAggregateDefinition implements AggregateDefinition 
+{
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTANTS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    // the Aggregator interface has 3 parameter types
+    private static  final   int INPUT_TYPE = 0;
+    private static  final   int RETURN_TYPE = INPUT_TYPE + 1;
+    private static  final   int AGGREGATOR_TYPE = RETURN_TYPE + 1;
+    private static  final   int AGGREGATOR_PARAM_COUNT = AGGREGATOR_TYPE + 1;
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // STATE
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    private AliasDescriptor _alias;
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTRUCTOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 * Conjure out of thin air.
+	 */
+	public UserAggregateDefinition( AliasDescriptor alias )
+    {
+        _alias = alias;
+    }
+
+	/**
+	 * Determines the result datatype and verifies that the input datatype is correct.
+	 *
+	 * @param inputType	the input type
+	 * @param aggregatorClass (Output arg) the name of the Derby execution-time class which wraps the aggregate logic
+	 *
+	 * @return the result type of the user-defined aggregator
+	 */
+	public final DataTypeDescriptor	getAggregator
+        ( DataTypeDescriptor inputType, StringBuffer aggregatorClass )
+        throws StandardException
+	{
+		try
+		{
+			TypeId compType = inputType.getTypeId();
+		
+			CompilerContext cc = (CompilerContext)
+				ContextService.getContext(CompilerContext.CONTEXT_ID);
+			TypeCompilerFactory tcf = cc.getTypeCompilerFactory();
+			TypeCompiler tc = tcf.getTypeCompiler(compType);
+            ClassFactory    classFactory = cc.getClassFactory();
+
+            Class   userAggregatorClass = classFactory.loadApplicationClass( _alias.getJavaClassName() );
+            Class   derbyAggregatorInterface = classFactory.loadApplicationClass( "org.apache.derby.agg.Aggregator" );
+
+            Class[] aggregatorTypes = classFactory.getClassInspector().getGenericParameterTypes
+                ( derbyAggregatorInterface, userAggregatorClass );
+
+            if (
+                !derbyAggregatorInterface.isAssignableFrom( userAggregatorClass ) ||
+                (aggregatorTypes == null) ||
+                (aggregatorTypes.length != AGGREGATOR_PARAM_COUNT) ||
+                (aggregatorTypes[ INPUT_TYPE ] == null) ||
+                (aggregatorTypes[ RETURN_TYPE ] == null)
+               )
+            {
+				throw StandardException.newException
+                    (
+                     SQLState.LANG_ILLEGAL_UDA_CLASS,
+                     _alias.getSchemaName(),
+                     _alias.getName(),
+                     _alias.getJavaClassName()
+                     );
+            }
+
+            Class   actualInputClass = aggregatorTypes[ INPUT_TYPE ];
+            Class   actualReturnClass = aggregatorTypes[ RETURN_TYPE ];
+
+            AggregateAliasInfo  aai = (AggregateAliasInfo) _alias.getAliasInfo();
+            DataTypeDescriptor  expectedInputType = DataTypeDescriptor.getType( aai.getForType() );
+            DataTypeDescriptor  expectedReturnType = DataTypeDescriptor.getType( aai.getReturnType() );
+            Class       expectedInputClass = getJavaClass( expectedInputType );
+            Class       expectedReturnClass = getJavaClass( expectedReturnType );
+
+            // check that the aggregator has the correct input and return types
+            if ( actualInputClass != expectedInputClass )
+            {
+				throw StandardException.newException
+                    (
+                     SQLState.LANG_UDA_WRONG_INPUT_TYPE,
+                     _alias.getSchemaName(),
+                     _alias.getName(),
+                     expectedInputClass.toString(),
+                     actualInputClass.toString()
+                     );
+            }
+		
+            if ( actualReturnClass != expectedReturnClass )
+            {
+				throw StandardException.newException
+                    (
+                     SQLState.LANG_UDA_WRONG_RETURN_TYPE,
+                     _alias.getSchemaName(),
+                     _alias.getName(),
+                     expectedReturnClass.toString(),
+                     actualReturnClass.toString()
+                     );
+            }
+
+            aggregatorClass.append( ClassName.UserDefinedAggregator );
+
+            return expectedReturnType;
+		}
+		catch (ClassNotFoundException cnfe) { throw aggregatorInstantiation( cnfe ); }
+	}
+
+    /**
+     * Get the Java class corresponding to a Derby datatype.
+     */
+    private Class   getJavaClass( DataTypeDescriptor dtd )
+        throws StandardException, ClassNotFoundException
+    {
+        JSQLType    jsqlType = new JSQLType( dtd );
+        String  javaClassName = MethodCallNode.getObjectTypeName( jsqlType, null );
+
+        return Class.forName( javaClassName );
+    }
+
+    /**
+     * Make a "Could not instantiate aggregator" exception.
+     */
+    private StandardException   aggregatorInstantiation( Throwable t )
+        throws StandardException
+    {
+        return StandardException.newException
+            (
+             SQLState.LANG_UDA_INSTANTIATION,
+             t,
+             _alias.getJavaClassName(),
+             _alias.getSchemaName(),
+             _alias.getName(),
+             t.getMessage()
+             );
+    }
+    
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UserAggregateDefinition.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CountAggregator.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CountAggregator.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CountAggregator.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CountAggregator.java Wed Aug 29 16:52:58 2012
@@ -21,7 +21,9 @@
 
 package org.apache.derby.impl.sql.execute;
 
+import org.apache.derby.iapi.types.DataTypeDescriptor;
 import org.apache.derby.iapi.types.DataValueDescriptor;
+import org.apache.derby.iapi.services.loader.ClassFactory;
 import org.apache.derby.iapi.services.sanity.SanityManager;
 import org.apache.derby.iapi.error.StandardException;
 
@@ -43,7 +45,7 @@ public final class CountAggregator 
 
 	/**
 	 */
-	public void setup(String aggregateName)
+	public void setup( ClassFactory cf, String aggregateName, DataTypeDescriptor returnType )
 	{
 		isCountStar = aggregateName.equals("COUNT(*)");
 	}

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericAggregator.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericAggregator.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericAggregator.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericAggregator.java Wed Aug 29 16:52:58 2012
@@ -307,7 +307,13 @@ class GenericAggregator 
 				Object agg = aggregatorClass.newInstance();
 				aggregatorInstance = (ExecAggregator)agg;
 				cachedAggregator = aggregatorInstance;
-				aggregatorInstance.setup(aggInfo.getAggregateName());
+
+				aggregatorInstance.setup
+                    (
+                     cf,
+                     aggInfo.getAggregateName(),
+                     aggInfo.getResultDescription().getColumnInfo()[ 0 ].getType()
+                     );
 
 			} catch (Exception e)
 			{

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/MaxMinAggregator.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/MaxMinAggregator.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/MaxMinAggregator.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/MaxMinAggregator.java Wed Aug 29 16:52:58 2012
@@ -22,11 +22,13 @@
 package org.apache.derby.impl.sql.execute;
 
 import org.apache.derby.iapi.services.sanity.SanityManager;
+import org.apache.derby.iapi.types.DataTypeDescriptor;
 import org.apache.derby.iapi.types.DataValueDescriptor;
 import org.apache.derby.iapi.error.StandardException;
 
 import org.apache.derby.iapi.sql.execute.ExecAggregator;
 import org.apache.derby.iapi.services.io.StoredFormatIds;
+import org.apache.derby.iapi.services.loader.ClassFactory;
 import java.io.ObjectOutput;
 import java.io.ObjectInput;
 import java.io.IOException;
@@ -46,9 +48,9 @@ public final class MaxMinAggregator 
 
 	/**
 	 */
-	public void setup(String aggregateName)
+	public void setup( ClassFactory cf, String aggregateName, DataTypeDescriptor returnType )
 	{
-		super.setup(aggregateName);
+		super.setup( cf, aggregateName, returnType );
 		isMax = aggregateName.equals("MAX");
 	}
 	/**

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/OrderableAggregator.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/OrderableAggregator.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/OrderableAggregator.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/OrderableAggregator.java Wed Aug 29 16:52:58 2012
@@ -26,8 +26,10 @@ import java.io.ObjectInput;
 import java.io.ObjectOutput;
 
 import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.services.loader.ClassFactory;
 import org.apache.derby.iapi.services.sanity.SanityManager;
 import org.apache.derby.iapi.sql.execute.ExecAggregator;
+import org.apache.derby.iapi.types.DataTypeDescriptor;
 import org.apache.derby.iapi.types.DataValueDescriptor;
 
 /**
@@ -40,7 +42,7 @@ abstract class OrderableAggregator exten
 
 	/**
 	 */
-	public void setup(String aggregateName)
+	public void setup( ClassFactory cf, String aggregateName, DataTypeDescriptor returnDataType )
 	{
 	}
 

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UserDefinedAggregator.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UserDefinedAggregator.java?rev=1378639&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UserDefinedAggregator.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UserDefinedAggregator.java Wed Aug 29 16:52:58 2012
@@ -0,0 +1,225 @@
+/*
+
+   Derby - Class org.apache.derby.impl.sql.execute.UserDefinedAggregator
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derby.impl.sql.execute;
+
+import java.io.ObjectOutput;
+import java.io.ObjectInput;
+import java.io.IOException;
+import java.sql.SQLException;
+
+import org.apache.derby.agg.Aggregator;
+
+import org.apache.derby.iapi.services.monitor.Monitor;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.sql.execute.ExecAggregator;
+import org.apache.derby.iapi.types.DataTypeDescriptor;
+import org.apache.derby.iapi.types.DataValueDescriptor;
+import org.apache.derby.iapi.types.TypeId;
+
+import org.apache.derby.iapi.services.i18n.MessageService;
+import org.apache.derby.iapi.services.io.StoredFormatIds;
+import org.apache.derby.iapi.services.loader.ClassFactory;
+import org.apache.derby.iapi.reference.MessageId;
+import org.apache.derby.iapi.reference.SQLState;
+
+/**
+	Aggregator for user-defined aggregates. Wraps the application-supplied
+    implementation of org.apache.derby.agg.Aggregator.
+ */
+public final class UserDefinedAggregator  implements ExecAggregator
+{
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTANTS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    private static final int FIRST_VERSION = 0;
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // STATE
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    private Aggregator  _aggregator;
+    private DataTypeDescriptor  _resultType;
+    private boolean     _eliminatedNulls;
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTRUCTOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /** 0-arg constructor for Formatable interface */
+    public  UserDefinedAggregator() {}
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // ExecAggregator BEHAVIOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+	public void setup( ClassFactory classFactory, String aggregateName, DataTypeDescriptor resultType )
+	{
+        try {
+            setup( classFactory.loadApplicationClass( aggregateName ), resultType );
+        }
+        catch (ClassNotFoundException cnfe) { logAggregatorInstantiationError( aggregateName, cnfe ); }
+	}
+    /** Initialization logic shared by setup() and newAggregator() */
+    private void    setup( Class udaClass, DataTypeDescriptor resultType )
+    {
+        String  aggregateName = udaClass.getName();
+        
+        try {
+            _aggregator = (Aggregator) udaClass.newInstance();
+            _aggregator.init();
+        }
+        catch (InstantiationException ie) { logAggregatorInstantiationError( aggregateName, ie ); }
+        catch (IllegalAccessException iae) { logAggregatorInstantiationError( aggregateName, iae ); }
+
+        _resultType = resultType;
+    }
+
+	public boolean didEliminateNulls() { return _eliminatedNulls; }
+
+	public void accumulate( DataValueDescriptor addend, Object ga ) 
+		throws StandardException
+	{
+		if ( (addend == null) || addend.isNull() )
+        {
+			_eliminatedNulls = true;
+			return;
+		}
+
+        Object  value = addend.getObject();
+
+        _aggregator.accumulate( value );
+	}
+
+	public void merge(ExecAggregator addend)
+		throws StandardException
+	{
+        Aggregator  other = (Aggregator) addend;
+
+        _aggregator.merge( other );
+	}
+
+	/**
+	 * Return the result of the aggregation. .
+	 *
+	 * @return the aggregated result (could be a Java null).
+	 */
+	public DataValueDescriptor getResult() throws StandardException
+	{
+        Object  javaReturnValue = _aggregator.terminate();
+
+        if ( javaReturnValue == null ) { return null; }
+
+        DataValueDescriptor dvd = _resultType.getNull();
+        dvd.setObjectForCast( javaReturnValue, true, javaReturnValue.getClass().getName() );
+
+        return dvd;
+	}
+
+	/**
+	 */
+	public ExecAggregator newAggregator()
+	{
+		UserDefinedAggregator   uda = new UserDefinedAggregator();
+
+        uda.setup( _aggregator.getClass(), _resultType );
+
+        return uda;
+	}
+
+	/////////////////////////////////////////////////////////////
+	// 
+	// FORMATABLE INTERFACE
+	// 
+	/////////////////////////////////////////////////////////////
+
+	/** 
+	 *
+	 * @exception IOException on error
+	 */
+	public void writeExternal(ObjectOutput out) throws IOException
+	{
+		out.writeInt( FIRST_VERSION );
+        
+        out.writeObject( _aggregator );
+        out.writeObject( _resultType );
+        out.writeBoolean( _eliminatedNulls );
+	}
+
+	/** 
+	 * @see java.io.Externalizable#readExternal 
+	 *
+	 * @exception IOException on error
+	 */
+	public void readExternal(ObjectInput in) 
+		throws IOException, ClassNotFoundException
+	{
+		in.readInt();   // unused until we have a second rev of this class
+
+        _aggregator = (Aggregator) in.readObject();
+        _resultType = (DataTypeDescriptor) in.readObject();
+        _eliminatedNulls = in.readBoolean();
+	}
+
+	/**
+	 * Get the formatID which corresponds to this class.
+	 *
+	 *	@return	the formatID of this class
+	 */
+	public	int	getTypeFormatId()	{ return StoredFormatIds.AGG_USER_ADAPTOR_V01_ID; }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // MINIONS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Record an instantiation error trying to load the aggregator class.
+     */
+    private void   logAggregatorInstantiationError( String aggregateName, Throwable t )
+    {
+        String  errorMessage = MessageService.getTextMessage
+            (
+             MessageId.CM_CANNOT_LOAD_CLASS,
+             aggregateName,
+             t.getMessage()
+             );
+
+		Monitor.getStream().println( errorMessage );
+
+        Exception   e = new Exception( errorMessage, t );
+
+        e.printStackTrace( Monitor.getStream().getPrintWriter() );
+    }
+
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UserDefinedAggregator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Wed Aug 29 16:52:58 2012
@@ -2969,6 +2969,41 @@ Guide.
                 <arg>aggregateName</arg>
             </msg>
 
+            <msg>
+                <name>42ZC4</name>
+                <text>User defined aggregate '{0}'.'{1}' is bound to external class '{2}'. The parameter types of that class could not be resolved.</text>
+                <arg>schemaName</arg>
+                <arg>aggregateName</arg>
+                <arg>className</arg>
+            </msg>
+
+            <msg>
+                <name>42ZC6</name>
+                <text>User defined aggregate '{0}'.'{1}' was declared to have this input Java type: '{2}'. However, the actual input Java type is '{3}'.</text>
+                <arg>schemaName</arg>
+                <arg>aggregateName</arg>
+                <arg>javaDataType</arg>
+                <arg>javaDataType</arg>
+            </msg>
+
+            <msg>
+                <name>42ZC7</name>
+                <text>User defined aggregate '{0}'.'{1}' was declared to have this return Java type: '{2}'. However, the actual return Java type is '{3}'.</text>
+                <arg>schemaName</arg>
+                <arg>aggregateName</arg>
+                <arg>javaDataType</arg>
+                <arg>javaDataType</arg>
+            </msg>
+
+            <msg>
+                <name>42ZC8</name>
+                <text>Implementing class '{0}' for user defined aggregate '{1}'.'{2}' could not be instantiated or was malformed. Detailed message follows: {3}</text>
+                <arg>className</arg>
+                <arg>schemaName</arg>
+                <arg>aggregateName</arg>
+                <arg>detailedMessage</arg>
+            </msg>
+
         </family>
 
 
@@ -3590,6 +3625,12 @@ Guide.
                 <arg>limitDescriptor</arg>
             </msg>
 
+            <msg>
+                <name>XBCM5.S</name>
+                <text>This operation requires that the JVM level be at least {0}.</text>
+                <arg>vmLevel</arg>
+            </msg>
+
         </family>
 
 
@@ -7687,6 +7728,13 @@ MessageId.java.
                 <arg>detailedError</arg>
             </msg>
 
+            <msg>
+                <name>C008</name>
+                <text>Exception loading class {0}: {1}</text>
+                <arg>className</arg>
+                <arg>detailedError</arg>
+            </msg>
+
         </family>
 
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/modules.properties
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/modules.properties?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/modules.properties (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/modules.properties Wed Aug 29 16:52:58 2012
@@ -159,6 +159,11 @@ cloudscape.config.lockManagerJ6=all
 derby.module.classManagerJ2=org.apache.derby.impl.services.reflect.ReflectClassesJava2
 cloudscape.config.classManagerJ2=derby
 
+# Java5ClassFactory requires JDK 1.5 (constant 6)
+derby.module.classManagerJ6=org.apache.derby.impl.services.reflect.Java5ClassFactory
+derby.env.jdk.classManagerJ6=6
+cloudscape.config.classManagerJ6=derby
+
 # cryptography - requires JDK 1.2 and greater and com.sun.crypto.provider.SunJCE
 #
 derby.module.cryptographyJ2=org.apache.derby.impl.services.jce.JCECipherFactoryBuilder

Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/MessageId.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/MessageId.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/MessageId.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/MessageId.java Wed Aug 29 16:52:58 2012
@@ -106,6 +106,7 @@ public interface MessageId {
 	String CM_CLASS_LOADER_START			= "C005";
 	String CM_CLASS_LOAD					= "C006";
 	String CM_CLASS_LOAD_EXCEPTION			= "C007";
+	String CM_CANNOT_LOAD_CLASS			= "C008";
 
 
 	/*

Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java Wed Aug 29 16:52:58 2012
@@ -213,6 +213,7 @@ public interface SQLState {
 	String GENERATED_CLASS_INSTANCE_ERROR	= "XBCM2.S";
 	String GENERATED_CLASS_NO_SUCH_METHOD	= "XBCM3.S";
 	String GENERATED_CLASS_LIMIT_EXCEEDED	= "XBCM4.S";
+	String VM_LEVEL_TOO_LOW	= "XBCM5.S";
 
 	/*
 	** Cryptography
@@ -1125,6 +1126,10 @@ public interface SQLState {
 	String LANG_WINDOW_FUNCTION_CONTEXT_ERROR                          = "42ZC2";
 
 	String LANG_ILLEGAL_UDA_NAME                                  = "42ZC3";
+	String LANG_ILLEGAL_UDA_CLASS                                  = "42ZC4";
+	String LANG_UDA_WRONG_INPUT_TYPE                                  = "42ZC6";
+	String LANG_UDA_WRONG_RETURN_TYPE                                  = "42ZC7";
+	String LANG_UDA_INSTANTIATION                                  = "42ZC8";
 
 	//following 3 matches the DB2 sql states
 	String LANG_DECLARED_GLOBAL_TEMP_TABLE_ONLY_IN_SESSION_SCHEMA = "428EK";

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GenericMode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GenericMode.java?rev=1378639&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GenericMode.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GenericMode.java Wed Aug 29 16:52:58 2012
@@ -0,0 +1,134 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.functionTests.tests.lang.GenericMode
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.derbyTesting.functionTests.tests.lang;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.apache.derby.agg.Aggregator;
+
+public  class   GenericMode<V extends Comparable<V>>    implements  Aggregator<V,V,GenericMode<V>>
+{
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // NESTED CLASSES
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public  static  final   class   IntMode extends GenericMode<Integer> {}
+    public  static  final   class   StringMode extends GenericMode<String> {}
+    
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // STATE
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    private HashMap<V,Accumulator<V>>  _accumulators;
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTRUCTOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public  GenericMode() {}
+    
+    public  void    init()
+    {
+        _accumulators = new HashMap<V,Accumulator<V>>();
+    }
+    public  void    accumulate( V value )
+    {
+        getAccumulator( value ).add( 1 );
+    }
+    public  void    merge( GenericMode<V> otherAggregator )
+    {
+        HashMap<V,Accumulator<V>>  otherAccumulators = otherAggregator._accumulators;
+        
+        for ( V value : otherAccumulators.keySet() )
+        {
+            getAccumulator( value ).add( otherAccumulators.get( value ).getCount() );
+        }
+    }
+
+    // Generic arrays can't be created, so we have to cast the value on the way out.
+    // Suppress the resulting compiler warning.
+    @SuppressWarnings("unchecked")
+    public  V terminate()
+    {
+        int     numAccumulators = _accumulators.size();
+        if ( numAccumulators == 0 ) { return null; }
+        
+        Accumulator[]   accumulators = new Accumulator[ numAccumulators ];
+
+        accumulators = _accumulators.values().toArray( accumulators );
+        Arrays.sort( accumulators );
+        
+        return (V) accumulators[ numAccumulators - 1 ].getValue();
+    }
+
+    private Accumulator<V>   getAccumulator( V value )
+    {
+        Accumulator<V>   retval = _accumulators.get( value );
+        if ( retval == null )
+        {
+            retval = new Accumulator<V>( value );
+            _accumulators.put( value, retval );
+        }
+
+        return retval;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // NESTED CLASSES
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public  static  final   class   Accumulator<V extends Comparable<V>> implements  Comparable<Accumulator<V>>
+    {
+        private V _value;
+        private int         _count;
+
+        public  Accumulator( V value )
+        {
+            _value = value;
+            _count = 0;
+        }
+
+        public  void    add( int increment ) { _count += increment; }
+
+        public  V getValue() { return _value; }
+        public  int     getCount() { return _count; }
+
+        // Comparable behavior
+        public  int compareTo( Accumulator<V> that )
+        {
+            if ( that == null ) { return 1; }
+
+            int retval = this._count - that._count;
+
+            if ( retval != 0 ) { return retval; }
+            else { return this._value.compareTo( that._value ); }
+        }
+    }
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GenericMode.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ModeAggregate.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ModeAggregate.java?rev=1378639&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ModeAggregate.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ModeAggregate.java Wed Aug 29 16:52:58 2012
@@ -0,0 +1,123 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.functionTests.tests.lang.ModeAggregate
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.functionTests.tests.lang;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.apache.derby.agg.Aggregator;
+
+public  class   ModeAggregate    implements  Aggregator<Integer,Integer,ModeAggregate>
+{
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // STATE
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    private HashMap<Integer,Accumulator>  _accumulators;
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTRUCTOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public  ModeAggregate() {}
+    
+    public  void    init()
+    {
+        _accumulators = new HashMap<Integer,Accumulator>();
+    }
+    public  void    accumulate( Integer value )
+    {
+        getAccumulator( value ).add( 1 );
+    }
+    public  void    merge( ModeAggregate otherAggregator )
+    {
+        HashMap<Integer,Accumulator>  otherAccumulators = otherAggregator._accumulators;
+        
+        for ( Integer value : otherAccumulators.keySet() )
+        {
+            getAccumulator( value ).add( otherAccumulators.get( value ).getCount() );
+        }
+    }
+
+    public  Integer terminate()
+    {
+        int     numAccumulators = _accumulators.size();
+        if ( numAccumulators == 0 ) { return null; }
+        
+        Accumulator[]   accumulators = new Accumulator[ numAccumulators ];
+
+        accumulators = _accumulators.values().toArray( accumulators );
+        Arrays.sort( accumulators );
+        
+        return accumulators[ numAccumulators - 1 ].getValue();
+    }
+
+    private Accumulator   getAccumulator( Integer value )
+    {
+        Accumulator   retval = _accumulators.get( value );
+        if ( retval == null )
+        {
+            retval = new Accumulator( value );
+            _accumulators.put( value, retval );
+        }
+
+        return retval;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // NESTED CLASSES
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public  static  final   class   Accumulator implements  Comparable<Accumulator>
+    {
+        private Integer _value;
+        private int         _count;
+
+        public  Accumulator( Integer value )
+        {
+            _value = value;
+            _count = 0;
+        }
+
+        public  void    add( int increment ) { _count += increment; }
+
+        public  Integer getValue() { return _value; }
+        public  int     getCount() { return _count; }
+
+        // Comparable behavior
+        public  int compareTo( Accumulator that )
+        {
+            if ( that == null ) { return 1; }
+
+            int retval = this._count - that._count;
+
+            if ( retval != 0 ) { return retval; }
+            else { return this._value.intValue() - that._value.intValue(); }
+        }
+    }
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ModeAggregate.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UngroupedAggregatesNegativeTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UngroupedAggregatesNegativeTest.java?rev=1378639&r1=1378638&r2=1378639&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UngroupedAggregatesNegativeTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UngroupedAggregatesNegativeTest.java Wed Aug 29 16:52:58 2012
@@ -1,6 +1,6 @@
 /*
  * 
- * Derby - Class org.apache.derbyTesting.functionTests.tests.lang.UngroupedAggregatesTest
+ * Derby - Class org.apache.derbyTesting.functionTests.tests.lang.UngroupedAggregatesNegativeTest
  * 
  * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
  * agreements. See the NOTICE file distributed with this work for additional information
@@ -25,6 +25,7 @@ import junit.framework.Test;
 
 import org.apache.derbyTesting.junit.BaseJDBCTestCase;
 import org.apache.derbyTesting.junit.TestConfiguration;
+import org.apache.derbyTesting.junit.JDBC;
 
 /**
  * Test case for ungroupedAggregatesNegative.sql. 
@@ -103,4 +104,21 @@ public class UngroupedAggregatesNegative
         assertStatementError("21000", st, sql);
         st.close();
     }
+
+    /**
+     * Test that we get a reasonable error when trying to invoke
+     * a user-defined aggregate on a vm which doesn't support generics.
+     */
+    public  void    testUDAWithoutGenerics() throws Exception
+    {
+        if (JDBC.vmSupportsJDBC3()) { return; }
+        
+        Statement st = createStatement();
+
+        st.execute( "create derby aggregate bad_mode for int\n" +
+                    "external name 'org.apache.derbyTesting.functionTests.tests.lang.ModeAggregate'" );
+
+        assertStatementError("XBCM5", st,
+                             "select bad_mode( columnnumber ) from sys.syscolumns" );
+    }
 }



Mime
View raw message