Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / impl / sql / conn / GenericLanguageConnectionContext.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
new file mode 100644 (file)
index 0000000..ed2441f
--- /dev/null
@@ -0,0 +1,3108 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext\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.conn;\r
+\r
+import org.apache.derby.iapi.services.context.ContextImpl;\r
+import org.apache.derby.iapi.services.cache.CacheManager;\r
+\r
+import org.apache.derby.impl.sql.compile.CompilerContextImpl;\r
+import org.apache.derby.impl.sql.execute.InternalTriggerExecutionContext;\r
+import org.apache.derby.impl.sql.execute.AutoincrementCounter;\r
+import org.apache.derby.impl.sql.GenericPreparedStatement;\r
+import org.apache.derby.impl.sql.GenericStatement;\r
+import org.apache.derby.iapi.sql.Statement;\r
+\r
+import org.apache.derby.iapi.services.property.PropertyUtil;\r
+import org.apache.derby.iapi.services.context.ContextManager;\r
+import org.apache.derby.iapi.services.monitor.Monitor;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+import org.apache.derby.iapi.services.stream.HeaderPrintWriter;\r
+import org.apache.derby.iapi.services.loader.GeneratedClass;\r
+import org.apache.derby.iapi.services.cache.Cacheable;\r
+import org.apache.derby.iapi.db.Database;\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.sql.compile.CompilerContext;\r
+import org.apache.derby.iapi.sql.compile.OptimizerFactory;\r
+import org.apache.derby.iapi.sql.conn.Authorizer;\r
+import org.apache.derby.iapi.error.ExceptionSeverity;\r
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;\r
+import org.apache.derby.iapi.sql.conn.LanguageConnectionFactory;\r
+import org.apache.derby.iapi.sql.conn.StatementContext;\r
+import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptorList;\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;\r
+import org.apache.derby.iapi.types.DataValueFactory;\r
+import org.apache.derby.iapi.sql.compile.TypeCompilerFactory;\r
+import org.apache.derby.iapi.sql.depend.DependencyManager;\r
+import org.apache.derby.iapi.sql.depend.Provider;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.reference.Limits;\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.ExecPreparedStatement;\r
+import org.apache.derby.iapi.sql.execute.ExecutionContext;\r
+import org.apache.derby.iapi.sql.execute.ExecutionStmtValidator;\r
+import org.apache.derby.iapi.sql.Activation;\r
+import org.apache.derby.iapi.sql.LanguageFactory;\r
+import org.apache.derby.iapi.sql.PreparedStatement;\r
+import org.apache.derby.iapi.sql.ResultSet;\r
+import org.apache.derby.iapi.sql.ParameterValueSet;\r
+\r
+import org.apache.derby.iapi.store.access.TransactionController;\r
+import org.apache.derby.iapi.store.access.XATransactionController;\r
+import org.apache.derby.iapi.util.IdUtil;\r
+import org.apache.derby.iapi.util.StringUtil;\r
+\r
+import org.apache.derby.catalog.UUID;\r
+import org.apache.derby.iapi.sql.execute.RunTimeStatistics;\r
+import org.apache.derby.iapi.db.TriggerExecutionContext;\r
+import org.apache.derby.iapi.reference.Property;\r
+\r
+import java.util.List;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import java.util.Map;\r
+\r
+/**\r
+ * LanguageConnectionContext keeps the pool of prepared statements,\r
+ * activations, and cursors in use by the current connection.\r
+ * <p>\r
+ * The generic impl does not provide statement caching.\r
+ *\r
+ *\r
+ */\r
+public class GenericLanguageConnectionContext\r
+       extends ContextImpl \r
+       implements LanguageConnectionContext\r
+{\r
+\r
+       // make sure these are not zeros\r
+       private final static int NON_XA = 0;\r
+       private final static int XA_ONE_PHASE = 1;\r
+       private final static int XA_TWO_PHASE = 2;\r
+\r
+       /*\r
+               fields\r
+        */\r
+\r
+       private final ArrayList acts;\r
+       private volatile boolean unusedActs=false;\r
+       /** The maximum size of acts since the last time it was trimmed. Used to\r
+        * determine whether acts should be trimmed to reclaim space. */\r
+       private int maxActsSize;\r
+       protected int bindCount;\r
+       private boolean ddWriteMode;\r
+       private boolean runTimeStatisticsSetting ;\r
+       private boolean statisticsTiming;\r
+\r
+       //all the temporary tables declared for this connection\r
+       private ArrayList allDeclaredGlobalTempTables;\r
+       //The currentSavepointLevel is used to provide the rollback behavior of temporary tables.\r
+       //At any point, this variable has the total number of savepoints defined for the transaction.\r
+       private int currentSavepointLevel = 0;\r
+\r
+       protected long  nextCursorId;\r
+\r
+       protected int   nextSavepointId;\r
+\r
+       private RunTimeStatistics runTimeStatisticsObject;\r
+       private StringBuffer sb;\r
+\r
+       private Database db;\r
+\r
+       private final int instanceNumber;\r
+       private String drdaID;\r
+       private String dbname;\r
+    \r
+       /**\r
+       The transaction to use within this language connection context.  It may\r
+       be more appropriate to have it in a separate context (LanguageTransactionContext?).\r
+       REVISIT (nat): I shoehorned the transaction context that\r
+       the language uses into this class.  The main purpose is so\r
+       that the various language code can find out what its\r
+       transaction is.\r
+       **/\r
+       private final TransactionController tran;\r
+\r
+       /**\r
+        * If non-null indicates that a read-only nested \r
+     * user transaction is in progress.\r
+        */\r
+       private TransactionController readOnlyNestedTransaction;\r
+       \r
+       /**\r
+        * queryNestingDepth is a counter used to keep track of how many calls \r
+        * have been made to begin read-only nested transactions. Only the first call \r
+        * actually starts a Nested User Transaction with the store. Subsequent\r
+        * calls simply increment this counter. commitNestedTransaction only\r
+        * decrements the counter and when it drops to 0 actually commits the \r
+        * nested user transaction.\r
+        */\r
+       private int queryNestingDepth;\r
+\r
+       protected DataValueFactory dataFactory;\r
+       protected LanguageFactory langFactory;\r
+       protected TypeCompilerFactory tcf;\r
+       protected OptimizerFactory of;\r
+       protected LanguageConnectionFactory connFactory;\r
+       \r
+       /* \r
+        * A statement context is "pushed" and "popped" at the beginning and\r
+     * end of every statement so that only that statement is cleaned up\r
+     * on a Statement Exception.  As a performance optimization, we only push\r
+     * the outermost statement context once, and never pop it.  Also, we\r
+        * save off a 2nd StatementContext for speeding server side method\r
+        * invocation, though we still push and pop it as needed.  All other\r
+     * statement contexts will allocated and pushed and popped on demand.\r
+     */\r
+       private final StatementContext[] statementContexts = new StatementContext[2];\r
+       private int     statementDepth;\r
+       protected int     outermostTrigger = -1;\r
+\r
+    protected Authorizer authorizer;\r
+       protected String userName = null; //The name the user connects with.\r
+                                         //May still be quoted.\r
+       \r
+       protected SchemaDescriptor      sd;\r
+\r
+       // RESOLVE - How do we want to set the default.\r
+    private int defaultIsolationLevel = ExecutionContext.READ_COMMITTED_ISOLATION_LEVEL;\r
+       protected int isolationLevel = defaultIsolationLevel;\r
+\r
+       private boolean isolationLevelExplicitlySet = false;\r
+       // Isolation level can be changed using JDBC api Connection.setTransactionIsolation\r
+       // or it can be changed using SQL "set current isolation = NEWLEVEL".\r
+       // \r
+       // In XA transactions, BrokeredConnection keeps isolation state information.\r
+       // When isolation is changed in XA transaction using JDBC, that state gets\r
+       // correctly set in BrokeredConnection.setTransactionIsolation method. But\r
+       // when SQL is used to set the isolation level, the code path is different\r
+       // and it does not go through BrokeredConnection's setTransactionIsolation\r
+       // method and hence the state is not maintained correctly when coming through\r
+       // SQL. To get around this, I am adding following flag which will get set\r
+       // everytime the isolation level is set using JDBC or SQL. This flag will be\r
+       // checked at global transaction start and end time. If the flag is set to true\r
+       // then BrokeredConnection's isolation level state will be brought upto date\r
+       // with Real Connection's isolation level and this flag will be set to false\r
+       // after that.\r
+       private boolean isolationLevelSetUsingSQLorJDBC = false;\r
+\r
+       // isolation level to when preparing statements.\r
+       // if unspecified, the statement won't be prepared with a specific \r
+       // scan isolationlevel\r
+       protected int prepareIsolationLevel = ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL;\r
+\r
+       // Whether or not to write executing statement info to db2j.log\r
+       private boolean logStatementText;\r
+       private boolean logQueryPlan;\r
+       private HeaderPrintWriter istream;\r
+\r
+       // this used to be computed in OptimizerFactoryContextImpl; i.e everytime a\r
+       // connection was made. To keep the semantics same I'm putting it out here\r
+       // instead of in the OptimizerFactory which is only initialized when the\r
+       // database is booted.\r
+       private int lockEscalationThreshold; \r
+\r
+       private ArrayList stmtValidators;\r
+       private ArrayList triggerExecutionContexts;\r
+       private ArrayList triggerTables;\r
+\r
+       // OptimizerTrace\r
+       private boolean optimizerTrace;\r
+       private boolean optimizerTraceHtml;\r
+       private String lastOptimizerTraceOutput;\r
+       private String optimizerTraceOutput;\r
+\r
+       //// Support for AUTOINCREMENT\r
+\r
+       /**\r
+        * To support lastAutoincrementValue: This is a hashtable which maps\r
+        * schemaName,tableName,columnName to a Long value.\r
+        */\r
+       private HashMap autoincrementHT;\r
+       /**\r
+        * whether to allow updates or not. \r
+        */\r
+       private boolean autoincrementUpdate;\r
+       private long identityVal;       //support IDENTITY_VAL_LOCAL function\r
+       private boolean identityNotNull;        //frugal programmer\r
+\r
+       // cache of ai being handled in memory (bulk insert + alter table).\r
+       private HashMap autoincrementCacheHashtable;\r
+\r
+       /*\r
+          constructor\r
+       */\r
+       public GenericLanguageConnectionContext\r
+       (\r
+        ContextManager cm,\r
+        TransactionController tranCtrl,\r
+\r
+        LanguageFactory lf,\r
+        LanguageConnectionFactory lcf,\r
+        Database db,\r
+        String userName,\r
+        int instanceNumber,\r
+        String drdaID,\r
+        String dbname)\r
+                throws StandardException\r
+       {\r
+               super(cm, org.apache.derby.iapi.reference.ContextId.LANG_CONNECTION);\r
+               acts = new ArrayList();\r
+               tran = tranCtrl;\r
+\r
+               dataFactory = lcf.getDataValueFactory();\r
+               tcf = lcf.getTypeCompilerFactory();\r
+               of = lcf.getOptimizerFactory();\r
+               langFactory =  lf;\r
+               connFactory =  lcf;\r
+        this.db = db;\r
+               this.userName = userName;\r
+               this.instanceNumber = instanceNumber;\r
+               this.drdaID = drdaID;\r
+               this.dbname = dbname;\r
+\r
+               /* Find out whether or not to log info on executing statements to error log\r
+                */\r
+               String logStatementProperty = PropertyUtil.getServiceProperty(getTransactionCompile(),\r
+                                       "derby.language.logStatementText");\r
+               logStatementText = Boolean.valueOf(logStatementProperty).booleanValue();\r
+\r
+               String logQueryPlanProperty = PropertyUtil.getServiceProperty(getTransactionCompile(),\r
+                                       "derby.language.logQueryPlan");\r
+               logQueryPlan = Boolean.valueOf(logQueryPlanProperty).booleanValue();\r
+\r
+               setRunTimeStatisticsMode(logQueryPlan);\r
+\r
+               lockEscalationThreshold = \r
+                       PropertyUtil.getServiceInt(tranCtrl,\r
+                                                                          Property.LOCKS_ESCALATION_THRESHOLD,\r
+                                                                          Property.MIN_LOCKS_ESCALATION_THRESHOLD,\r
+                                                                          Integer.MAX_VALUE,\r
+                                                                          Property.DEFAULT_LOCKS_ESCALATION_THRESHOLD);                                                                                                                         \r
+               stmtValidators = new ArrayList();\r
+               triggerExecutionContexts = new ArrayList();\r
+               triggerTables = new ArrayList();\r
+       }\r
+\r
+       public void initialize() throws StandardException\r
+       {\r
+               //\r
+               //Creating the authorizer authorizes the connection.\r
+               authorizer = new GenericAuthorizer(IdUtil.getUserAuthorizationId(userName),this);\r
+\r
+               /*\r
+               ** Set the authorization id.  User shouldn't\r
+               ** be null or else we are going to blow up trying\r
+               ** to create a schema for this user.\r
+               */\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (getAuthorizationId() == null)\r
+                       {\r
+                               SanityManager.THROWASSERT("User name is null," +\r
+                                       " check the connection manager to make sure it is set" +\r
+                                       " reasonably");\r
+                       }\r
+               }\r
+\r
+\r
+               setDefaultSchema(initDefaultSchemaDescriptor());\r
+       }\r
+\r
+       protected SchemaDescriptor initDefaultSchemaDescriptor()\r
+               throws StandardException {\r
+               /*\r
+               ** - If the database supports schemas and a schema with the\r
+               ** same name as the user's name exists (has been created using\r
+               ** create schema already) the database will set the users\r
+               ** default schema to the the schema with the same name as the\r
+               ** user.\r
+        ** - Else Set the default schema to APP.\r
+        */\r
+               // SchemaDescriptor sd;\r
+\r
+               DataDictionary dd = getDataDictionary();\r
+        String authorizationId = getAuthorizationId();\r
+       \r
+               if ( (sd = dd.getSchemaDescriptor(authorizationId, getTransactionCompile(), false)) == null )\r
+               {\r
+                       sd = new SchemaDescriptor(dd, authorizationId, authorizationId, (UUID) null, false);\r
+               }\r
+               return sd;\r
+       }\r
+\r
+       //\r
+       // LanguageConnectionContext interface\r
+       //\r
+       /**\r
+        * @see LanguageConnectionContext#getLogStatementText\r
+        */\r
+       public boolean getLogStatementText()\r
+       {\r
+               return logStatementText;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#setLogStatementText\r
+        */\r
+       public void setLogStatementText(boolean logStatementText)\r
+       {\r
+               this.logStatementText = logStatementText;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#getLogQueryPlan\r
+        */\r
+       public boolean getLogQueryPlan()\r
+       {\r
+               return logQueryPlan;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#usesSqlAuthorization\r
+        */\r
+       public boolean usesSqlAuthorization()\r
+       {\r
+               return getDataDictionary().usesSqlAuthorization();\r
+       }\r
+\r
+       /**\r
+        * get the lock escalation threshold.\r
+        */\r
+       public int getLockEscalationThreshold()\r
+       {\r
+               return lockEscalationThreshold;\r
+       }\r
+\r
+       /**\r
+        * Add the activation to those known about by this connection.\r
+        */\r
+       public void addActivation(Activation a) \r
+               throws StandardException {\r
+               acts.add(a);\r
+\r
+               if (acts.size() > maxActsSize) {\r
+                       maxActsSize = acts.size();\r
+               }\r
+       }\r
+\r
+       public void closeUnusedActivations()\r
+                       throws StandardException\r
+       {\r
+               // DERBY-418. Activations which are marked unused,\r
+               // are closed here. Activations Vector is iterated \r
+               // to identify and close unused activations, only if \r
+               // unusedActs flag is set to true and if the total \r
+               // size exceeds 20.\r
+               if( (unusedActs) && (acts.size() > 20) ) {\r
+                       unusedActs = false;\r
+\r
+                       for (int i = acts.size() - 1; i >= 0; i--) {\r
+\r
+                               // it maybe the case that a Activation's reset() ends up\r
+                               // closing one or more activation leaving our index beyond\r
+                               // the end of the array\r
+                               if (i >= acts.size())\r
+                                       continue;\r
+\r
+                               Activation a1 = (Activation) acts.get(i);\r
+                               if (!a1.isInUse()) {\r
+                                       a1.close();\r
+                               }\r
+                       }\r
+               }\r
+\r
+               if (SanityManager.DEBUG) {\r
+\r
+                       if (SanityManager.DEBUG_ON("memoryLeakTrace")) {\r
+\r
+                               if (acts.size() > 20)\r
+                                       System.out.println("memoryLeakTrace:GenericLanguageContext:activations " + acts.size());\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Make a note that some activations are marked unused\r
+        */\r
+       public void notifyUnusedActivation() {\r
+           unusedActs = true;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#checkIfAnyDeclaredGlobalTempTablesForThisConnection\r
+        */\r
+       public boolean checkIfAnyDeclaredGlobalTempTablesForThisConnection() {\r
+               return (allDeclaredGlobalTempTables == null ? false : true);\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#addDeclaredGlobalTempTable\r
+        */\r
+       public void addDeclaredGlobalTempTable(TableDescriptor td)\r
+               throws StandardException {\r
+\r
+               if (findDeclaredGlobalTempTable(td.getName()) != null) //if table already declared, throw an exception\r
+               {\r
+                       throw\r
+                               StandardException.newException(\r
+                                                                                          SQLState.LANG_OBJECT_ALREADY_EXISTS_IN_OBJECT,\r
+                                                                                          "Declared global temporary table",\r
+                                                                                          td.getName(),\r
+                                                                                          "Schema",\r
+                                                                                          SchemaDescriptor.STD_DECLARED_GLOBAL_TEMPORARY_TABLES_SCHEMA_NAME);\r
+               }\r
+\r
+               //save all the information about temp table in this special class\r
+               TempTableInfo tempTableInfo = new TempTableInfo(td, currentSavepointLevel);\r
+\r
+               if (allDeclaredGlobalTempTables == null)\r
+                       allDeclaredGlobalTempTables = new ArrayList();\r
+\r
+               allDeclaredGlobalTempTables.add(tempTableInfo);\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#dropDeclaredGlobalTempTable\r
+        */\r
+       public boolean dropDeclaredGlobalTempTable(String tableName) {\r
+    TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName);\r
+               if (tempTableInfo != null)\r
+               {\r
+                       if (SanityManager.DEBUG)\r
+                               if (tempTableInfo.getDeclaredInSavepointLevel() > currentSavepointLevel)\r
+                                       SanityManager.THROWASSERT("declared in savepoint level can not be higher than the current savepoint level");\r
+\r
+                       //following checks if the table was declared in the current unit of work.\r
+                       if (tempTableInfo.getDeclaredInSavepointLevel() == currentSavepointLevel)\r
+                       {\r
+                               //since the table was declared in this unit of work,\r
+                               //the drop table method should remove it from the valid list of temp table for this unit of work\r
+                               allDeclaredGlobalTempTables.remove(allDeclaredGlobalTempTables.indexOf(tempTableInfo));\r
+                               if (allDeclaredGlobalTempTables.size() == 0)\r
+                                       allDeclaredGlobalTempTables = null;\r
+                       }\r
+                       else\r
+                       {\r
+                               //since the table was not declared in this unit of work, the drop table method will just mark the table as dropped\r
+                               //in the current unit of work. This information will be used at rollback time.\r
+                               tempTableInfo.setDroppedInSavepointLevel(currentSavepointLevel);\r
+                       }\r
+                       return true;\r
+               } else\r
+                       return false;\r
+       }\r
+\r
+       /**\r
+        * After a release of a savepoint, we need to go through our temp tables list. If there are tables with their declare or drop\r
+        * or modified in savepoint levels set to savepoint levels higher than the current savepoint level, then we should change them\r
+        * to the current savepoint level\r
+        */\r
+       private void tempTablesReleaseSavepointLevels() {\r
+    //unlike rollback, here we check for dropped in / declared in / modified in savepoint levels > current savepoint level only.\r
+    //This is because the temp tables with their savepoint levels same as currentSavepointLevel have correct value assigned to them and\r
+    //do not need to be changed and hence no need to check for >=\r
+               for (int i = 0; i < allDeclaredGlobalTempTables.size(); i++) {\r
+                       TempTableInfo tempTableInfo = (TempTableInfo)allDeclaredGlobalTempTables.get(i);\r
+                       if (tempTableInfo.getDroppedInSavepointLevel() > currentSavepointLevel)\r
+                               tempTableInfo.setDroppedInSavepointLevel(currentSavepointLevel);\r
+\r
+                       if (tempTableInfo.getDeclaredInSavepointLevel() > currentSavepointLevel)\r
+                               tempTableInfo.setDeclaredInSavepointLevel(currentSavepointLevel);\r
+\r
+                       if (tempTableInfo.getModifiedInSavepointLevel() > currentSavepointLevel)\r
+                               tempTableInfo.setModifiedInSavepointLevel(currentSavepointLevel);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * do the necessary work at commit time for temporary tables\r
+        * 1)If a temporary table was marked as dropped in this transaction, then remove it from the list of temp tables for this connection\r
+        * 2)If a temporary table was not dropped in this transaction, then mark it's declared savepoint level and modified savepoint level as -1\r
+        */\r
+       private void tempTablesAndCommit() {\r
+               for (int i = allDeclaredGlobalTempTables.size()-1; i >= 0; i--) {\r
+                       TempTableInfo tempTableInfo = (TempTableInfo)allDeclaredGlobalTempTables.get(i);\r
+                       if (tempTableInfo.getDroppedInSavepointLevel() != -1)\r
+                       {\r
+                               //this means table was dropped in this unit of work and hence should be removed from valid list of temp tables\r
+                               allDeclaredGlobalTempTables.remove(i);\r
+                       } else //this table was not dropped in this unit of work, hence set its declaredInSavepointLevel as -1 and also mark it as not modified \r
+                       {\r
+                               tempTableInfo.setDeclaredInSavepointLevel(-1);\r
+                               tempTableInfo.setModifiedInSavepointLevel(-1);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+               Reset the connection before it is returned (indirectly) by\r
+               a PooledConnection object. See EmbeddedConnection.\r
+        */\r
+       public void resetFromPool()\r
+                throws StandardException\r
+       {\r
+               // Reset IDENTITY_VAL_LOCAL\r
+               identityNotNull = false;\r
+\r
+               // drop all temp tables.\r
+               dropAllDeclaredGlobalTempTables();\r
+       }\r
+\r
+       /**\r
+        * Drop all the declared global temporary tables associated with this connection. This gets called\r
+        * when a getConnection() is done on a PooledConnection. This will ensure all the temporary tables\r
+        * declared on earlier connection handle associated with this physical database connection are dropped\r
+        * before a new connection handle is issued on that same physical database connection.\r
+        */\r
+       private void dropAllDeclaredGlobalTempTables() throws StandardException {\r
+               if (allDeclaredGlobalTempTables == null)\r
+                       return;\r
+    \r
+               DependencyManager dm = getDataDictionary().getDependencyManager();\r
+               StandardException topLevelStandardException = null;\r
+\r
+               //collect all the exceptions we might receive while dropping the temporary tables and throw them as one chained exception at the end.\r
+               for (int i = 0; i < allDeclaredGlobalTempTables.size(); i++) {\r
+                       try {\r
+                               TempTableInfo tempTableInfo = (TempTableInfo)allDeclaredGlobalTempTables.get(i);\r
+                               TableDescriptor td = tempTableInfo.getTableDescriptor();\r
+                               //the following 2 lines of code has been copied from DropTableConstantAction. If there are any changes made there in future,\r
+                               //we should check if they need to be made here too.\r
+                               dm.invalidateFor(td, DependencyManager.DROP_TABLE, this);\r
+                               tran.dropConglomerate(td.getHeapConglomerateId());\r
+                       } catch (StandardException e) {\r
+                               if (topLevelStandardException == null) {\r
+                                       // always keep the first exception unchanged\r
+                                       topLevelStandardException = e;\r
+                               } else {\r
+                                       try {\r
+                                               // Try to create a chain of exceptions. If successful,\r
+                                               // the current exception is the top-level exception,\r
+                                               // and the previous exception the cause of it.\r
+                                               e.initCause(topLevelStandardException);\r
+                                               topLevelStandardException = e;\r
+                                       } catch (IllegalStateException ise) {\r
+                                               // initCause() has already been called on e. We don't\r
+                                               // expect this to happen, but if it happens, just skip\r
+                                               // the current exception from the chain. This is safe\r
+                                               // since we always keep the first exception.\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+    \r
+               allDeclaredGlobalTempTables = null;\r
+               try {\r
+                       internalCommit(true);\r
+               } catch (StandardException e) {\r
+                       // do the same chaining as above\r
+                       if (topLevelStandardException == null) {\r
+                               topLevelStandardException = e;\r
+                       } else {\r
+                               try {\r
+                                       e.initCause(topLevelStandardException);\r
+                                       topLevelStandardException = e;\r
+                               } catch (IllegalStateException ise) { /* ignore */ }\r
+                       }\r
+               }\r
+               if (topLevelStandardException != null) throw topLevelStandardException;\r
+       }\r
+\r
+       //do the necessary work at rollback time for temporary tables\r
+       /**\r
+        * do the necessary work at rollback time for temporary tables\r
+        * 1)If a temp table was declared in the UOW, then drop it and remove it from list of temporary tables.\r
+        * 2)If a temp table was declared and dropped in the UOW, then remove it from list of temporary tables.\r
+        * 3)If an existing temp table was dropped in the UOW, then recreate it with no data.\r
+        * 4)If an existing temp table was modified in the UOW, then get rid of all the rows from the table.\r
+        */\r
+       private void tempTablesAndRollback()\r
+               throws StandardException {\r
+               for (int i = allDeclaredGlobalTempTables.size()-1; i >= 0; i--) {\r
+                       TempTableInfo tempTableInfo = (TempTableInfo)allDeclaredGlobalTempTables.get(i);\r
+                       if (tempTableInfo.getDeclaredInSavepointLevel() >= currentSavepointLevel)\r
+                       {\r
+                               if (tempTableInfo.getDroppedInSavepointLevel() == -1)\r
+                               {\r
+                                       //the table was declared but not dropped in the unit of work getting rolled back and hence we will remove\r
+                                       //it from valid list of temporary tables and drop the conglomerate associated with it\r
+                                       TableDescriptor td = tempTableInfo.getTableDescriptor();\r
+                                       tran.dropConglomerate(td.getHeapConglomerateId()); //remove the conglomerate created for this temp table\r
+                                       allDeclaredGlobalTempTables.remove(i); //remove it from the list of temp tables\r
+                               } else if (tempTableInfo.getDroppedInSavepointLevel() >= currentSavepointLevel)\r
+                               {\r
+                                       //the table was declared and dropped in the unit of work getting rolled back\r
+                                       allDeclaredGlobalTempTables.remove(i);\r
+                               }\r
+                       } else if (tempTableInfo.getDroppedInSavepointLevel() >= currentSavepointLevel) //this means the table was declared in an earlier savepoint unit / transaction and then dropped in current UOW \r
+                       {\r
+                               //restore the old definition of temp table because drop is being rolledback\r
+                               TableDescriptor td = tempTableInfo.getTableDescriptor();\r
+                               td = cleanupTempTableOnCommitOrRollback(td, false);\r
+                               //In order to store the old conglomerate information for the temp table, we need to replace the\r
+                               //existing table descriptor with the old table descriptor which has the old conglomerate information\r
+                               tempTableInfo.setTableDescriptor(td);\r
+                               tempTableInfo.setDroppedInSavepointLevel(-1);\r
+                               //following will mark the table as not modified. This is because the table data has been deleted as part of the current rollback\r
+                               tempTableInfo.setModifiedInSavepointLevel(-1);\r
+                               allDeclaredGlobalTempTables.set(i, tempTableInfo);\r
+                       } else if (tempTableInfo.getModifiedInSavepointLevel() >= currentSavepointLevel) //this means the table was declared in an earlier savepoint unit / transaction and modified in current UOW\r
+                       {\r
+                               //following will mark the table as not modified. This is because the table data will be deleted as part of the current rollback\r
+                               tempTableInfo.setModifiedInSavepointLevel(-1);\r
+                               TableDescriptor td = tempTableInfo.getTableDescriptor();\r
+                               getDataDictionary().getDependencyManager().invalidateFor(td, DependencyManager.DROP_TABLE, this);\r
+                               cleanupTempTableOnCommitOrRollback(td, true);\r
+                       } // there is no else here because there is no special processing required for temp tables declares in earlier work of unit/transaction and not modified\r
+               }\r
+    \r
+               if (allDeclaredGlobalTempTables.size() == 0)\r
+                       allDeclaredGlobalTempTables = null;\r
+       }\r
+\r
+       /**\r
+        * This is called at the commit time for temporary tables with ON COMMIT DELETE ROWS\r
+        * If a temp table with ON COMMIT DELETE ROWS doesn't have any held cursor open on them, we delete the data from\r
+        * them by dropping the conglomerate and recreating the conglomerate. In order to store the new conglomerate\r
+        * information for the temp table, we need to replace the existing table descriptor with the new table descriptor\r
+        * which has the new conglomerate information\r
+        * @param tableName Temporary table name whose table descriptor is getting changed\r
+        * @param td New table descriptor for the temporary table\r
+        */\r
+       private void replaceDeclaredGlobalTempTable(String tableName, TableDescriptor td) {\r
+    TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName);\r
+               tempTableInfo.setDroppedInSavepointLevel(-1);\r
+               tempTableInfo.setDeclaredInSavepointLevel(-1);\r
+               tempTableInfo.setTableDescriptor(td);\r
+               allDeclaredGlobalTempTables.set(allDeclaredGlobalTempTables.indexOf(tempTableInfo), tempTableInfo);\r
+  }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#getTableDescriptorForDeclaredGlobalTempTable\r
+        */\r
+       public TableDescriptor getTableDescriptorForDeclaredGlobalTempTable(String tableName) {\r
+    TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName);\r
+               if (tempTableInfo == null)\r
+                       return null;\r
+               else\r
+                       return tempTableInfo.getTableDescriptor();\r
+       }\r
+\r
+       /**\r
+        * Find the declared global temporary table in the list of temporary tables known by this connection.\r
+        * @param tableName look for this table name in the saved list\r
+        * @return data structure defining the temporary table if found. Else, return null \r
+        *\r
+        */\r
+       private TempTableInfo findDeclaredGlobalTempTable(String tableName) {\r
+               if (allDeclaredGlobalTempTables == null)\r
+                       return null;\r
+\r
+               for (int i = 0; i < allDeclaredGlobalTempTables.size(); i++) {\r
+                       if (((TempTableInfo)allDeclaredGlobalTempTables.get(i)).matches(tableName))\r
+                               return (TempTableInfo)allDeclaredGlobalTempTables.get(i);\r
+               }\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#markTempTableAsModifiedInUnitOfWork\r
+        */\r
+       public void markTempTableAsModifiedInUnitOfWork(String tableName) {\r
+    TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName);\r
+    tempTableInfo.setModifiedInSavepointLevel(currentSavepointLevel);\r
+       }\r
+\r
+        /**\r
+        * @see LanguageConnectionContext#prepareInternalStatement\r
+        */\r
+        public PreparedStatement prepareInternalStatement(SchemaDescriptor compilationSchema, String sqlText, boolean isForReadOnly, boolean forMetaData) \r
+           throws StandardException \r
+        {\r
+           return connFactory.getStatement(compilationSchema, sqlText, isForReadOnly).prepare(this, forMetaData);\r
+       }\r
+\r
+        /**\r
+        * @see LanguageConnectionContext#prepareInternalStatement\r
+        */\r
+        public PreparedStatement prepareInternalStatement(String sqlText) \r
+           throws StandardException \r
+        {\r
+           return connFactory.getStatement(sd, sqlText, true).prepare(this);\r
+       }      \r
+\r
+       /**\r
+        * Remove the activation to those known about by this connection.\r
+        *\r
+        */\r
+       public void removeActivation(Activation a) \r
+       {\r
+               if (SanityManager.DEBUG) {\r
+                       SanityManager.ASSERT(a.isClosed(), "Activation is not closed");\r
+               }\r
+\r
+               acts.remove(a);\r
+\r
+               if (maxActsSize > 20 && (maxActsSize > 2 * acts.size())) {\r
+                       acts.trimToSize();\r
+                       maxActsSize = acts.size();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Return the number of activations known for this connection.\r
+        * Note that some of these activations may not be in use\r
+        * (when a prepared statement is finalized, its activations\r
+        * are marked as unused and later closed and removed on\r
+        * the next commit/rollback).\r
+        */\r
+       public int getActivationCount() {\r
+               return acts.size();\r
+       }\r
+\r
+       /**\r
+        * See if a given cursor is available for use.\r
+        * if so return its activation. Returns null if not found.\r
+        * For use in execution.\r
+        *\r
+        * @return the activation for the given cursor, null\r
+        *      if none was found.\r
+        */\r
+       public CursorActivation lookupCursorActivation(String cursorName) {\r
+\r
+               int size = acts.size();\r
+               if (size > 0)\r
+               {\r
+                       for (int i = 0; i < size; i++) {\r
+                                Activation a = (Activation) acts.get(i);\r
+\r
+                                if (!a.isInUse())\r
+                                {\r
+                                       continue;\r
+                                }\r
+\r
+\r
+\r
+                               String executingCursorName = a.getCursorName();\r
+\r
+                                if (cursorName.equals(executingCursorName)) {\r
+\r
+                                       ResultSet rs = a.getResultSet();\r
+                                       if (rs == null)\r
+                                               continue;\r
+\r
+                                        // if the result set is closed, the the cursor doesn't exist\r
+                                        if (rs.isClosed()) {                                   \r
+                                               continue;\r
+                                        }\r
+\r
+                                       return (CursorActivation)a;\r
+                                }\r
+                       }\r
+               }\r
+               return null;\r
+       }\r
+\r
+       /**\r
+       *  This method will remove a statement from the  statement cache.\r
+       *  It will be called,  for example, if there is an exception preparing\r
+       *  the statement.\r
+       *\r
+       *  @param statement Statement to remove\r
+       *  @exception StandardException thrown if lookup goes wrong.\r
+       */      \r
+       public void removeStatement(Statement statement)\r
+               throws StandardException {\r
+        \r
+        CacheManager statementCache =\r
+            getLanguageConnectionFactory().getStatementCache();\r
+\r
+               if (statementCache == null)\r
+                       return;\r
\r
+                       Cacheable cachedItem = statementCache.findCached(statement);\r
+                       if (cachedItem != null)\r
+                               statementCache.remove(cachedItem);\r
+       }\r
+\r
+       /**\r
+        * See if a given statement has already been compiled for this user, and\r
+        * if so use its prepared statement. Returns null if not found.\r
+        *\r
+        * @exception StandardException thrown if lookup goes wrong.\r
+        * @return the prepared statement for the given string, null\r
+        *      if none was found.\r
+        */\r
+       public PreparedStatement lookupStatement(GenericStatement statement)\r
+               throws StandardException {\r
+\r
+        CacheManager statementCache =\r
+            getLanguageConnectionFactory().getStatementCache();\r
+            \r
+               if (statementCache == null)\r
+                       return null;\r
+\r
+               // statement caching disable when in DDL mode\r
+               if (dataDictionaryInWriteMode()) {\r
+                       return null;\r
+               }\r
+\r
+               Cacheable cachedItem = statementCache.find(statement);\r
+\r
+               CachedStatement cs = (CachedStatement) cachedItem;\r
+\r
+\r
+               GenericPreparedStatement ps = cs.getPreparedStatement();\r
+\r
+               synchronized (ps) {\r
+                       if (ps.upToDate()) {\r
+                               GeneratedClass ac = ps.getActivationClass();\r
+\r
+                               // Check to see if the statement was prepared before some change\r
+                               // in the class loading set. If this is the case then force it to be invalid\r
+                               int currentClasses =\r
+                                               getLanguageConnectionFactory().getClassFactory().getClassLoaderVersion();\r
+\r
+                               if (ac.getClassLoaderVersion() != currentClasses) {\r
+                                       ps.makeInvalid(DependencyManager.INTERNAL_RECOMPILE_REQUEST, this);\r
+                               }\r
+\r
+                               // note that the PreparedStatement is not kept in the cache. This is because\r
+                               // having items kept in the cache that ultimately are held onto by\r
+                               // user code is impossible to manage. E.g. an open ResultSet would hold onto\r
+                               // a PreparedStatement (through its activation) and the user can allow\r
+                               // this object to be garbage collected. Pushing a context stack is impossible\r
+                               // in garbage collection as it may deadlock with the open connection and\r
+                               // the context manager assumes a singel current thread per context stack\r
+                       }\r
+               }\r
+\r
+               statementCache.release(cachedItem);\r
+               return ps;\r
+       }\r
+\r
+       /**\r
+               Get a connection unique system generated name for a cursor.\r
+       */\r
+       public String getUniqueCursorName() \r
+       {\r
+               return getNameString("SQLCUR", nextCursorId++);\r
+       }\r
+\r
+       /**\r
+               Get a connection unique system generated name for an unnamed savepoint.\r
+       */\r
+       public String getUniqueSavepointName()\r
+       {\r
+               return getNameString("SAVEPT", nextSavepointId++);\r
+       }\r
+\r
+       /**\r
+               Get a connection unique system generated id for an unnamed savepoint.\r
+       */\r
+       public int getUniqueSavepointID()\r
+       {\r
+               return nextSavepointId-1;\r
+       }\r
+\r
+       /**\r
+        * Build a String for a statement name.\r
+        *\r
+        * @param prefix        The prefix for the statement name.\r
+        * @param number        The number to append for uniqueness\r
+        *\r
+        * @return      A unique String for a statement name.\r
+        */\r
+       private String getNameString(String prefix, long number)\r
+       {\r
+               if (sb != null)\r
+               {\r
+                       sb.setLength(0);\r
+               }\r
+               else\r
+               {\r
+                       sb = new StringBuffer();\r
+               }\r
+               sb.append(prefix).append(number);\r
+\r
+               return sb.toString();\r
+       }\r
+\r
+       /**\r
+        * Do a commit as appropriate for an internally generated\r
+        * commit (e.g. as needed by sync, or autocommit).\r
+        *\r
+        * @param       commitStore     true if we should commit the Store transaction\r
+        *\r
+        * @exception StandardException thrown on failure\r
+        */\r
+       public void internalCommit(boolean commitStore) throws StandardException\r
+       {\r
+               doCommit(commitStore,\r
+                                                                 true,\r
+                                                                 NON_XA,\r
+                                                                 false);\r
+       }\r
+\r
+       /**\r
+        * Do a commmit as is appropriate for a user requested\r
+        * commit (e.g. a java.sql.Connection.commit() or a language\r
+        * 'COMMIT' statement.  Does some extra checking to make\r
+        * sure that users aren't doing anything bad.\r
+        *\r
+        * @exception StandardException thrown on failure\r
+        */\r
+       public void userCommit() throws StandardException\r
+       {\r
+               doCommit(true,\r
+                                                                 true,\r
+                                                                 NON_XA,\r
+                                                                 true);\r
+       }\r
+\r
+\r
+       /**\r
+               Commit the language transaction by doing a commitNoSync()\r
+               on the store's TransactionController.\r
+\r
+               <p>\r
+               Do *NOT* tell the data dictionary that the transaction is\r
+               finished. The reason is that this would allow other transactions\r
+               to see comitted DDL that could be undone in the event of a\r
+               system crash.\r
+\r
+               @param  commitflag      the flags to pass to commitNoSync in the store's\r
+                                                       TransactionController\r
+\r
+               @exception StandardException thrown on failure\r
+        */\r
+       public final void internalCommitNoSync(int commitflag) throws StandardException\r
+       {\r
+               doCommit(true, false, commitflag, false);\r
+       }\r
+\r
+\r
+       /**\r
+               Same as userCommit except commit a distributed transaction.   \r
+               This commit always commit store and sync the commit.\r
+\r
+               @param onePhase if true, allow it to commit without first going thru a\r
+               prepared state.\r
+\r
+               @exception StandardException    thrown if something goes wrong\r
+        */\r
+       public final void xaCommit(boolean onePhase) throws StandardException\r
+       {\r
+               // further overload internalCommit to make it understand 2 phase commit\r
+               doCommit(true /* commit store */,\r
+                                                                 true /* sync */,\r
+                                                                 onePhase ? XA_ONE_PHASE : XA_TWO_PHASE,\r
+                                                                 true);\r
+       }\r
+\r
+\r
+       /**\r
+        * This is where the work on internalCommit(), userCOmmit() and \r
+        * internalCommitNoSync() actually takes place.\r
+        * <p>\r
+        * When a commit happens, the language connection context\r
+        * will close all open activations/cursors and commit the\r
+        * Store transaction.\r
+        * <p>\r
+        * REVISIT: we talked about having a LanguageTransactionContext,\r
+        * but since store transaction management is currently in flux\r
+        * and our context might want to delegate to that context,\r
+        * for now all commit/rollback actions are handled directly by\r
+        * the language connection context.\r
+        * REVISIT: this may need additional alterations when\r
+        * RELEASE SAVEPOINT/ROLLBACK TO SAVEPOINT show up.\r
+        * <P>\r
+        * Since the access manager's own context takes care of its own\r
+        * resources on commit, and the transaction stays open, there is\r
+        * nothing that this context has to do with the transaction controller.\r
+        * <p>\r
+        * Also, tell the data dictionary that the transaction is finished,\r
+        * if necessary (that is, if the data dictionary was put into\r
+        * DDL mode in this transaction.\r
+        *\r
+        *\r
+        * @param       commitStore     true if we should commit the Store transaction\r
+        * @param       sync            true means do a synchronized commit,\r
+        *                                              false means do an unsynchronized commit\r
+        * @param       commitflag      if this is an unsynchronized commit, the flags to\r
+        *                                              pass to commitNoSync in the store's\r
+        *                                              TransactionController.  If this is a synchronized\r
+        *                                              commit, this flag is overloaded for xacommit.\r
+     * @param   requestedByUser    False iff the commit is for internal use and\r
+        *                      we should ignore the check to prevent commits\r
+        *                      in an atomic statement.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+\r
+       protected void doCommit(boolean commitStore,\r
+                                                                                          boolean sync,\r
+                                                                                          int commitflag,\r
+                                                                                          boolean requestedByUser)\r
+                throws StandardException\r
+       {\r
+               StatementContext statementContext = getStatementContext();\r
+               if (requestedByUser  &&\r
+                       (statementContext != null) &&\r
+                       statementContext.inUse() &&\r
+                       statementContext.isAtomic())\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_NO_COMMIT_IN_NESTED_CONNECTION);\r
+               }\r
+\r
+               // Log commit to error log, if appropriate\r
+               if (logStatementText)\r
+               {\r
+                       if (istream == null)\r
+                       {\r
+                               istream = Monitor.getStream();\r
+                       }\r
+                       String xactId = tran.getTransactionIdString();\r
+                       istream.printlnWithHeader(LanguageConnectionContext.xidStr + \r
+                                                                         xactId + \r
+                                                                         "), " +\r
+                                                                         LanguageConnectionContext.lccStr +\r
+                                                                         instanceNumber +\r
+                                                                         "), " + LanguageConnectionContext.dbnameStr +\r
+                                                                                 dbname +\r
+                                                                                 "), " +\r
+                                                                                 LanguageConnectionContext.drdaStr +\r
+                                                                                 drdaID +\r
+                                                                         "), Committing");\r
+               }\r
+\r
+               endTransactionActivationHandling(false);\r
+\r
+               //do the clean up work required for temporary tables at the commit time. This cleanup work\r
+               //can possibly remove entries from allDeclaredGlobalTempTables and that's why we need to check\r
+               //again later to see if we there are still any entries in allDeclaredGlobalTempTables\r
+               if (allDeclaredGlobalTempTables != null)\r
+               {\r
+                       tempTablesAndCommit();\r
+                       //at commit time, for all the temp tables declared with ON COMMIT DELETE ROWS, make sure there are no held cursor open on them.\r
+                       //If there are no held cursors open on ON COMMIT DELETE ROWS, drop those temp tables and redeclare them to get rid of all the data in them\r
+                       if (allDeclaredGlobalTempTables != null) {\r
+                               for (int i=0; i<allDeclaredGlobalTempTables.size(); i++)\r
+                               {\r
+                                       TableDescriptor td = ((TempTableInfo)(allDeclaredGlobalTempTables.get(i))).getTableDescriptor();\r
+                                       if (td.isOnCommitDeleteRows() == false) //do nothing for temp table with ON COMMIT PRESERVE ROWS\r
+                                       {\r
+                                               continue;\r
+                                       }\r
+                                       if (checkIfAnyActivationHasHoldCursor(td.getName()) == false)//temp tables with ON COMMIT DELETE ROWS and no open held cursors\r
+                                       {\r
+                                               getDataDictionary().getDependencyManager().invalidateFor(td, DependencyManager.DROP_TABLE, this);\r
+                                               cleanupTempTableOnCommitOrRollback(td, true);\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+\r
+\r
+               currentSavepointLevel = 0; //reset the current savepoint level for the connection to 0 at the end of commit work for temp tables\r
+\r
+               // Do *NOT* tell the DataDictionary to start using its cache again\r
+               // if this is an unsynchronized commit. The reason is that it\r
+               // would allow other transactions to see this transaction's DDL,\r
+               // which could be rolled back in case of a system crash.\r
+               if (sync)\r
+               {\r
+                       finishDDTransaction();\r
+               }\r
+        \r
+        // Check that any nested transaction has been destoyed\r
+        // before a commit.\r
+        if (SanityManager.DEBUG)\r
+        {\r
+            if (readOnlyNestedTransaction != null)\r
+            {\r
+                SanityManager.THROWASSERT("Nested transaction active!");\r
+            }\r
+        }\r
+\r
+               // now commit the Store transaction\r
+               TransactionController tc = getTransactionExecute();\r
+               if ( tc != null && commitStore ) \r
+               { \r
+                       if (sync)\r
+                       {\r
+                               if (commitflag == NON_XA)\r
+                               {\r
+                                       // regular commit\r
+                                       tc.commit();\r
+                               }\r
+                               else\r
+                               {\r
+                                       // This may be a xa_commit, check overloaded commitflag.\r
+\r
+                                       if (SanityManager.DEBUG)\r
+                                               SanityManager.ASSERT(commitflag == XA_ONE_PHASE ||\r
+                                                                                        commitflag == XA_TWO_PHASE,\r
+                                                                                          "invalid commit flag");\r
+\r
+                                       ((XATransactionController)tc).xa_commit(commitflag == XA_ONE_PHASE);\r
+\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               tc.commitNoSync(commitflag);\r
+                       }\r
+\r
+                       // reset the savepoints to the new\r
+                       // location, since any outer nesting\r
+                       // levels expect there to be a savepoint\r
+                       resetSavepoints();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * If dropAndRedeclare is true, that means we have come here for temp \r
+     * tables with on commit delete rows and no held curosr open on them. We \r
+     * will drop the existing conglomerate and redeclare a new conglomerate\r
+        * similar to old conglomerate. This is a more efficient way of deleting \r
+     * all rows from the table.\r
+        *\r
+        * If dropAndRedeclare is false, that means we have come here for the \r
+     * rollback cleanup work. We are trying to restore old definition of the \r
+     * temp table (because the drop on it is being rolled back).\r
+        */\r
+       private TableDescriptor cleanupTempTableOnCommitOrRollback(\r
+    TableDescriptor td, \r
+    boolean         dropAndRedeclare)\r
+                throws StandardException\r
+       {\r
+               //create new conglomerate with same properties as the old conglomerate \r
+        //and same row template as the old conglomerate\r
+               long conglomId = \r
+            tran.createConglomerate(\r
+                "heap", // we're requesting a heap conglomerate\r
+                td.getEmptyExecRow().getRowArray(), // row template\r
+                null, //column sort order - not required for heap\r
+                td.getColumnCollationIds(),  // same ids as old conglomerate\r
+                null, // properties\r
+                (TransactionController.IS_TEMPORARY | \r
+                 TransactionController.IS_KEPT));\r
+\r
+               long cid = td.getHeapConglomerateId();\r
+\r
+               //remove the old conglomerate descriptor from the table descriptor\r
+               ConglomerateDescriptor cgd = td.getConglomerateDescriptor(cid);\r
+               td.getConglomerateDescriptorList().dropConglomerateDescriptorByUUID(cgd.getUUID());\r
+               //add the new conglomerate descriptor to the table descriptor\r
+               cgd = getDataDictionary().getDataDescriptorGenerator().newConglomerateDescriptor(conglomId, null, false, null, false, null, td.getUUID(),\r
+               td.getSchemaDescriptor().getUUID());\r
+               ConglomerateDescriptorList conglomList = td.getConglomerateDescriptorList();\r
+               conglomList.add(cgd);\r
+\r
+               //reset the heap conglomerate number in table descriptor to -1 so it will be refetched next time with the new value\r
+               td.resetHeapConglomNumber();\r
+\r
+               if(dropAndRedeclare)\r
+               {\r
+                       tran.dropConglomerate(cid); //remove the old conglomerate from the system\r
+                       replaceDeclaredGlobalTempTable(td.getName(), td);\r
+               }\r
+\r
+               return(td);\r
+       }\r
+\r
+       /**\r
+         Do a rollback as appropriate for an internally generated\r
+         rollback (e.g. as needed by sync, or autocommit).\r
+        \r
+         When a rollback happens, we \r
+         close all open activations and invalidate their\r
+         prepared statements.  We then tell the cache to\r
+         age out everything else, which effectively invalidates\r
+         them.  Thus, all prepared statements will be\r
+         compiled anew on their 1st execution after\r
+         a rollback.\r
+         <p>\r
+         The invalidated statements can revalidate themselves without\r
+         a full recompile if they verify their dependencies' providers still\r
+         exist unchanged. REVISIT when invalidation types are created.\r
+         <p>\r
+         REVISIT: this may need additional alterations when\r
+         RELEASE SAVEPOINT/ROLLBACK TO SAVEPOINT show up.\r
+         <p>\r
+         Also, tell the data dictionary that the transaction is finished,\r
+         if necessary (that is, if the data dictionary was put into\r
+         DDL mode in this transaction.\r
+\r
+         @exception StandardException thrown on failure\r
+        */\r
+\r
+       public void internalRollback() throws StandardException \r
+       {\r
+               doRollback(false /* non-xa */, false);\r
+       }\r
+\r
+       /**\r
+        * Do a rollback as is appropriate for a user requested\r
+        * rollback (e.g. a java.sql.Connection.rollback() or a language\r
+        * 'ROLLBACk' statement.  Does some extra checking to make\r
+        * sure that users aren't doing anything bad.\r
+        *\r
+        * @exception StandardException thrown on failure\r
+        */\r
+       public void userRollback() throws StandardException\r
+       {\r
+               doRollback(false /* non-xa */, true);\r
+       }\r
+\r
+       /**\r
+           Same as userRollback() except rolls back a distrubuted transaction.\r
+\r
+               @exception StandardException    thrown if something goes wrong\r
+        */\r
+       public void xaRollback() throws StandardException\r
+       {\r
+               doRollback(true /* xa */, true);\r
+       }\r
+\r
+       /**\r
+        * When a rollback happens, the language connection context\r
+        * will close all open activations and invalidate\r
+        * their prepared statements. Then the language will abort the\r
+        * Store transaction.\r
+        * <p>\r
+        * The invalidated statements can revalidate themselves without\r
+        * a full recompile if they verify their dependencies' providers still\r
+        * exist unchanged. REVISIT when invalidation types are created.\r
+        * <p>\r
+        * REVISIT: this may need additional alterations when\r
+        * RELEASE SAVEPOINT/ROLLBACK TO SAVEPOINT show up.\r
+        * <p>\r
+        * Also, tell the data dictionary that the transaction is finished,\r
+        * if necessary (that is, if the data dictionary was put into\r
+        * DDL mode in this transaction.\r
+        *\r
+        * @param xa    true if this is an xa rollback\r
+        * @param requestedByUser       true if requested by user\r
+        *\r
+        * @exception StandardException thrown on failure\r
+        */\r
+       private void doRollback(boolean xa, boolean requestedByUser) throws StandardException\r
+       {\r
+               StatementContext statementContext = getStatementContext();\r
+               if (requestedByUser &&\r
+                       (statementContext != null) &&\r
+                       statementContext.inUse() &&\r
+                       statementContext.isAtomic())\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_NO_ROLLBACK_IN_NESTED_CONNECTION);\r
+               }\r
+\r
+               // Log rollback to error log, if appropriate\r
+               if (logStatementText)\r
+               {\r
+                       if (istream == null)\r
+                       {\r
+                               istream = Monitor.getStream();\r
+                       }\r
+                       String xactId = tran.getTransactionIdString();\r
+                       istream.printlnWithHeader(LanguageConnectionContext.xidStr +\r
+                                                                         xactId + \r
+                                                                         "), " +\r
+                                                                         LanguageConnectionContext.lccStr +\r
+                                                                         instanceNumber +\r
+                                                                         "), " + LanguageConnectionContext.dbnameStr +\r
+                                                                                 dbname +\r
+                                                                                 "), " +\r
+                                                                                 LanguageConnectionContext.dbnameStr +\r
+                                                                                 dbname +\r
+                                                                                 "), " +\r
+                                                                                 LanguageConnectionContext.drdaStr +\r
+                                                                                 drdaID +\r
+                                                                         "), Rolling back");\r
+               }\r
+\r
+               endTransactionActivationHandling(true);\r
+\r
+               currentSavepointLevel = 0; //reset the current savepoint level for the connection to 0 at the beginning of rollback work for temp tables\r
+               if (allDeclaredGlobalTempTables != null)\r
+                       tempTablesAndRollback();\r
+\r
+               finishDDTransaction();\r
+        \r
+        // If a nested transaction is active then\r
+        // ensure it is destroyed before working\r
+        // with the user transaction.\r
+        if (readOnlyNestedTransaction != null)\r
+        {\r
+            readOnlyNestedTransaction.destroy();\r
+            readOnlyNestedTransaction = null;\r
+            queryNestingDepth = 0;\r
+        }\r
+\r
+               // now rollback the Store transaction\r
+               TransactionController tc = getTransactionExecute();\r
+               if (tc != null) \r
+               {       \r
+                       if (xa)\r
+                               ((XATransactionController)tc).xa_rollback();\r
+                       else\r
+                               tc.abort(); \r
+            \r
+                       // reset the savepoints to the new\r
+                       // location, since any outer nesting\r
+                       // levels expet there to be a savepoint\r
+                       resetSavepoints();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Reset all statement savepoints. Traverses the StatementContext\r
+        * stack from bottom to top, calling resetSavePoint()\r
+        * on each element.\r
+        *\r
+        * @exception StandardException thrown if something goes wrong\r
+        */\r
+       private void resetSavepoints() throws StandardException \r
+       {\r
+               final ContextManager cm = getContextManager();\r
+               final List stmts = cm.getContextStack(org.apache.derby.\r
+                                                                                         iapi.reference.\r
+                                                                                         ContextId.LANG_STATEMENT);\r
+               final int end = stmts.size();\r
+               for (int i = 0; i < end; ++i) {\r
+                       ((StatementContext)stmts.get(i)).resetSavePoint();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Let the context deal with a rollback to savepoint\r
+        *\r
+        * @param       savepointName   Name of the savepoint that needs to be rolled back\r
+        * @param       refreshStyle    boolean indicating whether or not the controller should close\r
+        * open conglomerates and scans. Also used to determine if language should close\r
+        * open activations.\r
+        * @param       kindOfSavepoint  A NULL value means it is an internal savepoint (ie not a user defined savepoint)\r
+        * Non NULL value means it is a user defined savepoint which can be a SQL savepoint or a JDBC savepoint\r
+        *   A String value for kindOfSavepoint would mean it is SQL savepoint\r
+        *   A JDBC Savepoint object value for kindOfSavepoint would mean it is JDBC savepoint\r
+        *\r
+        * @exception StandardException thrown if something goes wrong\r
+        */\r
+       public void internalRollbackToSavepoint( String savepointName, boolean refreshStyle, Object kindOfSavepoint )\r
+               throws StandardException\r
+       {\r
+               // now rollback the Store transaction to the savepoint\r
+               TransactionController tc = getTransactionExecute();\r
+               if (tc != null)\r
+               {\r
+                       boolean         closeConglomerates;\r
+\r
+                       if ( refreshStyle ) \r
+                       {\r
+                               closeConglomerates = true;\r
+                               // bug 5145 - don't forget to close the activations while rolling\r
+                               // back to a savepoint\r
+                               endTransactionActivationHandling(true);\r
+                       }\r
+                       else { closeConglomerates = false; }\r
+\r
+                       currentSavepointLevel = tc.rollbackToSavePoint( savepointName, closeConglomerates, kindOfSavepoint );\r
+               }\r
+\r
+               if (tc != null && refreshStyle && allDeclaredGlobalTempTables != null)\r
+                       tempTablesAndRollback();\r
+       }\r
+\r
+       /**\r
+         Let the context deal with a release of a savepoint\r
+\r
+         @param        savepointName   Name of the savepoint that needs to be released\r
+         @param        kindOfSavepoint  A NULL value means it is an internal savepoint (ie not a user defined savepoint)\r
+         Non NULL value means it is a user defined savepoint which can be a SQL savepoint or a JDBC savepoint\r
+         A String value for kindOfSavepoint would mean it is SQL savepoint\r
+         A JDBC Savepoint object value for kindOfSavepoint would mean it is JDBC savepoint\r
+\r
+         @exception StandardException thrown if something goes wrong\r
+        */\r
+       public  void    releaseSavePoint( String savepointName, Object kindOfSavepoint )  throws StandardException\r
+       {\r
+               TransactionController tc = getTransactionExecute();\r
+               if (tc != null)\r
+               {\r
+                       currentSavepointLevel = tc.releaseSavePoint( savepointName, kindOfSavepoint );\r
+                       //after a release of a savepoint, we need to go through our temp tables list.\r
+                       if (allDeclaredGlobalTempTables != null)\r
+                               tempTablesReleaseSavepointLevels();\r
+               }\r
+       }\r
+\r
+       /**\r
+         Sets a savepoint. Causes the Store to set a savepoint.\r
+\r
+         @param        savepointName   name of savepoint\r
+         @param        kindOfSavepoint  A NULL value means it is an internal savepoint (ie not a user defined savepoint)\r
+         Non NULL value means it is a user defined savepoint which can be a SQL savepoint or a JDBC savepoint\r
+         A String value for kindOfSavepoint would mean it is SQL savepoint\r
+         A JDBC Savepoint object value for kindOfSavepoint would mean it is JDBC savepoint\r
+\r
+               @exception StandardException thrown if something goes wrong\r
+         */\r
+       public  void    languageSetSavePoint( String savepointName, Object kindOfSavepoint )  throws StandardException\r
+       {\r
+               TransactionController tc = getTransactionExecute();\r
+               if (tc != null)\r
+               {\r
+                       currentSavepointLevel = tc.setSavePoint( savepointName, kindOfSavepoint );\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Start a Nested User Transaction (NUT) with the store. If a NUT is \r
+        * already active simply increment a counter, queryNestingDepth, to keep\r
+        * track of how many times we have tried to start a NUT.\r
+        */\r
+       public void beginNestedTransaction(boolean readOnly) throws StandardException\r
+       {\r
+        // DERBY-2490 incremental rework, currently this is only called\r
+        // with read-only true. Future changes will have this\r
+        // method support read-write nested transactions as well\r
+        // instead of callers using the startNestedUserTransaction\r
+        // directly on tran.\r
+               if (readOnlyNestedTransaction == null)\r
+                       readOnlyNestedTransaction = tran.startNestedUserTransaction(readOnly);\r
+               queryNestingDepth++;\r
+       }\r
+\r
+       public void commitNestedTransaction()\r
+               throws StandardException\r
+       {\r
+               if (--queryNestingDepth == 0)\r
+               {\r
+                       readOnlyNestedTransaction.commit();\r
+                       readOnlyNestedTransaction.destroy();\r
+                       readOnlyNestedTransaction = null;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Get the transaction controller to use at compile time with this language\r
+        * connection context. If a NUT is active then return NUT else return parent\r
+        * transaction.\r
+        */\r
+       public TransactionController getTransactionCompile()\r
+       {\r
+               return (readOnlyNestedTransaction != null) ? readOnlyNestedTransaction : tran;\r
+       }\r
+\r
+       public TransactionController getTransactionExecute()\r
+       {\r
+               return tran;\r
+       }\r
+\r
+ /** Get the data value factory to use with this language connection\r
+               context.\r
+        */\r
+       public DataValueFactory getDataValueFactory() {\r
+               return dataFactory;\r
+       }\r
+       \r
+       /**\r
+               Get the language factory to use with this language connection\r
+               context.\r
+        */\r
+       public LanguageFactory getLanguageFactory() {\r
+               return langFactory;\r
+       }\r
+               \r
+       public OptimizerFactory getOptimizerFactory() {\r
+               return of;\r
+       }\r
+\r
+       /**\r
+               Get the language connection factory to use with this language connection\r
+               context.\r
+        */\r
+       public LanguageConnectionFactory getLanguageConnectionFactory() {\r
+               return connFactory;\r
+       }\r
+\r
+       /**\r
+        * check if there are any activations that reference this temporary table\r
+        * @param tableName look for any activations referencing this table name\r
+        * @return boolean  false if found no activations\r
+        */\r
+       private boolean checkIfAnyActivationHasHoldCursor(String tableName)\r
+                       throws StandardException\r
+       {\r
+               for (int i = acts.size() - 1; i >= 0; i--) {\r
+                       Activation a = (Activation) acts.get(i);\r
+                       if (a.checkIfThisActivationHasHoldCursor(tableName))\r
+                               return true;\r
+    }\r
+    return false;\r
+       }\r
+\r
+\r
+       /**\r
+        * Verify that there are no activations with open held result sets.\r
+        *\r
+        * @return boolean  Found no open (held) resultsets.\r
+        *\r
+        * @exception StandardException thrown on failure\r
+        */\r
+       /* This gets used in case of hold cursors. If there are any hold cursors open\r
+        * then user can't change the isolation level without closing them. At the\r
+        * execution time, set transaction isolation level calls this method before\r
+        * changing the isolation level.\r
+        */\r
+       public boolean verifyAllHeldResultSetsAreClosed()\r
+                       throws StandardException\r
+       {\r
+               boolean seenOpenResultSets = false;\r
+\r
+               /* For every activation */\r
+               for (int i = acts.size() - 1; i >= 0; i--) {\r
+\r
+                       Activation a = (Activation) acts.get(i);\r
+\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               SanityManager.ASSERT(a instanceof CursorActivation, "a is not a CursorActivation");\r
+                       }\r
+\r
+                       if (!a.isInUse())\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       if (!a.getResultSetHoldability())\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       ResultSet rs = ((CursorActivation) a).getResultSet();\r
+\r
+                       /* is there an open result set? */\r
+                       if ((rs != null) && !rs.isClosed() && rs.returnsRows())\r
+                       {\r
+                               seenOpenResultSets = true;\r
+                               break;\r
+                       }\r
+               }\r
+\r
+               if (!seenOpenResultSets)\r
+                       return(true);\r
+\r
+               // There may be open ResultSet's that are yet to be garbage collected\r
+               // let's try and force these out rather than throw an error\r
+               System.gc();\r
+               System.runFinalization();\r
+\r
+\r
+               /* For every activation */\r
+               for (int i = acts.size() - 1; i >= 0; i--) {\r
+                               \r
+                       Activation a = (Activation) acts.get(i);\r
+\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               SanityManager.ASSERT(a instanceof CursorActivation, "a is not a CursorActivation");\r
+                       }\r
+\r
+                       if (!a.isInUse())\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       if (!a.getResultSetHoldability())\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       ResultSet rs = ((CursorActivation) a).getResultSet();\r
+\r
+                       /* is there an open held result set? */\r
+                       if ((rs != null) && !rs.isClosed() && rs.returnsRows())\r
+                       {\r
+                               return(false);\r
+                       }\r
+               }\r
+               return(true);\r
+       }\r
+\r
+       /**\r
+        * Verify that there are no activations with open result sets\r
+        * on the specified prepared statement.\r
+        *\r
+        * @param pStmt         The prepared Statement\r
+        * @param provider      The object precipitating a possible invalidation\r
+        * @param action        The action causing the possible invalidation\r
+        *\r
+        * @return Nothing.\r
+        *\r
+        * @exception StandardException thrown on failure\r
+        */\r
+       public boolean verifyNoOpenResultSets(PreparedStatement pStmt, Provider provider,\r
+                                                                          int action)\r
+                       throws StandardException\r
+       {\r
+               /*\r
+               ** It is not a problem to create an index when there is an open\r
+               ** result set, since it doesn't invalidate the access path that was\r
+               ** chosen for the result set.\r
+               */\r
+               boolean seenOpenResultSets = false;\r
+\r
+               /* For every activation */\r
+\r
+               // synchronize on acts as other threads may be closing activations\r
+               // in this list, thus invalidating the Enumeration\r
+               for (int i = acts.size() - 1; i >= 0; i--) {\r
+                               \r
+                       Activation a = (Activation) acts.get(i);\r
+\r
+                       if (!a.isInUse())\r
+                       {\r
+                               continue;\r
+                       }\r
+                       \r
+                       /* for this prepared statement */\r
+                       if (pStmt == a.getPreparedStatement()) {\r
+                               ResultSet rs = a.getResultSet();\r
+\r
+                               /* is there an open result set? */\r
+                               if (rs != null && ! rs.isClosed())\r
+                               {\r
+                                       if (!rs.returnsRows())\r
+                                               continue;\r
+                                       seenOpenResultSets = true;\r
+                                       break;\r
+                               }\r
+                               \r
+                       }\r
+               }\r
+\r
+               if (!seenOpenResultSets)\r
+                       return false;\r
+\r
+               // There may be open ResultSet's that are yet to be garbage collected\r
+               // let's try and force these out rather than throw an error\r
+               System.gc();\r
+               System.runFinalization();\r
+\r
+\r
+               /* For every activation */\r
+               // synchronize on acts as other threads may be closing activations\r
+               // in this list, thus invalidating the Enumeration\r
+               for (int i = acts.size() - 1; i >= 0; i--) {\r
+                               \r
+                       Activation a = (Activation) acts.get(i);\r
+\r
+                       if (!a.isInUse())\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       /* for this prepared statement */\r
+                       if (pStmt == a.getPreparedStatement()) {\r
+                               ResultSet rs = a.getResultSet();\r
+\r
+                               /* is there an open result set? */\r
+                               if (rs != null && ! rs.isClosed())\r
+                               {\r
+                                       if ((provider != null) && rs.returnsRows()) {\r
+                                       DependencyManager dmgr = getDataDictionary().getDependencyManager();\r
+\r
+                                       throw StandardException.newException(SQLState.LANG_CANT_INVALIDATE_OPEN_RESULT_SET, \r
+                                                                       dmgr.getActionString(action), \r
+                                                                       provider.getObjectName());\r
+\r
+                                       }\r
+                                       return true;\r
+                               }\r
+                       }\r
+               }\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        *      Get the Authorization Id\r
+        *\r
+        * @return String       the authorization id\r
+        */\r
+       public String getAuthorizationId()\r
+       { \r
+               return authorizer.getAuthorizationId();\r
+       }\r
+\r
+       /**\r
+        *      Get the default schema\r
+        *\r
+        * @return SchemaDescriptor     the default schema\r
+        */\r
+       public SchemaDescriptor getDefaultSchema() \r
+       { \r
+               return sd; \r
+       }\r
+       /**\r
+        * Get the current schema name\r
+        *\r
+        * @return current schema name\r
+        */\r
+       public String getCurrentSchemaName()\r
+       {\r
+        if( null == sd)\r
+            return null;\r
+               return sd.getSchemaName();\r
+       }\r
+\r
+       /**\r
+        * Set the default schema -- used by SET SCHEMA.\r
+        * \r
+        * @param sd the new default schema.\r
+        * If null, then the default schema descriptor is used.\r
+        *\r
+        * @exception StandardException thrown on failure\r
+        */\r
+       public void setDefaultSchema(SchemaDescriptor sd)\r
+               throws StandardException\r
+       {       \r
+               if (sd == null)\r
+               {       \r
+                   sd = initDefaultSchemaDescriptor();\r
+               }\r
+               this.sd = sd;\r
+               \r
+       }\r
+\r
+       /**\r
+        * Get the identity column value most recently generated.\r
+        *\r
+        * @return the generated identity column value\r
+        */\r
+       public Long getIdentityValue()\r
+       {\r
+               return identityNotNull ? new Long(identityVal) : null;\r
+       }\r
+\r
+       /**\r
+        * Set the field of most recently generated identity column value.\r
+        *\r
+        * @param val the generated identity column value\r
+        */\r
+       public void setIdentityValue(long val)\r
+       {\r
+               identityVal = val;\r
+               identityNotNull = true;\r
+       }\r
+\r
+       /**\r
+        * Push a CompilerContext on the context stack with\r
+        * the current default schema as the default schema\r
+        * which we compile against.\r
+        *\r
+        * @return the compiler context\r
+        *\r
+        * @exception StandardException thrown on failure\r
+        */\r
+       public  final CompilerContext pushCompilerContext()\r
+       {\r
+               return pushCompilerContext((SchemaDescriptor)null);\r
+       }\r
+\r
+       /**\r
+        * Push a CompilerContext on the context stack with\r
+        * the passed in schema sd as the default schema\r
+        * we compile against.\r
+        *\r
+        * @param sd the default schema \r
+        *\r
+        * @return the compiler context\r
+        *\r
+        * For the parameter sd, there are 3 possible values(of interest) that can \r
+        * get passed into this method:\r
+        * \r
+        * a) A null SchemaDescriptor which indicates to the system to use the \r
+        *    CURRENT SCHEMA as the compilation schema.\r
+        *    \r
+        * b) A SchemaDescriptor with its UUID == null, this indicates that either \r
+        *    the schema has not been physically created yet or that the LCC's \r
+        *    getDefaultSchema() is not yet up-to-date with its actual UUID. \r
+        *    The system will use the CURRENT SCHEMA as the compilation schema. \r
+        *    \r
+        * c) A SchemaDescriptor with its UUID != null, this means that the schema \r
+        *    has been physically created.  The system will use this schema as the \r
+        *    compilation schema (e.g.: for trigger or view recompilation cases, \r
+        *    etc.). \r
+        *    \r
+        * The compiler context's compilation schema will be set accordingly based \r
+        * on the given input above.   \r
+        */\r
+       public  CompilerContext pushCompilerContext(SchemaDescriptor sd)\r
+       {\r
+               CompilerContext cc;\r
+               boolean                 firstCompilerContext = false;\r
+\r
+               //      DEBUG   END\r
+\r
+               cc = (CompilerContext) (getContextManager().getContext(CompilerContext.CONTEXT_ID));\r
+\r
+               /*\r
+               ** If there is no compiler context, this is the first one on the\r
+               ** stack, so don't pop it when we're done (saves time).\r
+               */\r
+               if (cc == null) { firstCompilerContext = true; }\r
+\r
+               if (cc == null || cc.getInUse())\r
+               {\r
+                       cc = new CompilerContextImpl(getContextManager(), this, tcf);\r
+                       if (firstCompilerContext) { cc.firstOnStack(); }\r
+               }\r
+               else\r
+               {\r
+                       /* Reset the next column,table, subquery and ResultSet numbers at \r
+                       * the beginning of each statement \r
+                       */\r
+                       cc.resetContext();\r
+               }\r
+\r
+               cc.setInUse(true);\r
+\r
+               // Save off the current isolation level on entry so that it gets restored\r
+               cc.setEntryIsolationLevel( getCurrentIsolationLevel());\r
+\r
+               StatementContext sc = getStatementContext();\r
+               if (sc.getSystemCode())\r
+                       cc.setReliability(CompilerContext.INTERNAL_SQL_LEGAL);\r
+\r
+               /*\r
+                * Set the compilation schema when its UUID is available.\r
+                * i.e.:  Schema may not have been physically created yet, so\r
+                *        its UUID will be null.\r
+                * \r
+                * o For trigger SPS recompilation, the system must use its\r
+                *   compilation schema to recompile the statement. \r
+                * \r
+                * o For view recompilation, we set the compilation schema\r
+                *   for this compiler context if its UUID is available.\r
+                *   Otherwise, the compilation schema will be determined\r
+                *   at execution time of view creation.\r
+                */\r
+               if (sd != null && sd.getUUID() != null)\r
+               {\r
+                       cc.setCompilationSchema(sd);\r
+               }\r
+               \r
+               return  cc;\r
+       }\r
+\r
+\r
+       /**\r
+        * Pop a CompilerContext off the context stack.\r
+        *\r
+        * @param cc  The compiler context.\r
+        */\r
+       public void popCompilerContext(CompilerContext cc)\r
+       {\r
+               cc.setCurrentDependent(null);\r
+\r
+               cc.setInUse(false);\r
+\r
+               // Restore the isolation level at the time of entry to CompilerContext\r
+               isolationLevel = cc.getEntryIsolationLevel();\r
+\r
+               /*\r
+               ** Only pop the compiler context if it's not the first one\r
+               ** on the stack.\r
+               */\r
+               if (! cc.isFirstOnStack()) \r
+               { \r
+                       cc.popMe(); \r
+               }\r
+               else\r
+               {\r
+                       cc.setCompilationSchema((SchemaDescriptor)null);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Push a StatementContext on the context stack.\r
+        *\r
+        * @param isAtomic whether this statement is atomic or not\r
+        * @param isForReadOnly whether this statement is for a read only resultset\r
+        * @param stmtText the text of the statement.  Needed for any language\r
+        *      statement (currently, for any statement that can cause a trigger\r
+        *      to fire).  Please set this unless you are some funky jdbc setXXX\r
+        *      method or something.\r
+        * @param pvs parameter value set, if it has one\r
+        * @param rollbackParentContext True if 1) the statement context is\r
+        *      NOT a top-level context, AND 2) in the event of a statement-level\r
+        *      exception, the parent context needs to be rolled back, too.\r
+     * @param timeoutMillis timeout value for this statement, in milliseconds.\r
+     *  The value 0 means that no timeout is set.\r
+        *\r
+        * @return StatementContext  The statement context.\r
+        *\r
+        */\r
+       public StatementContext pushStatementContext (boolean isAtomic, boolean isForReadOnly, \r
+                                                     String stmtText, ParameterValueSet pvs, \r
+                                                     boolean rollbackParentContext, \r
+                                                     long timeoutMillis)\r
+       {\r
+               int                                     parentStatementDepth = statementDepth;\r
+               boolean                         inTrigger = false;\r
+               boolean                         parentIsAtomic = false;\r
+\r
+               // by default, assume we are going to use the outermost statement context\r
+               StatementContext        statementContext = statementContexts[0];\r
+\r
+               /*\r
+               ** If we haven't allocated any statement contexts yet, allocate\r
+               ** the outermost stmt context now and push it.\r
+               */\r
+               if (statementContext == null)\r
+               {\r
+                       statementContext = statementContexts[0] = new GenericStatementContext(this);\r
+               }\r
+               else if (statementDepth > 0)\r
+               {\r
+                       StatementContext        parentStatementContext;\r
+                       /*\r
+                       ** We also cache a 2nd statement context, though we still\r
+                       ** push and pop it. Note, new contexts are automatically pushed.\r
+                       */\r
+                       if (statementDepth == 1)\r
+                       {\r
+                               statementContext = statementContexts[1];\r
+\r
+                               if (statementContext == null)\r
+                                       statementContext = statementContexts[1] = new GenericStatementContext(this);\r
+                               else\r
+                                       statementContext.pushMe();\r
+\r
+                               parentStatementContext = statementContexts[0];\r
+                       }\r
+                       else\r
+                       {\r
+                               parentStatementContext = getStatementContext();\r
+                               statementContext = new GenericStatementContext(this);\r
+                       }\r
+\r
+                       inTrigger = parentStatementContext.inTrigger() || (outermostTrigger == parentStatementDepth);\r
+                       parentIsAtomic = parentStatementContext.isAtomic();\r
+                       statementContext.setSQLAllowed(parentStatementContext.getSQLAllowed(), false);\r
+                       if (parentStatementContext.getSystemCode())\r
+                               statementContext.setSystemCode();\r
+               }\r
+\r
+               incrementStatementDepth();\r
+\r
+               statementContext.setInUse(inTrigger, isAtomic || parentIsAtomic, isForReadOnly, stmtText, pvs, timeoutMillis);\r
+               if (rollbackParentContext)\r
+                       statementContext.setParentRollback();\r
+               return statementContext;\r
+       }\r
+\r
+       /**\r
+        * Pop a StatementContext of the context stack.\r
+        *\r
+        * @param statementContext  The statement context.\r
+        * @param error                         The error, if any  (Only relevant for DEBUG)\r
+        */\r
+       public void popStatementContext(StatementContext statementContext,\r
+                                                                       Throwable error) \r
+       {\r
+               if ( statementContext != null ) \r
+               { \r
+                       /*\r
+                       ** If someone beat us to the punch, then it is ok,\r
+                       ** just silently ignore it.  We probably got here\r
+                       ** because we had a try catch block around a push/pop\r
+                       ** statement context, and we already got the context\r
+                       ** on a cleanupOnError.\r
+                       */\r
+                       if (!statementContext.inUse())\r
+                       {\r
+                               return;\r
+                       }\r
+                       statementContext.clearInUse(); \r
+               }\r
+\r
+               decrementStatementDepth();\r
+               if (statementDepth == -1)\r
+               {\r
+                       /*\r
+                        * Only ignore the pop request for an already\r
+                        * empty stack when dealing with a session exception.\r
+                        */\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               int severity = (error instanceof StandardException) ?\r
+                                                                       ((StandardException)error).getSeverity() :\r
+                                                               0;\r
+                               SanityManager.ASSERT(error != null,\r
+                                       "Must have error to try popStatementContext with 0 depth");\r
+                               SanityManager.ASSERT(\r
+                                       (severity == ExceptionSeverity.SESSION_SEVERITY),\r
+                                       "Must have session severity error to try popStatementContext with 0 depth");\r
+                               SanityManager.ASSERT(statementContext == statementContexts[0],\r
+                                       "statementContext is expected to equal statementContexts[0]");\r
+                       }\r
+                       resetStatementDepth(); // pretend we did nothing.\r
+               }\r
+               else if (statementDepth == 0)\r
+               {\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               /* Okay to pop last context on a session exception.\r
+                                * (We call clean up on error when exiting connection.)\r
+                                */\r
+                               int severity = (error instanceof StandardException) ?\r
+                                                                       ((StandardException)error).getSeverity() :\r
+                                                               0;\r
+                               if ((error == null) || \r
+                                       (severity != ExceptionSeverity.SESSION_SEVERITY))\r
+                               {\r
+                                       SanityManager.ASSERT(statementContext == statementContexts[0],\r
+                                               "statementContext is expected to equal statementContexts[0]");\r
+                               }\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               SanityManager.ASSERT(statementContext != statementContexts[0],\r
+                                       "statementContext is not expected to equal statementContexts[0]");\r
+                               if (statementDepth <= 0)\r
+                                       SanityManager.THROWASSERT(\r
+                                               "statement depth expected to be >0, was "+statementDepth);\r
+                \r
+                if (getContextManager().getContext(statementContext.getIdName()) != statementContext)\r
+                {\r
+                    SanityManager.THROWASSERT("trying to pop statement context from middle of stack");\r
+                }\r
+                       }\r
+\r
+            statementContext.popMe();          \r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Push a new execution statement validator.  An execution statement \r
+        * validator is an object that validates the current statement to\r
+        * ensure that it is permitted given the current execution context.\r
+        * An example of a validator a trigger ExecutionStmtValidator that\r
+        * doesn't allow ddl on the trigger target table.\r
+        * <p>\r
+        * Multiple ExecutionStmtValidators may be active at any given time.\r
+        * This mirrors the way there can be multiple connection nestings\r
+        * at a single time.  The validation is performed by calling each\r
+        * validator's validateStatement() method.  This yields the union\r
+        * of all validations.\r
+        *\r
+        * @param validator the validator to add\r
+        */\r
+       public void pushExecutionStmtValidator(ExecutionStmtValidator validator)\r
+       {\r
+               stmtValidators.add(validator);\r
+       }\r
+\r
+       /**\r
+        * Remove the validator.  Does an object identity (validator == validator)\r
+        * comparison.  Asserts that the validator is found.\r
+        *\r
+        * @param validator the validator to remove\r
+        *\r
+        * @exception StandardException on error\r
+        */\r
+       public void popExecutionStmtValidator(ExecutionStmtValidator validator)\r
+               throws StandardException\r
+       {\r
+               boolean foundElement = stmtValidators.remove(validator);\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (!foundElement)\r
+                       {\r
+                               SanityManager.THROWASSERT("statement validator "+validator+" not found");\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Push a new trigger execution context.\r
+        * <p>\r
+        * Multiple TriggerExecutionContexts may be active at any given time.\r
+        *\r
+        * @param tec the trigger execution context\r
+        *\r
+        * @exception StandardException on trigger recursion error\r
+        */\r
+       public void pushTriggerExecutionContext(TriggerExecutionContext tec) throws StandardException\r
+       {\r
+               if (outermostTrigger == -1) \r
+               {\r
+                       outermostTrigger = statementDepth; \r
+               }\r
+\r
+               /* Maximum 16 nesting levels allowed */\r
+               if (triggerExecutionContexts.size() >= Limits.DB2_MAX_TRIGGER_RECURSION)\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_TRIGGER_RECURSION_EXCEEDED);\r
+               }\r
+\r
+               triggerExecutionContexts.add(tec);\r
+       }\r
+\r
+       /**\r
+        * Remove the tec.  Does an object identity (tec == tec)\r
+        * comparison.  Asserts that the tec is found.\r
+        *\r
+        * @param tec the tec to remove\r
+        *\r
+        * @exception StandardException on error\r
+        */\r
+       public void popTriggerExecutionContext(TriggerExecutionContext tec)\r
+               throws StandardException\r
+       {\r
+               if (outermostTrigger == statementDepth)\r
+               {\r
+                       outermostTrigger = -1; \r
+               }\r
+\r
+               boolean foundElement = triggerExecutionContexts.remove(tec);\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (!foundElement)\r
+                       {\r
+                               SanityManager.THROWASSERT("trigger execution context "+tec+" not found");\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Get the topmost tec.  \r
+        *\r
+        * @return the tec\r
+        */\r
+       public TriggerExecutionContext getTriggerExecutionContext()\r
+       {\r
+               return triggerExecutionContexts.size() == 0 ? \r
+                               (TriggerExecutionContext)null :\r
+                               (TriggerExecutionContext)triggerExecutionContexts.get(\r
+                                       triggerExecutionContexts.size() - 1);   \r
+       }\r
+\r
+       /**\r
+        * Validate a statement.  Does so by stepping through all the validators\r
+        * and executing them.  If a validator throws and exception, then the\r
+        * checking is stopped and the exception is passed up.\r
+        *\r
+        * @param constantAction the constantAction that is about to be executed (and\r
+        *      should be validated\r
+        *\r
+        * @exception StandardException on validation failure\r
+        */\r
+       public void validateStmtExecution(ConstantAction constantAction)\r
+               throws StandardException\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT(constantAction!=null, "constantAction is null");\r
+               }\r
+\r
+               if (stmtValidators.size() > 0)\r
+               {\r
+                       for (Iterator it = stmtValidators.iterator(); it.hasNext(); )\r
+                       {\r
+                               ((ExecutionStmtValidator)it.next())\r
+                                       .validateStatement(constantAction);\r
+                       }\r
+               }\r
+       }\r
+       \r
+       /**\r
+        * Set the trigger table descriptor.  Used to compile\r
+        * statements that may special trigger pseudo tables.\r
+        *\r
+        * @param td the table that the trigger is \r
+        * defined upon\r
+        *\r
+        */\r
+       public void pushTriggerTable(TableDescriptor td)\r
+       {\r
+               triggerTables.add(td);\r
+       }\r
+\r
+       /**\r
+        * Remove the trigger table descriptor.\r
+        *\r
+        * @param td the table to remove from the stack.\r
+        */\r
+       public void popTriggerTable(TableDescriptor td)\r
+       {\r
+               boolean foundElement = triggerTables.remove(td);\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (!foundElement)\r
+                       {\r
+                               SanityManager.THROWASSERT("trigger table not found: "+td);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Get the topmost trigger table descriptor\r
+        *\r
+        * @return the table descriptor, or null if we\r
+        * aren't in the middle of compiling a create\r
+        * trigger.\r
+        */\r
+       public TableDescriptor getTriggerTable()\r
+       {\r
+               return triggerTables.size() == 0 ? \r
+                       (TableDescriptor)null :\r
+                       (TableDescriptor)triggerTables.get(triggerTables.size() - 1);\r
+       }\r
+       /**\r
+        * @see LanguageConnectionContext#getDatabase\r
+        */\r
+       public Database\r
+       getDatabase()\r
+       {\r
+               return db;\r
+       }\r
+\r
+       /** @see LanguageConnectionContext#incrementBindCount */\r
+       public int incrementBindCount()\r
+       {\r
+               bindCount++;\r
+               return bindCount;\r
+       }\r
+\r
+       \r
+       /** @see LanguageConnectionContext#decrementBindCount */\r
+       public int decrementBindCount()\r
+       {\r
+               bindCount--;\r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (bindCount < 0)\r
+                               SanityManager.THROWASSERT(\r
+                                       "Level of nested binding == " + bindCount);\r
+               }\r
+\r
+               return bindCount;\r
+       }\r
+\r
+       /** @see LanguageConnectionContext#getBindCount */\r
+       public int getBindCount()\r
+       {\r
+               return bindCount;\r
+       }\r
+\r
+       /** @see LanguageConnectionContext#setDataDictionaryWriteMode */\r
+       public final void setDataDictionaryWriteMode()\r
+       {\r
+               ddWriteMode = true;\r
+       }\r
+\r
+       /** @see LanguageConnectionContext#dataDictionaryInWriteMode */\r
+       public final boolean dataDictionaryInWriteMode()\r
+       {\r
+               return ddWriteMode;\r
+       }\r
+\r
+       /** @see LanguageConnectionContext#setRunTimeStatisticsMode */\r
+       public void setRunTimeStatisticsMode(boolean onOrOff)\r
+       {\r
+               runTimeStatisticsSetting = onOrOff;\r
+       }\r
+\r
+       /** @see LanguageConnectionContext#getRunTimeStatisticsMode */\r
+       public boolean getRunTimeStatisticsMode()\r
+       {\r
+               return runTimeStatisticsSetting;\r
+       }\r
+\r
+       /** @see LanguageConnectionContext#setStatisticsTiming */\r
+       public void setStatisticsTiming(boolean onOrOff)\r
+       {\r
+               statisticsTiming = onOrOff;\r
+       }\r
+\r
+       /** @see LanguageConnectionContext#getStatisticsTiming */\r
+       public boolean getStatisticsTiming()\r
+       {\r
+               return statisticsTiming;\r
+       }\r
+\r
+       /** @see LanguageConnectionContext#setRunTimeStatisticsObject */\r
+       public void setRunTimeStatisticsObject(RunTimeStatistics runTimeStatisticsObject)\r
+       {\r
+               this.runTimeStatisticsObject = runTimeStatisticsObject;\r
+       }\r
+\r
+       /** @see LanguageConnectionContext#getRunTimeStatisticsObject */\r
+       public RunTimeStatistics getRunTimeStatisticsObject()\r
+       {\r
+               return runTimeStatisticsObject;\r
+       }\r
+\r
+\r
+    /**\r
+         *     Reports how many statement levels deep we are.\r
+         *\r
+         *     @return a statement level >= OUTERMOST_STATEMENT\r
+         */\r
+       public  int             getStatementDepth()\r
+       { return statementDepth; }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#isIsolationLevelSetUsingSQLorJDBC\r
+        */\r
+       public boolean isIsolationLevelSetUsingSQLorJDBC()\r
+       {\r
+               return isolationLevelSetUsingSQLorJDBC;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#resetIsolationLevelFlagUsedForSQLandJDBC\r
+        */\r
+       public void resetIsolationLevelFlagUsedForSQLandJDBC()\r
+       {\r
+               isolationLevelSetUsingSQLorJDBC = false;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#setIsolationLevel\r
+        */\r
+       public void setIsolationLevel(int isolationLevel) throws StandardException\r
+       {\r
+               StatementContext stmtCtxt = getStatementContext();\r
+               if (stmtCtxt!= null && stmtCtxt.inTrigger())\r
+                       throw StandardException.newException(SQLState.LANG_NO_XACT_IN_TRIGGER, getTriggerExecutionContext().toString());\r
+\r
+               // find if there are any held cursors from previous isolation level.\r
+               // if yes, then throw an exception that isolation change not allowed until\r
+               // the held cursors are closed.\r
+               // I had to move this check outside of transaction idle check because if a\r
+               // transactions creates held cursors and commits the transaction, then\r
+               // there still would be held cursors but the transaction state would be idle.\r
+               // In order to check the above mentioned case, the held cursor check\r
+               // shouldn't rely on transaction state.\r
+               if (this.isolationLevel != isolationLevel)\r
+               {\r
+                       if (!verifyAllHeldResultSetsAreClosed())\r
+                       {\r
+                               throw StandardException.newException(SQLState.LANG_CANT_CHANGE_ISOLATION_HOLD_CURSOR);\r
+                       }\r
+               }\r
+\r
+               /* Commit and set to new isolation level.\r
+                * NOTE: We commit first in case there's some kind\r
+                * of error, like can't commit within a server side jdbc call.\r
+                */\r
+               TransactionController tc = getTransactionExecute();\r
+               if (!tc.isIdle())\r
+               {\r
+                       // If this transaction is in progress, commit it.\r
+                       // However, do not allow commit to happen if this is a global\r
+                       // transaction.\r
+                       if (tc.isGlobal())\r
+                               throw StandardException.newException(SQLState.LANG_NO_SET_TRAN_ISO_IN_GLOBAL_CONNECTION);\r
+\r
+                       userCommit();\r
+               }\r
+               this.isolationLevel = isolationLevel;\r
+               this.isolationLevelExplicitlySet = true;\r
+               this.isolationLevelSetUsingSQLorJDBC = true;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#getCurrentIsolationLevel\r
+        */\r
+       public int getCurrentIsolationLevel()\r
+       {\r
+               return (isolationLevel == ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL) ? defaultIsolationLevel : isolationLevel;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#getCurrentIsolationLevel\r
+        */\r
+       public String getCurrentIsolationLevelStr()\r
+       {\r
+        if( isolationLevel >= 0 && isolationLevel < ExecutionContext.CS_TO_SQL_ISOLATION_MAP.length)\r
+            return ExecutionContext.CS_TO_SQL_ISOLATION_MAP[ isolationLevel][0];\r
+        return ExecutionContext.CS_TO_SQL_ISOLATION_MAP[ ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL][0];\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#setPrepareIsolationLevel\r
+        */\r
+       public void setPrepareIsolationLevel(int level) \r
+       {\r
+                       prepareIsolationLevel = level;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#getPrepareIsolationLevel\r
+        */\r
+       public int getPrepareIsolationLevel()\r
+       {\r
+               if (!isolationLevelExplicitlySet)\r
+                       return prepareIsolationLevel;\r
+               else\r
+                       return ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#getExecutionContext\r
+        */\r
+       public ExecutionContext getExecutionContext()\r
+       {\r
+               return (ExecutionContext) getContextManager().getContext(ExecutionContext.CONTEXT_ID);\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#getStatementContext\r
+        */\r
+       public StatementContext getStatementContext()\r
+       {       \r
+               return (StatementContext) getContextManager().getContext(org.apache.derby.iapi.reference.ContextId.LANG_STATEMENT);\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#setOptimizerTrace\r
+        */\r
+       public boolean setOptimizerTrace(boolean onOrOff)\r
+       {\r
+               if (of == null)\r
+               {\r
+                       return false;\r
+               }\r
+               if (! of.supportsOptimizerTrace())\r
+               {\r
+                       return false;\r
+               }\r
+               optimizerTrace = onOrOff;\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#getOptimizerTrace\r
+        */\r
+       public boolean getOptimizerTrace()\r
+       {\r
+               return optimizerTrace;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#setOptimizerTraceHtml\r
+        */\r
+       public boolean setOptimizerTraceHtml(boolean onOrOff)\r
+       {\r
+               if (of == null)\r
+               {\r
+                       return false;\r
+               }\r
+               if (! of.supportsOptimizerTrace())\r
+               {\r
+                       return false;\r
+               }\r
+               optimizerTraceHtml = onOrOff;\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#getOptimizerTraceHtml\r
+        */\r
+       public boolean getOptimizerTraceHtml()\r
+       {\r
+               return optimizerTraceHtml;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#setOptimizerTraceOutput\r
+        */\r
+       public void setOptimizerTraceOutput(String startingText)\r
+       {\r
+               if (optimizerTrace)\r
+               {\r
+                       lastOptimizerTraceOutput = optimizerTraceOutput;\r
+                       optimizerTraceOutput = startingText;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#appendOptimizerTraceOutput\r
+        */\r
+       public void appendOptimizerTraceOutput(String output)\r
+       {\r
+               optimizerTraceOutput = \r
+                       (optimizerTraceOutput == null) ? output : optimizerTraceOutput + output;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#getOptimizerTraceOutput\r
+        */\r
+       public String getOptimizerTraceOutput()\r
+       {\r
+               return lastOptimizerTraceOutput;\r
+       }\r
+\r
+    /**\r
+         *     Reports whether there is any outstanding work in the transaction.\r
+         *\r
+         *     @return true if there is outstanding work in the transaction\r
+         *                             false otherwise\r
+         */\r
+       public  boolean isTransactionPristine()\r
+       {\r
+               return getTransactionExecute().isPristine();\r
+       }\r
+\r
+\r
+       //\r
+       // Context interface\r
+       //\r
+       /**\r
+               If worse than a transaction error, everything goes; we\r
+               rely on other contexts to kill the context manager\r
+               for this session.\r
+               <p>\r
+               If a transaction error, act like we saw a rollback.\r
+               <p>\r
+               If more severe or a java error, the outer cleanup\r
+               will shutdown the connection, so we don't have to clean up.\r
+               <p>\r
+               REMIND: connection should throw out all contexts and start\r
+               over when the connection is closed... perhaps by throwing\r
+               out the context manager?\r
+               <p>\r
+               REVISIT: If statement error, should we do anything?\r
+               <P>\r
+               Since the access manager's own context takes care of its own\r
+               resources on errors, there is nothing that this context has\r
+               to do with the transaction controller.\r
+\r
+               @exception StandardException thrown on error. REVISIT: don't want\r
+               cleanupOnError's to throw exceptions.\r
+        */\r
+       public void cleanupOnError(Throwable error) throws StandardException {\r
+\r
+               /*\r
+               ** If it isn't a StandardException, then assume\r
+               ** session severity. It is probably an unexpected\r
+               ** java error somewhere in the language.\r
+        ** Store layer treats JVM error as session severity, \r
+        ** hence to be consistent and to avoid getting rawstore\r
+        ** protocol violation errors, we treat java errors here\r
+        ** to be of session severity.\r
+        */  \r
+\r
+               int severity = (error instanceof StandardException) ?\r
+                       ((StandardException) error).getSeverity() :\r
+                       ExceptionSeverity.SESSION_SEVERITY;\r
\r
+               if (statementContexts[0] != null)\r
+               {\r
+                       statementContexts[0].clearInUse();\r
+            \r
+            // Force the StatementContext that's normally\r
+            // left on the stack for optimization to be popped\r
+            // when the session is closed. Ensures full cleanup\r
+            // and no hanging refrences in the ContextManager.\r
+            if (severity >= ExceptionSeverity.SESSION_SEVERITY)\r
+                statementContexts[0].popMe();\r
+               }\r
+               if (statementContexts[1] != null)\r
+               {\r
+                       statementContexts[1].clearInUse();                \r
+               }\r
+\r
+               // closing the activations closes all the open cursors.\r
+               // the activations are, for all intents and purposes, the\r
+               // cursors.\r
+               if (severity >= ExceptionSeverity.SESSION_SEVERITY) \r
+               {\r
+                       for (int i = acts.size() - 1; i >= 0; i--) {\r
+                               // it maybe the case that a reset()/close() ends up closing\r
+                               // one or more activation leaving our index beyond\r
+                               // the end of the array\r
+                               if (i >= acts.size())\r
+                                       continue;\r
+                               Activation a = (Activation) acts.get(i);\r
+                               a.reset();\r
+                               a.close();\r
+                       }\r
+                       \r
+                       popMe();\r
+               }\r
+\r
+               /*\r
+               ** We have some global state that we need\r
+               ** to clean up no matter what.  Be sure\r
+               ** to do so.\r
+               */\r
+               else if (severity >= ExceptionSeverity.TRANSACTION_SEVERITY) \r
+               {\r
+                       internalRollback();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @see org.apache.derby.iapi.services.context.Context#isLastHandler\r
+        */\r
+       public boolean isLastHandler(int severity)\r
+       {\r
+               return false;\r
+       }\r
+\r
+       //\r
+       // class implementation\r
+       //\r
+\r
+       /**\r
+               If we are called as part of rollback code path, then we will reset all \r
+               the activations that have resultset returning rows associated with \r
+               them. DERBY-3304 Resultsets that do not return rows should be left \r
+               alone when the rollback is through the JDBC Connection object. If the \r
+               rollback is caused by an exception, then at that time, all kinds of\r
+               resultsets should be closed. \r
+               \r
+               If we are called as part of commit code path, then we will do one of \r
+               the following if the activation has resultset assoicated with it. Also,\r
+               we will clear the conglomerate used while scanning for update/delete\r
+               1)Close result sets that return rows and are not held across commit.\r
+               2)Clear the current row of the resultsets that return rows and are\r
+               held across commit.\r
+               3)Leave the result sets untouched if they do not return rows\r
+               \r
+               Additionally, clean up (close()) activations that have been\r
+               marked as unused during statement finalization.\r
+\r
+               @exception StandardException thrown on failure\r
+        */\r
+       private void endTransactionActivationHandling(boolean forRollback) throws StandardException {\r
+\r
+               // don't use an enumeration as the activation may remove\r
+               // itself from the list, thus invalidating the Enumeration\r
+               for (int i = acts.size() - 1; i >= 0; i--) {\r
+\r
+                       // it maybe the case that a reset() ends up closing\r
+                       // one or more activation leaving our index beyond\r
+                       // the end of the array\r
+                       if (i >= acts.size())\r
+                               continue;\r
+\r
+                       Activation a = (Activation) acts.get(i);\r
+                       /*\r
+                       ** Look for stale activations.  Activations are\r
+                       ** marked as unused during statement finalization.\r
+                       ** Here, we sweep and remove this inactive ones.\r
+                       */      \r
+                       if (!a.isInUse())\r
+                       {\r
+                               a.close();\r
+                               continue;\r
+                       }\r
+\r
+                       //Determine if the activation has a resultset and if that resultset\r
+                       //returns rows. For such an activation, we need to take special\r
+                       //actions during commit and rollback as explained in the comments\r
+                       //below.\r
+                       ResultSet activationResultSet = a.getResultSet();\r
+                       boolean resultsetReturnsRows =  \r
+                               (activationResultSet != null) && activationResultSet.returnsRows(); ;\r
+\r
+                       if (forRollback) { \r
+                               if (resultsetReturnsRows)\r
+                                       //Since we are dealing with rollback, we need to reset \r
+                                       //the activation no matter what the holdability might \r
+                                       //be provided that resultset returns rows. An example\r
+                                       //where we do not want to close a resultset that does\r
+                                       //not return rows would be a java procedure which has\r
+                                       //user invoked rollback inside of it. That rollback\r
+                                       //should not reset the activation associated with\r
+                                       //the call to java procedure because that activation\r
+                                       //is still being used.\r
+                                       a.reset();\r
+                               // Only invalidate statements if we performed DDL.\r
+                               if (dataDictionaryInWriteMode()) {\r
+                                       ExecPreparedStatement ps = a.getPreparedStatement();\r
+                                       if (ps != null) {\r
+                                               ps.makeInvalid(DependencyManager.ROLLBACK, this);\r
+                                       }\r
+                               }\r
+                       } else {\r
+                               //We are dealing with commit here. \r
+                               if (resultsetReturnsRows){\r
+                                       if (a.getResultSetHoldability() == false)\r
+                                               //Close result sets that return rows and are not held \r
+                                               //across commit. This is to implement closing JDBC \r
+                                               //result sets that are CLOSE_CURSOR_ON_COMMIT at commit \r
+                                               //time. \r
+                                               activationResultSet.close();\r
+                                       else \r
+                                               //Clear the current row of the result sets that return\r
+                                               //rows and are held across commit. This is to implement\r
+                                               //keeping JDBC result sets open that are \r
+                                               //HOLD_CURSORS_OVER_COMMIT at commit time and marking\r
+                                               //the resultset to be not on a valid row position. The \r
+                                               //user will need to reposition within the resultset \r
+                                               //before doing any row operations.\r
+                                               activationResultSet.clearCurrentRow();                                                  \r
+                               }\r
+                               a.clearHeapConglomerateController();\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+               Finish the data dictionary transaction, if any.\r
+\r
+               @exception StandardException    Thrown on error\r
+        */\r
+       private void finishDDTransaction() throws StandardException {\r
+\r
+               /* Was the data dictionary put into write mode? */\r
+               if (ddWriteMode) {\r
+                       DataDictionary dd = getDataDictionary();\r
+\r
+                       /* Tell the data dictionary that the transaction is finished */\r
+                       dd.transactionFinished();\r
+\r
+                       /* The data dictionary isn't in write mode any more */\r
+                       ddWriteMode = false;\r
+               }\r
+       }\r
+\r
+       ////////////////////////////////////////////////////////////////////\r
+       //\r
+       //      MINIONS\r
+       //\r
+       ////////////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+         *     Increments the statement depth.\r
+         */\r
+    private    void    incrementStatementDepth() { statementDepth++; }\r
+\r
+    /**\r
+         * Decrements the statement depth\r
+         */\r
+       private void    decrementStatementDepth()\r
+       {\r
+               statementDepth--;\r
+       }\r
+\r
+       /**\r
+         *     Resets the statementDepth.\r
+         */\r
+       protected       void    resetStatementDepth()\r
+       {\r
+               statementDepth = 0;\r
+       }\r
+\r
+       public DataDictionary getDataDictionary()\r
+       {\r
+        return getDatabase().getDataDictionary();\r
+       }\r
+\r
+       /**\r
+         @see LanguageConnectionContext#setReadOnly\r
+         @exception StandardException The operation is disallowed.\r
+         */\r
+       public void setReadOnly(boolean on) throws StandardException\r
+       {\r
+               if (!tran.isPristine())\r
+                       throw StandardException.newException(SQLState.AUTH_SET_CONNECTION_READ_ONLY_IN_ACTIVE_XACT);\r
+               authorizer.setReadOnlyConnection(on,true);\r
+       }\r
+\r
+       /**\r
+         @see LanguageConnectionContext#isReadOnly\r
+         */\r
+       public boolean isReadOnly()\r
+       {\r
+               return authorizer.isReadOnlyConnection();\r
+       }\r
+\r
+       /**\r
+         @see LanguageConnectionContext#getAuthorizer\r
+        */\r
+       public Authorizer getAuthorizer()\r
+       {\r
+               return authorizer;\r
+       }\r
+\r
+       /**\r
+        * Implements ConnectionInfo.lastAutoincrementValue.\r
+        * lastAutoincrementValue searches for the last autoincrement value inserted\r
+        * into a column specified by the user. The search for the "last" value\r
+        * supports nesting levels caused by triggers (Only triggers cause nesting,\r
+        * not server side JDBC). \r
+        * If lastAutoincrementValue is called from within a trigger, the search\r
+        * space for ai-values are those values that are inserted by this trigger as\r
+        * well as previous triggers; \r
+        * i.e if a SQL statement fires trigger T1, which in turn does something\r
+        * that fires trigger t2, and if lastAutoincrementValue is called from\r
+        * within t2, then autoincrement values genereated by t1 are visible to\r
+        * it. By the same logic, if it is called from within t1, then it does not\r
+        * see values inserted by t2.\r
+        *\r
+        * @see LanguageConnectionContext#lastAutoincrementValue\r
+        * @see org.apache.derby.iapi.db.ConnectionInfo#lastAutoincrementValue\r
+        */\r
+       public Long lastAutoincrementValue(String schemaName, String tableName,\r
+                                                                          String columnName)\r
+       {\r
+               String aiKey = AutoincrementCounter.makeIdentity(schemaName, tableName, columnName);\r
+               \r
+               int size = triggerExecutionContexts.size();\r
+               //              System.out.println(" searching for " + aiKey);\r
+               for (int i = size - 1; i >= 0; i--)\r
+               {\r
+                       // first loop through triggers.\r
+                       InternalTriggerExecutionContext itec = \r
+                               (InternalTriggerExecutionContext)triggerExecutionContexts.get(i);\r
+                       Long value = itec.getAutoincrementValue(aiKey);\r
+                       if (value == null)\r
+                               continue;\r
+\r
+                       return value;\r
+               }\r
+               if (autoincrementHT == null)\r
+                       return null;\r
+               return (Long)autoincrementHT.get(aiKey);\r
+       }       \r
+\r
+       /**\r
+        * @see LanguageConnectionContext#setAutoincrementUpdate\r
+        */\r
+       public void setAutoincrementUpdate(boolean flag)\r
+       {\r
+               autoincrementUpdate = flag;\r
+       }\r
+       \r
+       /**\r
+        * @see LanguageConnectionContext#getAutoincrementUpdate\r
+        */\r
+       public boolean getAutoincrementUpdate()\r
+       {\r
+               return autoincrementUpdate;\r
+       }\r
+       \r
+       /**\r
+        * @see LanguageConnectionContext#autoincrementCreateCounter\r
+        */\r
+       public void autoincrementCreateCounter(String s, String t, String c,\r
+                                                                                  Long initialValue, long increment,\r
+                                                                                  int position)\r
+       {\r
+               String key = AutoincrementCounter.makeIdentity(s,t,c);\r
+               \r
+               if (autoincrementCacheHashtable == null)\r
+               {\r
+                       autoincrementCacheHashtable = new HashMap();\r
+               }\r
+\r
+               AutoincrementCounter aic = \r
+                       (AutoincrementCounter)autoincrementCacheHashtable.get(key);\r
+               if (aic != null)\r
+               {\r
+                       if (SanityManager.DEBUG)                        \r
+                       {\r
+                               SanityManager.THROWASSERT(\r
+                                                         "Autoincrement Counter already exists:" + key);\r
+                       }\r
+                       return;\r
+               }\r
+               \r
+               aic = new AutoincrementCounter(initialValue, \r
+                                                                          increment, 0, s, t, c, position);\r
+               autoincrementCacheHashtable.put(key, aic);\r
+       }\r
+\r
+       /**\r
+        * returns the <b>next</b> value to be inserted into an autoincrement col.\r
+        * This is used internally by the system to generate autoincrement values\r
+        * which are going to be inserted into a autoincrement column. This is\r
+        * used when as autoincrement column is added to a table by an alter \r
+        * table statemenet and during bulk insert.\r
+        *\r
+        * @param schemaName\r
+        * @param tableName\r
+        * @param columnName identify the column uniquely in the system.\r
+        */\r
+       public long nextAutoincrementValue(String schemaName, String tableName,\r
+                                                                          String columnName)\r
+                       throws StandardException                                                   \r
+       {\r
+               String key = AutoincrementCounter.makeIdentity(schemaName,tableName,\r
+                                                                                                          columnName);\r
+               \r
+               AutoincrementCounter aic = \r
+                       (AutoincrementCounter)autoincrementCacheHashtable.get(key);\r
+\r
+               if (aic == null)\r
+               {\r
+                       if (SanityManager.DEBUG)                        \r
+                       {\r
+                               SanityManager.THROWASSERT("counter doesn't exist:" + key);\r
+                       }\r
+                       return 0;\r
+               }\r
+               else\r
+               {\r
+                       return aic.update();\r
+               }\r
+       }\r
+       \r
+       /**\r
+        * Flush the cache of autoincrement values being kept by the lcc.\r
+        * This will result in the autoincrement values being written to the\r
+        * SYSCOLUMNS table as well as the mapping used by lastAutoincrementValue\r
+        * \r
+        * @exception StandardException thrown on error.\r
+        * @see LanguageConnectionContext#lastAutoincrementValue\r
+        * @see GenericLanguageConnectionContext#lastAutoincrementValue\r
+        * @see org.apache.derby.iapi.db.ConnectionInfo#lastAutoincrementValue\r
+        */\r
+       public void autoincrementFlushCache(UUID tableUUID)\r
+               throws StandardException\r
+       {\r
+               if (autoincrementCacheHashtable == null)\r
+                       return;\r
+\r
+               if (autoincrementHT == null)\r
+                       autoincrementHT = new HashMap();\r
+\r
+               DataDictionary dd = getDataDictionary();\r
+               for (Iterator it = autoincrementCacheHashtable.keySet().iterator();\r
+                        it.hasNext(); )\r
+               {\r
+                       Object key = it.next();\r
+                       AutoincrementCounter aic = \r
+                               (AutoincrementCounter)autoincrementCacheHashtable.get(key);\r
+                       Long value = aic.getCurrentValue();\r
+                       aic.flushToDisk(getTransactionExecute(), dd, tableUUID);\r
+                       if (value != null)\r
+                       {\r
+                               autoincrementHT.put(key, value);\r
+                       }\r
+               }\r
+               autoincrementCacheHashtable.clear();\r
+       }\r
+\r
+       /**\r
+        * Copies an existing autoincrement mapping\r
+        * into autoincrementHT, the cache of autoincrement values \r
+        * kept in the languageconnectioncontext.\r
+        */\r
+       public void copyHashtableToAIHT(Map from)\r
+       {\r
+               if (from.isEmpty())\r
+                       return;\r
+               if (autoincrementHT == null)\r
+                       autoincrementHT = new HashMap();\r
+               \r
+               autoincrementHT.putAll(from);\r
+       }\r
+       \r
+       /**\r
+        * @see LanguageConnectionContext#getInstanceNumber\r
+        */\r
+       public int getInstanceNumber()\r
+       {\r
+               return instanceNumber;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#getDrdaID\r
+        */\r
+       public String getDrdaID()\r
+       {\r
+               return drdaID;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#setDrdaID\r
+        */\r
+       public void setDrdaID(String drdaID)\r
+       {\r
+               this.drdaID = drdaID;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#getDbname\r
+        */\r
+       public String getDbname()\r
+       {\r
+               return dbname;\r
+       }\r
+\r
+       /**\r
+        * @see LanguageConnectionContext#getLastActivation\r
+        */\r
+       public Activation getLastActivation()\r
+       {\r
+               return (Activation)acts.get(acts.size() - 1);\r
+       }\r
+\r
+       public StringBuffer appendErrorInfo() {\r
+\r
+               TransactionController tc = getTransactionExecute();\r
+               if (tc == null)\r
+                       return null;\r
+\r
+               StringBuffer sb = new StringBuffer(200);\r
+\r
+               sb.append(LanguageConnectionContext.xidStr);\r
+               sb.append(tc.getTransactionIdString());\r
+               sb.append("), ");\r
+\r
+               sb.append(LanguageConnectionContext.lccStr);\r
+               sb.append(Integer.toString(getInstanceNumber()));\r
+               sb.append("), ");\r
+\r
+               sb.append(LanguageConnectionContext.dbnameStr);\r
+               sb.append(getDbname());\r
+               sb.append("), ");\r
+\r
+               sb.append(LanguageConnectionContext.drdaStr);\r
+               sb.append(getDrdaID());\r
+               sb.append("), ");\r
+\r
+               return sb;\r
+       }\r
+}\r