db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kmars...@apache.org
Subject svn commit: r711916 - in /db/derby/code/branches/10.3/java: engine/org/apache/derby/impl/sql/compile/AggregateNode.java testing/org/apache/derbyTesting/functionTests/tests/lang/GroupByTest.java
Date Thu, 06 Nov 2008 17:27:48 GMT
Author: kmarsden
Date: Thu Nov  6 09:26:33 2008
New Revision: 711916

URL: http://svn.apache.org/viewvc?rev=711916&view=rev
Log:
DERBY-3880 NPE on a query with having clause involving a join

remap expression for AggregateNode operand if the JoinNode has been flattened.

Fix contributed by Army Brown


Modified:
    db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/compile/AggregateNode.java
    db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GroupByTest.java

Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/compile/AggregateNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/compile/AggregateNode.java?rev=711916&r1=711915&r2=711916&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/compile/AggregateNode.java
(original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/compile/AggregateNode.java
Thu Nov  6 09:26:33 2008
@@ -552,6 +552,27 @@
 			this.getNewNullResultExpression() :
 			operand;
 
+
+		/* The operand for this aggregate node was initialized at bind
+		 * time. Between then and now it's possible that certain changes
+		 * have been made to the query tree which affect this operand. In
+		 * particular, if the operand was pointing to a result column in
+		 * a JoinNode and then that JoinNode was flattened during pre-
+		 * processing, all of the references to that JoinNode--including
+		 * this aggregate's operand--need to be updated to reflect the
+		 * fact that the Join Node no longer exists. So check to see if
+		 * the operand is a column reference, and if so, make a call to
+		 * remap it to its underlying expression. If nothing has happened
+		 * then this will be a no-op; but if something has changed to void
+		 * out the result column to which the operand points, the result
+		 * column will be marked "redundant" and the following call should
+		 * remap as appropriate. DERBY-3880.
+		 */
+		if (operand instanceof ColumnReference)
+		{
+			((ColumnReference)operand).remapColumnReferencesToExpressions();
+		}
+
 		return (ResultColumn) getNodeFactory().getNode(
 								C_NodeTypes.RESULT_COLUMN,
 								"##aggregate expression",

Modified: db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GroupByTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GroupByTest.java?rev=711916&r1=711915&r2=711916&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GroupByTest.java
(original)
+++ db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GroupByTest.java
Thu Nov  6 09:26:33 2008
@@ -588,5 +588,28 @@
         }
         return rows;
     }
+
+    public void testHavingWithInnerJoinDerby3880() throws SQLException {
+        Statement s = createStatement();
+        // tables for DERBY-3880 testing
+        s.executeUpdate("CREATE TABLE T1_D3880(i int, c varchar(20))");
+        s.executeUpdate("create table t2_D3880(i int, c2 varchar(20), i2 int)");
+        s.executeUpdate("insert into t1_D3880 values(1, 'abc')");
+        s.executeUpdate("insert into t1_D3880 values(2, 'abc')");
+        s.executeUpdate("insert into t2_D3880 values(1, 'xyz', 10)");
+        s.executeUpdate("insert into t2_D3880 values(1, 'aaa', 20)");
+        s.executeUpdate("insert into t2_D3880 values(2, 'xxx', 30)");
+        
+        ResultSet rs = s.executeQuery("select   t1_D3880.i, avg(t2_D3880.i2)  from t1_D3880
" +
+                "inner join t2_D3880 on (t1_D3880.i = t2_D3880.i) group by t1_D3880.i having
"  +
+                        "avg(t2_D3880.i2) > 0");
+        String[][] expRs = new String[][] {{"1","15"},{"2","30"}};
+        JDBC.assertFullResultSet(rs,expRs);
+        s.executeUpdate("DROP TABLE T1_D3880");
+        s.executeUpdate("DROP TABLE T2_D3880");
+    
+    }
+
+
 }
 



Mime
View raw message