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 da...@apache.org on 2010/09/17 17:10:53 UTC
svn commit: r998170 - in /db/derby/code/trunk/java:
engine/org/apache/derby/impl/sql/execute/BaseActivation.java
testing/org/apache/derbyTesting/functionTests/tests/lang/OuterJoinTest.java
Author: dag
Date: Fri Sep 17 15:10:53 2010
New Revision: 998170
URL: http://svn.apache.org/viewvc?rev=998170&view=rev
Log:
DERBY-4798 NPE in nested outer join
Patch derby-4798a.
Reintroduces the bailout code in BaseActivation#getColumnFromRow which
was removed in DERBY-3097 until we understand why it is needed.
Adds the repro for this issue to OuterJoinTest
Modified:
db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OuterJoinTest.java
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java?rev=998170&r1=998169&r2=998170&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java Fri Sep 17 15:10:53 2010
@@ -1474,7 +1474,23 @@ public abstract class BaseActivation imp
protected final DataValueDescriptor getColumnFromRow(int rsNumber, int colId)
throws StandardException {
- return row[rsNumber].getColumn(colId);
+ if (row[rsNumber] == null) {
+ /* This actually happens. NoPutResultSetImpl.clearOrderableCache
+ * attempts to prefetch invariant values into a cache. This fails
+ * in some deeply nested joins. See Beetle 4736 and 4880.*/
+
+ /*
+ * Update: DERBY-4798 shows a query for which we get an NPE unless
+ * this escape is in place (once removed by DERBY-3097, but
+ * reintroduced by DERBY-4798 until we understand how we can get
+ * rid of this anomaly). Thus, for now,
+ * OuterJoinTest#testDerby_4798_NPE will provoke an NPE if this
+ * code is removed.
+ */
+ return null;
+ }
+
+ return row[rsNumber].getColumn(colId);
}
/**
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OuterJoinTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OuterJoinTest.java?rev=998170&r1=998169&r2=998170&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OuterJoinTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OuterJoinTest.java Fri Sep 17 15:10:53 2010
@@ -35,7 +35,6 @@ import org.apache.derbyTesting.junit.Bas
import org.apache.derbyTesting.junit.CleanDatabaseTestSetup;
import org.apache.derbyTesting.junit.RuntimeStatisticsParser;
import org.apache.derbyTesting.junit.TestConfiguration;
-import org.apache.derby.iapi.services.sanity.SanityManager;
public final class OuterJoinTest extends BaseJDBCTestCase
{
@@ -3379,4 +3378,121 @@ public final class OuterJoinTest extends
JDBC.assertFullResultSet(rs, expRS);
}
+
+
+ /**
+ * Test the queries reported in DERBY-4798 as giving null pointer
+ * exceptions. Should fail with NPE before the fix went in.
+ */
+ public void testDerby_4798_NPE() throws Exception
+ {
+ setAutoCommit(false);
+
+ Statement st = createStatement();
+ ResultSet rs = null;
+ String [][] expRS;
+
+ st.executeUpdate("create table t0(x0 int)");
+ st.executeUpdate("create table t1(x1 int)");
+ st.executeUpdate("create table t2(x2 int)");
+ st.executeUpdate("create table t3(x3 int)");
+ st.executeUpdate("create table t4(x4 int)");
+ st.executeUpdate("insert into t4 values(0)");
+ st.executeUpdate("insert into t4 values(1)");
+ st.executeUpdate("insert into t4 values(2)");
+ st.executeUpdate("insert into t4 values(3)");
+ st.executeUpdate("create table t5(x5 int)");
+ st.executeUpdate("insert into t5 values(0)");
+ st.executeUpdate("insert into t5 values(1)");
+ st.executeUpdate("insert into t5 values(2)");
+ st.executeUpdate("insert into t5 values(3)");
+ st.executeUpdate("insert into t5 values(4)");
+ st.executeUpdate("create table t6(x6 int)");
+ st.executeUpdate("insert into t6 values(0)");
+ st.executeUpdate("insert into t6 values(1)");
+ st.executeUpdate("insert into t6 values(2)");
+ st.executeUpdate("insert into t6 values(3)");
+ st.executeUpdate("insert into t6 values(4)");
+ st.executeUpdate("insert into t6 values(5)");
+ st.executeUpdate("create table t7(x7 int)");
+ st.executeUpdate("insert into t7 values(0)");
+ st.executeUpdate("insert into t7 values(1)");
+ st.executeUpdate("insert into t7 values(2)");
+ st.executeUpdate("insert into t7 values(3)");
+ st.executeUpdate("insert into t7 values(4)");
+ st.executeUpdate("insert into t7 values(5)");
+ st.executeUpdate("insert into t7 values(6)");
+ st.executeUpdate("insert into t0 values(1)");
+ st.executeUpdate("insert into t1 values(2)");
+ st.executeUpdate("insert into t0 values(3)");
+ st.executeUpdate("insert into t1 values(3)");
+ st.executeUpdate("insert into t2 values(4)");
+ st.executeUpdate("insert into t0 values(5)");
+ st.executeUpdate("insert into t2 values(5)");
+ st.executeUpdate("insert into t1 values(6)");
+ st.executeUpdate("insert into t2 values(6)");
+ st.executeUpdate("insert into t0 values(7)");
+ st.executeUpdate("insert into t1 values(7)");
+ st.executeUpdate("insert into t2 values(7)");
+ st.executeUpdate("insert into t3 values(8)");
+ st.executeUpdate("insert into t0 values(9)");
+ st.executeUpdate("insert into t3 values(9)");
+ st.executeUpdate("insert into t1 values(10)");
+ st.executeUpdate("insert into t3 values(10)");
+ st.executeUpdate("insert into t0 values(11)");
+ st.executeUpdate("insert into t1 values(11)");
+ st.executeUpdate("insert into t3 values(11)");
+ st.executeUpdate("insert into t2 values(12)");
+ st.executeUpdate("insert into t3 values(12)");
+ st.executeUpdate("insert into t0 values(13)");
+ st.executeUpdate("insert into t2 values(13)");
+ st.executeUpdate("insert into t3 values(13)");
+ st.executeUpdate("insert into t1 values(14)");
+ st.executeUpdate("insert into t2 values(14)");
+ st.executeUpdate("insert into t3 values(14)");
+ st.executeUpdate("insert into t0 values(15)");
+ st.executeUpdate("insert into t1 values(15)");
+ st.executeUpdate("insert into t2 values(15)");
+ st.executeUpdate("insert into t3 values(15)");
+
+ rs = st.executeQuery(
+ "SELECT t0.x0, " +
+ " t1.x1," +
+ " t2.x2," +
+ " t3.x3," +
+ " t4.x4," +
+ " t5.x5," +
+ " t6.x6," +
+ " t7.x7 " +
+ "FROM " +
+ " ((t0 " +
+ " LEFT OUTER JOIN ((t1 " +
+ " LEFT OUTER JOIN (t2 " +
+ " LEFT OUTER JOIN t3 " +
+ " ON t2.x2 = t3.x3 ) " +
+ " ON t1.x1 = t2.x2 ) " +
+ " LEFT OUTER JOIN (t4 " +
+ " INNER JOIN (t5 " +
+ " LEFT OUTER JOIN t6 " +
+ " ON t5.x5 = t6.x6)" +
+ " ON t4.x4 = t5.x5 ) " +
+ " ON t1.x1 = t5.x5 ) " +
+ " ON t0.x0 = t5.x5 ) " +
+ " LEFT OUTER JOIN t7 " +
+ " ON t3.x3 = t7.x7 ) ");
+
+ expRS = new String [][]
+ {
+ {"1", "1", null, null, null, null, null, null},
+ {"3", "3", "3", null, "3", "3", "3", null},
+ {"5", "5", null, null, null, null, null, null},
+ {"7", "7", null, null, null, null, null, null},
+ {"9", "9", null, null, null, null, null, null},
+ {"11", "11", null, null, null, null, null, null},
+ {"13", "13", null, null, null, null, null, null},
+ {"15", "15", null, null, null, null, null, null}
+ };
+
+ JDBC.assertFullResultSet(rs, expRS);
+ }
}