db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kahat...@apache.org
Subject svn commit: r1413586 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/reference/ engine/org/apache/derby/iapi/services/compiler/ engine/org/apache/derby/iapi/sql/execute/ engine/org/apache/derby/impl/services/bytecode/ engine/org/apache/der...
Date Mon, 26 Nov 2012 13:05:36 GMT
Author: kahatlen
Date: Mon Nov 26 13:05:33 2012
New Revision: 1413586

URL: http://svn.apache.org/viewvc?rev=1413586&view=rev
Log:
DERBY-5947: Factor out common code from generated classes

Move execution count from generated class to GenericPreparedStatement.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/ClassName.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/compiler/ClassBuilder.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/compiler/MethodBuilder.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecPreparedStatement.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCClass.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCMethod.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericPreparedStatement.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ActivationClassBuilder.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ExpressionClassBuilder.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StatementNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstantActionActivation.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/BasicSetup.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/ClassName.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/ClassName.java?rev=1413586&r1=1413585&r2=1413586&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/ClassName.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/ClassName.java Mon Nov
26 13:05:33 2012
@@ -61,7 +61,6 @@ public interface ClassName
 
 	String BaseActivation = "org.apache.derby.impl.sql.execute.BaseActivation";
 	String BaseExpressionActivation = "org.apache.derby.impl.sql.execute.BaseExpressionActivation";
-    String RowCountStats = "org.apache.derby.impl.sql.execute.BaseActivation$RowCountStats";
 
 	String CursorActivation = "org.apache.derby.impl.sql.execute.CursorActivation";
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/compiler/ClassBuilder.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/compiler/ClassBuilder.java?rev=1413586&r1=1413585&r2=1413586&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/compiler/ClassBuilder.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/compiler/ClassBuilder.java
Mon Nov 26 13:05:33 2012
@@ -167,10 +167,6 @@ public interface ClassBuilder {
 	 * This is used to start a constructor as well; pass in
 	 * null for the returnType when used in that manner.
      * <p>
-     * If the modifiers include static, the returned method builder is for
-     * a class or interface initialization method. Otherwise, the builder is
-     * for an instance initialization method.
-     * <p>
 	 *
 	 * @param modifiers the | of the Modifier
 	 *	constants representing the visibility and control of this

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/compiler/MethodBuilder.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/compiler/MethodBuilder.java?rev=1413586&r1=1413585&r2=1413586&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/compiler/MethodBuilder.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/compiler/MethodBuilder.java
Mon Nov 26 13:05:33 2012
@@ -161,17 +161,6 @@ public interface MethodBuilder {
 	*/
 	public void getField(LocalField field);
 
-    /**
-     * Push the contents of the static field onto the stack.
-     * <pre>
-     * Stack ... =>
-     *       ...,field_value
-     * </pre>
-     *
-     * @param field a static field
-     */
-    public void getStaticField(LocalField field);
-
 	/**
 		Push the contents of the described field onto the stack.
 		This call requires the instance (reference) to be pushed by the caller.
@@ -205,17 +194,6 @@ public interface MethodBuilder {
 	*/
 	public void setField(LocalField field);
 
-    /**
-     * Pop the top stack value and store it in the static field.
-     * <pre>
-     * Stack ...,value =>
-     *       ...
-     * </pre>
-     *
-     * @param field a static field
-     */
-    public void setStaticField(LocalField field);
-
 	/**
 		Pop the top stack value and store it in the local field. 
 		This call pushes the this instance required to access the field itself.

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecPreparedStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecPreparedStatement.java?rev=1413586&r1=1413585&r2=1413586&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecPreparedStatement.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecPreparedStatement.java
Mon Nov 26 13:05:33 2012
@@ -179,5 +179,35 @@ public interface ExecPreparedStatement 
 	 *         the database does not use SQL standard authorization
 	 */
 	List getRequiredPermissionsList();
-}
 
+    // Methods for stale plan checking.
+
+    /**
+     * Increment and return the execution count for this statement.
+     * @return execution count for this statement after the last compilation
+     */
+    int incrementExecutionCount();
+
+    /**
+     * Get the initial row count of the specified result set. If the initial
+     * row count has not yet been set, initialize it with the value of the
+     * current row count.
+     * @param rsNum the result set to get the initial row count for
+     * @param currentRowCount the current row count for the result set
+     * @return the row count from the first execution of the result set
+     */
+    long getInitialRowCount(int rsNum, long currentRowCount);
+
+    /**
+     * Set the stale plan check interval.
+     * @param interval the stale plan check interval
+     */
+    void setStalePlanCheckInterval(int interval);
+
+    /**
+     * Get the stale plan check interval.
+     * @return the stale plan check interval, or zero if it has not been
+     * initialized yet
+     */
+    int getStalePlanCheckInterval();
+}

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCClass.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCClass.java?rev=1413586&r1=1413585&r2=1413586&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCClass.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCClass.java Mon
Nov 26 13:05:33 2012
@@ -264,10 +264,6 @@ class BCClass extends GClass {
 	 * This is used to start a constructor as well; pass in
 	 * null for the returnType when used in that manner.
      * <p>
-     * If the modifiers include static, the returned method builder is for
-     * a class or interface initialization method. Otherwise, the builder is
-     * for an instance initialization method.
-     * <p>
 	 *
 	 * See Modifiers
 	 * @param modifiers the | of the Modifiers
@@ -277,8 +273,7 @@ class BCClass extends GClass {
 	 * @return the method builder for the constructor.
 	 */
 	public MethodBuilder newConstructorBuilder(int modifiers) {
-        String method = Modifier.isStatic(modifiers) ? "<clinit>" : "<init>";
-        return new BCMethod(this, "void", method, modifiers, null, factory);
+        return new BCMethod(this, "void", "<init>", modifiers, null, factory);
 	}
   	//
 	// class interface

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCMethod.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCMethod.java?rev=1413586&r1=1413585&r2=1413586&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCMethod.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/bytecode/BCMethod.java
Mon Nov 26 13:05:33 2012
@@ -885,12 +885,6 @@ class BCMethod implements MethodBuilder 
 
 	}
 
-    public void getStaticField(LocalField field) {
-        BCLocalField lf = (BCLocalField) field;
-        myCode.addInstrU2(VMOpcode.GETSTATIC, lf.cpi);
-        growStack(lf.type);
-    }
-
 	public void getField(String declaringClass, String fieldName, String fieldType) {
 		Type dt = popStack();
 
@@ -926,13 +920,6 @@ class BCMethod implements MethodBuilder 
         overflowMethodCheck();
 	}
 
-    public void setStaticField(LocalField field) {
-        BCLocalField lf = (BCLocalField) field;
-        myCode.addInstrU2(VMOpcode.PUTSTATIC, lf.cpi);
-        popStack();
-        overflowMethodCheck();
-    }
-
 	/**
 		Upon entry the top word(s) on the stack is
 		the value to be put into the field. Ie.

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericPreparedStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericPreparedStatement.java?rev=1413586&r1=1413585&r2=1413586&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericPreparedStatement.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericPreparedStatement.java
Mon Nov 26 13:05:33 2012
@@ -37,6 +37,7 @@ import org.apache.derby.iapi.services.ca
 import org.apache.derby.catalog.UUID;
 import org.apache.derby.iapi.services.uuid.UUIDFactory;
 import org.apache.derby.iapi.util.ByteArray;
+import org.apache.derby.iapi.util.ReuseFactory;
 
 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
@@ -72,6 +73,8 @@ import org.apache.derby.iapi.services.lo
 
 import java.sql.Timestamp;
 import java.sql.SQLWarning;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -178,6 +181,12 @@ public class GenericPreparedStatement
      */
     private long versionCounter;
 
+    /**
+     * Holder for row counts and execution count. Used for determining
+     * whether the statement should be recompiled.
+     */
+    private RowCountStatistics rowCountStats = new RowCountStatistics();
+
 	//
 	// constructors
 	//
@@ -1002,7 +1011,7 @@ recompileOutOfDatePlan:
 		}
 		isValid = true;
 
-		return;
+        rowCountStats.reset();
 	}
 
 	public GeneratedClass getActivationClass()
@@ -1189,6 +1198,7 @@ recompileOutOfDatePlan:
 		clone.updateColumns = updateColumns;
 		clone.updateMode = updateMode;	
 		clone.needsSavepoint = needsSavepoint;
+        clone.rowCountStats = rowCountStats;
 
 		return clone;
 	}
@@ -1254,4 +1264,107 @@ recompileOutOfDatePlan:
     public final void incrementVersionCounter() {
         ++versionCounter;
     }
+
+    // Stale plan checking.
+
+    /**
+     * This class holds information about stale plan check interval,
+     * execution count and row count statistics for a GenericPreparedStatement.
+     *
+     * The fields and methods should ideally live in GenericPreparedStatement,
+     * not in a separate class. However, triggers clone the GPS on each
+     * execution, which means the statistics would be reset on each execution
+     * if they lived directly inside GPS. Instead, keep the statistics in an
+     * object that can be shared between multiple GPS instances when they
+     * are cloned.
+     */
+    private static class RowCountStatistics {
+        private int stalePlanCheckInterval;
+        private int executionCount;
+        private ArrayList rowCounts;
+
+        // No synchronization for executionCount. Since it's accessed on
+        // every execution, we want to avoid synchronization. Nothing serious
+        // happens if the execution count is off, we just risk checking for
+        // stale plans at a different frequency than specified by
+        // derby.language.stalePlanCheckInterval.
+        //
+        // We might want to use a java.util.concurrent.atomic.AtomicInteger
+        // and its atomic incrementAndGet() method once support for pre-Java 5
+        // JVMs is dropped.
+
+        /** @see ExecPreparedStatement#incrementExecutionCount() */
+        int incrementExecutionCount() {
+            return ++executionCount;
+        }
+
+        /** @see ExecPreparedStatement#getInitialRowCount(int, long) */
+        synchronized long getInitialRowCount(int rsNum, long rowCount) {
+            // Allocate the list of row counts lazily.
+            if (rowCounts == null) {
+                rowCounts = new ArrayList();
+            }
+
+            // Make sure the list is big enough to hold the row count for
+            // the specified result set number.
+            if (rsNum >= rowCounts.size()) {
+                int newSize = rsNum + 1;
+                rowCounts.addAll(
+                        Collections.nCopies(newSize - rowCounts.size(), null));
+            }
+
+            // Get the initial row count for the specified result set, and
+            // set it if it is not already set.
+            Long initialCount = (Long) rowCounts.get(rsNum);
+            if (initialCount == null) {
+                rowCounts.set(rsNum, ReuseFactory.getLong(rowCount));
+                return rowCount;
+            } else {
+                return initialCount.longValue();
+            }
+        }
+
+        // No synchronization for stale plan check interval. Same reason as
+        // stated above for executionCount. Since int accesses are guaranteed
+        // atomic, the worst that could happen is that one thread sees it as
+        // uninitialized (zero) when another thread in fact has initialized it,
+        // and we end up doing the initialization work twice.
+
+        /** @see ExecPreparedStatement#setStalePlanCheckInterval(int) */
+        void setStalePlanCheckInterval(int interval) {
+            stalePlanCheckInterval = interval;
+        }
+
+        /** @see ExecPreparedStatement#getStalePlanCheckInterval() */
+        int getStalePlanCheckInterval() {
+            return stalePlanCheckInterval;
+        }
+
+        /** Reset all the row count statistics. */
+        synchronized void reset() {
+            stalePlanCheckInterval = 0;
+            executionCount = 0;
+            rowCounts = null;
+        }
+    }
+
+    /** @see ExecPreparedStatement#incrementExecutionCount() */
+    public int incrementExecutionCount() {
+        return rowCountStats.incrementExecutionCount();
+    }
+
+    /** @see ExecPreparedStatement#setStalePlanCheckInterval(int) */
+    public void setStalePlanCheckInterval(int interval) {
+        rowCountStats.setStalePlanCheckInterval(interval);
+    }
+
+    /** @see ExecPreparedStatement#getStalePlanCheckInterval() */
+    public int getStalePlanCheckInterval() {
+        return rowCountStats.getStalePlanCheckInterval();
+    }
+
+    /** @see ExecPreparedStatement#getInitialRowCount(int, long) */
+    public long getInitialRowCount(int rsNum, long currentRowCount) {
+        return rowCountStats.getInitialRowCount(rsNum, currentRowCount);
+    }
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ActivationClassBuilder.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ActivationClassBuilder.java?rev=1413586&r1=1413585&r2=1413586&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ActivationClassBuilder.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ActivationClassBuilder.java
Mon Nov 26 13:05:33 2012
@@ -188,24 +188,6 @@ class ActivationClassBuilder	extends	Exp
             executeMethod.complete();
         }
 
-        // Create and initialize a static field that holds row count statistics.
-        LocalField rowCountField = newFieldDeclaration(
-                Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL,
-                ClassName.RowCountStats);
-        MethodBuilder init = getStaticInitializer();
-        init.pushNewStart(ClassName.RowCountStats);
-        init.pushNewComplete(0);
-        init.setStaticField(rowCountField);
-
-        // Create a method that returns the row count statistics.
-        MethodBuilder getRowCountStats = cb.newMethodBuilder(
-                Modifier.PROTECTED | Modifier.FINAL,
-                ClassName.RowCountStats,
-                "getRowCountStats");
-        getRowCountStats.getStaticField(rowCountField);
-        getRowCountStats.methodReturn();
-        getRowCountStats.complete();
-
 		if (closeActivationMethod != null) {
 			closeActivationMethod.methodReturn();
 			closeActivationMethod.complete();

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ExpressionClassBuilder.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ExpressionClassBuilder.java?rev=1413586&r1=1413585&r2=1413586&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ExpressionClassBuilder.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ExpressionClassBuilder.java
Mon Nov 26 13:05:33 2012
@@ -72,7 +72,6 @@ abstract	class ExpressionClassBuilder im
 	protected int nextNonFastExpr;
 	protected int nextFieldNum;
 	protected MethodBuilder constructor;
-    protected MethodBuilder staticInitializer;
 	CompilerContext myCompCtx;
 	MethodBuilder executeMethod; // to find it fast
 
@@ -169,13 +168,6 @@ abstract	class ExpressionClassBuilder im
 		return constructor;
 	}
 
-    MethodBuilder getStaticInitializer() {
-        if (staticInitializer == null) {
-            staticInitializer = cb.newConstructorBuilder(Modifier.STATIC);
-        }
-        return staticInitializer;
-    }
-
 	ClassBuilder getClassBuilder() {
 		return cb;
 	}
@@ -248,17 +240,6 @@ abstract	class ExpressionClassBuilder im
 		constructor.complete();
 	}
 
-    /**
-     * Finish the static initializer, if there is one, by putting a return
-     * at the end of it.
-     */
-    void finishStaticInitializer() throws StandardException {
-        if (staticInitializer != null) {
-            staticInitializer.methodReturn();
-            staticInitializer.complete();
-        }
-    }
-
 	/**
 	 * Generate the assignment for row = new ExecRow[numResultSets]
 	 *

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StatementNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StatementNode.java?rev=1413586&r1=1413585&r2=1413586&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StatementNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StatementNode.java Mon
Nov 26 13:05:33 2012
@@ -329,9 +329,6 @@ public abstract class StatementNode exte
 		// wrap up the constructor by putting a return at the end of it
 		generatingClass.finishConstructor();
 
-        // wrap up the static initializer by putting a return at the end of it
-        generatingClass.finishStaticInitializer();
-
 		try {
 			// cook the completed class into a real class
 			// and stuff it into activationClass

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=1413586&r1=1413585&r2=1413586&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
Mon Nov 26 13:05:33 2012
@@ -27,7 +27,6 @@ import java.sql.SQLWarning;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Hashtable;
-import java.util.List;
 import java.util.Vector;
 
 import	org.apache.derby.catalog.Dependable;
@@ -920,35 +919,6 @@ public abstract class BaseActivation imp
 		}
 	}
 
-    /**
-     * This class holds row count statistics for a query.
-     */
-    protected static class RowCountStats {
-        /**
-         * Stale plan check interval tells how often the row counts should be
-         * checked. Cached here so that we don't need to query the database
-         * properties on each execution.
-         */
-        private int stalePlanCheckInterval;
-        /** The number of times this query has been executed. */
-        private int executionCount;
-        /** List with row count estimates for each table in the query. */
-        private final List rowCounts;
-
-        public RowCountStats() {
-            rowCounts = new ArrayList();
-        }
-    }
-
-    /**
-     * Get the object holding row count statistics for this activation.
-     *
-     * It may return {@code null} if row count statistics are not maintained
-     * for the activation. In that case, {@link #shouldWeCheckRowCounts()}
-     * must return {@code false}.
-     */
-    protected abstract RowCountStats getRowCountStats();
-
 	/**
 		@see Activation#informOfRowCount
 		@exception StandardException	Thrown on error
@@ -968,121 +938,90 @@ public abstract class BaseActivation imp
 			/* Check each result set only once per execution */
 			if (rowCountsCheckedThisExecution.add(rsn))
 			{
-                final RowCountStats stats = getRowCountStats();
-                synchronized (stats)
-				{
-                    final List rowCountCheckVector = stats.rowCounts;
-					Long firstRowCount = null;
+                long n1 = getPreparedStatement()
+                        .getInitialRowCount(resultSetNumber, currentRowCount);
 
-					/*
-					** Check whether this resultSet has been seen yet.
-					*/
-					if (resultSetNumber < rowCountCheckVector.size())
-					{
-						firstRowCount =
-                            (Long) rowCountCheckVector.get(resultSetNumber);
-					}
-					else
-					{
-                        int newSize = resultSetNumber + 1;
-                        while (rowCountCheckVector.size() < newSize) {
-                            rowCountCheckVector.add(null);
+                /*
+                ** Has the row count changed significantly?
+                */
+                if (currentRowCount != n1)
+                {
+                    if (n1 >= TEN_PERCENT_THRESHOLD)
+                    {
+                        /*
+                        ** For tables with more than
+                        ** TEN_PERCENT_THRESHOLD rows, the
+                        ** threshold is 10% of the size of the table.
+                        */
+                        long changeFactor = n1 / (currentRowCount - n1);
+                        if (Math.abs(changeFactor) <= 10) {
+                            significantChange = true;
                         }
-					}
-
-					if (firstRowCount != null)
-					{
-						/*
-						** This ResultSet has been seen - has the row count
-						** changed significantly?
-						*/
-						long n1 = firstRowCount.longValue();
-
-						if (currentRowCount != n1)
-						{
-							if (n1 >= TEN_PERCENT_THRESHOLD)
-							{
-								/*
-								** For tables with more than
-								** TEN_PERCENT_THRESHOLD rows, the
-								** threshold is 10% of the size of the table.
-								*/
-								long changeFactor = n1 / (currentRowCount - n1);
-								if (Math.abs(changeFactor) <= 10)
-									significantChange = true;
-							}
-							else
-							{
-								/*
-								** For tables with less than
-								** TEN_PERCENT_THRESHOLD rows, the threshold
-								** is non-linear.  This is because we want
-								** recompilation to happen sooner for small
-								** tables that change size.  This formula
-								** is for a second-order equation (a parabola).
-								** The derivation is:
-								**
-								**   c * n1 = (difference in row counts) ** 2
-								**				- or - 
-								**   c * n1 = (currentRowCount - n1) ** 2
-								**
-								** Solving this for currentRowCount, we get:
-								**
-								**   currentRowCount = n1 + sqrt(c * n1)
-								**
-								**				- or -
-								**
-								**   difference in row counts = sqrt(c * n1)
-								**
-								**				- or -
-								**
-								**   (difference in row counts) ** 2 =
-								**					c * n1
-								**
-								** Which means that we should recompile when
-								** the current row count exceeds n1 (the first
-								** row count) by sqrt(c * n1), or when the
-								** square of the difference exceeds c * n1.
-								** A good value for c seems to be 4.
-								**
-								** We don't use this formula when c is greater
-								** than TEN_PERCENT_THRESHOLD because we never
-								** want to recompile unless the number of rows
-								** changes by more than 10%, and this formula
-								** is more sensitive than that for values of
-								** n1 greater than TEN_PERCENT_THRESHOLD.
-								*/
-								long changediff = currentRowCount - n1;
-
-								/*
-								** Square changediff rather than take the square
-								** root of (4 * n1), because multiplying is
-								** faster than taking a square root.  Also,
-								** check to be sure that squaring changediff
-								** will not cause an overflow by comparing it
-								** with the square root of the maximum value
-								** for a long (this square root is taken only
-								** once, when the class is loaded, or during
-								** compilation if the compiler is smart enough).
-								*/
-								if (Math.abs(changediff) <= MAX_SQRT)
-								{
-									if ((changediff * changediff) >
-															Math.abs(4 * n1))
-									{
-										significantChange = true;
-									}
-								}
-							}
-						}
-					}
-					else
-					{
-                        rowCountCheckVector.set(
-                            resultSetNumber, new Long(currentRowCount));
-
-					}
-				}
+                    }
+                    else
+                    {
+                        /*
+                        ** For tables with less than
+                        ** TEN_PERCENT_THRESHOLD rows, the threshold
+                        ** is non-linear.  This is because we want
+                        ** recompilation to happen sooner for small
+                        ** tables that change size.  This formula
+                        ** is for a second-order equation (a parabola).
+                        ** The derivation is:
+                        **
+                        **   c * n1 = (difference in row counts) ** 2
+                        **				- or -
+                        **   c * n1 = (currentRowCount - n1) ** 2
+                        **
+                        ** Solving this for currentRowCount, we get:
+                        **
+                        **   currentRowCount = n1 + sqrt(c * n1)
+                        **
+                        **				- or -
+                        **
+                        **   difference in row counts = sqrt(c * n1)
+                        **
+                        **				- or -
+                        **
+                        **   (difference in row counts) ** 2 =
+                        **					c * n1
+                        **
+                        ** Which means that we should recompile when
+                        ** the current row count exceeds n1 (the first
+                        ** row count) by sqrt(c * n1), or when the
+                        ** square of the difference exceeds c * n1.
+                        ** A good value for c seems to be 4.
+                        **
+                        ** We don't use this formula when c is greater
+                        ** than TEN_PERCENT_THRESHOLD because we never
+                        ** want to recompile unless the number of rows
+                        ** changes by more than 10%, and this formula
+                        ** is more sensitive than that for values of
+                        ** n1 greater than TEN_PERCENT_THRESHOLD.
+                        */
+                        long changediff = currentRowCount - n1;
+
+                        /*
+                        ** Square changediff rather than take the square
+                        ** root of (4 * n1), because multiplying is
+                        ** faster than taking a square root.  Also,
+                        ** check to be sure that squaring changediff
+                        ** will not cause an overflow by comparing it
+                        ** with the square root of the maximum value
+                        ** for a long (this square root is taken only
+                        ** once, when the class is loaded, or during
+                        ** compilation if the compiler is smart enough).
+                        */
+                        if (Math.abs(changediff) <= MAX_SQRT)
+                        {
+                            if ((changediff * changediff) >
+                                                    Math.abs(4 * n1))
+                            {
+                                significantChange = true;
+                            }
+                        }
+                    }
+                }
 			}
 
 			/* Invalidate outside of the critical section */
@@ -1225,7 +1164,7 @@ public abstract class BaseActivation imp
      */
 	protected boolean shouldWeCheckRowCounts() throws StandardException
 	{
-        final RowCountStats stats = getRowCountStats();
+        final ExecPreparedStatement ps = getPreparedStatement();
 
 		/*
 		** Check the row count only every N executions.  OK to check this
@@ -1233,7 +1172,7 @@ public abstract class BaseActivation imp
 		** critical.  The value of N is determined by the property
 		** derby.language.stalePlanCheckInterval.
 		*/
-        int executionCount = ++stats.executionCount;
+        int executionCount = ps.incrementExecutionCount();
 
 		/*
 		** Always check row counts the first time, to establish the
@@ -1255,7 +1194,7 @@ public abstract class BaseActivation imp
 		}
 		else
 		{
-            int stalePlanCheckInterval = stats.stalePlanCheckInterval;
+            int stalePlanCheckInterval = ps.getStalePlanCheckInterval();
 
 			/*
 			** Only query the database property once.  We can tell because
@@ -1273,7 +1212,8 @@ public abstract class BaseActivation imp
 							Integer.MAX_VALUE,
 							Property.DEFAULT_LANGUAGE_STALE_PLAN_CHECK_INTERVAL
 							);
-                stats.stalePlanCheckInterval = stalePlanCheckInterval;
+
+                ps.setStalePlanCheckInterval(stalePlanCheckInterval);
 			}
 
             return (executionCount % stalePlanCheckInterval) == 1;

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstantActionActivation.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstantActionActivation.java?rev=1413586&r1=1413585&r2=1413586&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstantActionActivation.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstantActionActivation.java
Mon Nov 26 13:05:33 2012
@@ -47,13 +47,6 @@ public final class ConstantActionActivat
         return false;
     }
 
-    /**
-     * Always return null since constant actions never check row counts.
-     */
-    protected RowCountStats getRowCountStats() {
-        return null;
-    }
-
     protected ResultSet createResultSet() throws StandardException {
         return getResultSetFactory().getDDLResultSet(this);
     }

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/BasicSetup.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/BasicSetup.java?rev=1413586&r1=1413585&r2=1413586&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/BasicSetup.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/BasicSetup.java
Mon Nov 26 13:05:33 2012
@@ -32,9 +32,6 @@ import org.apache.derbyTesting.junit.JDB
 import org.apache.derbyTesting.junit.TestConfiguration;
 import org.apache.derbyTesting.junit.XML;
 
-import org.apache.derbyTesting.junit.IndexStatsUtil;
-
-import junit.framework.Assert;
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
@@ -46,8 +43,25 @@ public class BasicSetup extends UpgradeC
     
     public static Test suite() {
         TestSuite suite = new TestSuite("Upgrade basic setup");
-        
-        suite.addTestSuite(BasicSetup.class);
+
+        // Make the test cases run in a fixed order so they become
+        // more deterministic. Some orderings may make them run into
+        // problems in old versions. Since it's too late to fix bugs
+        // in old versions, we have to work around them like this
+        // instead.
+        //
+        // The specific problem that prompted this particular
+        // workaround, was a combination of DERBY-5947 and DERBY-4577.
+        // DERBY-5947 changed the size of the trigger plans stored in
+        // SYS.SYSSTATEMENTS. Although that change should be harmless
+        // in itself, it happened to make some of the triggers in this
+        // test have plans of the exact right size to hit DERBY-4577
+        // when downgrading to a version without the fix for
+        // DERBY-4577 in the post soft-upgrade phase. This only
+        // happened for some orderings, so always run the test with a
+        // known good ordering.
+
+        suite.addTest(TestConfiguration.orderedSuite(BasicSetup.class));
 
         if (XML.classpathMeetsXMLReqs()) {
             // Only test XML operators if they are supported by the version



Mime
View raw message