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 2006/09/01 17:53:09 UTC

svn commit: r439358 - in /db/derby/code/branches/10.2/java: engine/org/apache/derby/iapi/sql/compile/ engine/org/apache/derby/impl/sql/compile/ engine/org/apache/derby/loc/ shared/org/apache/derby/shared/common/reference/ testing/org/apache/derbyTestin...

Author: rhillegas
Date: Fri Sep  1 08:53:05 2006
New Revision: 439358

URL: http://svn.apache.org/viewvc?rev=439358&view=rev
Log:
DERBY-1725: Merge patches from trunk to 10.2 branch: No JIRA (436955), DERBY-883 (437070), DERBY-1555 (437009, 436965, 436957).

Added:
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/SubstituteExpressionVisitor.java
      - copied unchanged from r437071, db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SubstituteExpressionVisitor.java
    db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/All.java
      - copied unchanged from r437071, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/All.java
    db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/AllPackages.java
      - copied unchanged from r437071, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/AllPackages.java
    db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/Client.java
      - copied unchanged from r437071, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/Client.java
    db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/Embedded.java
      - copied unchanged from r437071, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/Embedded.java
    db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GroupByExpressionTest.java
      - copied unchanged from r437071, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GroupByExpressionTest.java
    db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/junit/ChangeConfigurationSetup.java
      - copied unchanged from r437071, db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/ChangeConfigurationSetup.java
Modified:
    db/derby/code/branches/10.2/java/engine/org/apache/derby/iapi/sql/compile/Visitor.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/BaseColumnNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/BinaryListOperatorNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/BinaryOperatorNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CastNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CoalesceFunctionNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ConditionalNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ConstantNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CurrentDatetimeOperatorNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CurrentRowLocationNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/DefaultNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/GroupByColumn.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/GroupByList.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/GroupByNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/JavaToSQLValueNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ParameterNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ResultColumn.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/SpecialFunctionNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/SubqueryNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/UnaryOperatorNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ValueNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/VerifyAggregateExpressionsVisitor.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/VirtualColumnNode.java
    db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj
    db/derby/code/branches/10.2/java/engine/org/apache/derby/loc/messages_en.properties
    db/derby/code/branches/10.2/java/shared/org/apache/derby/shared/common/reference/SQLState.java
    db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/master/groupBy.out
    db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/build.xml
    db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/derbylang.runall
    db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/jdbc40.runall
    db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java
    db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURDataModelSetup.java
    db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/tests/lang/groupBy.sql
    db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java
    db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/iapi/sql/compile/Visitor.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/iapi/sql/compile/Visitor.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/iapi/sql/compile/Visitor.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/iapi/sql/compile/Visitor.java Fri Sep  1 08:53:05 2006
@@ -91,5 +91,5 @@
 	 * 
 	 * @return true/false
 	 */
-	boolean skipChildren(Visitable node);
+	boolean skipChildren(Visitable node) throws StandardException;
 }	

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/BaseColumnNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/BaseColumnNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/BaseColumnNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/BaseColumnNode.java Fri Sep  1 08:53:05 2006
@@ -171,4 +171,18 @@
 	{
 		return Qualifier.SCAN_INVARIANT;
 	}
+        
+        /**
+         * @inheritDoc
+         */
+	protected boolean isEquivalent(ValueNode o)
+	{
+		if (isSameNodeType(o)) 
+		{
+			BaseColumnNode other = (BaseColumnNode)o;
+			return other.tableName.equals(other.tableName) 
+			&& other.columnName.equals(columnName);
+		} 
+		return false;
+	}
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/BinaryListOperatorNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/BinaryListOperatorNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/BinaryListOperatorNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/BinaryListOperatorNode.java Fri Sep  1 08:53:05 2006
@@ -423,4 +423,36 @@
 			
 		return returnNode;
 	}
+        
+        /**
+         * @inheritDoc
+         */
+	protected boolean isEquivalent(ValueNode o) throws StandardException
+	{
+		if (!isSameNodeType(o))
+		{
+			return false;
+		}
+		BinaryListOperatorNode other = (BinaryListOperatorNode)o;
+		if (!operator.equals(other.operator)
+				|| !leftOperand.isEquivalent(other.getLeftOperand())) 
+		{
+			return false;
+		}
+		
+		int sz = getRightOperandList().size();
+		if (sz != other.rightOperandList.size())
+		{
+			return false;
+		}
+		for (int i = 0; i < sz; i++)
+		{
+			ValueNode e = (ValueNode)rightOperandList.elementAt(i);
+			if (!e.isEquivalent((ValueNode)other.rightOperandList.elementAt(i))) 
+			{
+				return false;
+			}
+		}
+		return true;
+	}
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/BinaryOperatorNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/BinaryOperatorNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/BinaryOperatorNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/BinaryOperatorNode.java Fri Sep  1 08:53:05 2006
@@ -870,6 +870,21 @@
 		return returnNode;
 	}
 
+        /**
+         * @inheritDoc
+         */
+        protected boolean isEquivalent(ValueNode o) throws StandardException
+        {
+        	if (!isSameNodeType(o))
+        	{
+        		return false;
+        	}
+        	BinaryOperatorNode other = (BinaryOperatorNode)o;
+        	return methodName.equals(other.methodName)
+        	       && leftOperand.isEquivalent(other.leftOperand)
+        	       && rightOperand.isEquivalent(other.rightOperand);
+        }
+
 	/**
 	 * Push the fields necessary to generate an instance of
 	 * SqlXmlExecutor, which will then be used at execution

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CastNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CastNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CastNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CastNode.java Fri Sep  1 08:53:05 2006
@@ -1031,6 +1031,21 @@
 	{
 		return forDataTypeFunction;
 	}
+        
+	/**
+	 * {@inheritDoc}
+	 * @throws StandardException 
+	 */
+	protected boolean isEquivalent(ValueNode o) throws StandardException
+	{
+		if (isSameNodeType(o)) 
+		{
+			CastNode other = (CastNode)o;
+			return castTarget.equals(other.castTarget)
+				&& castOperand.isEquivalent(other.castOperand);
+		}
+		return false;
+	}
 }
 
 

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CoalesceFunctionNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CoalesceFunctionNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CoalesceFunctionNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CoalesceFunctionNode.java Fri Sep  1 08:53:05 2006
@@ -34,9 +34,12 @@
 
 import org.apache.derby.iapi.services.compiler.LocalField;
 import org.apache.derby.iapi.services.compiler.MethodBuilder;
+import org.apache.derby.iapi.sql.compile.Visitable;
+import org.apache.derby.iapi.sql.compile.Visitor;
 
 import java.lang.reflect.Modifier;
 
+import java.util.Iterator;
 import java.util.Vector;
 
 /**
@@ -306,7 +309,8 @@
 	/*
 		print the non-node subfields
 	 */
-	public String toString() {
+	public String toString() 
+	{
 		if (SanityManager.DEBUG)
 		{
 			return super.toString()+functionName+"("+argumentsList+")\n";
@@ -316,7 +320,53 @@
 			return "";
 		}
 	}
-
+        
+	/**
+	 * {@inheritDoc}
+	 */
+	protected boolean isEquivalent(ValueNode o) throws StandardException
+	{
+		if (!isSameNodeType(o))
+		{
+			return false;
+		}
+		
+		CoalesceFunctionNode other = (CoalesceFunctionNode)o;
+		if (other.argumentsList.size() != argumentsList.size())
+		{
+			return false;
+			
+		}
+		
+		int size = argumentsList.size();
+		for (int index = 0; index < size; index++)
+		{
+			ValueNode v1 = (ValueNode)argumentsList.elementAt(index);
+			ValueNode v2 = (ValueNode)other.argumentsList.elementAt(index);
+			if (!v1.isEquivalent(v2)) 
+			{
+				return false;
+			}
+		}
+		return true;
+	}
+	public Visitable accept(Visitor v) throws StandardException 
+	{
+		Visitable returnNode = v.visit(this);
+		
+		if (v.skipChildren(this) || v.stopTraversal())
+		{
+			return returnNode;
+		}
+		
+		int size = argumentsList.size();
+		for (int index = 0; index < size; index++)
+		{
+			argumentsList.setElementAt(
+					(QueryTreeNode)(argumentsList.elementAt(index)).accept(v), index);
+		}
+		return returnNode;
+	}
 	/**
 	 * Preprocess an expression tree.  We do a number of transformations
 	 * here (including subqueries, IN lists, LIKE and BETWEEN) plus

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java Fri Sep  1 08:53:05 2006
@@ -1120,6 +1120,16 @@
 		colNum[0] = -1;
 		return null;
 	}
+	
+	protected boolean isEquivalent(ValueNode o) throws StandardException
+	{
+		if (!isSameNodeType(o)) {
+			return false;
+		}
+		ColumnReference other = (ColumnReference)o;
+		return (tableNumber == other.tableNumber 
+				&& columnName.equals(other.getColumnName()));
+	}
 
 	/**
 	 * Mark this column reference as "scoped", which means that it

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ConditionalNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ConditionalNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ConditionalNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ConditionalNode.java Fri Sep  1 08:53:05 2006
@@ -488,4 +488,32 @@
 		
 		return returnNode;
 	}
+        
+	/**
+	 * @{inheritDoc}
+	 */
+	protected boolean isEquivalent(ValueNode o) throws StandardException
+	{
+		if (isSameNodeType(o)) 
+		{
+			ConditionalNode other = (ConditionalNode)o;
+			if (thenElseList.size() == other.thenElseList.size()
+					&& (testCondition.isEquivalent(other.testCondition))) 
+			{
+				int sz = thenElseList.size();
+				for (int i = 0; i < sz; i++)
+				{
+					ValueNode v1 = (ValueNode)thenElseList.elementAt(i);
+					ValueNode v2 = (ValueNode)other.thenElseList.elementAt(i);
+					if (!v1.isEquivalent(v2)) 
+					{
+						return false;
+					}
+					
+				}
+				return true;
+			}
+		}
+		return false;
+	}
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ConstantNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ConstantNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ConstantNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ConstantNode.java Fri Sep  1 08:53:05 2006
@@ -277,4 +277,13 @@
 		// Constants are constant for the life of the query
 		return Qualifier.CONSTANT;
 	}
+        
+	protected boolean isEquivalent(ValueNode o) throws StandardException
+	{
+		if (isSameNodeType(o)) {
+			ConstantNode other = (ConstantNode)o;
+			return other.getValue().compare(getValue()) == 0;
+		}
+		return false;
+	}
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CurrentDatetimeOperatorNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CurrentDatetimeOperatorNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CurrentDatetimeOperatorNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CurrentDatetimeOperatorNode.java Fri Sep  1 08:53:05 2006
@@ -180,4 +180,17 @@
 			return "";
 		}
 	}
+        
+        /**
+         * {@inheritDoc}
+         */
+	protected boolean isEquivalent(ValueNode o)
+	{
+		if (isSameNodeType(o)) 
+		{
+			CurrentDatetimeOperatorNode other = (CurrentDatetimeOperatorNode)o;
+			return other.whichType == whichType;
+		}
+		return false;
+	}
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CurrentRowLocationNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CurrentRowLocationNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CurrentRowLocationNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/CurrentRowLocationNode.java Fri Sep  1 08:53:05 2006
@@ -162,4 +162,9 @@
 		mbex.pushThis();
 		mbex.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null, mb.getName(), ClassName.DataValueDescriptor, 0);
 	}
+	
+	protected boolean isEquivalent(ValueNode o)
+	{
+		return false;
+	}
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/DefaultNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/DefaultNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/DefaultNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/DefaultNode.java Fri Sep  1 08:53:05 2006
@@ -276,4 +276,12 @@
 				"generateExpression not expected to be called");
 		}
 	}
+
+    /**
+     * @inheritDoc
+     */
+	protected boolean isEquivalent(ValueNode other)
+    {
+		return false;
+    }
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/GroupByColumn.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/GroupByColumn.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/GroupByColumn.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/GroupByColumn.java Fri Sep  1 08:53:05 2006
@@ -40,8 +40,8 @@
  */
 public class GroupByColumn extends OrderedColumn 
 {
-	private ColumnReference	colRef;
-
+	private ValueNode columnExpression;
+	
 	/**
 	 * Initializer.
 	 *
@@ -49,7 +49,7 @@
 	 */
 	public void init(Object colRef) 
 	{
-		this.colRef = (ColumnReference) colRef;
+		this.columnExpression = (ValueNode)colRef;
 	}
 
 	/**
@@ -62,7 +62,7 @@
 	{
 		if (SanityManager.DEBUG)
 		{
-			return "Column Reference: "+colRef+super.toString();
+			return "Column Expression: "+columnExpression+super.toString();
 		}
 		else
 		{
@@ -83,10 +83,10 @@
 		{
 			super.printSubNodes(depth);
 
-			if (colRef != null)
+			if (columnExpression != null)
 			{
 				printLabel(depth, "colRef: ");
-				colRef.treePrint(depth + 1);
+				columnExpression.treePrint(depth + 1);
 			}
 		}
 	}
@@ -98,49 +98,7 @@
 	 */
 	public String getColumnName() 
 	{
-		return colRef.getColumnName();
-	}
-
-	/**
-	 * Get the ColumnReference from this GroupByColumn.
-	 *
-	 * @return ColumnReference	The ColumnReference from this node.
-	 */
-	public ColumnReference getColumnReference()
-	{
-		return colRef;
-	}
-
-	/**
-	 * Set the ColumnReference for this GroupByColumn.
-	 *
-	 * @param colRef	The new ColumnReference for this node.
-	 */
-	public void setColumnReference(ColumnReference colRef)
-	{
-		this.colRef = colRef;
-	}
-
-	/**
-	 * Get the table number for this GroupByColumn.
-	 *
-	 * @return	int The table number for this GroupByColumn
-	 */
-
-	public int getTableNumber()
-	{
-		return colRef.getTableNumber();
-	}
-
-	/**
-	 * Get the source this GroupByColumn
-	 *
-	 * @return	The source of this GroupByColumn
-	 */
-
-	public ResultColumn getSource()
-	{
-		return colRef.getSource();
+		return columnExpression.getColumnName();
 	}
 
 	/**
@@ -162,12 +120,16 @@
 				throws StandardException
 	{
 		/* Bind the ColumnReference to the FromList */
-		colRef = (ColumnReference) colRef.bindExpression(fromList,
+		columnExpression = (ValueNode) columnExpression.bindExpression(fromList,
 							  subqueryList,
 							  aggregateVector);
 
 		// Verify that we can group on the column
-
+		if (columnExpression.isParameterNode()) 
+		{
+			throw StandardException.newException(SQLState.LANG_INVALID_COL_REF_GROUPED_SELECT_LIST,
+					columnExpression);
+		}
 		/*
 		 * Do not check to see if we can map user types
 		 * to built-in types.  The ability to do so does
@@ -175,11 +137,22 @@
 		 * as of version 2.0, ordering does not work on
 		 * user types.
 		 */
-		TypeId ctid = colRef.getTypeId();
+		TypeId ctid = columnExpression.getTypeId();
 		if (! ctid.orderable(getClassFactory()))
 		{
 			throw StandardException.newException(SQLState.LANG_COLUMN_NOT_ORDERABLE_DURING_EXECUTION, 
 							ctid.getSQLTypeName());
 		}
+	}
+
+	public ValueNode getColumnExpression() 
+	{
+		return columnExpression;
+	}
+
+	public void setColumnExpression(ValueNode cexpr) 
+	{
+		this.columnExpression = cexpr;
+		
 	}
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/GroupByList.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/GroupByList.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/GroupByList.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/GroupByList.java Fri Sep  1 08:53:05 2006
@@ -142,37 +142,26 @@
 									  dummySubqueryList, aggregateVector);
 		}
 
-		/* Verify that the columns in the GROUP BY list are unique.
-		 * (Unique on table number and source ResultColumn.)
-		 */
-		verifyUniqueGroupingColumns();
-
+		
+		int				rclSize = selectRCL.size();
 		for (int index = 0; index < size; index++)
 		{
 			boolean				matchFound = false;
 			GroupByColumn		groupingCol = (GroupByColumn) elementAt(index);
-			String				curName = groupingCol.getColumnName();
 
 			/* Verify that this entry in the GROUP BY list matches a
 			 * grouping column in the select list.
 			 */
-			int				groupingColTableNum = groupingCol.getTableNumber();
-			ResultColumn	groupingSource = groupingCol.getSource();
-			int				rclSize = selectRCL.size();
 			for (int inner = 0; inner < rclSize; inner++)
 			{
-				ColumnReference selectListCR;
 				ResultColumn selectListRC = (ResultColumn) selectRCL.elementAt(inner);
-
-				if (! (selectListRC.getExpression() instanceof ColumnReference))
-				{
+				if (!(selectListRC.getExpression() instanceof ColumnReference)) {
 					continue;
 				}
-				selectListCR = (ColumnReference) selectListRC.getExpression();
+				
+				ColumnReference selectListCR = (ColumnReference) selectListRC.getExpression();
 
-				if (groupingColTableNum == selectListCR.getTableNumber() &&
-					groupingSource == selectListCR.getSource())
-				{
+				if (selectListCR.isEquivalent(groupingCol.getColumnExpression())) { 
 					/* Column positions for grouping columns are 0-based */
 					groupingCol.setColumnPosition(inner + 1);
 
@@ -182,19 +171,21 @@
 					break;
 				}
 			}
-
 			/* If no match found in the SELECT list, then add a matching
 			 * ResultColumn/ColumnReference pair to the SelectNode's RCL.
 			 */
-			if (! matchFound)
+			if (! matchFound && 
+			    groupingCol.getColumnExpression() instanceof ColumnReference) 
 			{
+			    	// only add matching columns for column references not 
+			    	// expressions yet. See DERBY-883 for details. 
 				ResultColumn newRC;
 
 				/* Get a new ResultColumn */
 				newRC = (ResultColumn) getNodeFactory().getNode(
 								C_NodeTypes.RESULT_COLUMN,
 								groupingCol.getColumnName(),
-								groupingCol.getColumnReference().getClone(),
+								groupingCol.getColumnExpression().getClone(),
 								getContextManager());
 				newRC.setVirtualColumnId(selectRCL.size() + 1);
 				newRC.markGenerated();
@@ -231,125 +222,33 @@
 		numGroupingColsAdded+= numColsAddedHere;
 	}
 
+	
 
 	/**
-	 * Check the uniqueness of the column names within a GROUP BY list.
-	 *
-	 * @exception StandardException		Thrown on error
+	 * Find the matching grouping column if any for the given expression
+	 * 
+	 * @param node an expression for which we are trying to find a match
+	 * in the group by list.
+	 * 
+	 * @return the matching GroupByColumn if one exists, null otherwise.
+	 * 
+	 * @throws StandardException
 	 */
-	public void verifyUniqueGroupingColumns() throws StandardException
+	public GroupByColumn findGroupingColumn(ValueNode node)
+	        throws StandardException
 	{
-		int				size = size();
-		String			colName;
-
-		for (int outer = 0; outer < size; outer++)
+		int sz = size();
+		for (int i = 0; i < sz; i++) 
 		{
-			GroupByColumn		groupingCol = (GroupByColumn) elementAt(outer);
-			int					outerTabNum = groupingCol.getTableNumber();
-			ResultColumn		outerRC = groupingCol.getSource();
-			String				curName = groupingCol.getColumnName();
-			/* Verify that this column's name is unique within the list */
-			colName = groupingCol.getColumnName();
-
-			for (int inner = outer + 1; inner < size; inner++)
+			GroupByColumn gbc = (GroupByColumn)elementAt(i);
+			if (gbc.getColumnExpression().isEquivalent(node))
 			{
-				GroupByColumn		innerGBC = (GroupByColumn) elementAt(inner);
-				int					innerTabNum = innerGBC.getTableNumber();
-				ResultColumn		innerRC = innerGBC.getSource();
-				if (outerTabNum == innerTabNum &&
-					outerRC == innerRC)
-				{
-					throw StandardException.newException(SQLState.LANG_AMBIGUOUS_GROUPING_COLUMN, colName);
-				}
+				return gbc;
 			}
 		}
-
-		/* No duplicate column names */
-	}
-
-	/**
-	 * Add any grouping columns which are not already in the appropriate RCL
-	 * to the RCL.
-	 * NOTE: The RC/VCNs in the SELECT list will point to the same pool of
-	 *		 ResultColumns as the GroupByColumns in this list.
-	 *
-	 * @param selectNode	The SelectNode whose RCL we add to.
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public void addNewGroupingColumnsToRCL(SelectNode selectNode)
-		throws StandardException
-	{
-		FromList			fromList = selectNode.getFromList();
-		int					size = size();
-		ResultColumnList	rcl = selectNode.getResultColumns();
-
-		if (SanityManager.DEBUG)
-		{
-			SanityManager.ASSERT(selectNode.getGroupByList() == this,
-				"selectNode.getGroupByList() expected to equal this");
-		}
-
-		for (int index = 0; index < size; index++)
-		{
-			GroupByColumn		gbc = (GroupByColumn) elementAt(index);
-			ResultColumn		newRC;
-			VirtualColumnNode	newVCN;
-
-			/* Skip over GBCs which have a match */
-			if (gbc.getColumnPosition() != GroupByColumn.UNMATCHEDPOSITION)
-			{
-				continue;
-			}
-
-			/* Get and bind a new VCN */
-			newVCN = (VirtualColumnNode) getNodeFactory().getNode(
-							C_NodeTypes.VIRTUAL_COLUMN_NODE,
-							fromList.getFromTableByResultColumn(gbc.getSource()),
-							gbc.getSource(),
-							ReuseFactory.getInteger(rcl.size() + 2),
-							getContextManager());
-			newVCN.setType(gbc.getColumnReference().getTypeServices());
-
-			/* Get and bind a new ResultColumn */
-			newRC = (ResultColumn) getNodeFactory().getNode(
-							C_NodeTypes.RESULT_COLUMN,
-							gbc.getColumnName(),
-							newVCN,
-							getContextManager());
-			newRC.setType(newVCN.getTypeServices());
-			newRC.setVirtualColumnId(rcl.size() + 2);
-
-			/* Add the new RC/VCN to the RCL */
-			rcl.addElement(newRC);
-
-			/* Set the columnPosition in the GroupByColumn, now that it
-			 * has a matching entry in the SELECT list.
-			 */
-			gbc.setColumnPosition(rcl.size());
-		}
-	}
-
-	/**
-	 *
-	 */
-	public GroupByColumn containsColumnReference(ColumnReference cr)
-	{
-		int size = size();
-		for (int index = 0; index < size; index++)
-		{
-			GroupByColumn		groupingCol = (GroupByColumn) elementAt(index);
-
-			if (groupingCol.getSource() == cr.getSource() &&
-				groupingCol.getTableNumber() == cr.getTableNumber())
-			{
-				return groupingCol;
-			}
-		}
-
 		return null;
 	}
-
+	
 	/**
 	 * Remap all ColumnReferences in this tree to be clones of the
 	 * underlying expression.
@@ -371,7 +270,7 @@
 			ValueNode	retVN;
 			gbc = (GroupByColumn) elementAt(index);
 
-			retVN = gbc.getColumnReference().remapColumnReferencesToExpressions();
+			retVN = gbc.getColumnExpression().remapColumnReferencesToExpressions();
 
 			if (SanityManager.DEBUG)
 			{
@@ -380,7 +279,7 @@
 					retVN.getClass().getName());
 			}
 
-			gbc.setColumnReference((ColumnReference) retVN);
+			gbc.setColumnExpression(retVN);
 		}
 	}
 
@@ -405,5 +304,18 @@
 		{
 			return "";
 		}
+	}
+
+	public void preprocess(
+			int numTables, FromList fromList, SubqueryList whereSubquerys, 
+			PredicateList wherePredicates) throws StandardException 
+	{
+		for (int index = 0; index < size(); index++)
+		{
+			GroupByColumn	groupingCol = (GroupByColumn) elementAt(index);
+			groupingCol.setColumnExpression(
+					groupingCol.getColumnExpression().preprocess(
+							numTables, fromList, whereSubquerys, wherePredicates));
+		}		
 	}
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/GroupByNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/GroupByNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/GroupByNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/GroupByNode.java Fri Sep  1 08:53:05 2006
@@ -202,14 +202,25 @@
 
 			// Now populate the CR array and see if ordered
 			int glSize = this.groupingList.size();
-			for (int index = 0; index < glSize; index++)
+			int index;
+			for (index = 0; index < glSize; index++)
 			{
 				GroupByColumn gc =
 						(GroupByColumn) this.groupingList.elementAt(index);
-				crs[index] = gc.getColumnReference();
+				if (gc.getColumnExpression() instanceof ColumnReference) 
+				{
+					crs[index] = (ColumnReference)gc.getColumnExpression();
+				} 
+				else 
+				{
+					isInSortedOrder = false;
+					break;
+				}
+				
+			}
+			if (index == glSize) {
+				isInSortedOrder = childResult.isOrderedOn(crs, true, (Vector)null);
 			}
-
-			isInSortedOrder = childResult.isOrderedOn(crs, true, (Vector)null);
 		}
 	}
 
@@ -314,6 +325,70 @@
 
 	}
 
+	/**
+	 * In the query rewrite for group by, add the columns on which
+	 * we are doing the group by.
+
+	 * @see #addNewColumnsForAggregation
+	 */
+	private void addUnAggColumns() throws StandardException
+	{
+		ResultColumnList bottomRCL  = childResult.getResultColumns();
+		ResultColumnList groupByRCL = resultColumns;
+
+		int sz = groupingList.size();
+		for (int i = 0; i < sz; i++) 
+		{
+			GroupByColumn gbc = (GroupByColumn) groupingList.elementAt(i);
+			ResultColumn newRC = (ResultColumn) getNodeFactory().getNode(
+					C_NodeTypes.RESULT_COLUMN,
+					"##UnaggColumn",
+					gbc.getColumnExpression(),
+					getContextManager());
+
+			// add this result column to the bottom rcl
+			bottomRCL.addElement(newRC);
+			newRC.markGenerated();
+			newRC.bindResultColumnToExpression();
+			newRC.setVirtualColumnId(bottomRCL.size());
+			
+			// now add this column to the groupbylist
+			ResultColumn gbRC = (ResultColumn) getNodeFactory().getNode(
+					C_NodeTypes.RESULT_COLUMN,
+					"##UnaggColumn",
+					gbc.getColumnExpression(),
+					getContextManager());
+			groupByRCL.addElement(gbRC);
+			gbRC.markGenerated();
+			gbRC.bindResultColumnToExpression();
+			gbRC.setVirtualColumnId(groupByRCL.size());
+
+			/*
+			 ** Reset the original node to point to the
+			 ** Group By result set.
+			 */
+			VirtualColumnNode vc = (VirtualColumnNode) getNodeFactory().getNode(
+					C_NodeTypes.VIRTUAL_COLUMN_NODE,
+					this, // source result set.
+					gbRC,
+					new Integer(groupByRCL.size()),
+					getContextManager());
+
+			// we replace each group by expression 
+			// in the projection list with a virtual column node
+			// that effectively points to a result column 
+			// in the result set doing the group by
+			SubstituteExpressionVisitor se = 
+				new SubstituteExpressionVisitor(
+						gbc.getColumnExpression(),
+						vc,
+						AggregateNode.class);
+			parent.getResultColumns().accept(se);
+
+			// finally reset gbc to its new position.
+			gbc.setColumnPosition(bottomRCL.size());
+		}
+	}
 
 	/**
 	 * Add a whole slew of columns needed for 
@@ -357,19 +432,26 @@
 	private void addNewColumnsForAggregation()
 		throws StandardException
 	{
-		/*
-		** Now we have two new nodes, the sort and a new PR above
-		** it.  They all map to the child result set.  Now we must
-		** find every aggregate and massage the tree.  For now we
-		** will examine every result column of the original select
-		** list.
-		*/
-		DataDictionary			dd;
+		aggInfo = new AggregatorInfoList();
+		if (groupingList != null)
+		{
+			addUnAggColumns();
+		}
+		addAggregateColumns();
+	}
+	
+	/**
+	 * In the query rewrite involving aggregates, add the columns for
+	 * aggregation.
+	 *
+	 * @see #addNewColumnsForAggregation
+	 */
+	private void addAggregateColumns() throws StandardException
+	{
+		DataDictionary			dd = getDataDictionary();
 		AggregateNode	aggregate = null;
 		ColumnReference	newColumnRef;
-		ResultColumn	rcBottom;
 		ResultColumn	newRC;
-		ResultColumn	gbRC;
 		ResultColumn	tmpRC;
 		ResultColumn	aggInputRC;
 		ResultColumnList bottomRCL  = childResult.getResultColumns();
@@ -378,84 +460,21 @@
 		int				aggregatorVColId;
 		int				aggInputVColId;
 		int				aggResultVColId;
-
-		LanguageFactory lf = getLanguageConnectionContext().getLanguageFactory();
-		dd = getDataDictionary();
-		aggInfo = new AggregatorInfoList();
-
-		/*
-		** Get a list of all column references in the
-		** parent RCL, skipping (not going below) AggregateNodes
-		*/
-		CollectNodesVisitor getUnaggVisitor = new CollectNodesVisitor(ColumnReference.class, AggregateNode.class);
-		parent.getResultColumns().accept(getUnaggVisitor);
-		Vector colRefVector = getUnaggVisitor.getList();
-
-		/*
-		** Walk the list of unaggregated column references
-		** and push them down.
-		*/
-		int crvSize = colRefVector.size();
-		for (int index = 0; index < crvSize; index++)
-		{
-			ColumnReference origColumnRef = (ColumnReference) colRefVector.elementAt(index);
-			newColumnRef = (ColumnReference)origColumnRef.getClone();
-
-			/*
-			** Put the column reference in the bottom PR.
-			*/
-			newRC = (ResultColumn) getNodeFactory().getNode(
-									C_NodeTypes.RESULT_COLUMN,
-									"##UnaggColumn",
-									newColumnRef,
-									getContextManager());
-			newRC.setExpression(newColumnRef);
-			bottomRCL.addElement(newRC);
-			newRC.markGenerated();
-			newRC.bindResultColumnToExpression();
-			newRC.setVirtualColumnId(bottomRCL.size());
-
-			/*
-			** Reset the group by column position
-			*/
-			if (groupingList != null) 
-			{
-				GroupByColumn	gbColumn;
-				if ((gbColumn = 
-						groupingList.containsColumnReference(newColumnRef)) 
-					!= null)
-				{
-					gbColumn.setColumnPosition(bottomRCL.size());
-				}
-			}
 		
-			/*
-			** Add the column to the group by list
-			*/
-			gbRC = getColumnReference(newRC, dd);
-			groupByRCL.addElement(gbRC);
-			gbRC.markGenerated();
-			gbRC.bindResultColumnToExpression();
-			gbRC.setVirtualColumnId(groupByRCL.size());
-	
-			/*
-			** Reset the original node to point to the
-			** Group By result set.
-			*/
-			origColumnRef.setSource(gbRC);
-		}
 		/*
-		** Now process all of the aggregates.  Replace
-		** every aggregate with an RC.  We toss out
-		** the list of RCs, we need to get each RC
-		** as we process its corresponding aggregate.
-		*/
+		 ** Now process all of the aggregates.  Replace
+		 ** every aggregate with an RC.  We toss out
+		 ** the list of RCs, we need to get each RC
+		 ** as we process its corresponding aggregate.
+		 */
+		LanguageFactory lf = getLanguageConnectionContext().getLanguageFactory();
+		
 		ReplaceAggregatesWithCRVisitor replaceAggsVisitor = 
 			new ReplaceAggregatesWithCRVisitor(
 					(ResultColumnList) getNodeFactory().getNode(
-										C_NodeTypes.RESULT_COLUMN_LIST,
-										getContextManager()),
-					((FromTable) childResult).getTableNumber());
+							C_NodeTypes.RESULT_COLUMN_LIST,
+							getContextManager()),
+				((FromTable) childResult).getTableNumber());
 		parent.getResultColumns().accept(replaceAggsVisitor);
 
 		/*
@@ -471,10 +490,10 @@
 			** bottom project restrict.
 			*/
 			newRC = (ResultColumn) getNodeFactory().getNode(
-										C_NodeTypes.RESULT_COLUMN,
-										"##aggregate result",
-										aggregate.getNewNullResultExpression(),
-										getContextManager());
+					C_NodeTypes.RESULT_COLUMN,
+					"##aggregate result",
+					aggregate.getNewNullResultExpression(),
+					getContextManager());
 			newRC.markGenerated();
 			newRC.bindResultColumnToExpression();
 			bottomRCL.addElement(newRC);
@@ -488,19 +507,19 @@
 			** ReplaceAggregatesWithColumnReferencesVisitor()
 			*/
 			newColumnRef = (ColumnReference) getNodeFactory().getNode(
-												C_NodeTypes.COLUMN_REFERENCE,
-												newRC.getName(),
-												null,
-												getContextManager());
+					C_NodeTypes.COLUMN_REFERENCE,
+					newRC.getName(),
+					null,
+					getContextManager());
 			newColumnRef.setSource(newRC);
 			newColumnRef.setType(newRC.getExpressionType());
 			newColumnRef.setNestingLevel(this.getLevel());
 			newColumnRef.setSourceLevel(this.getLevel());
 			tmpRC = (ResultColumn) getNodeFactory().getNode(
-								C_NodeTypes.RESULT_COLUMN,
-								newRC.getColumnName(),
-								newColumnRef,
-								getContextManager());
+					C_NodeTypes.RESULT_COLUMN,
+					newRC.getColumnName(),
+					newColumnRef,
+					getContextManager());
 			tmpRC.markGenerated();
 			tmpRC.bindResultColumnToExpression();
 			groupByRCL.addElement(tmpRC);
@@ -559,8 +578,8 @@
 			** to this agg if it is a user agg.
 			*/
 			aggRCL = (ResultColumnList) getNodeFactory().getNode(
-											C_NodeTypes.RESULT_COLUMN_LIST,
-											getContextManager());
+					C_NodeTypes.RESULT_COLUMN_LIST,
+					getContextManager());
 			aggRCL.addElement(aggInputRC);
 
 			/*
@@ -568,14 +587,14 @@
 			** so we have to subtract 1.
 			*/
 			aggInfo.addElement(new AggregatorInfo(
-							aggregate.getAggregateName(),
-							aggregate.getAggregatorClassName(),
-							aggInputVColId - 1,			// aggregate input column
-							aggResultVColId -1,			// the aggregate result column
-							aggregatorVColId - 1,		// the aggregator column	
-							aggregate.isDistinct(),
-							lf.getResultDescription(aggRCL.makeResultDescriptors(), "SELECT")
-						));
+					aggregate.getAggregateName(),
+					aggregate.getAggregatorClassName(),
+					aggInputVColId - 1,			// aggregate input column
+					aggResultVColId -1,			// the aggregate result column
+					aggregatorVColId - 1,		// the aggregator column	
+					aggregate.isDistinct(),
+					lf.getResultDescription(aggRCL.makeResultDescriptors(), "SELECT")
+			));
 		}
 	}
 

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/JavaToSQLValueNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/JavaToSQLValueNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/JavaToSQLValueNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/JavaToSQLValueNode.java Fri Sep  1 08:53:05 2006
@@ -354,4 +354,13 @@
 		
 		return returnNode;
 	}
+        
+	/**
+	 * {@inheritDoc}
+	 */
+    protected boolean isEquivalent(ValueNode o)
+    {
+    	// anything in the java domain is not equiavlent.
+    	return false;
+    }
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ParameterNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ParameterNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ParameterNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ParameterNode.java Fri Sep  1 08:53:05 2006
@@ -485,4 +485,12 @@
 	{
 		return true;
 	}
+
+    /**
+     * @inheritDoc
+     */
+    protected boolean isEquivalent(ValueNode o)
+    {
+    	return false;
+    }
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ResultColumn.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ResultColumn.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ResultColumn.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ResultColumn.java Fri Sep  1 08:53:05 2006
@@ -1433,8 +1433,9 @@
 
   		if (isAutoincrement())
   			newResultColumn.setAutoincrement();
-		
-		return newResultColumn;
+  		if (isGroupingColumn()) 
+  			newResultColumn.markAsGroupingColumn();
+  		return newResultColumn;
 	}
 
 	/**
@@ -1592,6 +1593,12 @@
   	{
   		autoincrement = true;
   	}
+        
+        public boolean isGroupingColumn()
+        {
+        	return isGroupingColumn;
+        }
+        
 	/**
 	 * @exception StandardException		Thrown on error
 	 */
@@ -1815,6 +1822,18 @@
 		// reference nor a FromBaseTable beneath it--for example,
 		// if it is of type BaseColumnNode. 
 		return -1;
+	}
+	
+	public boolean isEquivalent(ValueNode o) throws StandardException 
+	{
+        if (o.getNodeType() == getNodeType()) 
+        {                
+        	ResultColumn other = (ResultColumn)o;
+        	if (expression != null) {
+        		return expression.isEquivalent(other.expression);
+        	}
+        }
+        return false;
 	}
 
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java Fri Sep  1 08:53:05 2006
@@ -282,16 +282,6 @@
 	}
 
 	/**
-	 * Return the groupByList for this SelectNode.
-	 *
-	 * @return GroupByList	The groupByList for this SelectNode.
-	 */
-	public GroupByList getGroupByList()
-	{
-		return groupByList;
-	}
-
-	/**
 	 * Find colName in the result columns and return underlying columnReference.
 	 * Note that this function returns null if there are more than one FromTable
 	 * for this SelectNode and the columnReference needs to be directly under
@@ -612,14 +602,14 @@
 						"Unexpected Aggregate vector generated by Group By clause");
 			}
 		}
-
 		/* If ungrouped query with aggregates in SELECT list, verify
 		 * that all result columns are valid aggregate expressions -
 		 * no column references outside of an aggregate.
 		 * If grouped query with aggregates in SELECT list, verify that all
-		 * result columns are either grouping columns or valid 
-		 * grouped aggregate expressions - the only column references allowed
-		 * outside of an aggregage are columns in the group by list.
+		 * result columns are either grouping expressions or valid
+		 * grouped aggregate expressions - the only column references
+		 * allowed outside of an aggregate are columns in expressions in 
+		 * the group by list.
 		 */
 		if (groupByList != null || selectAggregates.size() > 0)
 		{
@@ -627,7 +617,7 @@
   			VerifyAggregateExpressionsVisitor visitor = 
   				new VerifyAggregateExpressionsVisitor(groupByList);
 			resultColumns.accept(visitor);
-		}
+		}       
 
 		/*
 		** RESOLVE: for now, only one distinct aggregate is supported
@@ -966,6 +956,15 @@
 								   wherePredicates);
 		}
 
+		/* Preprocess the group by list too. We need to compare 
+		 * expressions in the group by list with the select list and we 
+		 * can't rewrite one and not the other.
+		 */
+		if (groupByList != null)
+		{
+			groupByList.preprocess(numTables, fromList, whereSubquerys, wherePredicates);
+		}
+		
 		/* Pull apart the expression trees */
 		if (whereClause != null)
 		{

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/SpecialFunctionNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/SpecialFunctionNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/SpecialFunctionNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/SpecialFunctionNode.java Fri Sep  1 08:53:05 2006
@@ -222,4 +222,14 @@
 			return "";
 		}
 	}
+        
+	protected boolean isEquivalent(ValueNode o)
+	{
+		if (isSameNodeType(o))
+		{
+			SpecialFunctionNode other = (SpecialFunctionNode)o;
+			return methodName.equals(other.methodName);
+		}
+		return false;
+	}
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/SubqueryNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/SubqueryNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/SubqueryNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/SubqueryNode.java Fri Sep  1 08:53:05 2006
@@ -2292,4 +2292,12 @@
 		}
 		setType(dts);
 	}
+        
+    /**
+     * {@inheritDoc}
+     */    
+    protected boolean isEquivalent(ValueNode o)
+    {
+    	return false;
+    }
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/TernaryOperatorNode.java Fri Sep  1 08:53:05 2006
@@ -915,4 +915,17 @@
 	private DataTypeDescriptor getVarcharDescriptor() {
 		return new DataTypeDescriptor(TypeId.getBuiltInTypeId(Types.VARCHAR), true);
 	}
+        
+    protected boolean isEquivalent(ValueNode o) throws StandardException
+    {
+    	if (isSameNodeType(o)) 
+	{
+		TernaryOperatorNode other = (TernaryOperatorNode)o;
+    		return (other.methodName.equals(methodName)
+				&& other.receiver.isEquivalent(receiver)
+    				&& other.leftOperand.isEquivalent(leftOperand)
+    				&& other.rightOperand.isEquivalent(rightOperand));
+        }
+    	return false;
+    }
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/UnaryOperatorNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/UnaryOperatorNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/UnaryOperatorNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/UnaryOperatorNode.java Fri Sep  1 08:53:05 2006
@@ -857,4 +857,22 @@
         mb.push(((Boolean)additionalArgs[0]).booleanValue());
         return 3;
     }
+    
+    /**
+     * @throws StandardException 
+     * {@inheritDoc}
+     */
+    protected boolean isEquivalent(ValueNode o) throws StandardException
+    {
+    	if (isSameNodeType(o)) 
+    	{
+		// the first condition in the || covers the case when 
+	    	// both operands are null.
+    		UnaryOperatorNode other = (UnaryOperatorNode)o;
+    		return (operator.equals(other.operator) && 
+			((operand == other.operand)|| 
+			 ((operand != null) && operand.isEquivalent(other.operand))));
+    	}
+    	return false;
+    }
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ValueNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ValueNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ValueNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/ValueNode.java Fri Sep  1 08:53:05 2006
@@ -1329,5 +1329,35 @@
 	{
 		return false;
 	}
+	
+	/**
+	 * Tests if this node is equivalent to the specified ValueNode. Two 
+	 * ValueNodes are considered equivalent if they will evaluate to the same
+	 * value during query execution. 
+	 * 
+	 * @param other the node to compare this ValueNode against.
+	 * @return <code>true</code> if the two nodes are equivalent, 
+	 * <code>false</code> otherwise.
+	 * 
+	 * @throws StandardException 
+	 */
+	protected abstract boolean isEquivalent(ValueNode other)
+		throws StandardException;
 
+	/**
+	 * Tests if this node is of the same type as the specified node as
+	 * reported by {@link QueryTreeNode#getNodeType()}.
+	 * 
+	 * @param other the node to compare this value node against. 
+	 * 
+	 * @return <code>true</code> if the two nodes are of the same type.  
+	 */
+	protected final boolean isSameNodeType(ValueNode other)
+	{
+		if (other != null) {
+			return other.getNodeType() == getNodeType();
+		}
+		return false;
+	}
+	
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/VerifyAggregateExpressionsVisitor.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/VerifyAggregateExpressionsVisitor.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/VerifyAggregateExpressionsVisitor.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/VerifyAggregateExpressionsVisitor.java Fri Sep  1 08:53:05 2006
@@ -64,8 +64,8 @@
 	 *
 	 * @return me
 	 *
-	 * @exception StandardException on ColumnReferernce not
-	 *	in group by list, ValueNode or 
+	 * @exception StandardException on ColumnReference not
+	 * 	in group by list, ValueNode or	
 	 * 	JavaValueNode that isn't under an
 	 * 	aggregate
 	 */
@@ -81,11 +81,12 @@
 				throw StandardException.newException(SQLState.LANG_INVALID_COL_REF_NON_GROUPED_SELECT_LIST, cr.getSQLColumnName());
 			}
 
-			if (groupByList.containsColumnReference(cr) == null)
+			if (groupByList.findGroupingColumn(cr) == null)
 			{
-				throw StandardException.newException(SQLState.LANG_INVALID_COL_REF_GROUPED_SELECT_LIST, cr.getSQLColumnName());
+				throw StandardException.newException(SQLState.LANG_INVALID_GROUPED_SELECT_LIST);
 			}
 		} 
+		
 		/*
 		** Subqueries are only valid if they do not have
 		** correlations and are expression subqueries.  RESOLVE:
@@ -119,22 +120,34 @@
 							SQLState.LANG_INVALID_NON_GROUPED_SELECT_LIST :
 							SQLState.LANG_INVALID_GROUPED_SELECT_LIST);
 			}
+		} else if (node instanceof JavaToSQLValueNode) 
+		{
+			// disallow any expression which involves native java computation. 
+		    	// Not possible to consider java expressions for equivalence.
+			throw StandardException.newException( (groupByList == null) ?
+					SQLState.LANG_INVALID_NON_GROUPED_SELECT_LIST :
+						SQLState.LANG_INVALID_GROUPED_SELECT_LIST);
 		}
 
 		return node;
 	}
 
 	/**
-	 * Don't visit children under an aggregate
+	 * Don't visit children under an aggregate, subquery or any node which
+	 * is equivalent to any of the group by expressions.
 	 *
 	 * @param node 	the node to process
 	 *
 	 * @return true/false
+	 * @throws StandardException 
 	 */
-	public boolean skipChildren(Visitable node)
+	public boolean skipChildren(Visitable node) throws StandardException 
 	{
-		return (node instanceof AggregateNode) ||
-				(node instanceof SubqueryNode);
+		return ((node instanceof AggregateNode) ||
+				(node instanceof SubqueryNode) ||
+				(node instanceof ValueNode &&
+						groupByList != null 
+						&& groupByList.findGroupingColumn((ValueNode)node) != null));
 	}
 	
 	public boolean stopTraversal()

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/VirtualColumnNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/VirtualColumnNode.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/VirtualColumnNode.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/VirtualColumnNode.java Fri Sep  1 08:53:05 2006
@@ -288,4 +288,13 @@
         }
         return dtd;
     } // end of getTypeServices
+    
+    protected boolean isEquivalent(ValueNode o) throws StandardException
+    {
+    	if (isSameNodeType(o)) {
+    		VirtualColumnNode other = (VirtualColumnNode)o;
+    		return sourceColumn.isEquivalent(other.sourceColumn);
+    	}
+    	return false;
+    }
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj Fri Sep  1 08:53:05 2006
@@ -9408,15 +9408,26 @@
 void
 groupingColumnReference(GroupByList groupingCols) throws StandardException :
 {
-	ColumnReference colRef;
+        ValueNode columnExpression;
 }
 {
-	colRef = columnReference() 
+	columnExpression = additiveExpression(null, 0, false)
 	{
+		if (columnExpression.isParameterNode()) 
+	    	{
+			throw StandardException.newException(SQLState.LANG_SYNTAX_ERROR, "?");
+	    	}
+		if (columnExpression instanceof AggregateNode)
+		{
+			AggregateNode agNode = (AggregateNode)columnExpression;
+			throw StandardException.newException(
+				SQLState.LANG_AGGREGATE_IN_GROUPBY_LIST, 
+				agNode.getAggregateName());
+		}        
 		groupingCols.addGroupByColumn(
 			(GroupByColumn) nodeFactory.getNode(
 							C_NodeTypes.GROUP_BY_COLUMN,
-							colRef,
+							columnExpression,
 							getContextManager()));
 	}
 }

Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/loc/messages_en.properties
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/loc/messages_en.properties?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/loc/messages_en.properties (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/loc/messages_en.properties Fri Sep  1 08:53:05 2006
@@ -633,20 +633,20 @@
 42Z99=String or Hex literal cannot exceed 64K.
 42Y16=No public static method ''{0}'' was found in class ''{1}''. The method might exist, but it is not public, or it is not static. 
 42846=Cannot convert types ''{0}'' to ''{1}''.
-42Y19=''{0}'' appears multiple times in the GROUP BY list. Columns in the GROUP BY list must be unambiguous.
+#42Y19=''{0}'' appears multiple times in the GROUP BY list. Columns in the GROUP BY list must be unambiguous.
 42Y22=Aggregate {0} cannot operate on type {1}.
 42Y23=Incorrect JDBC type info returned for column {0}.
 42Y24=View ''{0}'' is not updatable. (Views are currently not updatable.) 
 42Y25=''{0}'' is a system table.  Users are not allowed to modify the contents of this table.
-#42Y26=Parameters are not allowed in the WHEN clause of a trigger.
+42Y26=Aggregates are not allowed in the GROUP BY list.
 42Y27=Parameters are not allowed in the trigger action.
 42Y29=The SELECT list of a non-grouped query contains at least one invalid expression. When the SELECT list contains at least one aggregate then all entries must be valid aggregate expressions.
-42Y30=The SELECT list of a grouped query contains at least one invalid expression. If a SELECT list has a GROUP BY, the list may only contain grouping columns and valid aggregate expressions.  
+42Y30=The SELECT list of a grouped query contains at least one invalid expression. If a SELECT list has a GROUP BY, the list may only contain valid grouping expressions and valid aggregate expressions.  
 42Y32=Aggregator class ''{0}'' for aggregate ''{1}'' on type {2} does not implement com.ibm.db2j.aggregates.Aggregator. 
 42Y33=Aggregate {0} contains one or more aggregates.
 42Y34=Column name ''{0}'' matches more than one result column in table ''{1}''.
 42Y35=Column reference ''{0}'' is invalid. When the SELECT list contains at least one aggregate then all entries must be valid aggregate expressions.  
-42Y36=Column reference ''{0}'' is invalid.  For a SELECT list with a GROUP BY, the list may only contain grouping columns and valid aggregate expressions.  
+42Y36=Column reference ''{0}'' is invalid.  For a SELECT list with a GROUP BY, the list may only contain valid grouping expressions and valid aggregate expressions.  
 42Y37=''{0}'' is a Java primitive and cannot be used with this operator.
 42Y38=insertMode = replace is not permitted on an insert where the target table, ''{0}'', is referenced in the SELECT.
 # NOTE: The parameter to this message is a keyword used as a noun phrase.

Modified: db/derby/code/branches/10.2/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/branches/10.2/java/shared/org/apache/derby/shared/common/reference/SQLState.java Fri Sep  1 08:53:05 2006
@@ -858,17 +858,18 @@
 	String LANG_NO_METHOD_MATCHING_ALIAS                               = "42Y16";
 	// String LANG_DROP_SYSTEM_TABLE_ATTEMPTED                         = "42Y17"; -- replaced by 42X62
 	String LANG_INVALID_CAST                                           = "42846";
-	String LANG_AMBIGUOUS_GROUPING_COLUMN                              = "42Y19";
+    //	String LANG_AMBIGUOUS_GROUPING_COLUMN                              = "42Y19"; -- unused post 883.
 	//	String LANG_UNMATCHED_GROUPING_COLUMN                              =	//	"42Y20"; -- not used
 	String LANG_USER_AGGREGATE_BAD_TYPE                                = "42Y22";
 	String LANG_BAD_J_D_B_C_TYPE_INFO                                  = "42Y23";
 	String LANG_VIEW_NOT_UPDATEABLE                                    = "42Y24";
 	String LANG_UPDATE_SYSTEM_TABLE_ATTEMPTED                          = "42Y25";
-	//	String LANG_NO_PARAMS_IN_TRIGGER_WHEN                              = "42Y26"; -- not used.
+    	String LANG_AGGREGATE_IN_GROUPBY_LIST                              = "42Y26";
 	String LANG_NO_PARAMS_IN_TRIGGER_ACTION                            = "42Y27";
 	// String LANG_NO_TRIGGER_ON_SYSTEM_TABLE                             = "42Y28"; -- replaced by 42X62
 	String LANG_INVALID_NON_GROUPED_SELECT_LIST                        = "42Y29";
 	String LANG_INVALID_GROUPED_SELECT_LIST                            = "42Y30";
+	
 	String LANG_TOO_MANY_ELEMENTS                            = "54004";
 	String LANG_BAD_AGGREGATOR_CLASS2                                  = "42Y32";
 	String LANG_USER_AGGREGATE_CONTAINS_AGGREGATE                      = "42Y33";

Modified: db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/master/groupBy.out
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/master/groupBy.out?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/master/groupBy.out (original)
+++ db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/master/groupBy.out Fri Sep  1 08:53:05 2006
@@ -5,24 +5,20 @@
 0 rows inserted/updated/deleted
 ij> insert into t2 values (1,1,1), (2,2,2);
 2 rows inserted/updated/deleted
-ij> -- group by position
+ij> -- group by constant. should compile but fail because
+-- it is not a valid grouping expression.
 select * from t1 group by 1;
-ERROR 42X01: Syntax error: Encountered "1" at line 2, column 27.
+ERROR 42Y30: The SELECT list of a grouped query contains at least one invalid expression. If a SELECT list has a GROUP BY, the list may only contain valid grouping expressions and valid aggregate expressions.  
 ij> -- column in group by list not in from list
 select a as d from t1 group by d;
 ERROR 42X04: Column 'D' is either not in any table in the FROM list or appears within a join specification and is outside the scope of the join specification or appears in a HAVING clause and is not in the GROUP BY list. If this is a CREATE or ALTER TABLE  statement then 'D' is not a column in the target table.
 ij> -- column in group by list not in select list
 select a as b from t1 group by b;
-ERROR 42Y36: Column reference 'A' is invalid.  For a SELECT list with a GROUP BY, the list may only contain grouping columns and valid aggregate expressions.  
+ERROR 42Y30: The SELECT list of a grouped query contains at least one invalid expression. If a SELECT list has a GROUP BY, the list may only contain valid grouping expressions and valid aggregate expressions.  
 ij> select a from t1 group by b;
-ERROR 42Y36: Column reference 'A' is invalid.  For a SELECT list with a GROUP BY, the list may only contain grouping columns and valid aggregate expressions.  
+ERROR 42Y30: The SELECT list of a grouped query contains at least one invalid expression. If a SELECT list has a GROUP BY, the list may only contain valid grouping expressions and valid aggregate expressions.  
 ij> select a, char(b) from t1 group by a;
-ERROR 42Y36: Column reference 'B' is invalid.  For a SELECT list with a GROUP BY, the list may only contain grouping columns and valid aggregate expressions.  
-ij> -- columns in group by list must be unique
-select a, b from t1 group by a, a;
-ERROR 42Y19: 'A' appears multiple times in the GROUP BY list. Columns in the GROUP BY list must be unambiguous.
-ij> select a, b from t1 group by a, t1.a;
-ERROR 42Y19: 'A' appears multiple times in the GROUP BY list. Columns in the GROUP BY list must be unambiguous.
+ERROR 42Y30: The SELECT list of a grouped query contains at least one invalid expression. If a SELECT list has a GROUP BY, the list may only contain valid grouping expressions and valid aggregate expressions.  
 ij> -- cursor with group by is not updatable
 get cursor c1 as 'select a from t1 group by a for update';
 ERROR 42Y90: FOR UPDATE is not permitted in this type of statement.  
@@ -31,7 +27,7 @@
 ERROR 21000: Scalar subquery is only allowed to return a single row.
 ij> -- correlation on outer table
 select t2.a, (select b from t1 where t1.b = t2.b) from t1 t2 group by t2.a;
-ERROR 42Y30: The SELECT list of a grouped query contains at least one invalid expression. If a SELECT list has a GROUP BY, the list may only contain grouping columns and valid aggregate expressions.  
+ERROR 42Y30: The SELECT list of a grouped query contains at least one invalid expression. If a SELECT list has a GROUP BY, the list may only contain valid grouping expressions and valid aggregate expressions.  
 ij> -- having clause
 -- cannot contain column references which are not grouping columns
 select a from t1 group by a having c = 1;
@@ -40,7 +36,7 @@
 ERROR 42X04: Column 'B.O' is either not in any table in the FROM list or appears within a join specification and is outside the scope of the join specification or appears in a HAVING clause and is not in the GROUP BY list. If this is a CREATE or ALTER TABLE  statement then 'B.O' is not a column in the target table.
 ij> -- ?s in group by
 select a from t1 group by ?;
-ERROR 42X01: Syntax error: Encountered "?" at line 2, column 27.
+ERROR 42X01: Syntax error: ?.
 ij> -- group by on long varchar type
 create table unmapped(c1 long varchar);
 0 rows inserted/updated/deleted

Modified: db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/build.xml
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/build.xml?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/build.xml (original)
+++ db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/build.xml Fri Sep  1 08:53:05 2006
@@ -36,13 +36,34 @@
   <property file="${properties.dir}/compilepath.properties"/> 
 
 <!-- Targets -->
-  <target name="suites" depends="copyfiles"/>
+  <target name="suites" depends="junitsuites,copyfiles"/>
 
   <target name="copyfiles">
     <copy todir="${out.dir}/${derby.testing.suites.dir}">
       <fileset dir="${derby.testing.src.dir}/${derby.testing.functest.dir}/suites" includes="*.runall,*.properties,*.exclude,*.policy"/>
     </copy>
   </target>
-
+	  <target name="junitsuites" 
+	          description="Build Derby JUnit suites">
+	    <javac
+	      source="1.3"
+	      target="1.3"
+	      bootclasspath="${empty}"
+	      nowarn="on"
+	      debug="${debug}"
+	      depend="${depend}"
+	      deprecation="${deprecation}"
+	      optimize="${optimize}"
+	      proceed="${proceed}"
+	      verbose="${verbose}" 
+	      srcdir="${derby.testing.src.dir}"
+	      destdir="${out.dir}">
+	      <classpath>
+	        <pathelement path="${compile.classpath}"/>
+	        <pathelement path="${junit}"/>
+	      </classpath>
+	      <include name="${derby.testing.functest.dir}/suites/*.java"/>
+	    </javac>
+	  </target>
 </project>
 

Modified: db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/derbylang.runall
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/derbylang.runall?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/derbylang.runall (original)
+++ db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/derbylang.runall Fri Sep  1 08:53:05 2006
@@ -1,6 +1,7 @@
 jdbcapi/metadata.java
 jdbcapi/metadataMultiConn.java
 jdbcapi/odbc_metadata.java
+lang/GroupByExpressionTest.junit
 lang/AIjdbc.java
 lang/AggregateClassLoading.java
 lang/CharUTF8.java

Modified: db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/jdbc40.runall
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/jdbc40.runall?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/jdbc40.runall (original)
+++ db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/jdbc40.runall Fri Sep  1 08:53:05 2006
@@ -9,20 +9,5 @@
 # JUnit tests
 jdbc4/AutoloadBooting.junit
 jdbc4/AutoloadTest.junit
-jdbc4/BlobTest.junit
-jdbc4/CallableStatementTest.junit
-jdbc4/ClobTest.junit
-jdbc4/ClosedObjectTest.junit
-jdbc4/ConnectionTest.junit
-jdbc4/DataSourceTest.junit
-jdbc4/JDBC40TranslationTest.junit
-jdbc4/ParameterMetaDataWrapperTest.junit
-jdbc4/PreparedStatementTest.junit
-jdbc4/ResultSetMetaDataTest.junit
-jdbc4/ResultSetTest.junit
-jdbc4/RowIdNotImplementedTest.junit
-jdbc4/StatementEventsTest.junit
-jdbc4/StatementTest.junit
-jdbc4/UnsupportedVetter.junit
 jdbc4/VerifySignatures.junit
-jdbc4/XA40Test.junit
+jdbc4/_Suite.junit

Modified: db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java (original)
+++ db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java Fri Sep  1 08:53:05 2006
@@ -46,8 +46,10 @@
 
 		TestSuite suite = new TestSuite();
 
+        // These really need to run standalone.
 		//suite.addTestSuite(AutoloadBooting.class);
 		//suite.addTestSuite(AutoloadTest.class);
+        
 		suite.addTest(BlobTest.suite());
 		suite.addTest(CallableStatementTest.suite());
 		suite.addTest(ClobTest.suite());
@@ -62,9 +64,13 @@
 		suite.addTest(RowIdNotImplementedTest.suite());
 		suite.addTest(StatementEventsTest.suite());
 		suite.addTest(StatementTest.suite());
-		suite.addTestSuite(UnsupportedVetter.class);
-		suite.addTest(VerifySignatures.suite());
+		suite.addTestSuite(UnsupportedVetter.class);		
 		suite.addTest(XA40Test.suite());
+        
+        // This test is a little strange in its suite
+        // method in that it accesses 
+        // the database to determine the set of tests to run.
+        // suite.addTest(VerifySignatures.suite());
 		
 		return suite;
 	}

Modified: db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURDataModelSetup.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURDataModelSetup.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURDataModelSetup.java (original)
+++ db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SURDataModelSetup.java Fri Sep  1 08:53:05 2006
@@ -22,6 +22,7 @@
 import org.apache.derbyTesting.junit.BaseJDBCTestCase;
 import org.apache.derbyTesting.junit.BaseJDBCTestSetup;
 import org.apache.derbyTesting.junit.BaseTestCase;
+import org.apache.derbyTesting.junit.TestConfiguration;
 
 import java.sql.Connection;
 import java.sql.PreparedStatement;
@@ -71,7 +72,7 @@
                          TABLE_EXISTS_SQL_STATE, e.getSQLState());
             
             // The net framework does not give any valuable error code
-            if (TestUtil.isNetFramework()) {
+            if (!TestConfiguration.getCurrent().getJDBCClient().isEmbedded()) {
                 
                 assertEquals("'drop table t1' failed with unexpected error code",
                              NET_ERROR, e.getErrorCode());

Modified: db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/tests/lang/groupBy.sql
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/tests/lang/groupBy.sql?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/tests/lang/groupBy.sql (original)
+++ db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/tests/lang/groupBy.sql Fri Sep  1 08:53:05 2006
@@ -5,7 +5,8 @@
 create table t2 (a int, b int, c int);
 insert into t2 values (1,1,1), (2,2,2);
 
--- group by position
+-- group by constant. should compile but fail because
+-- it is not a valid grouping expression.
 select * from t1 group by 1;
 
 -- column in group by list not in from list
@@ -15,10 +16,6 @@
 select a as b from t1 group by b;
 select a from t1 group by b;
 select a, char(b) from t1 group by a;
-
--- columns in group by list must be unique
-select a, b from t1 group by a, a;
-select a, b from t1 group by a, t1.a;
 
 -- cursor with group by is not updatable
 get cursor c1 as 'select a from t1 group by a for update';

Modified: db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java (original)
+++ db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java Fri Sep  1 08:53:05 2006
@@ -28,6 +28,8 @@
 import java.io.UnsupportedEncodingException;
 import java.sql.*;
 
+import junit.framework.AssertionFailedError;
+
 import org.apache.derby.tools.ij;
 
 
@@ -358,7 +360,6 @@
 
     /**
      * Assert that SQLState is as expected.
-     * The expected SQLState is truncated to five characters if required.
      *
      * @param message message to print on failure.
      * @param expected the expected SQLState.
@@ -372,22 +373,29 @@
         assertNotNull("Exception cannot be null when asserting on SQLState", 
                       exception);
         
-        String state = exception.getSQLState();
-        
-        if ( state != null )
-            assertTrue("The exception's SQL state must be five characters long",
-                exception.getSQLState().length() == 5);
-        
-        if ( expected != null )
-            assertTrue("The expected SQL state must be five characters long",
-                expected.length() == 5);
-        
-        assertEquals(message, expected, state);
+        try {
+            String state = exception.getSQLState();
+            
+            if ( state != null )
+                assertTrue("The exception's SQL state must be five characters long",
+                        state.length() == 5);
+            
+            if ( expected != null )
+                assertTrue("The expected SQL state must be five characters long",
+                    expected.length() == 5);
+            
+            assertEquals(message, expected, state);
+        } catch (AssertionFailedError e) {
+            
+            // Save the SQLException
+            // e.initCause(exception);
+
+            throw e;
+        }
     }
 
     /**
      * Assert that SQLState is as expected.
-     * The expected SQLState is truncated to five characters if required.
      *
      * @param expected the expected SQLState.
      * @param exception the exception to check the SQLState of.
@@ -395,5 +403,23 @@
     public static void assertSQLState(String expected, SQLException exception) {
         assertSQLState("Unexpected SQL state.", expected, exception);
     }
+    /**
+     * Assert that the query does not compile and throws
+     * a SQLException with the expected state.
+     * 
+     * @param sqlstate expected sql state.
+     * @param query the query to compile.
+     */
+    public void assertCompileError(String sqlState, String query) {
+
+        try {
+            prepareStatement(query).close();
+            fail("expected compile error: " + sqlState);
+        } catch (SQLException se) {
+            assertSQLState(sqlState, se);
+        }
+    }
 
 } // End class BaseJDBCTestCase
+
+

Modified: db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java?rev=439358&r1=439357&r2=439358&view=diff
==============================================================================
--- db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java (original)
+++ db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java Fri Sep  1 08:53:05 2006
@@ -20,6 +20,7 @@
 package org.apache.derbyTesting.junit;
 
 import java.io.File;
+import java.lang.reflect.Method;
 import java.security.*;
 import java.sql.Connection;
 import java.sql.DriverManager;
@@ -67,12 +68,11 @@
      * Set this Thread's current configuration for running tests.
      * @param config Configuration to set it to.
      */
-    private static void setCurrent(TestConfiguration config)
+    static void setCurrent(TestConfiguration config)
     {
         CURRENT_CONFIG.set(config);
     }
     /**
-     * WORK IN PROGRESS
      * Return a decorator for the passed in tests that sets the
      * configuration for the client to be Derby's JDBC client
      * and to start the network server at setUp and shut it
@@ -84,19 +84,67 @@
      * The previous TestConfiguration is restored at tearDown.
      * @param tests
      * @return
+     * @throws Exception 
      */
-    public static Test derbyClientServerDecorator(Test tests)
+    public static Test derbyClientServerDecorator(Class suite) throws Exception
     {
         TestConfiguration config = TestConfiguration.getCurrent();
         
-        // Already in the correct configuration, do nothing.
-        if (config.getJDBCClient().isDerbyNetClient())
-            return tests;
+        TestConfiguration derbyClientConfig =
+            new TestConfiguration(config, JDBCClient.DERBYNETCLIENT,
+                    DEFAULT_HOSTNAME, DEFAULT_PORT);
+        
+        TestConfiguration.setCurrent(derbyClientConfig);
         
-        TestConfiguration derbyClientConfig = null;
-            // new TestConfiguration(config, JDBCClient.DERBYNETCLIENT);
+        Test test = addSuiteByReflection(suite);
         
-        return null;
+        TestConfiguration.setCurrent(config);
+            
+        test = new NetworkServerTestSetup(test);
+            
+        return new ChangeConfigurationSetup(derbyClientConfig, test);
+
+    }
+    private static Test addSuiteByReflection(Class clz) throws Exception
+    {
+        Method sm = clz.getMethod("suite", null);
+              
+        return (Test) sm.invoke(null, null);
+    }  
+    
+    
+    /**
+     * Default embedded configuration
+     *
+     */
+    private TestConfiguration() {
+        this.dbName = DEFAULT_DBNAME;
+        this.userName = DEFAULT_USER_NAME;
+        this.userPassword = DEFAULT_USER_PASSWORD;
+        this.hostName = null;
+        this.port = -1;
+        this.singleLegXA = false;
+        
+        this.jdbcClient = JDBCClient.EMBEDDED;
+        url = createJDBCUrlWithDatabaseName(dbName);
+ 
+    }
+    
+    private TestConfiguration(TestConfiguration copy, JDBCClient client,
+            String hostName, int port)
+    {
+        this.dbName = copy.dbName;
+        this.userName = copy.userName;
+        this.userPassword = copy.userPassword;
+
+        this.isVerbose = copy.isVerbose;
+        this.singleLegXA = copy.singleLegXA;
+        this.port = port;
+        
+        this.jdbcClient = client;
+        this.hostName = hostName;
+        
+        this.url = createJDBCUrlWithDatabaseName(dbName);
     }
 
     /**
@@ -106,7 +154,7 @@
      */
     private TestConfiguration(Properties props) 
         throws NumberFormatException {
-		systemStartupProperties = props;
+
         dbName = props.getProperty(KEY_DBNAME, DEFAULT_DBNAME);
         userName = props.getProperty(KEY_USER_NAME, DEFAULT_USER_NAME);
         userPassword = props.getProperty(KEY_USER_PASSWORD, 
@@ -141,14 +189,6 @@
     }
 
     /**
-     * Get the given system property as specified at startup.
-     */
-	private	String	getSystemStartupProperty( String key )
-	{
-		return systemStartupProperties.getProperty( key );
-	}
-
-    /**
      * Get the system properties in a privileged block.
      *
      * @return the system properties.
@@ -390,7 +430,6 @@
     /**
      * Immutable data members in test configuration
      */
-	private	final Properties systemStartupProperties;
     private final String dbName;
     private final String url;
     private final String userName;