Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / impl / sql / execute / BaseActivation.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java
new file mode 100644 (file)
index 0000000..81c2736
--- /dev/null
@@ -0,0 +1,1627 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.execute.BaseActivation\r
+\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to you under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+      http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.sql.execute;\r
+\r
+import java.sql.Connection;\r
+import java.sql.SQLException;\r
+import java.sql.SQLWarning;\r
+import java.util.ArrayList;\r
+import java.util.HashSet;\r
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.jdbc.ConnectionContext;\r
+import org.apache.derby.iapi.reference.Property;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.services.context.Context;\r
+import org.apache.derby.iapi.services.context.ContextManager;\r
+import org.apache.derby.iapi.services.io.FormatableBitSet;\r
+import org.apache.derby.iapi.services.loader.GeneratedByteCode;\r
+import org.apache.derby.iapi.services.loader.GeneratedClass;\r
+import org.apache.derby.iapi.services.loader.GeneratedMethod;\r
+import org.apache.derby.iapi.services.property.PropertyUtil;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+import org.apache.derby.iapi.sql.Activation;\r
+import org.apache.derby.iapi.sql.ParameterValueSet;\r
+import org.apache.derby.iapi.sql.ResultDescription;\r
+import org.apache.derby.iapi.sql.ResultSet;\r
+import org.apache.derby.iapi.sql.compile.Optimizer;\r
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;\r
+import org.apache.derby.iapi.sql.depend.DependencyManager;\r
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;\r
+import org.apache.derby.iapi.sql.execute.ConstantAction;\r
+import org.apache.derby.iapi.sql.execute.CursorActivation;\r
+import org.apache.derby.iapi.sql.execute.CursorResultSet;\r
+import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;\r
+import org.apache.derby.iapi.sql.execute.ExecRow;\r
+import org.apache.derby.iapi.sql.execute.ExecutionFactory;\r
+import org.apache.derby.iapi.sql.execute.NoPutResultSet;\r
+import org.apache.derby.iapi.sql.execute.ResultSetFactory;\r
+import org.apache.derby.iapi.sql.execute.TemporaryRowHolder;\r
+import org.apache.derby.iapi.store.access.ConglomerateController;\r
+import org.apache.derby.iapi.store.access.Qualifier;\r
+import org.apache.derby.iapi.store.access.ScanController;\r
+import org.apache.derby.iapi.store.access.TransactionController;\r
+import org.apache.derby.iapi.types.DataTypeDescriptor;\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+import org.apache.derby.iapi.types.DataValueFactory;\r
+import org.apache.derby.iapi.types.NumberDataValue;\r
+import org.apache.derby.iapi.types.RowLocation;\r
+import org.apache.derby.iapi.util.ReuseFactory;\r
+\r
+/**\r
+ * BaseActivation\r
+ * provides the fundamental support we expect all activations to have.\r
+ * Doesn't actually implement any of the activation interface,\r
+ * expects the subclasses to do that.\r
+ */\r
+public abstract class BaseActivation implements CursorActivation, GeneratedByteCode\r
+\r
+{\r
+       private LanguageConnectionContext       lcc;\r
+       protected ContextManager                        cm;\r
+\r
+       protected ExecPreparedStatement preStmt;\r
+       protected ResultSet resultSet;\r
+       protected ResultDescription resultDescription;\r
+       protected boolean closed;\r
+       private String cursorName;\r
+       \r
+       protected int numSubqueries;\r
+\r
+       private boolean singleExecution;\r
+\r
+       // This flag is declared volatile to ensure it is \r
+       // visible when it has been modified by the finalizer thread.\r
+       private volatile boolean inUse;\r
+\r
+       private java.sql.ResultSet targetVTI;\r
+       private SQLWarning warnings;\r
+\r
+       private GeneratedClass gc;      // my Generated class object.\r
+\r
+       private boolean checkRowCounts;\r
+       private HashSet rowCountsCheckedThisExecution = new HashSet(4, 0.9f);\r
+\r
+       private static final long MAX_SQRT = (long) Math.sqrt(Long.MAX_VALUE);\r
+\r
+       // When the row count exceeds this number, we should recompile if\r
+       // the difference in row counts is greater than 10%.  If it's less\r
+       // than this number, we use an entirely different technique to check\r
+       // for recompilation.  See comments below, in informOfRowCount()\r
+       private static final int TEN_PERCENT_THRESHOLD = 400;\r
+\r
+       /* Performance optimization for update/delete - only\r
+        * open heap ConglomerateController once when doing\r
+        * index row to base row on search\r
+        */\r
+       private ConglomerateController  updateHeapCC;\r
+       private ScanController                  indexSC;\r
+       private long                                    indexConglomerateNumber = -1;\r
+\r
+       private TableDescriptor ddlTableDescriptor;\r
+\r
+       private int maxRows = -1;\r
+       private boolean                 forCreateTable;\r
+\r
+       private boolean                 scrollable;\r
+\r
+       private boolean resultSetHoldability;\r
+\r
+       //beetle 3865: updateable cursor using index.  A way of communication\r
+       //between cursor activation and update activation.\r
+       private CursorResultSet forUpdateIndexScan;\r
+\r
+       //Following three are used for JDBC3.0 auto-generated keys feature.\r
+       //autoGeneratedKeysResultSetMode will be set true if at the time of statement execution,\r
+       //either Statement.RETURN_GENERATED_KEYS was passed or an array of (column positions or\r
+       //column names) was passed\r
+       private boolean autoGeneratedKeysResultSetMode;\r
+       private int[] autoGeneratedKeysColumnIndexes ;\r
+       private String[] autoGeneratedKeysColumnNames ;\r
+\r
+       //Following is the position of the session table names list in savedObjects in compiler context\r
+       //This is updated to be the correct value at cursor generate time if the cursor references any session table names.\r
+       //If the cursor does not reference any session table names, this will stay negative\r
+       protected int indexOfSessionTableNamesInSavedObjects = -1;\r
+\r
+       // WARNING: these fields are accessed by code generated in the \r
+       // ExpressionClassBuilder: don't change them unless you \r
+       // make the appropriate changes there.\r
+       protected ExecRow[] row;\r
+       protected ParameterValueSet pvs;\r
+\r
+       //\r
+       // constructors\r
+       //\r
+\r
+       protected BaseActivation()\r
+       {\r
+               super();\r
+       }\r
+\r
+       public final void initFromContext(Context context) \r
+               throws StandardException {\r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT(context!=null, "NULL context passed to BaseActivation.initFromContext");\r
+               }\r
+               this.cm = context.getContextManager();\r
+\r
+               lcc = (LanguageConnectionContext) cm.getContext(LanguageConnectionContext.CONTEXT_ID);\r
+\r
+               if (SanityManager.DEBUG) {\r
+                       if (lcc == null)\r
+                               SanityManager.THROWASSERT("lcc is null in activation type " + getClass());\r
+               }\r
+\r
+               // mark in use\r
+               inUse = true;\r
+               \r
+               // add this activation to the pool for the connection.\r
+               lcc.addActivation(this);\r
+       }\r
+\r
+\r
+       //\r
+       // Activation interface\r
+       //\r
+\r
+       public final ExecPreparedStatement getPreparedStatement() {\r
+               return preStmt;\r
+       }\r
+\r
+       public ConstantAction getConstantAction() {\r
+               return preStmt.getConstantAction();\r
+       }\r
+\r
+\r
+       public final void checkStatementValidity() throws StandardException {\r
+\r
+               if (preStmt == null)\r
+                       return;\r
+\r
+               synchronized (preStmt) {\r
+\r
+                       if ((gc == preStmt.getActivationClass()) && preStmt.upToDate())\r
+                               return;\r
+               }\r
+\r
+               StandardException se = StandardException.newException(SQLState.LANG_STATEMENT_NEEDS_RECOMPILE);\r
+               se.setReport(StandardException.REPORT_NEVER);\r
+               throw se;\r
+       }\r
+\r
+       /**\r
+               Link this activation with its PreparedStatement.\r
+               It can be called with null to break the link with the\r
+               PreparedStatement.\r
+\r
+       */\r
+       public final void setupActivation(ExecPreparedStatement ps, boolean scrollable) \r
+       throws StandardException {\r
+               preStmt = ps;\r
+                               \r
+               if (ps != null) {\r
+                       // get the result set description\r
+                       resultDescription = ps.getResultDescription();\r
+                       this.scrollable = scrollable;\r
+                       \r
+                       // Initialize the parameter set to have allocated\r
+                       // DataValueDescriptor objects for each parameter.\r
+                       if (pvs != null && pvs.getParameterCount() != 0)\r
+                               pvs.initialize(ps.getParameterTypes());\r
+\r
+               } else {\r
+                       resultDescription = null;\r
+                       this.scrollable = false;\r
+               }\r
+       }\r
+\r
+       public ResultSet getResultSet() {\r
+               return resultSet;\r
+       }\r
+\r
+       /**\r
+               Get the saved RowLocation.\r
+\r
+               @param itemNumber       The saved item number.\r
+\r
+               @return A RowLocation template for the conglomerate\r
+        */\r
+       public RowLocation getRowLocationTemplate(int itemNumber)\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT(itemNumber >= 0,\r
+                               "itemNumber expected to be >= 0");\r
+                       if (! (getPreparedStatement().getSavedObject(itemNumber) instanceof RowLocation))\r
+                       {\r
+                               SanityManager.THROWASSERT(\r
+                                       "getPreparedStatement().getSavedObject(itemNumber) expected to be " +\r
+                                       "instance of RowLocation, not " +\r
+                                       getPreparedStatement().getSavedObject(itemNumber).getClass().getName() +\r
+                                       ", query is " + getPreparedStatement().getSource());\r
+                       }\r
+                       RowLocation rl = (RowLocation) getPreparedStatement().getSavedObject(itemNumber);\r
+                       if (! (rl.cloneObject() instanceof RowLocation))\r
+                       {\r
+                               SanityManager.THROWASSERT(\r
+                                       "rl.cloneObject() expected to be " +\r
+                                       "instance of RowLocation, not " +\r
+                                       rl.getClass().getName() +\r
+                                       ", query is " + getPreparedStatement().getSource());\r
+                       }\r
+               }\r
+               /* We have to return a clone of the saved RowLocation due\r
+                * to the shared cache of SPSs.\r
+                */\r
+               return (RowLocation)\r
+                       ((RowLocation)(getPreparedStatement().getSavedObject(itemNumber))).cloneObject();\r
+       }\r
+\r
+       /*\r
+        */\r
+       public ResultDescription getResultDescription() {\r
+               if (SanityManager.DEBUG)\r
+               SanityManager.ASSERT(resultDescription != null, "Must have a result description");\r
+                   return resultDescription;\r
+       }\r
+\r
+       /**\r
+               This is a partial implementation of reset.\r
+               Subclasses will want to reset information\r
+               they are aware of, such as parameters.\r
+               <p>\r
+               All subclasses must call super.reset() and\r
+               then do their cleanup.\r
+               <p>\r
+               The execute call must set the resultSet field\r
+               to be the resultSet that it has returned.\r
+\r
+               @exception StandardException on error\r
+        */\r
+       public void reset() throws StandardException\r
+       {\r
+               if (resultSet != null) \r
+                       resultSet.close();\r
+               \r
+               updateHeapCC = null;\r
+               // REMIND: do we need to get them to stop input as well?\r
+\r
+               if (!isSingleExecution())\r
+                       clearWarnings();\r
+       }\r
+\r
+       /**\r
+               Closing an activation marks it as unusable. Any other\r
+               requests made on it will fail.  An activation should be\r
+               marked closed when it is expected to not be used any longer,\r
+               i.e. when the connection for it is closed, or it has suffered some\r
+               sort of severe error.\r
+\r
+               This should also remove it from the language connection context.\r
+\r
+               @exception StandardException on error\r
+        */\r
+       public final void close() throws StandardException \r
+       {\r
+               if (! closed) { \r
+                       \r
+                       // markUnused();\r
+\r
+                       // we call reset so that if the actual type of "this"\r
+                       // is a subclass of BaseActivation, its cleanup will\r
+                       // also happen -- reset in the actual type is called,\r
+                       // not reset in BaseActivation.  Subclass reset's\r
+                       // are supposed to call super.reset() as well.\r
+                       reset(); // get everything related to executing released\r
+\r
+                       if (resultSet != null)\r
+                       {\r
+                               // Finish the resultSet, it will never be used again.\r
+                               resultSet.finish();\r
+                               resultSet = null;\r
+                       }\r
+\r
+                       closed = true;\r
+\r
+                       LanguageConnectionContext lcc = getLanguageConnectionContext();\r
+\r
+                       lcc.removeActivation(this);\r
+                       if (preStmt != null) {\r
+                               preStmt.finish(lcc);\r
+                               preStmt = null;\r
+                       }\r
+\r
+                       try {\r
+                               closeActivationAction();\r
+                       } catch (Throwable e) {\r
+                               throw StandardException.plainWrapException(e);\r
+                       }\r
+\r
+               }\r
+               \r
+       }\r
+\r
+       /**\r
+               A generated class can create its own closeActivationAction\r
+               method to invoke special logic when the activation is closed.\r
+       */\r
+       protected void closeActivationAction() throws Exception {\r
+               // no code to be added here as generated code\r
+               // will not call super.closeActivationAction()\r
+       }\r
+\r
+       /**\r
+               Find out if the activation closed or not.\r
+               @return true if the prepared statement has been closed.\r
+        */\r
+       public boolean isClosed() {\r
+               return closed;\r
+       }\r
+\r
+       /**\r
+               Set this Activation for a single execution.\r
+\r
+               @see Activation#setSingleExecution\r
+       */\r
+       public void setSingleExecution() {\r
+               singleExecution = true;\r
+       }\r
+\r
+       /**\r
+               Returns true if this Activation is only going to be used for\r
+               one execution.\r
+\r
+               @see Activation#isSingleExecution\r
+       */\r
+       public boolean isSingleExecution() {\r
+               return singleExecution;\r
+       }\r
+\r
+       /**\r
+               Get the number of subqueries in the entire query.\r
+               @return int      The number of subqueries in the entire query.\r
+        */\r
+       public int getNumSubqueries() {\r
+               return numSubqueries;\r
+       }\r
+\r
+       /**\r
+        * @see Activation#isCursorActivation\r
+        */\r
+       public boolean isCursorActivation()\r
+       {\r
+               return false;\r
+       }\r
+\r
+       //\r
+       // GeneratedByteCode interface\r
+       //\r
+\r
+       public final void setGC(GeneratedClass gc) {\r
+               this.gc = gc;\r
+       }\r
+\r
+       public final GeneratedClass getGC() {\r
+\r
+               if (SanityManager.DEBUG) {\r
+                       if (gc == null)\r
+                               SanityManager.THROWASSERT("move code requiring GC to postConstructor() method!!");\r
+               }\r
+               return gc;\r
+       }\r
+\r
+       public final GeneratedMethod getMethod(String methodName) throws StandardException {\r
+\r
+               return getGC().getMethod(methodName);\r
+       }\r
+       public Object e0() throws StandardException { return null; } \r
+       public Object e1() throws StandardException { return null; }\r
+       public Object e2() throws StandardException { return null; }\r
+       public Object e3() throws StandardException { return null; }\r
+       public Object e4() throws StandardException { return null; } \r
+       public Object e5() throws StandardException { return null; }\r
+       public Object e6() throws StandardException { return null; }\r
+       public Object e7() throws StandardException { return null; }\r
+       public Object e8() throws StandardException { return null; } \r
+       public Object e9() throws StandardException { return null; }\r
+\r
+       //\r
+       // class interface\r
+       //\r
+\r
+       /**\r
+        * Temporary tables can be declared with ON COMMIT DELETE ROWS. But if the table has a held curosr open at\r
+        * commit time, data should not be deleted from the table. This method, (gets called at commit time) checks if this\r
+        * activation held cursor and if so, does that cursor reference the passed temp table name.\r
+        *\r
+        * @return      true if this activation has held cursor and if it references the passed temp table name\r
+        */\r
+       public boolean checkIfThisActivationHasHoldCursor(String tableName)\r
+       {\r
+               if (!inUse)\r
+                       return false;\r
+\r
+               if (resultSetHoldability == false) //if this activation is not held over commit, do not need to worry about it\r
+                       return false;\r
+\r
+               if (indexOfSessionTableNamesInSavedObjects == -1) //if this activation does not refer to session schema tables, do not need to worry about it\r
+                       return false;\r
+\r
+               /* is there an open result set? */\r
+               if ((resultSet != null) && !resultSet.isClosed() && resultSet.returnsRows())\r
+               {\r
+                       //If we came here, it means this activation is held over commit and it reference session table names\r
+                       //Now let's check if it referneces the passed temporary table name which has ON COMMIT DELETE ROWS defined on it.\r
+                       return ((ArrayList)getPreparedStatement().getSavedObject(indexOfSessionTableNamesInSavedObjects)).contains(tableName);\r
+               }\r
+\r
+               return false;\r
+       }\r
+\r
+       /**\r
+          remember the cursor name\r
+        */\r
+\r
+       public void     setCursorName(String cursorName)\r
+       {\r
+               if (isCursorActivation())\r
+                       this.cursorName = cursorName;\r
+       }\r
+\r
+\r
+       /**\r
+         get the cursor name.  For something that isn't\r
+         a cursor, this is used as a string name of the\r
+         result set for messages from things like the\r
+         dependency manager.\r
+         <p>\r
+         Activations that do support cursors will override\r
+         this. \r
+       */\r
+       public String getCursorName() {\r
+\r
+               return isCursorActivation() ? cursorName : null;\r
+       }\r
+\r
+       public void setResultSetHoldability(boolean resultSetHoldability)\r
+       {\r
+               this.resultSetHoldability = resultSetHoldability;\r
+       }\r
+\r
+       public boolean getResultSetHoldability()\r
+       {\r
+               return resultSetHoldability;\r
+       }\r
+\r
+       /** @see Activation#setAutoGeneratedKeysResultsetInfo */\r
+       public void setAutoGeneratedKeysResultsetInfo(int[] columnIndexes, String[] columnNames)\r
+       {\r
+               autoGeneratedKeysResultSetMode = true;\r
+               autoGeneratedKeysColumnIndexes = columnIndexes;\r
+               autoGeneratedKeysColumnNames = columnNames;\r
+       }\r
+\r
+       /** @see Activation#getAutoGeneratedKeysResultsetMode */\r
+       public boolean getAutoGeneratedKeysResultsetMode()\r
+       {\r
+               return autoGeneratedKeysResultSetMode;\r
+       }\r
+\r
+       /** @see Activation#getAutoGeneratedKeysColumnIndexes */\r
+       public int[] getAutoGeneratedKeysColumnIndexes()\r
+       {\r
+               return autoGeneratedKeysColumnIndexes;\r
+       }\r
+\r
+       /** @see Activation#getAutoGeneratedKeysColumnNames */\r
+       public String[] getAutoGeneratedKeysColumnNames()\r
+       {\r
+               return autoGeneratedKeysColumnNames;\r
+       }\r
+\r
+       //\r
+       // class implementation\r
+       //\r
+\r
+\r
+       /**\r
+               Used in the execute method of activations for\r
+               generating the result sets that they concatenate together.\r
+        */\r
+       public final ResultSetFactory getResultSetFactory() {\r
+               return getExecutionFactory().getResultSetFactory();\r
+       }\r
+\r
+       /**\r
+               Used in activations for generating rows.\r
+        */\r
+       public final ExecutionFactory getExecutionFactory() {\r
+               return getLanguageConnectionContext().\r
+            getLanguageConnectionFactory().getExecutionFactory();\r
+       }\r
+\r
+\r
+       /**\r
+               Used in CurrentOfResultSet to get to the target result set\r
+               for a cursor. Overridden by activations generated for\r
+               updatable cursors.  Those activations capture the target\r
+               result set in a field in their execute() method, and then\r
+               return the value of that field in their version of this method.\r
+\r
+               @return null.\r
+        */\r
+       public CursorResultSet getTargetResultSet() {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.THROWASSERT("Must be overridden to be used.");\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * Called by generated code to compute the next autoincrement value.\r
+        * \r
+        * @return The next autoincrement value which should be inserted.\r
+        * returns the correct number datatype.\r
+        */\r
+       protected DataValueDescriptor \r
+               getSetAutoincrementValue(int columnPosition, long increment)\r
+              throws StandardException\r
+       {\r
+               DataValueDescriptor l =\r
+                       ((InsertResultSet)resultSet).getSetAutoincrementValue(columnPosition, increment);\r
+               return l;\r
+\r
+       }\r
+\r
+       /**\r
+               Used in CurrentOfResultSet to get to the cursor result set\r
+               for a cursor.  Overridden by activations generated for\r
+               updatable cursors.  Those activations capture the cursor\r
+               result set in a field in their execute() method, and then\r
+               return the value of that field in their version of this method.\r
+\r
+               @return null\r
+        */\r
+       public CursorResultSet getCursorResultSet() {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.THROWASSERT("Must be overridden to be used.");\r
+               return null;\r
+       }\r
+\r
+       /**\r
+               Various activation methods need to disallow their\r
+               invocation if the activation is closed. This lets them\r
+               check and throw without generating alot of code.\r
+               <p>\r
+               The code to write to generate the call to this is approximately:\r
+               <verbatim>\r
+                       // jf is a JavaFactory\r
+                       CallableExpression ce = jf.newMethodCall(\r
+                               jf.thisExpression(),\r
+                               BaseActivation.CLASS_NAME,\r
+                               "throwIfClosed",\r
+                               "void",\r
+                               acb.exprArray(jf.newStringLiteral(...some literal here...)));\r
+\r
+                       //mb is a MethodBuilder\r
+                       mb.addStatement(jf.newStatement(ce));\r
+               </verbatim>\r
+               The java code to write to call this is:\r
+               <verbatim>\r
+                       this.throwIfClosed(...some literal here...);\r
+               </verbatim>\r
+               In both cases, "...some literal here..." gets replaced with\r
+               an expression of type String that evaluates to the name\r
+               of the operation that is being checked, like "execute" or\r
+               "reset".\r
+\r
+               @exception StandardException thrown if closed\r
+        */\r
+       public void throwIfClosed(String op) throws StandardException {\r
+               if (closed)\r
+                       throw StandardException.newException(SQLState.LANG_ACTIVATION_CLOSED, op);\r
+       }\r
+\r
+       /**\r
+        * Set a column position in an array of column positions.\r
+        *\r
+        * @param columnPositions       The array of column positions\r
+        * @param positionToSet         The place to put the column position\r
+        * @param column                        The column position\r
+        */\r
+       public static void setColumnPosition(\r
+                                                       int[] columnPositions,\r
+                                                       int positionToSet,\r
+                                                       int column)\r
+       {\r
+               columnPositions[positionToSet] = column;\r
+       }\r
+\r
+       /**\r
+        * Allocate an array of qualifiers and initialize in Qualifier[][]\r
+        *\r
+        * @param qualifiers    The array of Qualifier arrays.\r
+        * @param position              The position in the array to set\r
+        * @param length                The array length of the qualifier array to allocate.\r
+        */\r
+       public static void allocateQualArray(\r
+    Qualifier[][]   qualifiers,\r
+    int             position,\r
+    int             length)\r
+       {\r
+        qualifiers[position] = new Qualifier[length];\r
+       }\r
+\r
+\r
+       /**\r
+        * Set a Qualifier in a 2 dimensional array of Qualifiers.\r
+     *\r
+     * Set a single Qualifier into one slot of a 2 dimensional array of \r
+     * Qualifiers.  @see Qualifier for detailed description of layout of\r
+     * the 2-d array.\r
+        *\r
+        * @param qualifiers    The array of Qualifiers\r
+        * @param qualifier             The Qualifier\r
+        * @param position_1    The Nth array index into qualifiers[N][M]\r
+        * @param position_2    The Nth array index into qualifiers[N][M]\r
+        */\r
+       public static void setQualifier(\r
+    Qualifier[][]   qualifiers,\r
+    Qualifier      qualifier,\r
+    int                            position_1,\r
+    int             position_2)\r
+       {\r
+               qualifiers[position_1][position_2] = qualifier;\r
+       }\r
+\r
+       /**\r
+        * Reinitialize all Qualifiers in an array of Qualifiers.\r
+        *\r
+        * @param qualifiers    The array of Qualifiers\r
+        */\r
+       public static void reinitializeQualifiers(Qualifier[][] qualifiers)\r
+       {\r
+               if (qualifiers != null)\r
+               {\r
+            for (int term = 0; term < qualifiers.length; term++)\r
+            {\r
+                for (int i = 0; i < qualifiers[term].length; i++)\r
+                {\r
+                    qualifiers[term][i].reinitialize();\r
+                }\r
+            }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Mark the activation as unused.  \r
+        */\r
+       public final void markUnused()\r
+       {\r
+               if(isInUse()) {\r
+                       inUse = false;\r
+                       lcc.notifyUnusedActivation();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Is the activation in use?\r
+        *\r
+        * @return true/false\r
+        */\r
+       public final boolean isInUse()\r
+       {\r
+               return inUse;\r
+       }\r
+\r
+       /**\r
+         @see org.apache.derby.iapi.sql.Activation#addWarning\r
+         */\r
+       public void addWarning(SQLWarning w)\r
+       {\r
+               if (warnings == null)\r
+                       warnings = w;\r
+               else\r
+                       warnings.setNextWarning(w);\r
+       }\r
+\r
+       /**\r
+         @see org.apache.derby.iapi.sql.Activation#getWarnings\r
+         */\r
+       public SQLWarning getWarnings()\r
+       {\r
+               return warnings;\r
+       }\r
+\r
+       /**\r
+         @see org.apache.derby.iapi.sql.Activation#clearWarnings\r
+         */\r
+       public void clearWarnings()\r
+       {\r
+               warnings = null;\r
+       }\r
+\r
+       /**\r
+        * @exception StandardException on error\r
+        */\r
+       protected static void nullToPrimitiveTest(DataValueDescriptor dvd, String primitiveType)\r
+               throws StandardException\r
+       {\r
+               if (dvd.isNull())\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_NULL_TO_PRIMITIVE_PARAMETER, primitiveType);\r
+               }\r
+       }\r
+\r
+       /**\r
+               @see Activation#informOfRowCount\r
+               @exception StandardException    Thrown on error\r
+        */\r
+       public void informOfRowCount(NoPutResultSet resultSet, long currentRowCount)\r
+                                       throws StandardException\r
+       {\r
+\r
+               /* Do we want to check the row counts during this execution? */\r
+               if (checkRowCounts)\r
+               {\r
+                       boolean significantChange = false;\r
+\r
+                       int resultSetNumber = resultSet.resultSetNumber();\r
+                       Integer rsn = ReuseFactory.getInteger(resultSetNumber);\r
+\r
+                       /* Check each result set only once per execution */\r
+                       if (rowCountsCheckedThisExecution.add(rsn))\r
+                       {\r
+                               synchronized (getPreparedStatement())\r
+                               {\r
+                                       Vector rowCountCheckVector = getRowCountCheckVector();\r
+\r
+                                       if (rowCountCheckVector == null) {\r
+                                               rowCountCheckVector = new Vector();\r
+                                               setRowCountCheckVector(rowCountCheckVector);\r
+                                       }\r
+\r
+                                       Long firstRowCount = null;\r
+\r
+                                       /*\r
+                                       ** Check whether this resultSet has been seen yet.\r
+                                       */\r
+                                       if (resultSetNumber < rowCountCheckVector.size())\r
+                                       {\r
+                                               firstRowCount =\r
+                                                       (Long) rowCountCheckVector.elementAt(resultSetNumber);\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               rowCountCheckVector.setSize(resultSetNumber + 1);\r
+                                       }\r
+\r
+                                       if (firstRowCount != null)\r
+                                       {\r
+                                               /*\r
+                                               ** This ResultSet has been seen - has the row count\r
+                                               ** changed significantly?\r
+                                               */\r
+                                               long n1 = firstRowCount.longValue();\r
+\r
+                                               if (currentRowCount != n1)\r
+                                               {\r
+                                                       if (n1 >= TEN_PERCENT_THRESHOLD)\r
+                                                       {\r
+                                                               /*\r
+                                                               ** For tables with more than\r
+                                                               ** TEN_PERCENT_THRESHOLD rows, the\r
+                                                               ** threshold is 10% of the size of the table.\r
+                                                               */\r
+                                                               long changeFactor = n1 / (currentRowCount - n1);\r
+                                                               if (Math.abs(changeFactor) <= 10)\r
+                                                                       significantChange = true;\r
+                                                       }\r
+                                                       else\r
+                                                       {\r
+                                                               /*\r
+                                                               ** For tables with less than\r
+                                                               ** TEN_PERCENT_THRESHOLD rows, the threshold\r
+                                                               ** is non-linear.  This is because we want\r
+                                                               ** recompilation to happen sooner for small\r
+                                                               ** tables that change size.  This formula\r
+                                                               ** is for a second-order equation (a parabola).\r
+                                                               ** The derivation is:\r
+                                                               **\r
+                                                               **   c * n1 = (difference in row counts) ** 2\r
+                                                               **                              - or - \r
+                                                               **   c * n1 = (currentRowCount - n1) ** 2\r
+                                                               **\r
+                                                               ** Solving this for currentRowCount, we get:\r
+                                                               **\r
+                                                               **   currentRowCount = n1 + sqrt(c * n1)\r
+                                                               **\r
+                                                               **                              - or -\r
+                                                               **\r
+                                                               **   difference in row counts = sqrt(c * n1)\r
+                                                               **\r
+                                                               **                              - or -\r
+                                                               **\r
+                                                               **   (difference in row counts) ** 2 =\r
+                                                               **                                      c * n1\r
+                                                               **\r
+                                                               ** Which means that we should recompile when\r
+                                                               ** the current row count exceeds n1 (the first\r
+                                                               ** row count) by sqrt(c * n1), or when the\r
+                                                               ** square of the difference exceeds c * n1.\r
+                                                               ** A good value for c seems to be 4.\r
+                                                               **\r
+                                                               ** We don't use this formula when c is greater\r
+                                                               ** than TEN_PERCENT_THRESHOLD because we never\r
+                                                               ** want to recompile unless the number of rows\r
+                                                               ** changes by more than 10%, and this formula\r
+                                                               ** is more sensitive than that for values of\r
+                                                               ** n1 greater than TEN_PERCENT_THRESHOLD.\r
+                                                               */\r
+                                                               long changediff = currentRowCount - n1;\r
+\r
+                                                               /*\r
+                                                               ** Square changediff rather than take the square\r
+                                                               ** root of (4 * n1), because multiplying is\r
+                                                               ** faster than taking a square root.  Also,\r
+                                                               ** check to be sure that squaring changediff\r
+                                                               ** will not cause an overflow by comparing it\r
+                                                               ** with the square root of the maximum value\r
+                                                               ** for a long (this square root is taken only\r
+                                                               ** once, when the class is loaded, or during\r
+                                                               ** compilation if the compiler is smart enough).\r
+                                                               */\r
+                                                               if (Math.abs(changediff) <= MAX_SQRT)\r
+                                                               {\r
+                                                                       if ((changediff * changediff) >\r
+                                                                                                                       Math.abs(4 * n1))\r
+                                                                       {\r
+                                                                               significantChange = true;\r
+                                                                       }\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               firstRowCount = new Long(currentRowCount);\r
+                                               rowCountCheckVector.setElementAt(\r
+                                                                                                               firstRowCount,\r
+                                                                                                               resultSetNumber\r
+                                                                                                               );\r
+\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       /* Invalidate outside of the critical section */\r
+                       if (significantChange)\r
+                       {\r
+                               preStmt.makeInvalid(DependencyManager.INTERNAL_RECOMPILE_REQUEST, lcc);\r
+                       }\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * The subclass calls this method when it begins an execution.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void startExecution() throws StandardException\r
+       {\r
+               // determine if we should check row counts during this execution\r
+               shouldWeCheckRowCounts();\r
+\r
+               // If we are to check row counts, clear the hash table of row counts\r
+               // we have checked.\r
+               if (checkRowCounts)\r
+                       rowCountsCheckedThisExecution.clear();\r
+       }\r
+\r
+       /**\r
+        * @see Activation#getHeapConglomerateController\r
+        */\r
+       public ConglomerateController getHeapConglomerateController()\r
+       {\r
+               return updateHeapCC;\r
+       }\r
+\r
+\r
+       /**\r
+        * @see Activation#setHeapConglomerateController\r
+        */\r
+       public void setHeapConglomerateController(ConglomerateController updateHeapCC)\r
+       {\r
+               this.updateHeapCC = updateHeapCC;\r
+       }\r
+\r
+       /**\r
+        * @see Activation#clearHeapConglomerateController\r
+        */\r
+       public void clearHeapConglomerateController()\r
+       {\r
+               updateHeapCC = null;\r
+       }\r
+\r
+       /**\r
+        * @see Activation#getIndexScanController\r
+        */\r
+       public ScanController getIndexScanController()\r
+       {\r
+               return indexSC;\r
+       }\r
+\r
+       /**\r
+        * @see Activation#setIndexScanController\r
+        */\r
+       public void setIndexScanController(ScanController indexSC)\r
+       {\r
+               this.indexSC = indexSC;\r
+       }\r
+\r
+       /**\r
+        * @see Activation#getIndexConglomerateNumber\r
+        */\r
+       public long getIndexConglomerateNumber()\r
+       {\r
+               return indexConglomerateNumber;\r
+       }\r
+\r
+       /**\r
+        * @see Activation#setIndexConglomerateNumber\r
+        */\r
+       public void setIndexConglomerateNumber(long indexConglomerateNumber)\r
+       {\r
+               this.indexConglomerateNumber = indexConglomerateNumber;\r
+       }\r
+\r
+       /**\r
+        * @see Activation#clearIndexScanInfo\r
+        */\r
+       public void clearIndexScanInfo()\r
+       {\r
+               indexSC = null;\r
+               indexConglomerateNumber = -1;\r
+       }\r
+\r
+       /**\r
+        * @see Activation#setForCreateTable()\r
+        */\r
+       public void setForCreateTable()\r
+       {\r
+               forCreateTable = true;\r
+       }\r
+\r
+       /**\r
+        * @see Activation#getForCreateTable()\r
+        */\r
+       public boolean getForCreateTable()\r
+       {\r
+               return forCreateTable;\r
+       }\r
+\r
+       /**\r
+        * @see Activation#setDDLTableDescriptor\r
+        */\r
+       public void setDDLTableDescriptor(TableDescriptor td)\r
+       {\r
+               ddlTableDescriptor = td;\r
+       }\r
+\r
+       /**\r
+        * @see Activation#getDDLTableDescriptor\r
+        */\r
+       public TableDescriptor getDDLTableDescriptor()\r
+       {\r
+               return ddlTableDescriptor;\r
+       }\r
+\r
+       /**\r
+        * @see Activation#setMaxRows\r
+        */\r
+       public void setMaxRows(int maxRows)\r
+       {\r
+               this.maxRows = maxRows;\r
+       }\r
+\r
+       /**\r
+        * @see Activation#getMaxRows\r
+        */\r
+       public int getMaxRows()\r
+       {\r
+               return maxRows;\r
+       }\r
+\r
+       public void setTargetVTI(java.sql.ResultSet targetVTI)\r
+       {\r
+               this.targetVTI = targetVTI;\r
+       }\r
+\r
+       public java.sql.ResultSet getTargetVTI()\r
+       {\r
+               return targetVTI;\r
+       }\r
+\r
+       private void shouldWeCheckRowCounts() throws StandardException\r
+       {\r
+               /*\r
+               ** Check the row count only every N executions.  OK to check this\r
+               ** without synchronization, since the value of this number is not\r
+               ** critical.  The value of N is determined by the property\r
+               ** derby.language.stalePlanCheckInterval.\r
+               */\r
+               int executionCount = getExecutionCount() + 1;\r
+\r
+               /*\r
+               ** Always check row counts the first time, to establish the\r
+               ** row counts for each result set.  After that, don't check\r
+               ** if the execution count is below the minimum row count check\r
+               ** interval.  This saves us from checking a database property\r
+               ** when we don't have to (checking involves querying the store,\r
+               ** which can be expensive).\r
+               */\r
+\r
+               if (executionCount == 1)\r
+               {\r
+                       checkRowCounts = true;\r
+               }\r
+               else if (executionCount <\r
+                                                               Property.MIN_LANGUAGE_STALE_PLAN_CHECK_INTERVAL)\r
+               {\r
+                       checkRowCounts = false;\r
+               }\r
+               else\r
+               {\r
+                       int stalePlanCheckInterval = getStalePlanCheckInterval();\r
+\r
+                       /*\r
+                       ** Only query the database property once.  We can tell because\r
+                       ** the minimum value of the property is greater than zero.\r
+                       */\r
+                       if (stalePlanCheckInterval == 0)\r
+                       {\r
+                               TransactionController tc = getTransactionController();\r
+\r
+                               stalePlanCheckInterval =\r
+                                               PropertyUtil.getServiceInt(\r
+                                                       tc,\r
+                                                       Property.LANGUAGE_STALE_PLAN_CHECK_INTERVAL,\r
+                                                       Property.MIN_LANGUAGE_STALE_PLAN_CHECK_INTERVAL,\r
+                                                       Integer.MAX_VALUE,\r
+                                                       Property.DEFAULT_LANGUAGE_STALE_PLAN_CHECK_INTERVAL\r
+                                                       );\r
+                               setStalePlanCheckInterval(stalePlanCheckInterval);\r
+                       }\r
+\r
+                       checkRowCounts = (executionCount % stalePlanCheckInterval) == 1;\r
+\r
+\r
+               }\r
+\r
+               setExecutionCount(executionCount);\r
+       }\r
+\r
+       /*\r
+       ** These accessor methods are provided by the sub-class to help figure\r
+       ** out whether to check row counts during this execution.\r
+       */\r
+       abstract protected int getExecutionCount();\r
+\r
+       abstract protected void setExecutionCount(int newValue); \r
+\r
+       /*\r
+       ** These accessor methods are provided by the sub-class to help figure\r
+       ** out whether the row count for a particular result set has changed\r
+       ** enough to force recompilation.\r
+       */\r
+       abstract protected Vector getRowCountCheckVector();\r
+\r
+       abstract protected void setRowCountCheckVector(Vector newValue);\r
+\r
+       /*\r
+       ** These accessor methods are provided by the sub-class to remember the\r
+       ** value of the stale plan check interval property, so that we only\r
+       ** have to query the database properties once (there is heavyweight\r
+       ** synchronization around the database properties).\r
+       */\r
+       abstract protected int getStalePlanCheckInterval();\r
+\r
+       abstract protected void setStalePlanCheckInterval(int newValue);\r
+\r
+       public final boolean getScrollable() {\r
+               return scrollable;\r
+       }\r
+\r
+       protected final void setParameterValueSet(int paramCount, boolean hasReturnParam) {\r
+\r
+               pvs = lcc.getLanguageFactory().newParameterValueSet(\r
+                       lcc.getLanguageConnectionFactory().getClassFactory().getClassInspector(),\r
+                       paramCount, hasReturnParam);\r
+               }\r
+       \r
+       /**\r
+        * This method can help reduce the amount of generated code by changing\r
+        * instances of this.pvs.getParameter(position) to this.getParameter(position) \r
+        * @param position\r
+        * @throws StandardException\r
+        */\r
+       protected final DataValueDescriptor getParameter(int position) throws StandardException { \r
+               return pvs.getParameter(position); \r
+               } \r
+       \r
+       /**\r
+        return the parameters.\r
+        */\r
+       public ParameterValueSet        getParameterValueSet() \r
+       { \r
+               if (pvs == null)\r
+                       setParameterValueSet(0, false); \r
+               return pvs; \r
+       }\r
+\r
+       // how do we do/do we want any sanity checking for\r
+       // the number of parameters expected?\r
+       public void     setParameters(ParameterValueSet parameterValues, DataTypeDescriptor[] parameterTypes) throws StandardException\r
+       {\r
+               if (!isClosed())\r
+               {\r
+\r
+                       if (this.pvs == null || parameterTypes == null) {\r
+                               pvs = parameterValues;\r
+                               return;\r
+\r
+                       }\r
+\r
+                       DataTypeDescriptor[]    newParamTypes = preStmt.getParameterTypes();\r
+\r
+                       /*\r
+                       ** If there are old parameters but not new ones,\r
+                       ** they aren't compatible.\r
+                       */\r
+                       boolean match = false;\r
+                       if (newParamTypes != null) {\r
+\r
+                               if (newParamTypes.length == parameterTypes.length) {\r
+\r
+                                       /* Check each parameter */\r
+                                       match = true;\r
+                                       for (int i = 0; i < parameterTypes.length; i++)\r
+                                       {\r
+                                               DataTypeDescriptor      oldType = parameterTypes[i];\r
+                                               DataTypeDescriptor      newType = newParamTypes[i];\r
+\r
+                                               if (!oldType.isExactTypeAndLengthMatch(newType)) {\r
+                                                       match = false;\r
+                                                       break;\r
+                                               }\r
+                                               /*\r
+                                               ** We could probably get away without checking nullability,\r
+                                               ** since parameters are always nullable.\r
+                                               */\r
+                                               if (oldType.isNullable() != newType.isNullable()) {\r
+                                                       match = false;\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                               }\r
+\r
+                       }\r
+\r
+                       if (!match)\r
+                               throw StandardException.newException(SQLState.LANG_OBSOLETE_PARAMETERS);\r
+\r
+\r
+                       parameterValues.transferDataValues(pvs);\r
+\r
+               }\r
+               else if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.THROWASSERT("isClosed() is expected to return false");\r
+               }\r
+       }\r
+\r
+       /**\r
+               Throw an exception if any parameters are uninitialized.\r
+\r
+               @exception StandardException    Thrown if any parameters\r
+                                                                                               are unitialized\r
+        */\r
+\r
+       public void throwIfMissingParms() throws StandardException\r
+       {\r
+               if (pvs != null && !pvs.allAreSet())\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_MISSING_PARMS);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Remember the row for the specified ResultSet.\r
+        */\r
+       public void setCurrentRow(ExecRow currentRow, int resultSetNumber)\r
+       { \r
+               if (SanityManager.DEBUG) \r
+               {\r
+                       SanityManager.ASSERT(!isClosed(), "closed");\r
+                       if (row != null)\r
+                       {\r
+                               if (!(resultSetNumber >=0 && resultSetNumber < row.length))\r
+                               {\r
+                                       SanityManager.THROWASSERT("resultSetNumber = " + resultSetNumber +\r
+                                                                ", expected to be between 0 and " + row.length);\r
+                               }\r
+                       }\r
+               }\r
+               if (row != null)\r
+               {\r
+                       row[resultSetNumber] = currentRow;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Clear the current row for the specified ResultSet.\r
+        */\r
+       public void clearCurrentRow(int resultSetNumber)\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (row != null)\r
+                       {\r
+                               if (!(resultSetNumber >=0 && resultSetNumber < row.length))\r
+                               {\r
+                                       SanityManager.THROWASSERT("resultSetNumber = " + resultSetNumber +\r
+                                                                ", expected to be between 0 and " + row.length);\r
+                               }\r
+                       }\r
+               }\r
+               if (row != null)\r
+               {\r
+                       row[resultSetNumber] = null;\r
+               }\r
+       }\r
+\r
+       protected final DataValueDescriptor getColumnFromRow(int rsNumber, int colId)\r
+               throws StandardException {\r
+\r
+        if( row[rsNumber] == null)\r
+        {\r
+            /* This actually happens. NoPutResultSetImpl.clearOrderableCache attempts to prefetch invariant values\r
+             * into a cache. This fails in some deeply nested joins. See Beetle 4736 and 4880.\r
+             */\r
+            return null;\r
+        }\r
+               return row[rsNumber].getColumn(colId);\r
+       }\r
+\r
+    /**\r
+     * Check that a positioned statement is executing against a cursor\r
+     * from the same PreparedStatement (plan) that the positioned\r
+     * statement was original compiled against.\r
+     * \r
+     * Only called from generated code for positioned UPDATE and DELETE\r
+     * statements. See CurrentOfNode.\r
+     * \r
+     * @param cursorName Name of the cursor\r
+     * @param psName Object name of the PreparedStatement.\r
+     * @throws StandardException\r
+     */\r
+       protected void checkPositionedStatement(String cursorName, String psName)\r
+               throws StandardException {\r
+\r
+               ExecPreparedStatement ps = getPreparedStatement();\r
+               if (ps == null)\r
+                       return;\r
+                       \r
+               LanguageConnectionContext lcc = getLanguageConnectionContext();\r
+\r
+               CursorActivation cursorActivation = lcc.lookupCursorActivation(cursorName);\r
+\r
+               if (cursorActivation != null)\r
+               {\r
+                       // check we are compiled against the correct cursor\r
+                       if (!psName.equals(cursorActivation.getPreparedStatement().getObjectName())) {\r
+\r
+                               // our prepared statement is now invalid since there\r
+                               // exists another cursor with the same name but a different\r
+                               // statement.\r
+                               ps.makeInvalid(DependencyManager.CHANGED_CURSOR, lcc);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /* This method is used to materialize a resultset if can actually fit in the memory\r
+        * specified by "maxMemoryPerTable" system property.  It converts the result set into\r
+        * union(union(union...(union(row, row), row), ...row), row).  It returns this\r
+        * in-memory converted resultset, or the original result set if not converted.\r
+        * See beetle 4373 for details.\r
+        *\r
+        * Optimization implemented as part of Beetle: 4373 can cause severe stack overflow\r
+        * problems. See JIRA entry DERBY-634. With default MAX_MEMORY_PER_TABLE of 1MG, it is\r
+        * possible that this optimization could attempt to cache upto 250K rows as nested\r
+        * union results. At runtime, this would cause stack overflow.\r
+        *\r
+        * As Jeff mentioned in DERBY-634, right way to optimize original problem would have been\r
+        * to address subquery materialization during optimization phase, through hash joins.\r
+        * Recent Army's optimizer work through DEBRY-781 and related work introduced a way to\r
+        * materialize subquery results correctly and needs to be extended to cover this case.\r
+        * While his optimization needs to be made more generic and stable, I propose to avoid\r
+        * this regression by limiting size of the materialized resultset created here to be\r
+        * less than MAX_MEMORY_PER_TABLE and MAX_DYNAMIC_MATERIALIZED_ROWS.\r
+        *\r
+        *      @param  rs      input result set\r
+        *      @return materialized resultset, or original rs if it can't be materialized\r
+        */\r
+       public NoPutResultSet materializeResultSetIfPossible(NoPutResultSet rs)\r
+               throws StandardException\r
+       {\r
+               rs.openCore();\r
+               Vector rowCache = new Vector();\r
+               ExecRow aRow;\r
+               int cacheSize = 0;\r
+               FormatableBitSet toClone = null;\r
+\r
+               int maxMemoryPerTable = getLanguageConnectionContext().getOptimizerFactory().getMaxMemoryPerTable();\r
+\r
+               aRow = rs.getNextRowCore();\r
+               if (aRow != null)\r
+               {\r
+                       toClone = new FormatableBitSet(aRow.nColumns() + 1);\r
+                       toClone.set(1);\r
+               }\r
+               while (aRow != null)\r
+               {\r
+                       cacheSize += aRow.getColumn(1).getLength();\r
+                       if (cacheSize > maxMemoryPerTable ||\r
+                                       rowCache.size() > Optimizer.MAX_DYNAMIC_MATERIALIZED_ROWS)\r
+                               break;\r
+                       rowCache.addElement(aRow.getClone(toClone));\r
+                       aRow = rs.getNextRowCore();\r
+               }\r
+               rs.close();\r
+\r
+               if (aRow == null)\r
+               {\r
+                       int rsNum = rs.resultSetNumber();\r
+\r
+                       int numRows = rowCache.size();\r
+                       if (numRows == 0)\r
+                       {\r
+                               return new RowResultSet(\r
+                                                                               this,\r
+                                                                               (ExecRow) null,\r
+                                                                               true,\r
+                                                                               rsNum,\r
+                                                                               0,\r
+                                                                               0);\r
+                       }\r
+                       RowResultSet[] rrs = new RowResultSet[numRows];\r
+                       UnionResultSet[] urs = new UnionResultSet[numRows - 1];\r
+\r
+                       for (int i = 0; i < numRows; i++)\r
+                       {\r
+                               rrs[i] = new RowResultSet(\r
+                                                                               this,\r
+                                                                               (ExecRow) rowCache.elementAt(i),\r
+                                                                               true,\r
+                                                                               rsNum,\r
+                                                                               1,\r
+                                                                               0);\r
+                               if (i > 0)\r
+                               {\r
+                                       urs[i - 1] = new UnionResultSet (\r
+                                                                               (i > 1) ? (NoPutResultSet)urs[i - 2] : (NoPutResultSet)rrs[0],\r
+                                                                               rrs[i],\r
+                                                                               this,\r
+                                                                               rsNum,\r
+                                                                               i + 1,\r
+                                                                               0);\r
+                               }\r
+                       }\r
+\r
+                       rs.finish();\r
+\r
+                       if (numRows == 1)\r
+                               return rrs[0];\r
+                       else\r
+                               return urs[urs.length - 1];\r
+               }\r
+               return rs;\r
+       }\r
+\r
+\r
+\r
+       //WARNING : this field name is referred in the DeleteNode generate routines.\r
+       protected CursorResultSet[] raParentResultSets;\r
+\r
+\r
+       // maintain hash table of parent result set vector\r
+       // a table can have more than one parent source.\r
+       protected Hashtable parentResultSets;\r
+       public void setParentResultSet(TemporaryRowHolder rs, String resultSetId)\r
+       {\r
+               Vector  rsVector;\r
+               if(parentResultSets == null)\r
+                       parentResultSets = new Hashtable();\r
+               rsVector = (Vector) parentResultSets.get(resultSetId);\r
+               if(rsVector == null)\r
+               {\r
+                       rsVector = new Vector();\r
+                       rsVector.addElement(rs);\r
+               }else\r
+               {\r
+                       rsVector.addElement(rs);\r
+               }\r
+               parentResultSets.put(resultSetId , rsVector);\r
+       }\r
+\r
+       /**\r
+        * get the reference to parent table ResultSets, that will be needed by the \r
+        * referential action dependent table scans.\r
+        */\r
+       public Vector getParentResultSet(String resultSetId)\r
+       {\r
+               return (Vector) parentResultSets.get(resultSetId);\r
+       }\r
+\r
+       public Hashtable getParentResultSets()\r
+       {\r
+               return parentResultSets;\r
+       }\r
+\r
+       /**\r
+        ** prepared statement use the same activation for\r
+        ** multiple execution. For each excution we create new\r
+        ** set of temporary resultsets, we should clear this hash table.\r
+        ** otherwise we will refer to the released resources.\r
+        */\r
+       public void clearParentResultSets()\r
+       {\r
+               if(parentResultSets != null)\r
+                       parentResultSets.clear();\r
+       }\r
+\r
+       /**\r
+        * beetle 3865: updateable cursor using index.  A way of communication\r
+        * between cursor activation and update activation.\r
+        */\r
+       public void setForUpdateIndexScan(CursorResultSet forUpdateIndexScan)\r
+       {\r
+               this.forUpdateIndexScan = forUpdateIndexScan;\r
+       }\r
+\r
+       public CursorResultSet getForUpdateIndexScan()\r
+       {\r
+               return forUpdateIndexScan;\r
+       }\r
+\r
+       private java.util.Calendar cal;\r
+       /**\r
+               Return a calendar for use by this activation.\r
+               Calendar objects are not thread safe, the one returned\r
+               is purely for use by this activation and it is assumed\r
+               that is it single threded through the single active\r
+               thread in a connection model.\r
+       */\r
+       protected java.util.Calendar getCalendar() {\r
+               if (cal == null)\r
+                       cal = new java.util.GregorianCalendar();\r
+               return cal;\r
+\r
+       }\r
+\r
+\r
+       /*\r
+       ** Code originally in the parent class BaseExpressionActivation\r
+       */\r
+       /**\r
+           Get the language connection factory associated with this connection\r
+         */\r
+       public final LanguageConnectionContext  getLanguageConnectionContext()\r
+       {\r
+               return  lcc;\r
+       }\r
+\r
+       public final TransactionController getTransactionController()\r
+       {\r
+               return lcc.getTransactionExecute();\r
+       }\r
+                       \r
+       /**\r
+        * Get the Current ContextManager.\r
+        *\r
+        * @return Current ContextManager\r
+        */\r
+       public ContextManager getContextManager()\r
+       {\r
+               return cm;\r
+       }\r
+\r
+       /**\r
+               Used by activations to generate data values.  Most DML statements\r
+               will use this method.  Possibly some DDL statements will, as well.\r
+        */\r
+       public DataValueFactory getDataValueFactory()\r
+       {\r
+               return getLanguageConnectionContext().getDataValueFactory();\r
+       }\r
+\r
+       /**\r
+        * Used to get a proxy for the current connection.\r
+        *\r
+        * @exception SQLException              Thrown on failure to get connection\r
+        */\r
+       public Connection getCurrentConnection() throws SQLException {\r
+\r
+               ConnectionContext cc = \r
+                       (ConnectionContext) getContextManager().getContext(ConnectionContext.CONTEXT_ID);\r
+\r
+               return cc.getNestedConnection(true);\r
+       }       \r
+\r
+       /**\r
+               Real implementations of this method are provided by a generated class.\r
+       */\r
+       public java.sql.ResultSet[][] getDynamicResults() {\r
+               return null;\r
+       }\r
+       /**\r
+               Real implementations of this method are provided by a generated class.\r
+       */\r
+       public int getMaxDynamicResults() {\r
+               return 0;\r
+       }\r
+\r
+    /**\r
+     * Compute the DB2 compatible length of a value.\r
+     *\r
+     * @param value\r
+     * @param constantLength The length, if it is a constant modulo null/not null. -1 if the length is not constant\r
+     * @param reUse If non-null then re-use this as a container for the length\r
+     *\r
+     * @return the DB2 compatible length, set to null if value is null.\r
+     */\r
+    public NumberDataValue getDB2Length( DataValueDescriptor value,\r
+                                         int constantLength,\r
+                                         NumberDataValue reUse)\r
+        throws StandardException\r
+    {\r
+        if( reUse == null)\r
+            reUse = getDataValueFactory().getNullInteger( null);\r
+        if( value.isNull())\r
+            reUse.setToNull();\r
+        else\r
+        {\r
+            if( constantLength >= 0)\r
+                reUse.setValue( constantLength);\r
+            else\r
+            {\r
+                reUse.setValue(value.getLength());\r
+            }\r
+        }\r
+        return reUse;\r
+    } // end of getDB2Length\r
+}\r