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 mi...@apache.org on 2006/09/20 02:35:04 UTC

svn commit: r448018 - in /db/derby/code/branches/10.1/java: engine/org/apache/derby/impl/sql/compile/ testing/org/apache/derbyTesting/functionTests/master/ testing/org/apache/derbyTesting/functionTests/tests/lang/

Author: mikem
Date: Tue Sep 19 17:35:03 2006
New Revision: 448018

URL: http://svn.apache.org/viewvc?view=rev&rev=448018
Log:
DERBY-1777
contributed by Army Brown

merging change 446924 from trunk into 10.1 branch:

Commit Army's d1777_v2.patch, cleaning up an NPE in the optimizer.


Modified:
    db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java
    db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/sql/compile/OptimizerImpl.java
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/predicatePushdown.out
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/lang/predicatePushdown.sql

Modified: db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java?view=diff&rev=448018&r1=448017&r2=448018
==============================================================================
--- db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java (original)
+++ db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java Tue Sep 19 17:35:03 2006
@@ -1144,10 +1144,20 @@
 		rcExpr = rc.getExpression();
 		colNum[0] = getColumnNumber();
 
-		while ((rcExpr != null) && (rcExpr instanceof ColumnReference))
+		/* We have to make sure we enter this loop if rc is redundant,
+		 * so that we can navigate down to the actual source result
+		 * set (DERBY-1777). If rc *is* redundant, then rcExpr is not
+		 * guaranteed to be a ColumnReference, so we have to check
+		 * for that case inside the loop.
+		 */
+		while ((rcExpr != null) &&
+			(rc.isRedundant() || (rcExpr instanceof ColumnReference)))
 		{
-			colNum[0] = ((ColumnReference)rcExpr).getColumnNumber();
-			rc = ((ColumnReference)rcExpr).getSource();
+			if (rcExpr instanceof ColumnReference)
+			{
+				colNum[0] = ((ColumnReference)rcExpr).getColumnNumber();
+				rc = ((ColumnReference)rcExpr).getSource();
+			}
 
 			/* If "rc" is redundant then that means it points to another
 			 * ResultColumn that in turn points to the source expression.

Modified: db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/sql/compile/OptimizerImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/sql/compile/OptimizerImpl.java?view=diff&rev=448018&r1=448017&r2=448018
==============================================================================
--- db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/sql/compile/OptimizerImpl.java (original)
+++ db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/sql/compile/OptimizerImpl.java Tue Sep 19 17:35:03 2006
@@ -439,18 +439,21 @@
 					firstLookOrder[i] = bestJoinOrder[i];
 				permuteState = JUMPING;
 
-				// If we were in the middle of a join order when this
-				// happened, then reset the join order before jumping.
-				// The call to rewindJoinOrder() here will put joinPosition
-				// back to 0.  But that said, we'll then end up incrementing 
-				// joinPosition before we start looking for the next join
-				// order (see below), which means we need to set it to -1
-				// here so that it gets incremented to "0" and then
-				// processing can continue as normal from there.  Note:
-				// we don't need to set reloadBestPlan to true here
-				// because we only get here if we have *not* found a
-				// best plan yet.
-				if (joinPosition > 0)
+				/* If we already assigned at least one position in the
+				 * join order when this happened (i.e. if joinPosition
+				 * is greater than *or equal* to zero; DERBY-1777), then 
+				 * reset the join order before jumping.  The call to
+				 * rewindJoinOrder() here will put joinPosition back
+				 * to 0.  But that said, we'll then end up incrementing
+				 * joinPosition before we start looking for the next
+				 * join order (see below), which means we need to set
+				 * it to -1 here so that it gets incremented to "0" and
+				 * then processing can continue as normal from there.  
+				 * Note: we don't need to set reloadBestPlan to true
+				 * here because we only get here if we have *not* found
+				 * a best plan yet.
+				 */
+				if (joinPosition >= 0)
 				{
 					rewindJoinOrder();
 					joinPosition = -1;
@@ -1594,6 +1597,18 @@
 				optimizableList.getOptimizable(
 					proposedJoinOrder[joinPosition - 1]).
 						getBestAccessPath().getCostEstimate();
+		}
+
+		/* At this point outerCost should be non-null (DERBY-1777).
+		 * Do the assertion here so that we catch it right away;
+		 * otherwise we'd end up with an NPE somewhere further
+		 * down the tree and it'd be harder to figure out where
+		 * it came from.
+		 */
+		if (SanityManager.DEBUG)
+		{
+			SanityManager.ASSERT(outerCost != null,
+				"outerCost is not expected to be null");
 		}
 
 		Optimizable optimizable = optimizableList.getOptimizable(proposedJoinOrder[joinPosition]);

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/predicatePushdown.out
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/predicatePushdown.out?view=diff&rev=448018&r1=448017&r2=448018
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/predicatePushdown.out (original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/predicatePushdown.out Tue Sep 19 17:35:03 2006
@@ -1326,6 +1326,12 @@
     (select c1, c, c2, 28 from tc) xx1
       union select 'i','j','j',i from t2;
 0 rows inserted/updated/deleted
+ij> create view vz4 (z1, z2, z3, z4) as
+  select distinct xx1.c1, xx1.c2, 'bokibob' bb, xx1.c from
+    (select c1, c, c2, 28 from tc) xx1
+      union select 'i','j','j',i from t2
+      union select c1, c2, c3, c from tc;
+0 rows inserted/updated/deleted
 ij> -- Both sides of predicate reference aggregates.
 select x1.c1 from
   (select count(*) from t1 union select count(*) from t2) x1 (c1),
@@ -1518,6 +1524,22 @@
 Z4         
 -----------
 4          
+ij> -- Same as previous query but with a different nested
+-- view (vz4) that has double-nested unions in it.
+-- This is a test case for DERBY-1777.
+select x1.z4, x2.c2 from
+  (select z1, z4, z3 from vz4
+    union select '1', i+1, '3' from t1
+  ) x1 (z1, z4, z3),
+  (select distinct j from t2 union select j from t1) x2 (c2)
+where x1.z4 = x2.c2;
+Z4         |C2         
+-----------------------
+2          |2          
+4          |4          
+6          |6          
+2          |2          
+4          |4          
 ij> -- Queries with Select->Union->Select chains having differently-
 -- ordered result column lists with some non-column reference
 -- expressions.  In all of these queries we specify LEFT join
@@ -1694,6 +1716,8 @@
 ij> drop view vz2;
 0 rows inserted/updated/deleted
 ij> drop view vz3;
+0 rows inserted/updated/deleted
+ij> drop view vz4;
 0 rows inserted/updated/deleted
 ij> drop table tc;
 0 rows inserted/updated/deleted

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/lang/predicatePushdown.sql
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/lang/predicatePushdown.sql?view=diff&rev=448018&r1=448017&r2=448018
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/lang/predicatePushdown.sql (original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/lang/predicatePushdown.sql Tue Sep 19 17:35:03 2006
@@ -107,6 +107,12 @@
     (select c1, c, c2, 28 from tc) xx1
       union select 'i','j','j',i from t2;
 
+create view vz4 (z1, z2, z3, z4) as
+  select distinct xx1.c1, xx1.c2, 'bokibob' bb, xx1.c from
+    (select c1, c, c2, 28 from tc) xx1
+      union select 'i','j','j',i from t2
+      union select c1, c2, c3, c from tc;
+
 -- Both sides of predicate reference aggregates.
 select x1.c1 from
   (select count(*) from t1 union select count(*) from t2) x1 (c1),
@@ -266,6 +272,16 @@
   (select distinct j from t2 union select j from t1) x2 (c2)
 where x1.z4 = x2.c2;
 
+-- Same as previous query but with a different nested
+-- view (vz4) that has double-nested unions in it.
+-- This is a test case for DERBY-1777.
+select x1.z4, x2.c2 from
+  (select z1, z4, z3 from vz4
+    union select '1', i+1, '3' from t1
+  ) x1 (z1, z4, z3),
+  (select distinct j from t2 union select j from t1) x2 (c2)
+where x1.z4 = x2.c2;
+
 -- Queries with Select->Union->Select chains having differently-
 -- ordered result column lists with some non-column reference
 -- expressions.  In all of these queries we specify LEFT join
@@ -369,6 +385,7 @@
 drop view vz;
 drop view vz2;
 drop view vz3;
+drop view vz4;
 drop table tc;
 
 -- Now bump up the size of tables T3 and T4 to the point where