You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by rh...@apache.org on 2012/10/17 19:58:00 UTC
svn commit: r1399364 - in /db/derby/code/trunk/java:
engine/org/apache/derby/impl/sql/compile/
testing/org/apache/derbyTesting/functionTests/tests/lang/
Author: rhillegas
Date: Wed Oct 17 17:57:59 2012
New Revision: 1399364
URL: http://svn.apache.org/viewvc?rev=1399364&view=rev
Log:
DERBY-672: Forbid user-defined aggregates in GROUP BY clauses just as builtin aggregates are illegal there.
Modified:
db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CollectNodesVisitor.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/compile/sqlgrammar.jj
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UserDefinedAggregatesTest.java
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CollectNodesVisitor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CollectNodesVisitor.java?rev=1399364&r1=1399363&r2=1399364&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CollectNodesVisitor.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CollectNodesVisitor.java Wed Oct 17 17:57:59 2012
@@ -119,7 +119,7 @@ public class CollectNodesVisitor impleme
//
////////////////////////////////////////////////
/**
- * Reset the status so it can be run again.
+ * Return the list of matching nodes.
*
*/
public Vector getList()
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=1399364&r1=1399363&r2=1399364&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 Oct 17 17:57:59 2012
@@ -133,6 +133,8 @@ public class StaticMethodCallNode extend
private AggregateNode resolvedAggregate;
+ private boolean appearsInGroupBy = false;
+
/**
* Intializer for a NonStaticMethodCallNode
@@ -156,6 +158,9 @@ public class StaticMethodCallNode extend
* Get the aggregate, if any, which this method call resolves to.
*/
public AggregateNode getResolvedAggregate() { return resolvedAggregate; }
+
+ /** Flag that this function invocation appears in a GROUP BY clause */
+ public void setAppearsInGroupBy() { appearsInGroupBy = true; }
/**
* Bind this expression. This means binding the sub-expressions,
@@ -216,6 +221,13 @@ public class StaticMethodCallNode extend
getContextManager()
);
+ // The parser may have noticed that this aggregate is invoked in a
+ // GROUP BY clause. That is not allowed.
+ if ( appearsInGroupBy )
+ {
+ throw StandardException.newException(SQLState.LANG_AGGREGATE_IN_GROUPBY_LIST);
+ }
+
return this;
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj?rev=1399364&r1=1399363&r2=1399364&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj Wed Oct 17 17:57:59 2012
@@ -10147,6 +10147,20 @@ groupingColumnReference(GroupByList grou
{
throw StandardException.newException(SQLState.LANG_AGGREGATE_IN_GROUPBY_LIST);
}
+
+ // Look for user-defined aggregates too. At the parsing stage,
+ // they appear as function calls. Look for function calls
+ // inside the expression and mark them so that at bind() time
+ // we can reject them if they turn out to be user-defined aggregates
+ // rather than ordinary function calls.
+ CollectNodesVisitor functionSniffer = new CollectNodesVisitor( StaticMethodCallNode.class );
+ columnExpression.accept( functionSniffer );
+ Vector functionNodes = functionSniffer.getList();
+ for ( int i = 0; i < functionNodes.size(); i++ )
+ {
+ ((StaticMethodCallNode) functionNodes.elementAt( i )).setAppearsInGroupBy();
+ }
+
if (columnExpression.isParameterNode())
{
throw StandardException.newException(SQLState.LANG_SYNTAX_ERROR, "?");
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UserDefinedAggregatesTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UserDefinedAggregatesTest.java?rev=1399364&r1=1399363&r2=1399364&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UserDefinedAggregatesTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UserDefinedAggregatesTest.java Wed Oct 17 17:57:59 2012
@@ -68,6 +68,7 @@ public class UserDefinedAggregatesTest
public static final String XML_TYPE = "42ZB3";
public static final String INT_TRUNCATION = "22003";
public static final String CAST_FAILURE = "22018";
+ public static final String AGG_IN_GROUP_BY = "42Y26";
///////////////////////////////////////////////////////////////////////////////////
//
@@ -2042,4 +2043,30 @@ public class UserDefinedAggregatesTest
expectCompilationError( RETURN_OUTSIDE_BOUNDS, "select a, stringMagnitude_13( b ) from intValues_13 group by a" );
}
+ /**
+ * <p>
+ * Verify that user-defined aggregates are not allowed in GROUP BY clauses.
+ * </p>
+ */
+ public void test_14_inGroupBy() throws Exception
+ {
+ Connection conn = getConnection();
+
+ goodStatement
+ (
+ conn,
+ "create derby aggregate intMode_14 for int\n" +
+ "external name 'org.apache.derbyTesting.functionTests.tests.lang.GenericMode$IntMode'\n"
+ );
+ goodStatement
+ (
+ conn,
+ "create table intMode_14_mode_inputs( a int, b int )"
+ );
+
+ expectCompilationError
+ ( AGG_IN_GROUP_BY,
+ "select intMode_14( b ) from intMode_14_mode_inputs group by intMode_14( b )" );
+ }
+
}