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 km...@apache.org on 2008/11/06 18:27:48 UTC
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
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");
+
+ }
+
+
}