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 ka...@apache.org on 2009/10/06 16:19:09 UTC
svn commit: r822289 - in /db/derby/code/trunk/java:
engine/org/apache/derby/impl/sql/compile/BetweenOperatorNode.java
testing/org/apache/derbyTesting/functionTests/tests/lang/InbetweenTest.java
Author: kahatlen
Date: Tue Oct 6 14:19:07 2009
New Revision: 822289
URL: http://svn.apache.org/viewvc?rev=822289&view=rev
Log:
DERBY-4388: NullPointerException in RIGHT JOIN with NOT BETWEEN
Clone the left operand when performing not-elimination in
BetweenOperatorNode to prevent ColumnReferences from being shared, as
they can be remapped during optimization.
Modified:
db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/BetweenOperatorNode.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/InbetweenTest.java
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/BetweenOperatorNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/BetweenOperatorNode.java?rev=822289&r1=822288&r2=822289&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/BetweenOperatorNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/BetweenOperatorNode.java Tue Oct 6 14:19:07 2009
@@ -127,11 +127,17 @@
/* Set type info for the operator node */
leftBCO.bindComparisonOperator();
+ // DERBY-4388: If leftOperand is a ColumnReference, it may be remapped
+ // during optimization, and that requires the less-than node and the
+ // greater-than node to have separate objects.
+ ValueNode leftClone = (leftOperand instanceof ColumnReference) ?
+ leftOperand.getClone() : leftOperand;
+
/* leftO > rightOList.elementAt(1) */
rightBCO = (BinaryComparisonOperatorNode)
nodeFactory.getNode(
C_NodeTypes.BINARY_GREATER_THAN_OPERATOR_NODE,
- leftOperand,
+ leftClone,
rightOperandList.elementAt(1),
cm);
/* Set type info for the operator node */
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/InbetweenTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/InbetweenTest.java?rev=822289&r1=822288&r2=822289&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/InbetweenTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/InbetweenTest.java Tue Oct 6 14:19:07 2009
@@ -4501,4 +4501,27 @@
conn.rollback();
st.close();
}
+
+ /**
+ * Regression test cases for DERBY-4388, where the not elimination in
+ * BetweenOperatorNode could make column references point to the wrong
+ * result sets after optimization, causing NullPointerExceptions.
+ */
+ public void testDerby4388NotElimination() throws SQLException {
+ setAutoCommit(false); // for easy cleanup with rollback() in tearDown()
+ Statement s = createStatement();
+ s.execute("create table d4388_t1(a int)");
+ s.execute("create table d4388_t2(b int)");
+ s.execute("insert into d4388_t1 values 0,1,2,3,4,5,6");
+ s.execute("insert into d4388_t2 values 0,1,2,3");
+ // The queries below used to cause NullPointerException.
+ JDBC.assertFullResultSet(
+ s.executeQuery("select * from d4388_t1 left join d4388_t2 " +
+ "on a=b where b not between 1 and 5"),
+ new String[][]{{"0", "0"}});
+ JDBC.assertFullResultSet(
+ s.executeQuery("select * from d4388_t2 right join d4388_t1 " +
+ "on a=b where b not between 1 and 5"),
+ new String[][]{{"0", "0"}});
+ }
}