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 ba...@apache.org on 2006/06/06 23:37:35 UTC

svn commit: r412218 - in /db/derby/code/branches/10.1/java/engine/org/apache/derby: iapi/store/access/BackingStoreHashtable.java impl/sql/compile/OptimizerImpl.java

Author: bandaram
Date: Tue Jun  6 14:37:34 2006
New Revision: 412218

URL: http://svn.apache.org/viewvc?rev=412218&view=rev
Log:
DERBY-1365: Fixes two minor problems with logic in Optimizer. Here is the note from contributor:

In addition to fixing the two issues described, the patch also resolves another potential problem: there are several places in OptimizerImpl.getNextPermutation() where calls to rewindJoinOrder() are made. These calls typically indicate that the optimizer has decided to abandon or "short circuit" a join order before calculating the full cost. For some of these calls--esp. the ones that can occur in the middle of the join order (as opposed to those which will only occur on a complete join order)--the "rewind" operation needs to make sure to reload the best plans for the optimizables that are pulled as part of the "rewind" process. Otherwise Derby could end up generating a plan for an optimizable even though that plan was part of a join order that was "abandoned" (i.e. rewound in the middle), which is logically incorrect and could lead to sub-optimal performance. I've included changes for this issue as part of d1365_v1.patch.

I ran derbyall on Red Hat Linux with d1365_v1.patch applied and saw no new failures. I would appreciate reviews/comments/commit if anyone has the time... 

Submitted by Army Brown (qozinx@gmail.com)

Modified:
    db/derby/code/branches/10.1/java/engine/org/apache/derby/iapi/store/access/BackingStoreHashtable.java
    db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/sql/compile/OptimizerImpl.java

Modified: db/derby/code/branches/10.1/java/engine/org/apache/derby/iapi/store/access/BackingStoreHashtable.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/engine/org/apache/derby/iapi/store/access/BackingStoreHashtable.java?rev=412218&r1=412217&r2=412218&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/engine/org/apache/derby/iapi/store/access/BackingStoreHashtable.java (original)
+++ db/derby/code/branches/10.1/java/engine/org/apache/derby/iapi/store/access/BackingStoreHashtable.java Tue Jun  6 14:37:34 2006
@@ -272,7 +272,7 @@
                 // needed.
                 if (hash_table == null)
                 {
-					// Check to see how much memory we think the first row
+                    // Check to see how much memory we think the first row
                     // is going to take, and then use that to set the initial
                     // capacity of the Hashtable.
                     double rowUsage = getEstimatedMemUsage(row);
@@ -290,6 +290,16 @@
                 add_row_to_hash_table(hash_table, key, row);
             }
         }
+
+        // In the (unlikely) event that we received a "red flag" estimated_rowcnt
+        // that is too big (see comments above), it's possible that, if row_source
+        // was null or else didn't have any rows, hash_table could still be null
+        // at this point.  So we initialize it to an empty hashtable (representing
+        // an empty result set) so that calls to other methods on this
+        // BackingStoreHashtable (ex. "size()") will have a working hash_table
+        // on which to operate.
+        if (hash_table == null)
+            hash_table = new Hashtable();
     }
 
     /**************************************************************************

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?rev=412218&r1=412217&r2=412218&view=diff
==============================================================================
--- 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 Jun  6 14:37:34 2006
@@ -441,8 +441,20 @@
 
 				// 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)
+				{
 					rewindJoinOrder();
+					joinPosition = -1;
+				}
 			}
 
 			// Reset the timeExceeded flag so that we'll keep going
@@ -503,9 +515,15 @@
 				trace(SHORT_CIRCUITING, 0, 0, 0.0, null);
 			}
 		}
+
 		if (permuteState == JUMPING && !joinPosAdvanced && joinPosition >= 0)
 		{
 			//not feeling well in the middle of jump
+			// Note: we have to make sure we reload the best plans
+			// as we rewind since they may have been clobbered
+			// (as part of the current join order) before we gave
+			// up on jumping.
+			reloadBestPlan = true;
 			rewindJoinOrder();  //fall
 			permuteState = NO_JUMP;  //give up
 		}
@@ -621,8 +639,13 @@
 					// we went through all of the available optimizables
 					// and none of them were legal in the current position;
 					// so we give up and fall back to normal processing.
+					// Note: we have to make sure we reload the best plans
+					// as we rewind since they may have been clobbered
+					// (as part of the current join order) before we got
+					// here.
 						if (joinPosition > 0) {
 							joinPosition--;
+							reloadBestPlan = true;
 							rewindJoinOrder();
 						}
 						permuteState = NO_JUMP;
@@ -1051,10 +1074,15 @@
 					// if we're done we need to put it back to -1 to indicate
 					// that it's an empty slot.  Then we rewind and pull any
 					// other Optimizables at positions < joinPosition.
+					// Note: we have to make sure we reload the best plans
+					// as we rewind since they may have been clobbered
+					// (as part of the current join order) before we got
+					// here.
 					proposedJoinOrder[joinPosition] = -1;
 					joinPosition--;
 					if (joinPosition >= 0)
 					{
+						reloadBestPlan = true;
 						rewindJoinOrder();
 						joinPosition = -1;
 					}