db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mi...@apache.org
Subject svn commit: r960231 [2/2] - /db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
Date Sat, 03 Jul 2010 15:57:35 GMT

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java?rev=960231&r1=960230&r2=960231&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java Sat Jul  3 15:57:35 2010
@@ -97,257 +97,259 @@ import java.util.Map;
  *
  */
 public class GenericLanguageConnectionContext
-	extends ContextImpl 
-	implements LanguageConnectionContext
+    extends ContextImpl 
+    implements LanguageConnectionContext
 {
 
-	// make sure these are not zeros
-	private final static int NON_XA = 0;
-	private final static int XA_ONE_PHASE = 1;
-	private final static int XA_TWO_PHASE = 2;
-
-	/*
-		fields
-	 */
-
-	private final ArrayList acts;
-	private volatile boolean unusedActs=false;
-	/** The maximum size of acts since the last time it was trimmed. Used to
-	 * determine whether acts should be trimmed to reclaim space. */
-	private int maxActsSize;
-	protected int bindCount;
-	private boolean ddWriteMode;
-	private boolean runTimeStatisticsSetting ;
-	private boolean statisticsTiming;
-
-	/**
-	 * If xplainOnlyMode is set (via SYSCS_SET_XPLAIN_MODE), then the
-	 * connection does not actually execute statements, but only
-	 * compiles them, and emits the query plan information into the
-	 * XPLAIN tables.
-	 */
-	private boolean xplainOnlyMode = false;
-    
-	/** the current xplain schema. Is usually NULL. Can be set via
-	 * SYSCS_SET_XPLAIN_SCHEMA, in which case it species the schema into
-	 * which XPLAIN information should be stored in user tables.
-	 */
-	private String xplain_schema = null;
-	/**
-	 * For each XPLAIN table, this map stores a SQL INSERT statement which
-	 * can be prepared and used to insert rows into the table during the
-	 * capturing of statistics data into the user XPLAIN tables.
-	 */
-	private Map xplain_statements = new HashMap();
-	
-	//all the temporary tables declared for this connection
-	private ArrayList allDeclaredGlobalTempTables;
-	//The currentSavepointLevel is used to provide the rollback behavior of temporary tables.
-	//At any point, this variable has the total number of savepoints defined for the transaction.
-	private int currentSavepointLevel = 0;
-
-	protected long	nextCursorId;
-
-	protected int	nextSavepointId;
-
-	private RunTimeStatistics runTimeStatisticsObject;
-	private StringBuffer sb;
-
-	private Database db;
-
-	private final int instanceNumber;
-	private String drdaID;
-	private String dbname;
+    // make sure these are not zeros
+    private final static int NON_XA = 0;
+    private final static int XA_ONE_PHASE = 1;
+    private final static int XA_TWO_PHASE = 2;
+
+    /*
+        fields
+     */
+
+    private final ArrayList acts;
+    private volatile boolean unusedActs=false;
+    /** The maximum size of acts since the last time it was trimmed. Used to
+     * determine whether acts should be trimmed to reclaim space. */
+    private int maxActsSize;
+    protected int bindCount;
+    private boolean ddWriteMode;
+    private boolean runTimeStatisticsSetting ;
+    private boolean statisticsTiming;
+
+    /**
+     * If xplainOnlyMode is set (via SYSCS_SET_XPLAIN_MODE), then the
+     * connection does not actually execute statements, but only
+     * compiles them, and emits the query plan information into the
+     * XPLAIN tables.
+     */
+    private boolean xplainOnlyMode = false;
+    
+    /** the current xplain schema. Is usually NULL. Can be set via
+     * SYSCS_SET_XPLAIN_SCHEMA, in which case it species the schema into
+     * which XPLAIN information should be stored in user tables.
+     */
+    private String xplain_schema = null;
+    /**
+     * For each XPLAIN table, this map stores a SQL INSERT statement which
+     * can be prepared and used to insert rows into the table during the
+     * capturing of statistics data into the user XPLAIN tables.
+     */
+    private Map xplain_statements = new HashMap();
+    
+    //all the temporary tables declared for this connection
+    private ArrayList allDeclaredGlobalTempTables;
+
+    //The currentSavepointLevel is used to provide the rollback behavior of 
+    //temporary tables.  At any point, this variable has the total number of 
+    //savepoints defined for the transaction.
+    private int currentSavepointLevel = 0;
+
+    protected long  nextCursorId;
+
+    protected int   nextSavepointId;
+
+    private RunTimeStatistics runTimeStatisticsObject;
+    private StringBuffer sb;
+
+    private Database db;
+
+    private final int instanceNumber;
+    private String drdaID;
+    private String dbname;
 
     private Object lastQueryTree; // for debugging
     
-	/**
-	The transaction to use within this language connection context.  It may
-	be more appropriate to have it in a separate context (LanguageTransactionContext?).
-	REVISIT (nat): I shoehorned the transaction context that
-	the language uses into this class.  The main purpose is so
-	that the various language code can find out what its
-	transaction is.
-	**/
-	private final TransactionController tran;
+    /**
+    The transaction to use within this language connection context.  It may
+    be more appropriate to have it in a separate context (LanguageTransactionContext?).
+    REVISIT (nat): I shoehorned the transaction context that
+    the language uses into this class.  The main purpose is so
+    that the various language code can find out what its
+    transaction is.
+    **/
+    private final TransactionController tran;
 
-	/**
-	 * If non-null indicates that a read-only nested 
+    /**
+     * If non-null indicates that a read-only nested 
      * user transaction is in progress.
-	 */
-	private TransactionController readOnlyNestedTransaction;
-	
-	/**
-	 * queryNestingDepth is a counter used to keep track of how many calls 
-	 * have been made to begin read-only nested transactions. Only the first call 
-	 * actually starts a Nested User Transaction with the store. Subsequent
-	 * calls simply increment this counter. commitNestedTransaction only
-	 * decrements the counter and when it drops to 0 actually commits the 
-	 * nested user transaction.
-	 */
-	private int queryNestingDepth;
-
-	protected DataValueFactory dataFactory;
-	protected LanguageFactory langFactory;
-	protected TypeCompilerFactory tcf;
-	protected OptimizerFactory of;
-	protected LanguageConnectionFactory connFactory;
-	
-	/* 
-	 * A statement context is "pushed" and "popped" at the beginning and
+     */
+    private TransactionController readOnlyNestedTransaction;
+    
+    /**
+     * queryNestingDepth is a counter used to keep track of how many calls 
+     * have been made to begin read-only nested transactions. Only the first call 
+     * actually starts a Nested User Transaction with the store. Subsequent
+     * calls simply increment this counter. commitNestedTransaction only
+     * decrements the counter and when it drops to 0 actually commits the 
+     * nested user transaction.
+     */
+    private int queryNestingDepth;
+
+    protected DataValueFactory dataFactory;
+    protected LanguageFactory langFactory;
+    protected TypeCompilerFactory tcf;
+    protected OptimizerFactory of;
+    protected LanguageConnectionFactory connFactory;
+    
+    /* 
+     * A statement context is "pushed" and "popped" at the beginning and
      * end of every statement so that only that statement is cleaned up
      * on a Statement Exception.  As a performance optimization, we only push
      * the outermost statement context once, and never pop it.  Also, we
-	 * save off a 2nd StatementContext for speeding server side method
-	 * invocation, though we still push and pop it as needed.  All other
+     * save off a 2nd StatementContext for speeding server side method
+     * invocation, though we still push and pop it as needed.  All other
      * statement contexts will allocated and pushed and popped on demand.
      */
-	private final StatementContext[] statementContexts = new StatementContext[2];
-	private int     statementDepth;
-	protected int	  outermostTrigger = -1;
+    private final StatementContext[] statementContexts = new StatementContext[2];
+    private int     statementDepth;
+    protected int     outermostTrigger = -1;
 
     protected Authorizer authorizer;
-	protected String userName = null; //The name the user connects with.
-	                                  //May still be quoted.
-	/**
-	 * The top SQL session context stack frame (SQL 2003, section
-	 * 4.37.3), is kept in topLevelSSC. For nested session contexts,
-	 * the SQL session context is held by the activation of the
-	 * calling statement, cf. setupNestedSessionContext and it is
-	 * accessible through the current statement context
-	 * (compile-time), or via the current activation (execution-time).
-	 * @see GenericLanguageConnectionContext#getTopLevelSQLSessionContext
-	 */
-	private SQLSessionContext topLevelSSC;
-
-	/**
-	 * Used to hold the computed value of the initial default schema,
-	 * cf logic in initDefaultSchemaDescriptor.
-	 */
-	private SchemaDescriptor cachedInitialDefaultSchemaDescr = null;
+    protected String userName = null; //The name the user connects with.
+                                      //May still be quoted.
+    /**
+     * The top SQL session context stack frame (SQL 2003, section
+     * 4.37.3), is kept in topLevelSSC. For nested session contexts,
+     * the SQL session context is held by the activation of the
+     * calling statement, cf. setupNestedSessionContext and it is
+     * accessible through the current statement context
+     * (compile-time), or via the current activation (execution-time).
+     * @see GenericLanguageConnectionContext#getTopLevelSQLSessionContext
+     */
+    private SQLSessionContext topLevelSSC;
+
+    /**
+     * Used to hold the computed value of the initial default schema,
+     * cf logic in initDefaultSchemaDescriptor.
+     */
+    private SchemaDescriptor cachedInitialDefaultSchemaDescr = null;
 
-	// RESOLVE - How do we want to set the default.
+    // RESOLVE - How do we want to set the default.
     private int defaultIsolationLevel = ExecutionContext.READ_COMMITTED_ISOLATION_LEVEL;
-	protected int isolationLevel = defaultIsolationLevel;
+    protected int isolationLevel = defaultIsolationLevel;
+
+    private boolean isolationLevelExplicitlySet = false;
+    // Isolation level can be changed using JDBC api Connection.setTransactionIsolation
+    // or it can be changed using SQL "set current isolation = NEWLEVEL".
+    // 
+    // In XA transactions, BrokeredConnection keeps isolation state information.
+    // When isolation is changed in XA transaction using JDBC, that state gets
+    // correctly set in BrokeredConnection.setTransactionIsolation method. But
+    // when SQL is used to set the isolation level, the code path is different
+    // and it does not go through BrokeredConnection's setTransactionIsolation
+    // method and hence the state is not maintained correctly when coming through
+    // SQL. To get around this, I am adding following flag which will get set
+    // everytime the isolation level is set using JDBC or SQL. This flag will be
+    // checked at global transaction start and end time. If the flag is set to true
+    // then BrokeredConnection's isolation level state will be brought upto date
+    // with Real Connection's isolation level and this flag will be set to false
+    // after that.
+    private boolean isolationLevelSetUsingSQLorJDBC = false;
+
+    // isolation level to when preparing statements.
+    // if unspecified, the statement won't be prepared with a specific 
+    // scan isolationlevel
+    protected int prepareIsolationLevel = ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL;
+
+    // Whether or not to write executing statement info to db2j.log
+    private boolean logStatementText;
+    private boolean logQueryPlan;
+    private HeaderPrintWriter istream;
+
+    // this used to be computed in OptimizerFactoryContextImpl; i.e everytime a
+    // connection was made. To keep the semantics same I'm putting it out here
+    // instead of in the OptimizerFactory which is only initialized when the
+    // database is booted.
+    private int lockEscalationThreshold; 
+
+    private ArrayList stmtValidators;
+    private ArrayList triggerExecutionContexts;
+    private ArrayList triggerTables;
+
+    // OptimizerTrace
+    private boolean optimizerTrace;
+    private boolean optimizerTraceHtml;
+    private String lastOptimizerTraceOutput;
+    private String optimizerTraceOutput;
+
+    //// Support for AUTOINCREMENT
 
-	private boolean isolationLevelExplicitlySet = false;
-	// Isolation level can be changed using JDBC api Connection.setTransactionIsolation
-	// or it can be changed using SQL "set current isolation = NEWLEVEL".
-	// 
-	// In XA transactions, BrokeredConnection keeps isolation state information.
-	// When isolation is changed in XA transaction using JDBC, that state gets
-	// correctly set in BrokeredConnection.setTransactionIsolation method. But
-	// when SQL is used to set the isolation level, the code path is different
-	// and it does not go through BrokeredConnection's setTransactionIsolation
-	// method and hence the state is not maintained correctly when coming through
-	// SQL. To get around this, I am adding following flag which will get set
-	// everytime the isolation level is set using JDBC or SQL. This flag will be
-	// checked at global transaction start and end time. If the flag is set to true
-	// then BrokeredConnection's isolation level state will be brought upto date
-	// with Real Connection's isolation level and this flag will be set to false
-	// after that.
-	private boolean isolationLevelSetUsingSQLorJDBC = false;
-
-	// isolation level to when preparing statements.
-	// if unspecified, the statement won't be prepared with a specific 
-	// scan isolationlevel
-	protected int prepareIsolationLevel = ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL;
-
-	// Whether or not to write executing statement info to db2j.log
-	private boolean logStatementText;
-	private boolean logQueryPlan;
-	private HeaderPrintWriter istream;
-
-	// this used to be computed in OptimizerFactoryContextImpl; i.e everytime a
-	// connection was made. To keep the semantics same I'm putting it out here
-	// instead of in the OptimizerFactory which is only initialized when the
-	// database is booted.
-	private int lockEscalationThreshold; 
-
-	private ArrayList stmtValidators;
-	private ArrayList triggerExecutionContexts;
-	private ArrayList triggerTables;
-
-	// OptimizerTrace
-	private boolean optimizerTrace;
-	private boolean optimizerTraceHtml;
-	private String lastOptimizerTraceOutput;
-	private String optimizerTraceOutput;
-
-	//// Support for AUTOINCREMENT
-
-	/**
-	 * To support lastAutoincrementValue: This is a hashtable which maps
-	 * schemaName,tableName,columnName to a Long value.
-	 */
-	private HashMap autoincrementHT;
-	/**
-	 * whether to allow updates or not. 
-	 */
-	private boolean autoincrementUpdate;
-	private long identityVal;	//support IDENTITY_VAL_LOCAL function
-	private boolean identityNotNull;	//frugal programmer
+    /**
+     * To support lastAutoincrementValue: This is a hashtable which maps
+     * schemaName,tableName,columnName to a Long value.
+     */
+    private HashMap autoincrementHT;
+    /**
+     * whether to allow updates or not. 
+     */
+    private boolean autoincrementUpdate;
+    private long identityVal;   //support IDENTITY_VAL_LOCAL function
+    private boolean identityNotNull;    //frugal programmer
 
-	// cache of ai being handled in memory (bulk insert + alter table).
-	private HashMap autoincrementCacheHashtable;
+    // cache of ai being handled in memory (bulk insert + alter table).
+    private HashMap autoincrementCacheHashtable;
 
     // User-written inspector to print out query tree
     private ASTVisitor astWalker;
     
-	/*
-	   constructor
-	*/
-	public GenericLanguageConnectionContext
-	(
-	 ContextManager cm,
-	 TransactionController tranCtrl,
-
-	 LanguageFactory lf,
-	 LanguageConnectionFactory lcf,
-	 Database db,
-	 String userName,
-	 int instanceNumber,
-	 String drdaID,
-	 String dbname)
-		 throws StandardException
-	{
-		super(cm, org.apache.derby.iapi.reference.ContextId.LANG_CONNECTION);
-		acts = new ArrayList();
-		tran = tranCtrl;
-
-		dataFactory = lcf.getDataValueFactory();
-		tcf = lcf.getTypeCompilerFactory();
-		of = lcf.getOptimizerFactory();
-		langFactory =  lf;
-		connFactory =  lcf;
+    /*
+       constructor
+    */
+    public GenericLanguageConnectionContext
+    (
+     ContextManager cm,
+     TransactionController tranCtrl,
+
+     LanguageFactory lf,
+     LanguageConnectionFactory lcf,
+     Database db,
+     String userName,
+     int instanceNumber,
+     String drdaID,
+     String dbname)
+         throws StandardException
+    {
+        super(cm, org.apache.derby.iapi.reference.ContextId.LANG_CONNECTION);
+        acts = new ArrayList();
+        tran = tranCtrl;
+
+        dataFactory = lcf.getDataValueFactory();
+        tcf = lcf.getTypeCompilerFactory();
+        of = lcf.getOptimizerFactory();
+        langFactory =  lf;
+        connFactory =  lcf;
         this.db = db;
-		this.userName = userName;
-		this.instanceNumber = instanceNumber;
-		this.drdaID = drdaID;
-		this.dbname = dbname;
-
-		/* Find out whether or not to log info on executing statements to error log
-		 */
-		String logStatementProperty = PropertyUtil.getServiceProperty(getTransactionCompile(),
-					"derby.language.logStatementText");
-		logStatementText = Boolean.valueOf(logStatementProperty).booleanValue();
-
-		String logQueryPlanProperty = PropertyUtil.getServiceProperty(getTransactionCompile(),
-					"derby.language.logQueryPlan");
-		logQueryPlan = Boolean.valueOf(logQueryPlanProperty).booleanValue();
-
-		setRunTimeStatisticsMode(logQueryPlan);
-
-		lockEscalationThreshold = 
-			PropertyUtil.getServiceInt(tranCtrl,
-									   Property.LOCKS_ESCALATION_THRESHOLD,
-									   Property.MIN_LOCKS_ESCALATION_THRESHOLD,
-									   Integer.MAX_VALUE,
-									   Property.DEFAULT_LOCKS_ESCALATION_THRESHOLD);															 
-		stmtValidators = new ArrayList();
-		triggerExecutionContexts = new ArrayList();
-		triggerTables = new ArrayList();
-	}
+        this.userName = userName;
+        this.instanceNumber = instanceNumber;
+        this.drdaID = drdaID;
+        this.dbname = dbname;
+
+        /* Find out whether or not to log info on executing statements to error log
+         */
+        String logStatementProperty = PropertyUtil.getServiceProperty(getTransactionCompile(),
+                    "derby.language.logStatementText");
+        logStatementText = Boolean.valueOf(logStatementProperty).booleanValue();
+
+        String logQueryPlanProperty = PropertyUtil.getServiceProperty(getTransactionCompile(),
+                    "derby.language.logQueryPlan");
+        logQueryPlan = Boolean.valueOf(logQueryPlanProperty).booleanValue();
+
+        setRunTimeStatisticsMode(logQueryPlan);
+
+        lockEscalationThreshold = 
+            PropertyUtil.getServiceInt(tranCtrl,
+                                       Property.LOCKS_ESCALATION_THRESHOLD,
+                                       Property.MIN_LOCKS_ESCALATION_THRESHOLD,
+                                       Integer.MAX_VALUE,
+                                       Property.DEFAULT_LOCKS_ESCALATION_THRESHOLD);                                                             
+        stmtValidators = new ArrayList();
+        triggerExecutionContexts = new ArrayList();
+        triggerTables = new ArrayList();
+    }
 
     /**
      * In contrast to current user id, which may change (inside a routine
@@ -356,558 +358,708 @@ public class GenericLanguageConnectionCo
      */
     private String sessionUser = null;
 
-	public void initialize() throws StandardException
-	{
+    public void initialize() throws StandardException
+    {
         sessionUser = IdUtil.getUserAuthorizationId(userName);
-		//
-		//Creating the authorizer authorizes the connection.
+        //
+        //Creating the authorizer authorizes the connection.
         authorizer = new GenericAuthorizer(this);
 
-		/*
-		** Set the authorization id.  User shouldn't
-		** be null or else we are going to blow up trying
-		** to create a schema for this user.
-		*/
-		if (SanityManager.DEBUG)
-		{
+        /*
+        ** Set the authorization id.  User shouldn't
+        ** be null or else we are going to blow up trying
+        ** to create a schema for this user.
+        */
+        if (SanityManager.DEBUG)
+        {
             if (getSessionUserId() == null)
-			{
-				SanityManager.THROWASSERT("User name is null," +
-					" check the connection manager to make sure it is set" +
-					" reasonably");
-			}
-		}
-
-
-		setDefaultSchema(initDefaultSchemaDescriptor());
-	}
-
-	/**
-	 * Compute the initial default schema and set
-	 * cachedInitialDefaultSchemaDescr accordingly.
-	 *
-	 * @return computed initial default schema value for this session
-	 * @throws StandardException
-	 */
-	protected SchemaDescriptor initDefaultSchemaDescriptor()
-		throws StandardException {
-		/*
-		** - If the database supports schemas and a schema with the
-		** same name as the user's name exists (has been created using
-		** create schema already) the database will set the users
-		** default schema to the the schema with the same name as the
-		** user.
+            {
+                SanityManager.THROWASSERT("User name is null," +
+                    " check the connection manager to make sure it is set" +
+                    " reasonably");
+            }
+        }
+
+
+        setDefaultSchema(initDefaultSchemaDescriptor());
+    }
+
+    /**
+     * Compute the initial default schema and set
+     * cachedInitialDefaultSchemaDescr accordingly.
+     *
+     * @return computed initial default schema value for this session
+     * @throws StandardException
+     */
+    protected SchemaDescriptor initDefaultSchemaDescriptor()
+        throws StandardException {
+        /*
+        ** - If the database supports schemas and a schema with the
+        ** same name as the user's name exists (has been created using
+        ** create schema already) the database will set the users
+        ** default schema to the the schema with the same name as the
+        ** user.
         ** - Else Set the default schema to APP.
         */
-		if (cachedInitialDefaultSchemaDescr == null) {
-			DataDictionary dd = getDataDictionary();
+        if (cachedInitialDefaultSchemaDescr == null) {
+            DataDictionary dd = getDataDictionary();
             String authorizationId = getSessionUserId();
-			SchemaDescriptor sd =
-				dd.getSchemaDescriptor(
+            SchemaDescriptor sd =
+                dd.getSchemaDescriptor(
                     getSessionUserId(), getTransactionCompile(), false);
 
-			if (sd == null) {
-				sd = new SchemaDescriptor(
+            if (sd == null) {
+                sd = new SchemaDescriptor(
                     dd,
                     getSessionUserId(),
                     getSessionUserId(),
                     (UUID) null,
                     false);
-			}
+            }
 
-			cachedInitialDefaultSchemaDescr = sd;
-		}
-		return cachedInitialDefaultSchemaDescr;
-	}
-
-	/**
-	 * Get the computed value for the initial default schema.
-	 * @return the schema descriptor of the computed initial default schema
-	 */
-	private SchemaDescriptor getInitialDefaultSchemaDescriptor() {
-		return cachedInitialDefaultSchemaDescr;
-	}
-	
-
-	//
-	// LanguageConnectionContext interface
-	//
-	/**
-	 * @see LanguageConnectionContext#getLogStatementText
-	 */
-	public boolean getLogStatementText()
-	{
-		return logStatementText;
-	}
-
-	/**
-	 * @see LanguageConnectionContext#setLogStatementText
-	 */
-	public void setLogStatementText(boolean logStatementText)
-	{
-		this.logStatementText = logStatementText;
-	}
-
-	/**
-	 * @see LanguageConnectionContext#getLogQueryPlan
-	 */
-	public boolean getLogQueryPlan()
-	{
-		return logQueryPlan;
-	}
-
-	/**
-	 * @see LanguageConnectionContext#usesSqlAuthorization
-	 */
-	public boolean usesSqlAuthorization()
-	{
-		return getDataDictionary().usesSqlAuthorization();
-	}
-
-	/**
-	 * get the lock escalation threshold.
-	 */
-	public int getLockEscalationThreshold()
-	{
-		return lockEscalationThreshold;
-	}
-
-	/**
-	 * Add the activation to those known about by this connection.
-	 */
-	public void addActivation(Activation a) 
-		throws StandardException {
-		acts.add(a);
-
-		if (acts.size() > maxActsSize) {
-			maxActsSize = acts.size();
-		}
-	}
-
-	public void closeUnusedActivations()
-			throws StandardException
-	{
-		// DERBY-418. Activations which are marked unused,
-		// are closed here. Activations Vector is iterated 
-		// to identify and close unused activations, only if 
-		// unusedActs flag is set to true and if the total 
-		// size exceeds 20.
-		if( (unusedActs) && (acts.size() > 20) ) {
-			unusedActs = false;
-
-			for (int i = acts.size() - 1; i >= 0; i--) {
-
-				// it maybe the case that a Activation's reset() ends up
-				// closing one or more activation leaving our index beyond
-				// the end of the array
-				if (i >= acts.size())
-					continue;
-
-				Activation a1 = (Activation) acts.get(i);
-				if (!a1.isInUse()) {
-					a1.close();
-				}
-			}
-		}
-
-		if (SanityManager.DEBUG) {
-
-			if (SanityManager.DEBUG_ON("memoryLeakTrace")) {
-
-				if (acts.size() > 20)
-					System.out.println("memoryLeakTrace:GenericLanguageContext:activations " + acts.size());
-			}
-		}
-	}
-
-	/**
-	 * Make a note that some activations are marked unused
-	 */
-	public void notifyUnusedActivation() {
-	    unusedActs = true;
-	}
-
-	/**
-	 * @see LanguageConnectionContext#checkIfAnyDeclaredGlobalTempTablesForThisConnection
-	 */
-	public boolean checkIfAnyDeclaredGlobalTempTablesForThisConnection() {
-		return (allDeclaredGlobalTempTables == null ? false : true);
-	}
-
-	/**
-	 * @see LanguageConnectionContext#addDeclaredGlobalTempTable
-	 */
-	public void addDeclaredGlobalTempTable(TableDescriptor td)
-		throws StandardException {
-
-		if (findDeclaredGlobalTempTable(td.getName()) != null) //if table already declared, throw an exception
-		{
-			throw
-				StandardException.newException(
-											   SQLState.LANG_OBJECT_ALREADY_EXISTS_IN_OBJECT,
-											   "Declared global temporary table",
-											   td.getName(),
-											   "Schema",
-											   SchemaDescriptor.STD_DECLARED_GLOBAL_TEMPORARY_TABLES_SCHEMA_NAME);
-		}
-
-		//save all the information about temp table in this special class
-		TempTableInfo tempTableInfo = new TempTableInfo(td, currentSavepointLevel);
-
-		if (allDeclaredGlobalTempTables == null)
-			allDeclaredGlobalTempTables = new ArrayList();
-
-		allDeclaredGlobalTempTables.add(tempTableInfo);
-	}
-
-	/**
-	 * @see LanguageConnectionContext#dropDeclaredGlobalTempTable
-	 */
-	public boolean dropDeclaredGlobalTempTable(String tableName) {
-    TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName);
-		if (tempTableInfo != null)
-		{
-			if (SanityManager.DEBUG)
-				if (tempTableInfo.getDeclaredInSavepointLevel() > currentSavepointLevel)
-					SanityManager.THROWASSERT("declared in savepoint level can not be higher than the current savepoint level");
-
-			//following checks if the table was declared in the current unit of work.
-			if (tempTableInfo.getDeclaredInSavepointLevel() == currentSavepointLevel)
-			{
-				//since the table was declared in this unit of work,
-				//the drop table method should remove it from the valid list of temp table for this unit of work
-				allDeclaredGlobalTempTables.remove(allDeclaredGlobalTempTables.indexOf(tempTableInfo));
-				if (allDeclaredGlobalTempTables.size() == 0)
-					allDeclaredGlobalTempTables = null;
-			}
-			else
-			{
-				//since the table was not declared in this unit of work, the drop table method will just mark the table as dropped
-				//in the current unit of work. This information will be used at rollback time.
-				tempTableInfo.setDroppedInSavepointLevel(currentSavepointLevel);
-			}
-			return true;
-		} else
-			return false;
-	}
-
-	/**
-	 * After a release of a savepoint, we need to go through our temp tables list. If there are tables with their declare or drop
-	 * or modified in savepoint levels set to savepoint levels higher than the current savepoint level, then we should change them
-	 * to the current savepoint level
-	 */
-	private void tempTablesReleaseSavepointLevels() {
-    //unlike rollback, here we check for dropped in / declared in / modified in savepoint levels > current savepoint level only.
-    //This is because the temp tables with their savepoint levels same as currentSavepointLevel have correct value assigned to them and
-    //do not need to be changed and hence no need to check for >=
-		for (int i = 0; i < allDeclaredGlobalTempTables.size(); i++) {
-			TempTableInfo tempTableInfo = (TempTableInfo)allDeclaredGlobalTempTables.get(i);
-			if (tempTableInfo.getDroppedInSavepointLevel() > currentSavepointLevel)
-				tempTableInfo.setDroppedInSavepointLevel(currentSavepointLevel);
-
-			if (tempTableInfo.getDeclaredInSavepointLevel() > currentSavepointLevel)
-				tempTableInfo.setDeclaredInSavepointLevel(currentSavepointLevel);
-
-			if (tempTableInfo.getModifiedInSavepointLevel() > currentSavepointLevel)
-				tempTableInfo.setModifiedInSavepointLevel(currentSavepointLevel);
-		}
-	}
-
-	/**
-	 * do the necessary work at commit time for temporary tables
-	 * 1)If a temporary table was marked as dropped in this transaction, then remove it from the list of temp tables for this connection
-	 * 2)If a temporary table was not dropped in this transaction, then mark it's declared savepoint level and modified savepoint level as -1
-	 */
-	private void tempTablesAndCommit() {
-		for (int i = allDeclaredGlobalTempTables.size()-1; i >= 0; i--) {
-			TempTableInfo tempTableInfo = (TempTableInfo)allDeclaredGlobalTempTables.get(i);
-			if (tempTableInfo.getDroppedInSavepointLevel() != -1)
-			{
-				//this means table was dropped in this unit of work and hence should be removed from valid list of temp tables
-				allDeclaredGlobalTempTables.remove(i);
-			} else //this table was not dropped in this unit of work, hence set its declaredInSavepointLevel as -1 and also mark it as not modified 
-			{
-				tempTableInfo.setDeclaredInSavepointLevel(-1);
-				tempTableInfo.setModifiedInSavepointLevel(-1);
-			}
-		}
-	}
-
-	/**
-		Reset the connection before it is returned (indirectly) by
-		a PooledConnection object. See EmbeddedConnection.
-	 */
-	public void resetFromPool()
-		 throws StandardException
-	{
-		// Reset IDENTITY_VAL_LOCAL
-		identityNotNull = false;
+            cachedInitialDefaultSchemaDescr = sd;
+        }
+        return cachedInitialDefaultSchemaDescr;
+    }
+
+    /**
+     * Get the computed value for the initial default schema.
+     * @return the schema descriptor of the computed initial default schema
+     */
+    private SchemaDescriptor getInitialDefaultSchemaDescriptor() {
+        return cachedInitialDefaultSchemaDescr;
+    }
+    
+
+    //
+    // LanguageConnectionContext interface
+    //
+    /**
+     * @see LanguageConnectionContext#getLogStatementText
+     */
+    public boolean getLogStatementText()
+    {
+        return logStatementText;
+    }
+
+    /**
+     * @see LanguageConnectionContext#setLogStatementText
+     */
+    public void setLogStatementText(boolean logStatementText)
+    {
+        this.logStatementText = logStatementText;
+    }
+
+    /**
+     * @see LanguageConnectionContext#getLogQueryPlan
+     */
+    public boolean getLogQueryPlan()
+    {
+        return logQueryPlan;
+    }
+
+    /**
+     * @see LanguageConnectionContext#usesSqlAuthorization
+     */
+    public boolean usesSqlAuthorization()
+    {
+        return getDataDictionary().usesSqlAuthorization();
+    }
+
+    /**
+     * get the lock escalation threshold.
+     */
+    public int getLockEscalationThreshold()
+    {
+        return lockEscalationThreshold;
+    }
+
+    /**
+     * Add the activation to those known about by this connection.
+     */
+    public void addActivation(Activation a) 
+        throws StandardException {
+        acts.add(a);
+
+        if (acts.size() > maxActsSize) {
+            maxActsSize = acts.size();
+        }
+    }
+
+    public void closeUnusedActivations()
+            throws StandardException
+    {
+        // DERBY-418. Activations which are marked unused,
+        // are closed here. Activations Vector is iterated 
+        // to identify and close unused activations, only if 
+        // unusedActs flag is set to true and if the total 
+        // size exceeds 20.
+        if( (unusedActs) && (acts.size() > 20) ) {
+            unusedActs = false;
+
+            for (int i = acts.size() - 1; i >= 0; i--) {
+
+                // it maybe the case that a Activation's reset() ends up
+                // closing one or more activation leaving our index beyond
+                // the end of the array
+                if (i >= acts.size())
+                    continue;
+
+                Activation a1 = (Activation) acts.get(i);
+                if (!a1.isInUse()) {
+                    a1.close();
+                }
+            }
+        }
+
+        if (SanityManager.DEBUG) {
+
+            if (SanityManager.DEBUG_ON("memoryLeakTrace")) {
+
+                if (acts.size() > 20)
+                    System.out.println("memoryLeakTrace:GenericLanguageContext:activations " + acts.size());
+            }
+        }
+    }
+
+    /**
+     * Make a note that some activations are marked unused
+     */
+    public void notifyUnusedActivation() {
+        unusedActs = true;
+    }
+
+    /**
+     * @see LanguageConnectionContext#checkIfAnyDeclaredGlobalTempTablesForThisConnection
+     */
+    public boolean checkIfAnyDeclaredGlobalTempTablesForThisConnection() {
+        return (allDeclaredGlobalTempTables == null ? false : true);
+    }
+
+    /**
+     * @see LanguageConnectionContext#addDeclaredGlobalTempTable
+     */
+    public void addDeclaredGlobalTempTable(TableDescriptor td)
+        throws StandardException 
+    {
+
+        if (findDeclaredGlobalTempTable(td.getName()) != null) 
+        {
+            //if table already declared, throw an exception
+            throw StandardException.newException(
+                SQLState.LANG_OBJECT_ALREADY_EXISTS_IN_OBJECT,
+                "Declared global temporary table",
+                td.getName(),
+                "Schema",
+                SchemaDescriptor.STD_DECLARED_GLOBAL_TEMPORARY_TABLES_SCHEMA_NAME);
+        }
+
+        //save all the information about temp table in this special class
+        TempTableInfo tempTableInfo = 
+            new TempTableInfo(td, currentSavepointLevel);
+
+        // Rather than exist in a catalog, a simple array is kept of the 
+        // tables currently active in the transaction.
+
+        if (allDeclaredGlobalTempTables == null)
+            allDeclaredGlobalTempTables = new ArrayList();
+
+        allDeclaredGlobalTempTables.add(tempTableInfo);
+    }
 
-		// drop all temp tables.
-		dropAllDeclaredGlobalTempTables();
+    /**
+     * @see LanguageConnectionContext#dropDeclaredGlobalTempTable
+     */
+    public boolean dropDeclaredGlobalTempTable(String tableName) 
+    {
+        TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName);
+
+        if (tempTableInfo != null)
+        {
+            if (SanityManager.DEBUG)
+            {
+                if (tempTableInfo.getDeclaredInSavepointLevel() > 
+                        currentSavepointLevel)
+                {
+                    SanityManager.THROWASSERT(
+                        "declared in savepoint level (" + 
+                            tempTableInfo.getDeclaredInSavepointLevel() + 
+                        ") can not be higher than current savepoint level (" +
+                            currentSavepointLevel +
+                        ").");
+                }
+            }
+
+            // check if the table was declared in the current unit of work.
+            if (tempTableInfo.getDeclaredInSavepointLevel() == 
+                    currentSavepointLevel)
+            {
+                // since the table was declared in this unit of work, the drop 
+                // table method should remove it from the valid list of temp 
+                // table for this unit of work
+                allDeclaredGlobalTempTables.remove(
+                        allDeclaredGlobalTempTables.indexOf(tempTableInfo));
+
+                if (allDeclaredGlobalTempTables.size() == 0)
+                    allDeclaredGlobalTempTables = null;
+            }
+            else
+            {
+                // since the table was not declared in this unit of work, the
+                // drop table method will just mark the table as dropped
+                // in the current unit of work. This information will be used 
+                // at rollback time.
+
+                tempTableInfo.setDroppedInSavepointLevel(currentSavepointLevel);
+            }
+
+            return true;
+        } 
+        else
+        {
+            return false;
+        }
+    }
+
+    /**
+     * After a release of a savepoint, we need to go through our temp tables 
+     * list. If there are tables with their declare or drop or modified in 
+     * savepoint levels set to savepoint levels higher than the current 
+     * savepoint level, then we should change them to the current savepoint
+     * level
+     */
+    private void tempTablesReleaseSavepointLevels() 
+    {
+        // unlike rollback, here we check for dropped in / declared in / 
+        // modified in savepoint levels > current savepoint level only.
+        // This is because the temp tables with their savepoint levels same as 
+        // currentSavepointLevel have correct value assigned to them and
+        // do not need to be changed and hence no need to check for >=
+
+        for (int i = 0; i < allDeclaredGlobalTempTables.size(); i++) 
+        {
+            TempTableInfo tempTableInfo = 
+                (TempTableInfo)allDeclaredGlobalTempTables.get(i);
+
+            if (tempTableInfo.getDroppedInSavepointLevel() > 
+                    currentSavepointLevel)
+            {
+                tempTableInfo.setDroppedInSavepointLevel(currentSavepointLevel);
+            }
+
+            if (tempTableInfo.getDeclaredInSavepointLevel() > 
+                    currentSavepointLevel)
+            {
+                tempTableInfo.setDeclaredInSavepointLevel(
+                    currentSavepointLevel);
+            }
+
+            if (tempTableInfo.getModifiedInSavepointLevel() > 
+                    currentSavepointLevel)
+            {
+                tempTableInfo.setModifiedInSavepointLevel(
+                    currentSavepointLevel);
+            }
+        }
+    }
+
+    /**
+     * do the necessary work at commit time for temporary tables
+     * 1)If a temporary table was marked as dropped in this transaction, then 
+     *   remove it from the list of temp tables for this connection
+     * 2)If a temporary table was not dropped in this transaction, then mark 
+     *   it's declared savepoint level and modified savepoint level as -1
+     */
+    private void tempTablesAndCommit() 
+    {
+        for (int i = allDeclaredGlobalTempTables.size()-1; i >= 0; i--) 
+        {
+            TempTableInfo tempTableInfo = 
+                (TempTableInfo)allDeclaredGlobalTempTables.get(i);
+
+            if (tempTableInfo.getDroppedInSavepointLevel() != -1)
+            {
+                // this means table was dropped in this unit of work and hence 
+                // should be removed from valid list of temp tables
+
+                allDeclaredGlobalTempTables.remove(i);
+            } 
+            else 
+            {
+                //this table was not dropped in this unit of work, hence set 
+                //its declaredInSavepointLevel as -1 and also mark it as not 
+                //modified 
+
+                tempTableInfo.setDeclaredInSavepointLevel(-1);
+                tempTableInfo.setModifiedInSavepointLevel(-1);
+            }
+        }
+    }
+
+    /**
+        Reset the connection before it is returned (indirectly) by
+        a PooledConnection object. See EmbeddedConnection.
+     */
+    public void resetFromPool()
+         throws StandardException
+    {
+        // Reset IDENTITY_VAL_LOCAL
+        identityNotNull = false;
+
+        // drop all temp tables.
+        dropAllDeclaredGlobalTempTables();
 
         // Reset the current schema (see DERBY-3690).
         setDefaultSchema(null);
 
-		// Reset the current role
-		getCurrentSQLSessionContext().setRole(null);
+        // Reset the current role
+        getCurrentSQLSessionContext().setRole(null);
 
         // Reset the current user
         getCurrentSQLSessionContext().setUser(getSessionUserId());
-	}
+    }
 
     // debug methods
     public  void    setLastQueryTree( Object queryTree ) { lastQueryTree = queryTree; }
     public  Object    getLastQueryTree() { return lastQueryTree; }
 
-	/**
-	 * Drop all the declared global temporary tables associated with this connection. This gets called
-	 * when a getConnection() is done on a PooledConnection. This will ensure all the temporary tables
-	 * declared on earlier connection handle associated with this physical database connection are dropped
-	 * before a new connection handle is issued on that same physical database connection.
-	 */
-	private void dropAllDeclaredGlobalTempTables() throws StandardException {
-		if (allDeclaredGlobalTempTables == null)
-			return;
-    
-		DependencyManager dm = getDataDictionary().getDependencyManager();
-		StandardException topLevelStandardException = null;
-
-		//collect all the exceptions we might receive while dropping the temporary tables and throw them as one chained exception at the end.
-		for (int i = 0; i < allDeclaredGlobalTempTables.size(); i++) {
-			try {
-				TempTableInfo tempTableInfo = (TempTableInfo)allDeclaredGlobalTempTables.get(i);
-				TableDescriptor td = tempTableInfo.getTableDescriptor();
-				//the following 2 lines of code has been copied from DropTableConstantAction. If there are any changes made there in future,
-				//we should check if they need to be made here too.
-				dm.invalidateFor(td, DependencyManager.DROP_TABLE, this);
-				tran.dropConglomerate(td.getHeapConglomerateId());
-			} catch (StandardException e) {
-				if (topLevelStandardException == null) {
-					// always keep the first exception unchanged
-					topLevelStandardException = e;
-				} else {
-					try {
-						// Try to create a chain of exceptions. If successful,
-						// the current exception is the top-level exception,
-						// and the previous exception the cause of it.
-						e.initCause(topLevelStandardException);
-						topLevelStandardException = e;
-					} catch (IllegalStateException ise) {
-						// initCause() has already been called on e. We don't
-						// expect this to happen, but if it happens, just skip
-						// the current exception from the chain. This is safe
-						// since we always keep the first exception.
-					}
-				}
-			}
-		}
-    
-		allDeclaredGlobalTempTables = null;
-		try {
-			internalCommit(true);
-		} catch (StandardException e) {
-			// do the same chaining as above
-			if (topLevelStandardException == null) {
-				topLevelStandardException = e;
-			} else {
-				try {
-					e.initCause(topLevelStandardException);
-					topLevelStandardException = e;
-				} catch (IllegalStateException ise) { /* ignore */ }
-			}
-		}
-		if (topLevelStandardException != null) throw topLevelStandardException;
-	}
-
-	//do the necessary work at rollback time for temporary tables
-	/**
-	 * do the necessary work at rollback time for temporary tables
-	 * 1)If a temp table was declared in the UOW, then drop it and remove it from list of temporary tables.
-	 * 2)If a temp table was declared and dropped in the UOW, then remove it from list of temporary tables.
-	 * 3)If an existing temp table was dropped in the UOW, then recreate it with no data.
-	 * 4)If an existing temp table was modified in the UOW, then get rid of all the rows from the table.
-	 */
-	private void tempTablesAndRollback()
-		throws StandardException {
-		for (int i = allDeclaredGlobalTempTables.size()-1; i >= 0; i--) {
-			TempTableInfo tempTableInfo = (TempTableInfo)allDeclaredGlobalTempTables.get(i);
-			if (tempTableInfo.getDeclaredInSavepointLevel() >= currentSavepointLevel)
-			{
-				if (tempTableInfo.getDroppedInSavepointLevel() == -1)
-				{
-					//the table was declared but not dropped in the unit of work getting rolled back and hence we will remove
-					//it from valid list of temporary tables and drop the conglomerate associated with it
-					TableDescriptor td = tempTableInfo.getTableDescriptor();
-					tran.dropConglomerate(td.getHeapConglomerateId()); //remove the conglomerate created for this temp table
-					allDeclaredGlobalTempTables.remove(i); //remove it from the list of temp tables
-				} else if (tempTableInfo.getDroppedInSavepointLevel() >= currentSavepointLevel)
-				{
-					//the table was declared and dropped in the unit of work getting rolled back
-					allDeclaredGlobalTempTables.remove(i);
-				}
-			} else if (tempTableInfo.getDroppedInSavepointLevel() >= currentSavepointLevel) //this means the table was declared in an earlier savepoint unit / transaction and then dropped in current UOW 
-			{
-				//restore the old definition of temp table because drop is being rolledback
-				TableDescriptor td = tempTableInfo.getTableDescriptor();
-				td = cleanupTempTableOnCommitOrRollback(td, false);
-				//In order to store the old conglomerate information for the temp table, we need to replace the
-				//existing table descriptor with the old table descriptor which has the old conglomerate information
-				tempTableInfo.setTableDescriptor(td);
-				tempTableInfo.setDroppedInSavepointLevel(-1);
-				//following will mark the table as not modified. This is because the table data has been deleted as part of the current rollback
-				tempTableInfo.setModifiedInSavepointLevel(-1);
-				allDeclaredGlobalTempTables.set(i, tempTableInfo);
-			} else if (tempTableInfo.getModifiedInSavepointLevel() >= currentSavepointLevel) //this means the table was declared in an earlier savepoint unit / transaction and modified in current UOW
-			{
-				//following will mark the table as not modified. This is because the table data will be deleted as part of the current rollback
-				tempTableInfo.setModifiedInSavepointLevel(-1);
-				TableDescriptor td = tempTableInfo.getTableDescriptor();
-				getDataDictionary().getDependencyManager().invalidateFor(td, DependencyManager.DROP_TABLE, this);
-				cleanupTempTableOnCommitOrRollback(td, true);
-			} // 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
-		}
-    
-		if (allDeclaredGlobalTempTables.size() == 0)
-			allDeclaredGlobalTempTables = null;
-	}
-
-	/**
-	 * This is called at the commit time for temporary tables with ON COMMIT DELETE ROWS
-	 * If a temp table with ON COMMIT DELETE ROWS doesn't have any held cursor open on them, we delete the data from
-	 * them by dropping the conglomerate and recreating the conglomerate. In order to store the new conglomerate
-	 * information for the temp table, we need to replace the existing table descriptor with the new table descriptor
-	 * which has the new conglomerate information
-	 * @param tableName Temporary table name whose table descriptor is getting changed
-	 * @param td New table descriptor for the temporary table
-	 */
-	private void replaceDeclaredGlobalTempTable(String tableName, TableDescriptor td) {
-    TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName);
-		tempTableInfo.setDroppedInSavepointLevel(-1);
-		tempTableInfo.setDeclaredInSavepointLevel(-1);
-		tempTableInfo.setTableDescriptor(td);
-		allDeclaredGlobalTempTables.set(allDeclaredGlobalTempTables.indexOf(tempTableInfo), tempTableInfo);
-  }
-
-	/**
-	 * @see LanguageConnectionContext#getTableDescriptorForDeclaredGlobalTempTable
-	 */
-	public TableDescriptor getTableDescriptorForDeclaredGlobalTempTable(String tableName) {
+    /**
+     * Drop all the declared global temporary tables associated with this 
+     * connection. This gets called when a getConnection() is done on a 
+     * PooledConnection. This will ensure all the temporary tables declared on
+     * earlier connection handle associated with this physical database 
+     * connection are dropped before a new connection handle is issued on that 
+     * same physical database connection.
+     */
+    private void dropAllDeclaredGlobalTempTables() throws StandardException 
+    {
+        if (allDeclaredGlobalTempTables == null)
+            return;
+    
+        DependencyManager dm = getDataDictionary().getDependencyManager();
+        StandardException topLevelStandardException = null;
+
+        // collect all the exceptions we might receive while dropping the 
+        // temporary tables and throw them as one chained exception at the end.
+        for (int i = 0; i < allDeclaredGlobalTempTables.size(); i++) 
+        {
+            try 
+            {
+                TempTableInfo tempTableInfo = 
+                    (TempTableInfo)allDeclaredGlobalTempTables.get(i);
+
+                TableDescriptor td = tempTableInfo.getTableDescriptor();
+
+                // the following 2 lines of code has been copied from 
+                // DropTableConstantAction. If there are any changes made there
+                // in future, we should check if they need to be made here too.
+                dm.invalidateFor(td, DependencyManager.DROP_TABLE, this);
+                tran.dropConglomerate(td.getHeapConglomerateId());
+
+            } 
+            catch (StandardException e) 
+            {
+                if (topLevelStandardException == null) 
+                {
+                    // always keep the first exception unchanged
+                    topLevelStandardException = e;
+                } 
+                else 
+                {
+                    try 
+                    {
+                        // Try to create a chain of exceptions. If successful,
+                        // the current exception is the top-level exception,
+                        // and the previous exception the cause of it.
+                        e.initCause(topLevelStandardException);
+                        topLevelStandardException = e;
+                    } 
+                    catch (IllegalStateException ise) 
+                    {
+                        // initCause() has already been called on e. We don't
+                        // expect this to happen, but if it happens, just skip
+                        // the current exception from the chain. This is safe
+                        // since we always keep the first exception.
+                    }
+                }
+            }
+        }
+    
+        allDeclaredGlobalTempTables = null;
+        try 
+        {
+            internalCommit(true);
+        } 
+        catch (StandardException e) 
+        {
+            // do the same chaining as above
+            if (topLevelStandardException == null) 
+            {
+                topLevelStandardException = e;
+            } 
+            else 
+            {
+                try 
+                {
+                    e.initCause(topLevelStandardException);
+                    topLevelStandardException = e;
+                } 
+                catch (IllegalStateException ise) 
+                { 
+                    /* ignore */ 
+                }
+            }
+        }
+
+        if (topLevelStandardException != null) 
+            throw topLevelStandardException;
+    }
+
+    /**
+     * do the necessary work at rollback time for temporary tables
+     * 1)If a temp table was declared in the UOW, then drop it and remove it 
+     *   from list of temporary tables.
+     * 2)If a temp table was declared and dropped in the UOW, then remove it 
+     *   from list of temporary tables.
+     * 3)If an existing temp table was dropped in the UOW, then recreate it 
+     *   with no data.
+     * 4)If an existing temp table was modified in the UOW, then get rid of 
+     *   all the rows from the table.
+     */
+    private void tempTablesAndRollback()
+        throws StandardException 
+    {
+        for (int i = allDeclaredGlobalTempTables.size()-1; i >= 0; i--) 
+        {
+            TempTableInfo tempTableInfo = 
+                (TempTableInfo)allDeclaredGlobalTempTables.get(i);
+
+            if (tempTableInfo.getDeclaredInSavepointLevel() >= 
+                    currentSavepointLevel)
+            {
+                if (tempTableInfo.getDroppedInSavepointLevel() == -1)
+                {
+                    // the table was declared but not dropped in the unit of 
+                    // work getting rolled back and hence we will remove it 
+                    // from valid list of temporary tables and drop the 
+                    // conglomerate associated with it
+
+                    TableDescriptor td = tempTableInfo.getTableDescriptor();
+
+                    //remove the conglomerate created for this temp table
+                    tran.dropConglomerate(td.getHeapConglomerateId()); 
+
+                    //remove it from the list of temp tables
+                    allDeclaredGlobalTempTables.remove(i); 
+
+                } 
+                else if (tempTableInfo.getDroppedInSavepointLevel() >= 
+                            currentSavepointLevel)
+                {
+                    // the table was declared and dropped in the unit of work 
+                    // getting rolled back
+                    allDeclaredGlobalTempTables.remove(i);
+                }
+            } 
+            else if (tempTableInfo.getDroppedInSavepointLevel() >= 
+                        currentSavepointLevel) 
+            {
+                // this means the table was declared in an earlier savepoint 
+                // unit / transaction and then dropped in current UOW 
+
+                // restore the old definition of temp table because drop is 
+                // being rolledback
+                TableDescriptor td = tempTableInfo.getTableDescriptor();
+                td = cleanupTempTableOnCommitOrRollback(td, false);
+
+                // In order to store the old conglomerate information for the 
+                // temp table, we need to replace the existing table descriptor
+                // with the old table descriptor which has the old conglomerate 
+                // information
+                tempTableInfo.setTableDescriptor(td);
+                tempTableInfo.setDroppedInSavepointLevel(-1);
+
+                // following will mark the table as not modified. This is 
+                // because the table data has been deleted as part of the 
+                // current rollback
+                tempTableInfo.setModifiedInSavepointLevel(-1);
+                allDeclaredGlobalTempTables.set(i, tempTableInfo);
+                
+            } 
+            else if (tempTableInfo.getModifiedInSavepointLevel() >= 
+                    currentSavepointLevel) 
+            {
+                // this means the table was declared in an earlier savepoint 
+                // unit / transaction and modified in current UOW
+
+                // following will mark the table as not modified. This is 
+                // because the table data will be deleted as part of the 
+                // current rollback
+                tempTableInfo.setModifiedInSavepointLevel(-1);
+                TableDescriptor td = tempTableInfo.getTableDescriptor();
+
+                getDataDictionary().getDependencyManager().invalidateFor(
+                        td, DependencyManager.DROP_TABLE, this);
+
+                cleanupTempTableOnCommitOrRollback(td, true);
+            } 
+            // 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
+        }
+    
+        if (allDeclaredGlobalTempTables.size() == 0)
+            allDeclaredGlobalTempTables = null;
+    }
+
+    /**
+     * This is called at the commit time for temporary tables with 
+     * ON COMMIT DELETE ROWS
+     *
+     * If a temp table with ON COMMIT DELETE ROWS doesn't have any held cursor 
+     * open on them, we delete the data from them by dropping the conglomerate 
+     * and recreating the conglomerate. In order to store the new conglomerate
+     * information for the temp table, we need to replace the existing table 
+     * descriptor with the new table descriptor which has the new conglomerate
+     * information
+     *
+     * @param tableName Temporary table name whose table descriptor is 
+     *                  getting changed
+     * @param td        New table descriptor for the temporary table
+     */
+    private void replaceDeclaredGlobalTempTable(
+    String          tableName, 
+    TableDescriptor td) 
+    {
+        TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName);
+        
+        tempTableInfo.setDroppedInSavepointLevel(-1);
+        tempTableInfo.setDeclaredInSavepointLevel(-1);
+        tempTableInfo.setTableDescriptor(td);
+
+        allDeclaredGlobalTempTables.set(
+            allDeclaredGlobalTempTables.indexOf(tempTableInfo), tempTableInfo);
+    }
+
+    /**
+     * @see LanguageConnectionContext#getTableDescriptorForDeclaredGlobalTempTable
+     */
+    public TableDescriptor getTableDescriptorForDeclaredGlobalTempTable(String tableName) {
     TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName);
-		if (tempTableInfo == null)
-			return null;
-		else
-			return tempTableInfo.getTableDescriptor();
-	}
-
-	/**
-	 * Find the declared global temporary table in the list of temporary tables known by this connection.
-	 * @param tableName look for this table name in the saved list
-	 * @return data structure defining the temporary table if found. Else, return null 
-	 *
-	 */
-	private TempTableInfo findDeclaredGlobalTempTable(String tableName) {
-		if (allDeclaredGlobalTempTables == null)
-			return null;
-
-		for (int i = 0; i < allDeclaredGlobalTempTables.size(); i++) {
-			if (((TempTableInfo)allDeclaredGlobalTempTables.get(i)).matches(tableName))
-				return (TempTableInfo)allDeclaredGlobalTempTables.get(i);
-		}
-		return null;
-	}
-
-	/**
-	 * @see LanguageConnectionContext#markTempTableAsModifiedInUnitOfWork
-	 */
-	public void markTempTableAsModifiedInUnitOfWork(String tableName) {
+        if (tempTableInfo == null)
+            return null;
+        else
+            return tempTableInfo.getTableDescriptor();
+    }
+
+    /**
+     * Find the declared global temporary table in the list of temporary tables known by this connection.
+     * @param tableName look for this table name in the saved list
+     * @return data structure defining the temporary table if found. Else, return null 
+     *
+     */
+    private TempTableInfo findDeclaredGlobalTempTable(String tableName) {
+        if (allDeclaredGlobalTempTables == null)
+            return null;
+
+        for (int i = 0; i < allDeclaredGlobalTempTables.size(); i++) {
+            if (((TempTableInfo)allDeclaredGlobalTempTables.get(i)).matches(tableName))
+                return (TempTableInfo)allDeclaredGlobalTempTables.get(i);
+        }
+        return null;
+    }
+
+    /**
+     * @see LanguageConnectionContext#markTempTableAsModifiedInUnitOfWork
+     */
+    public void markTempTableAsModifiedInUnitOfWork(String tableName) {
     TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName);
     tempTableInfo.setModifiedInSavepointLevel(currentSavepointLevel);
-	}
+    }
 
         /**
-	 * @see LanguageConnectionContext#prepareInternalStatement
-	 */
+     * @see LanguageConnectionContext#prepareInternalStatement
+     */
         public PreparedStatement prepareInternalStatement(SchemaDescriptor compilationSchema, String sqlText, boolean isForReadOnly, boolean forMetaData) 
-	    throws StandardException 
+        throws StandardException 
         {
-        	if (forMetaData) {
-        		//DERBY-2946
-        		//Make sure that metadata queries always run with SYS as 
-        		//compilation schema. This will make sure that the collation
-        		//type of character string constants will be UCS_BASIC which
-        		//is also the collation of character string columns belonging
-        		//to system tables. 
-        		compilationSchema = getDataDictionary().getSystemSchemaDescriptor(); 
-        	}
-	    return connFactory.getStatement(compilationSchema, sqlText, isForReadOnly).prepare(this, forMetaData);
-    	}
+            if (forMetaData) {
+                //DERBY-2946
+                //Make sure that metadata queries always run with SYS as 
+                //compilation schema. This will make sure that the collation
+                //type of character string constants will be UCS_BASIC which
+                //is also the collation of character string columns belonging
+                //to system tables. 
+                compilationSchema = getDataDictionary().getSystemSchemaDescriptor(); 
+            }
+        return connFactory.getStatement(compilationSchema, sqlText, isForReadOnly).prepare(this, forMetaData);
+        }
 
         /**
-    	 * @see LanguageConnectionContext#prepareInternalStatement
-    	 */
+         * @see LanguageConnectionContext#prepareInternalStatement
+         */
         public PreparedStatement prepareInternalStatement(String sqlText) 
-	    throws StandardException 
+        throws StandardException 
+        {
+            return connFactory.
+                getStatement(getDefaultSchema(), sqlText, true).prepare(this);
+        }      
+
+    /**
+     * Remove the activation to those known about by this connection.
+     *
+     */
+    public void removeActivation(Activation a) 
+    {
+        if (SanityManager.DEBUG) {
+            SanityManager.ASSERT(a.isClosed(), "Activation is not closed");
+        }
+
+        acts.remove(a);
+
+        if (maxActsSize > 20 && (maxActsSize > 2 * acts.size())) {
+            acts.trimToSize();
+            maxActsSize = acts.size();
+        }
+    }
+
+    /**
+     * Return the number of activations known for this connection.
+     * Note that some of these activations may not be in use
+     * (when a prepared statement is finalized, its activations
+     * are marked as unused and later closed and removed on
+     * the next commit/rollback).
+     */
+    public int getActivationCount() {
+        return acts.size();
+    }
+
+    /**
+     * See if a given cursor is available for use.
+     * if so return its activation. Returns null if not found.
+     * For use in execution.
+     *
+     * @return the activation for the given cursor, null
+     *  if none was found.
+     */
+    public CursorActivation lookupCursorActivation(String cursorName) {
+
+        int size = acts.size();
+        if (size > 0)
         {
-			return connFactory.
-				getStatement(getDefaultSchema(), sqlText, true).prepare(this);
-    	}      
-
-	/**
-	 * Remove the activation to those known about by this connection.
-	 *
-	 */
-	public void removeActivation(Activation a) 
-	{
-		if (SanityManager.DEBUG) {
-			SanityManager.ASSERT(a.isClosed(), "Activation is not closed");
-		}
-
-		acts.remove(a);
-
-		if (maxActsSize > 20 && (maxActsSize > 2 * acts.size())) {
-			acts.trimToSize();
-			maxActsSize = acts.size();
-		}
-	}
-
-	/**
-	 * Return the number of activations known for this connection.
-	 * Note that some of these activations may not be in use
-	 * (when a prepared statement is finalized, its activations
-	 * are marked as unused and later closed and removed on
-	 * the next commit/rollback).
-	 */
-	public int getActivationCount() {
-		return acts.size();
-	}
-
-	/**
-	 * See if a given cursor is available for use.
-	 * if so return its activation. Returns null if not found.
-	 * For use in execution.
-	 *
-	 * @return the activation for the given cursor, null
-	 *	if none was found.
-	 */
-	public CursorActivation lookupCursorActivation(String cursorName) {
-
-		int size = acts.size();
-		if (size > 0)
-		{
             int cursorHash = cursorName.hashCode();
 
-			for (int i = 0; i < size; i++) {
-				 Activation a = (Activation) acts.get(i);
+            for (int i = 0; i < size; i++) {
+                 Activation a = (Activation) acts.get(i);
 
-				 if (!a.isInUse())
-				 {
-					continue;
-				 }
+                 if (!a.isInUse())
+                 {
+                    continue;
+                 }
 
 
 
-				String executingCursorName = a.getCursorName();
+                String executingCursorName = a.getCursorName();
 
                 // If the executing cursor has no name, or if the hash code of
                 // its name is different from the one we're looking for, it
@@ -925,2418 +1077,2441 @@ public class GenericLanguageConnectionCo
                     continue;
                 }
 
-				 if (cursorName.equals(executingCursorName)) {
+                 if (cursorName.equals(executingCursorName)) {
+
+                    ResultSet rs = a.getResultSet();
+                    if (rs == null)
+                        continue;
+
+                     // if the result set is closed, the the cursor doesn't exist
+                     if (rs.isClosed()) {                   
+                        continue;
+                     }
+
+                    return (CursorActivation)a;
+                 }
+            }
+        }
+        return null;
+    }
+
+    /**
+    *  This method will remove a statement from the  statement cache.
+    *  It should only be called if there is an exception preparing
+    *  the statement. The caller must have set the flag
+    *  {@code preparedStmt.compilingStatement} in the {@code GenericStatement}
+    *  before calling this method in order to prevent race conditions when
+    *  calling {@link CacheManager#remove(Cacheable)}.
+    *
+    *  @param statement Statement to remove
+    *  @exception StandardException thrown if lookup goes wrong.
+    */  
+    public void removeStatement(GenericStatement statement)
+        throws StandardException {
+        
+        CacheManager statementCache =
+            getLanguageConnectionFactory().getStatementCache();
+
+        if (statementCache == null)
+            return;
+ 
+        Cacheable cachedItem = statementCache.findCached(statement);
+        // No need to do anything if the statement is already removed
+        if (cachedItem != null) {
+            CachedStatement cs = (CachedStatement) cachedItem;
+            if (statement.getPreparedStatement() != cs.getPreparedStatement()) {
+                // DERBY-3786: Someone else has removed the statement from
+                // the cache, probably because of the same error that brought
+                // us here. In addition, someone else has recreated the
+                // statement. Since the recreated statement is not the same
+                // object as the one we are working on, we don't have the
+                // proper guarding (through the synchronized flag
+                // GenericStatement.preparedStmt.compilingStatement) to ensure
+                // that we're the only ones calling CacheManager.remove() on
+                // this statement. Therefore, just release the statement here
+                // so that we don't get in the way for the other thread that
+                // is trying to compile the same query.
+                statementCache.release(cachedItem);
+            } else {
+                // The statement object that we were trying to compile is still
+                // in the cache. Since the compilation failed, remove it.
+                statementCache.remove(cachedItem);
+            }
+        }
+    }
+
+    /**
+     * See if a given statement has already been compiled for this user, and
+     * if so use its prepared statement. Returns null if not found.
+     *
+     * @exception StandardException thrown if lookup goes wrong.
+     * @return the prepared statement for the given string, null
+     *  if none was found.
+     */
+    public PreparedStatement lookupStatement(GenericStatement statement)
+        throws StandardException {
+
+        CacheManager statementCache =
+            getLanguageConnectionFactory().getStatementCache();
+            
+        if (statementCache == null)
+            return null;
+
+        // statement caching disable when in DDL mode
+        if (dataDictionaryInWriteMode()) {
+            return null;
+        }
+
+        Cacheable cachedItem = statementCache.find(statement);
+
+        CachedStatement cs = (CachedStatement) cachedItem;
+
+
+        GenericPreparedStatement ps = cs.getPreparedStatement();
+
+        synchronized (ps) {
+            if (ps.upToDate()) {
+                GeneratedClass ac = ps.getActivationClass();
+
+                // Check to see if the statement was prepared before some change
+                // in the class loading set. If this is the case then force it to be invalid
+                int currentClasses =
+                        getLanguageConnectionFactory().getClassFactory().getClassLoaderVersion();
+
+                if (ac.getClassLoaderVersion() != currentClasses) {
+                    ps.makeInvalid(DependencyManager.INTERNAL_RECOMPILE_REQUEST, this);
+                }
+
+                // note that the PreparedStatement is not kept in the cache. This is because
+                // having items kept in the cache that ultimately are held onto by
+                // user code is impossible to manage. E.g. an open ResultSet would hold onto
+                // a PreparedStatement (through its activation) and the user can allow
+                // this object to be garbage collected. Pushing a context stack is impossible
+                // in garbage collection as it may deadlock with the open connection and
+                // the context manager assumes a singel current thread per context stack
+            }
+        }
+
+        statementCache.release(cachedItem);
+        return ps;
+    }
+
+    /**
+        Get a connection unique system generated name for a cursor.
+    */
+    public String getUniqueCursorName() 
+    {
+        return getNameString("SQLCUR", nextCursorId++);
+    }
+
+    /**
+        Get a connection unique system generated name for an unnamed savepoint.
+    */
+    public String getUniqueSavepointName()
+    {
+        return getNameString("SAVEPT", nextSavepointId++);
+    }
+
+    /**
+        Get a connection unique system generated id for an unnamed savepoint.
+    */
+    public int getUniqueSavepointID()
+    {
+        return nextSavepointId-1;
+    }
+
+    /**
+     * Build a String for a statement name.
+     *
+     * @param prefix    The prefix for the statement name.
+     * @param number    The number to append for uniqueness
+     *
+     * @return  A unique String for a statement name.
+     */
+    private String getNameString(String prefix, long number)
+    {
+        if (sb != null)
+        {
+            sb.setLength(0);
+        }
+        else
+        {
+            sb = new StringBuffer();
+        }
+        sb.append(prefix).append(number);
+
+        return sb.toString();
+    }
+
+    /**
+     * Do a commit as appropriate for an internally generated
+     * commit (e.g. as needed by sync, or autocommit).
+     *
+     * @param   commitStore true if we should commit the Store transaction
+     *
+     * @exception StandardException thrown on failure
+     */
+    public void internalCommit(boolean commitStore) throws StandardException
+    {
+        doCommit(commitStore, true, NON_XA, false);
+    }
+
+    /**
+     * Do a commmit as is appropriate for a user requested
+     * commit (e.g. a java.sql.Connection.commit() or a language
+     * 'COMMIT' statement.  Does some extra checking to make
+     * sure that users aren't doing anything bad.
+     *
+     * @exception StandardException thrown on failure
+     */
+    public void userCommit() throws StandardException
+    {
+        doCommit(true, true, NON_XA, true);
+    }
+
+
+    /**
+        Commit the language transaction by doing a commitNoSync()
+        on the store's TransactionController.
+
+        <p>
+        Do *NOT* tell the data dictionary that the transaction is
+        finished. The reason is that this would allow other transactions
+        to see comitted DDL that could be undone in the event of a
+        system crash.
+
+        @param  commitflag  the flags to pass to commitNoSync in the store's
+                            TransactionController
+
+        @exception StandardException thrown on failure
+     */
+    public final void internalCommitNoSync(int commitflag) 
+        throws StandardException
+    {
+        doCommit(true, false, commitflag, false);
+    }
+
+
+    /**
+        Same as userCommit except commit a distributed transaction.   
+        This commit always commit store and sync the commit.
+
+        @param onePhase if true, allow it to commit without first going thru a
+        prepared state.
+
+        @exception StandardException    thrown if something goes wrong
+     */
+    public final void xaCommit(boolean onePhase) throws StandardException
+    {
+        // further overload internalCommit to make it understand 2 phase commit
+        doCommit(true /* commit store */,
+                                  true /* sync */,
+                                  onePhase ? XA_ONE_PHASE : XA_TWO_PHASE,
+                                  true);
+    }
+
+
+    /**
+     * This is where the work on internalCommit(), userCOmmit() and 
+     * internalCommitNoSync() actually takes place.
+     * <p>
+     * When a commit happens, the language connection context
+     * will close all open activations/cursors and commit the
+     * Store transaction.
+     * <p>
+     * REVISIT: we talked about having a LanguageTransactionContext,
+     * but since store transaction management is currently in flux
+     * and our context might want to delegate to that context,
+     * for now all commit/rollback actions are handled directly by
+     * the language connection context.
+     * REVISIT: this may need additional alterations when
+     * RELEASE SAVEPOINT/ROLLBACK TO SAVEPOINT show up.
+     * <P>
+     * Since the access manager's own context takes care of its own
+     * resources on commit, and the transaction stays open, there is
+     * nothing that this context has to do with the transaction controller.
+     * <p>
+     * Also, tell the data dictionary that the transaction is finished,
+     * if necessary (that is, if the data dictionary was put into
+     * DDL mode in this transaction.
+     *
+     *
+     * @param   commitStore true if we should commit the Store transaction
+     * @param   sync        true means do a synchronized commit,
+     *                      false means do an unsynchronized commit
+     * @param   commitflag  if this is an unsynchronized commit, the flags to
+     *                      pass to commitNoSync in the store's
+     *                      TransactionController.  If this is a synchronized
+     *                      commit, this flag is overloaded for xacommit.
+     * @param   requestedByUser    False iff the commit is for internal use and
+     *                      we should ignore the check to prevent commits
+     *                      in an atomic statement.
+     *
+     * @exception StandardException     Thrown on error
+     */
+
+    protected void doCommit(boolean commitStore,
+                                               boolean sync,
+                                               int commitflag,
+                                               boolean requestedByUser)
+         throws StandardException
+    {
+        StatementContext statementContext = getStatementContext();
+        if (requestedByUser  &&
+            (statementContext != null) &&
+            statementContext.inUse() &&
+            statementContext.isAtomic())
+        {
+            throw StandardException.newException(SQLState.LANG_NO_COMMIT_IN_NESTED_CONNECTION);
+        }
+
+        // Log commit to error log, if appropriate
+        if (logStatementText)
+        {
+            if (istream == null)
+            {
+                istream = Monitor.getStream();
+            }
+            String xactId = tran.getTransactionIdString();
+            istream.printlnWithHeader(
+                LanguageConnectionContext.xidStr + 
+                xactId + 
+                "), " +
+                LanguageConnectionContext.lccStr +
+                instanceNumber +
+                "), " + LanguageConnectionContext.dbnameStr +
+                dbname +
+                "), " +
+                LanguageConnectionContext.drdaStr +
+                drdaID +
+                "), Committing");
+        }
+
+        endTransactionActivationHandling(false);
+
+        // do the clean up work required for temporary tables at the commit 
+        // time.  This cleanup work can possibly remove entries from 
+        // allDeclaredGlobalTempTables and that's why we need to check
+        // again later to see if we there are still any entries in 
+        // allDeclaredGlobalTempTables
+        if (allDeclaredGlobalTempTables != null)
+        {
+            tempTablesAndCommit();
+
+            // at commit time, for all the temp tables declared with 
+            // ON COMMIT DELETE ROWS, make sure there are no held cursor open
+            // on them.
+            // 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
+
+            if (allDeclaredGlobalTempTables != null) 
+            {
+                for (int i=0; i<allDeclaredGlobalTempTables.size(); i++)
+                {
+                    TableDescriptor td = 
+                        ((TempTableInfo)
+                         (allDeclaredGlobalTempTables.get(i))).getTableDescriptor();
+                    if (td.isOnCommitDeleteRows() == false) 
+                    {
+                        //do nothing for temp table with ON COMMIT PRESERVE ROWS
+                        continue;
+                    }
+
+                    if (checkIfAnyActivationHasHoldCursor(td.getName()) == 
+                            false)
+                    {
+                        // temp tables with ON COMMIT DELETE ROWS and 
+                        // no open held cursors
+                        getDataDictionary().getDependencyManager().invalidateFor(
+                            td, DependencyManager.DROP_TABLE, this);
+
+                        cleanupTempTableOnCommitOrRollback(td, true);
+                    }
+                }
+            }
+        }
+
+
+        //reset the current savepoint level for the connection to 0 at the end 
+        //of commit work for temp tables
+        currentSavepointLevel = 0; 
+
+        // Do *NOT* tell the DataDictionary to start using its cache again
+        // if this is an unsynchronized commit. The reason is that it
+        // would allow other transactions to see this transaction's DDL,
+        // which could be rolled back in case of a system crash.
+        if (sync)
+        {
+            finishDDTransaction();
+        }
+        
+        // Check that any nested transaction has been destoyed
+        // before a commit.
+        if (SanityManager.DEBUG)
+        {
+            if (readOnlyNestedTransaction != null)
+            {
+                SanityManager.THROWASSERT("Nested transaction active!");
+            }
+        }
+
+        // now commit the Store transaction
+        TransactionController tc = getTransactionExecute();
+        if ( tc != null && commitStore ) 
+        { 
+            if (sync)
+            {
+                if (commitflag == NON_XA)
+                {
+                    // regular commit
+                    tc.commit();
+                }
+                else
+                {
+                    // This may be a xa_commit, check overloaded commitflag.
+
+                    if (SanityManager.DEBUG)
+                        SanityManager.ASSERT(commitflag == XA_ONE_PHASE ||
+                                             commitflag == XA_TWO_PHASE,
+                                               "invalid commit flag");
+
+                    ((XATransactionController)tc).xa_commit(
+                            commitflag == XA_ONE_PHASE);
+
+                }
+            }
+            else
+            {
+                tc.commitNoSync(commitflag);
+            }
+
+            // reset the savepoints to the new
+            // location, since any outer nesting
+            // levels expect there to be a savepoint
+            resetSavepoints();
+        }
+    }
+
+    /**
+     * If dropAndRedeclare is true, that means we have come here for temp 
+     * tables with on commit delete rows and no held curosr open on them. We 
+     * will drop the existing conglomerate and redeclare a new conglomerate
+     * similar to old conglomerate. This is a more efficient way of deleting 
+     * all rows from the table.
+     *
+     * If dropAndRedeclare is false, that means we have come here for the 
+     * rollback cleanup work. We are trying to restore old definition of the 
+     * temp table (because the drop on it is being rolled back).
+     */
+    private TableDescriptor cleanupTempTableOnCommitOrRollback(
+    TableDescriptor td, 
+    boolean         dropAndRedeclare)
+         throws StandardException
+    {
+        //create new conglomerate with same properties as the old conglomerate 
+        //and same row template as the old conglomerate
+        long conglomId = 
+            tran.createConglomerate(
+                "heap", // we're requesting a heap conglomerate
+                td.getEmptyExecRow().getRowArray(), // row template
+                null, //column sort order - not required for heap
+                td.getColumnCollationIds(),  // same ids as old conglomerate
+                null, // properties
+                (TransactionController.IS_TEMPORARY | 
+                 TransactionController.IS_KEPT));
+
+        long cid = td.getHeapConglomerateId();
+
+        //remove the old conglomerate descriptor from the table descriptor
+        ConglomerateDescriptor cgd = td.getConglomerateDescriptor(cid);
+        td.getConglomerateDescriptorList().dropConglomerateDescriptorByUUID(
+            cgd.getUUID());
+
+        //add the new conglomerate descriptor to the table descriptor
+        cgd = getDataDictionary().getDataDescriptorGenerator().newConglomerateDescriptor(conglomId, null, false, null, false, null, td.getUUID(),
+        td.getSchemaDescriptor().getUUID());
+        ConglomerateDescriptorList conglomList = 
+            td.getConglomerateDescriptorList();
+        conglomList.add(cgd);
+
+        //reset the heap conglomerate number in table descriptor to -1 so it 
+        //will be refetched next time with the new value
+        td.resetHeapConglomNumber();
+
+        if(dropAndRedeclare)
+        {
+            //remove the old conglomerate from the system
+            tran.dropConglomerate(cid); 
+
+            replaceDeclaredGlobalTempTable(td.getName(), td);
+        }
+
+        return(td);
+    }
+
+    /**
+      Do a rollback as appropriate for an internally generated
+      rollback (e.g. as needed by sync, or autocommit).
+     
+      When a rollback happens, we 
+      close all open activations and invalidate their
+      prepared statements.  We then tell the cache to
+      age out everything else, which effectively invalidates
+      them.  Thus, all prepared statements will be
+      compiled anew on their 1st execution after
+      a rollback.
+      <p>
+      The invalidated statements can revalidate themselves without
+      a full recompile if they verify their dependencies' providers still
+      exist unchanged. REVISIT when invalidation types are created.
+      <p>
+      REVISIT: this may need additional alterations when
+      RELEASE SAVEPOINT/ROLLBACK TO SAVEPOINT show up.
+      <p>
+      Also, tell the data dictionary that the transaction is finished,
+      if necessary (that is, if the data dictionary was put into
+      DDL mode in this transaction.
+
+      @exception StandardException thrown on failure
+     */
+
+    public void internalRollback() throws StandardException 
+    {
+        doRollback(false /* non-xa */, false);
+    }
+
+    /**
+     * Do a rollback as is appropriate for a user requested
+     * rollback (e.g. a java.sql.Connection.rollback() or a language
+     * 'ROLLBACk' statement.  Does some extra checking to make
+     * sure that users aren't doing anything bad.
+     *
+     * @exception StandardException thrown on failure
+     */
+    public void userRollback() throws StandardException
+    {
+        doRollback(false /* non-xa */, true);
+    }
+
+    /**
+        Same as userRollback() except rolls back a distrubuted transaction.
+
+        @exception StandardException    thrown if something goes wrong
+     */
+    public void xaRollback() throws StandardException
+    {
+        doRollback(true /* xa */, true);
+    }
+
+    /**
+     * When a rollback happens, the language connection context
+     * will close all open activations and invalidate
+     * their prepared statements. Then the language will abort the
+     * Store transaction.
+     * <p>
+     * The invalidated statements can revalidate themselves without
+     * a full recompile if they verify their dependencies' providers still
+     * exist unchanged. REVISIT when invalidation types are created.
+     * <p>
+     * REVISIT: this may need additional alterations when
+     * RELEASE SAVEPOINT/ROLLBACK TO SAVEPOINT show up.
+     * <p>
+     * Also, tell the data dictionary that the transaction is finished,
+     * if necessary (that is, if the data dictionary was put into
+     * DDL mode in this transaction.
+     *
+     * @param xa    true if this is an xa rollback
+     * @param requestedByUser   true if requested by user
+     *
+     * @exception StandardException thrown on failure
+     */
+    private void doRollback(boolean xa, boolean requestedByUser) throws StandardException
+    {
+        StatementContext statementContext = getStatementContext();
+        if (requestedByUser &&
+            (statementContext != null) &&
+            statementContext.inUse() &&
+            statementContext.isAtomic())
+        {
+            throw StandardException.newException(SQLState.LANG_NO_ROLLBACK_IN_NESTED_CONNECTION);
+        }
+
+        // Log rollback to error log, if appropriate
+        if (logStatementText)
+        {
+            if (istream == null)
+            {
+                istream = Monitor.getStream();
+            }
+            String xactId = tran.getTransactionIdString();
+            istream.printlnWithHeader(LanguageConnectionContext.xidStr +
+                                      xactId + 
+                                      "), " +
+                                      LanguageConnectionContext.lccStr +
+                                      instanceNumber +
+                                      "), " + LanguageConnectionContext.dbnameStr +
+                                          dbname +
+                                          "), " +
+                                          LanguageConnectionContext.drdaStr +
+                                          drdaID +
+                                      "), Rolling back");
+        }
+
+        endTransactionActivationHandling(true);
+
+        currentSavepointLevel = 0; //reset the current savepoint level for the connection to 0 at the beginning of rollback work for temp tables
+        if (allDeclaredGlobalTempTables != null)
+            tempTablesAndRollback();
+
+        finishDDTransaction();
+        
+        // If a nested transaction is active then
+        // ensure it is destroyed before working
+        // with the user transaction.
+        if (readOnlyNestedTransaction != null)
+        {
+            readOnlyNestedTransaction.destroy();
+            readOnlyNestedTransaction = null;
+            queryNestingDepth = 0;
+        }
+
+        // now rollback the Store transaction
+        TransactionController tc = getTransactionExecute();
+        if (tc != null) 
+        {   
+            if (xa)
+                ((XATransactionController)tc).xa_rollback();
+            else
+                tc.abort(); 
+            
+            // reset the savepoints to the new
+            // location, since any outer nesting

[... 4607 lines stripped ...]


Mime
View raw message