EMMA Coverage Report (generated Wed Jun 28 22:15:27 PDT 2006)
[all classes][org.apache.derby.impl.sql.conn]

COVERAGE SUMMARY FOR SOURCE FILE [GenericLanguageConnectionContext.java]

nameclass, %method, %block, %line, %
GenericLanguageConnectionContext.java100% (1/1)90%  (129/144)88%  (2577/2917)88%  (650.2/739)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class GenericLanguageConnectionContext100% (1/1)90%  (129/144)88%  (2577/2917)88%  (650.2/739)
GenericLanguageConnectionContext (ContextManager, TransactionController, Lang... 100% (1/1)100% (133/133)100% (35/35)
addActivation (Activation): void 100% (1/1)32%  (8/25)60%  (3/5)
addDeclaredGlobalTempTable (TableDescriptor): void 100% (1/1)100% (34/34)100% (7/7)
anyoneBlocked (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
appendErrorInfo (): StringBuffer 100% (1/1)97%  (65/67)94%  (16/17)
appendOptimizerTraceOutput (String): void 0%   (0/1)0%   (0/17)0%   (0/2)
autoincrementCreateCounter (String, String, String, Long, long, int): void 100% (1/1)80%  (39/49)80%  (8/10)
autoincrementFlushCache (UUID): void 100% (1/1)100% (53/53)100% (15/15)
beginNestedTransaction (boolean): void 100% (1/1)100% (16/16)100% (4/4)
checkIfAnyActivationHasHoldCursor (String): boolean 100% (1/1)100% (24/24)100% (5/5)
checkIfAnyDeclaredGlobalTempTablesForThisConnection (): boolean 100% (1/1)100% (7/7)100% (1/1)
cleanupOnError (Throwable): void 100% (1/1)99%  (72/73)94%  (17/18)
cleanupTempTableOnCommitOrRollback (TableDescriptor, boolean): TableDescriptor 100% (1/1)100% (63/63)100% (12/12)
commitNestedTransaction (): void 100% (1/1)100% (19/19)100% (6/6)
convertIdentifierCase (String): String 100% (1/1)70%  (7/10)67%  (2/3)
copyHashtableToAIHT (Hashtable): void 100% (1/1)97%  (32/33)89%  (8/9)
dataDictionaryInWriteMode (): boolean 100% (1/1)100% (3/3)100% (1/1)
decrementBindCount (): int 100% (1/1)55%  (12/22)75%  (3/4)
decrementStatementDepth (): void 100% (1/1)100% (7/7)100% (2/2)
doCommit (boolean, boolean, int, boolean): void 100% (1/1)99%  (160/161)100% (31.9/32)
doRollback (boolean, boolean): void 100% (1/1)94%  (94/100)90%  (18/20)
dropAllDeclaredGlobalTempTables (): void 100% (1/1)78%  (49/63)69%  (14.5/21)
dropDeclaredGlobalTempTable (String): boolean 100% (1/1)90%  (38/42)82%  (9/11)
emptyCache (): void 100% (1/1)100% (7/7)100% (3/3)
findDeclaredGlobalTempTable (String): TempTableInfo 100% (1/1)100% (30/30)100% (6/6)
finishDDTransaction (): void 100% (1/1)100% (12/12)100% (5/5)
getAccessFactory (): AccessFactory 0%   (0/1)0%   (0/3)0%   (0/1)
getActivationCount (): int 100% (1/1)100% (4/4)100% (1/1)
getAuthorizationId (): String 100% (1/1)100% (4/4)100% (1/1)
getAuthorizationId (String): String 100% (1/1)100% (8/8)100% (3/3)
getAuthorizer (): Authorizer 100% (1/1)100% (3/3)100% (1/1)
getAutoincrementUpdate (): boolean 100% (1/1)100% (3/3)100% (1/1)
getBindCount (): int 100% (1/1)100% (3/3)100% (1/1)
getCacheSize (): int 0%   (0/1)0%   (0/9)0%   (0/3)
getCurrentIsolationLevel (): int 100% (1/1)100% (9/9)100% (1/1)
getCurrentIsolationLevelStr (): String 100% (1/1)71%  (15/21)67%  (2/3)
getCurrentSchemaName (): String 100% (1/1)80%  (8/10)67%  (2/3)
getDataDictionary (): DataDictionary 100% (1/1)85%  (11/13)75%  (3/4)
getDataValueFactory (): DataValueFactory 100% (1/1)100% (3/3)100% (1/1)
getDatabase (): Database 100% (1/1)100% (3/3)100% (1/1)
getDbname (): String 100% (1/1)100% (3/3)100% (1/1)
getDeclaredGlobalTemporaryTablesSchemaName (): String 100% (1/1)100% (4/4)100% (1/1)
getDefaultSchema (): SchemaDescriptor 100% (1/1)100% (3/3)100% (1/1)
getDrdaID (): String 100% (1/1)100% (3/3)100% (1/1)
getExecutionContext (): ExecutionContext 100% (1/1)100% (6/6)100% (1/1)
getIdentifierCasing (): int 100% (1/1)100% (10/10)100% (3/3)
getIdentityValue (): Long 100% (1/1)100% (11/11)100% (1/1)
getInstanceNumber (): int 100% (1/1)100% (3/3)100% (1/1)
getLanguageConnectionFactory (): LanguageConnectionFactory 100% (1/1)100% (3/3)100% (1/1)
getLanguageFactory (): LanguageFactory 100% (1/1)100% (3/3)100% (1/1)
getLastActivation (): Activation 0%   (0/1)0%   (0/5)0%   (0/1)
getLockEscalationThreshold (): int 100% (1/1)100% (3/3)100% (1/1)
getLockObject (int): Object 0%   (0/1)0%   (0/13)0%   (0/4)
getLogQueryPlan (): boolean 100% (1/1)100% (3/3)100% (1/1)
getLogStatementText (): boolean 100% (1/1)100% (3/3)100% (1/1)
getNameString (String, long): String 100% (1/1)100% (24/24)100% (5/5)
getOptimizerFactory (): OptimizerFactory 100% (1/1)100% (3/3)100% (1/1)
getOptimizerTrace (): boolean 100% (1/1)100% (3/3)100% (1/1)
getOptimizerTraceHtml (): boolean 100% (1/1)100% (3/3)100% (1/1)
getOptimizerTraceOutput (): String 0%   (0/1)0%   (0/3)0%   (0/1)
getPrepareIsolationLevel (): int 100% (1/1)100% (8/8)100% (3/3)
getRunTimeStatisticsMode (): boolean 100% (1/1)100% (3/3)100% (1/1)
getRunTimeStatisticsObject (): RunTimeStatistics 100% (1/1)100% (3/3)100% (1/1)
getStatementContext (): StatementContext 100% (1/1)100% (6/6)100% (1/1)
getStatementDepth (): int 100% (1/1)100% (3/3)100% (1/1)
getStatisticsTiming (): boolean 100% (1/1)100% (3/3)100% (1/1)
getSysIBMSchemaName (): String 100% (1/1)100% (4/4)100% (1/1)
getSystemDiagSchemaName (): String 100% (1/1)100% (4/4)100% (1/1)
getSystemSchemaName (): String 100% (1/1)100% (4/4)100% (1/1)
getSystemUtilSchemaName (): String 100% (1/1)100% (4/4)100% (1/1)
getTableDescriptorForDeclaredGlobalTempTable (String): TableDescriptor 100% (1/1)100% (11/11)100% (4/4)
getTransactionCompile (): TransactionController 100% (1/1)100% (9/9)100% (1/1)
getTransactionExecute (): TransactionController 100% (1/1)100% (3/3)100% (1/1)
getTriggerExecutionContext (): TriggerExecutionContext 100% (1/1)100% (12/12)100% (1/1)
getTriggerTable (): TableDescriptor 100% (1/1)75%  (9/12)75%  (0.8/1)
getUniqueCursorName (): String 100% (1/1)100% (11/11)100% (1/1)
getUniqueSavepointID (): int 100% (1/1)100% (5/5)100% (1/1)
getUniqueSavepointName (): String 100% (1/1)100% (12/12)100% (1/1)
incrementBindCount (): int 100% (1/1)100% (9/9)100% (2/2)
incrementStatementDepth (): void 100% (1/1)100% (7/7)100% (1/1)
initDefaultSchemaDescriptor (): SchemaDescriptor 100% (1/1)100% (30/30)100% (5/5)
initialize (boolean): void 100% (1/1)88%  (21/24)71%  (5/7)
internalCommit (boolean): void 100% (1/1)100% (7/7)100% (2/2)
internalCommitNoSync (int): void 100% (1/1)100% (7/7)100% (2/2)
internalRollback (): void 100% (1/1)100% (5/5)100% (2/2)
internalRollbackToSavepoint (String, boolean, Object): void 100% (1/1)100% (32/32)100% (10/10)
isIsolationLevelSetUsingSQLorJDBC (): boolean 100% (1/1)100% (3/3)100% (1/1)
isLastHandler (int): boolean 100% (1/1)100% (2/2)100% (1/1)
isReadOnly (): boolean 100% (1/1)100% (4/4)100% (1/1)
isTransactionPristine (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
languageSetSavePoint (String, Object): void 100% (1/1)100% (12/12)100% (4/4)
lastAutoincrementValue (String, String, String): Long 100% (1/1)56%  (24/43)44%  (4.9/11)
lookupCursorActivation (String): CursorActivation 100% (1/1)98%  (44/45)93%  (14/15)
lookupStatement (GenericStatement): PreparedStatement 100% (1/1)91%  (53/58)96%  (15.4/16)
markTempTableAsModifiedInUnitOfWork (String): void 100% (1/1)100% (9/9)100% (3/3)
nextAutoincrementValue (String, String, String): long 100% (1/1)59%  (16/27)67%  (4/6)
popCompilerContext (CompilerContext): void 100% (1/1)100% (22/22)100% (7/7)
popExecutionStmtValidator (ExecutionStmtValidator): void 100% (1/1)42%  (8/19)75%  (3/4)
popStatementContext (StatementContext, Throwable): void 100% (1/1)55%  (61/111)69%  (13.8/20)
popTriggerExecutionContext (TriggerExecutionContext): void 100% (1/1)59%  (16/27)83%  (5/6)
popTriggerTable (TableDescriptor): void 100% (1/1)47%  (8/17)75%  (3/4)
prepareInternalStatement (SchemaDescriptor, String): PreparedStatement 100% (1/1)100% (8/8)100% (1/1)
prepareInternalStatement (String): PreparedStatement 100% (1/1)100% (9/9)100% (1/1)
pushCompilerContext (): CompilerContext 100% (1/1)100% (5/5)100% (1/1)
pushCompilerContext (SchemaDescriptor): CompilerContext 100% (1/1)100% (52/52)100% (13/13)
pushExecutionStmtValidator (ExecutionStmtValidator): void 100% (1/1)100% (5/5)100% (2/2)
pushStatementContext (boolean, String, ParameterValueSet, boolean): Statement... 100% (1/1)100% (116/116)100% (25/25)
pushTriggerExecutionContext (TriggerExecutionContext): void 100% (1/1)100% (21/21)100% (6/6)
pushTriggerTable (TableDescriptor): void 100% (1/1)100% (5/5)100% (2/2)
releaseSavePoint (String, Object): void 100% (1/1)100% (17/17)100% (6/6)
removeActivation (Activation): void 100% (1/1)100% (27/27)100% (6/6)
removeStatement (Statement): void 100% (1/1)94%  (15/16)83%  (5/6)
replaceDeclaredGlobalTempTable (String, TableDescriptor): void 100% (1/1)100% (23/23)100% (6/6)
resetActivations (boolean): void 100% (1/1)98%  (49/50)93%  (14/15)
resetFromPool (): void 100% (1/1)100% (6/6)100% (3/3)
resetIsolationLevelFlagUsedForSQLandJDBC (): void 100% (1/1)100% (4/4)100% (2/2)
resetSavepoints (StatementContext): void 100% (1/1)100% (36/36)100% (12/12)
resetStatementDepth (): void 0%   (0/1)0%   (0/4)0%   (0/2)
setAutoincrementUpdate (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setDataDictionaryWriteMode (): void 100% (1/1)100% (4/4)100% (2/2)
setDefaultSchema (SchemaDescriptor): void 100% (1/1)100% (9/9)100% (4/4)
setDrdaID (String): void 100% (1/1)100% (4/4)100% (2/2)
setIdentityValue (long): void 100% (1/1)100% (7/7)100% (3/3)
setIsolationLevel (int): void 100% (1/1)81%  (39/48)87%  (13/15)
setLogStatementText (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setOptimizerTrace (boolean): boolean 0%   (0/1)0%   (0/16)0%   (0/6)
setOptimizerTraceHtml (boolean): boolean 0%   (0/1)0%   (0/16)0%   (0/6)
setOptimizerTraceOutput (String): void 0%   (0/1)0%   (0/11)0%   (0/4)
setPrepareIsolationLevel (int): void 100% (1/1)100% (4/4)100% (2/2)
setReadOnly (boolean): void 100% (1/1)100% (13/13)100% (4/4)
setRunTimeStatisticsMode (boolean): void 100% (1/1)100% (4/4)100% (2/2)
setRunTimeStatisticsObject (RunTimeStatistics): void 100% (1/1)100% (4/4)100% (2/2)
setStatisticsTiming (boolean): void 100% (1/1)100% (4/4)100% (2/2)
setTransaction (TransactionController): void 0%   (0/1)0%   (0/4)0%   (0/1)
tempTablesAndCommit (): void 100% (1/1)100% (33/33)100% (7/7)
tempTablesAndRollback (): void 100% (1/1)100% (110/110)100% (24/24)
tempTablesReleaseSavepointLevels (): void 100% (1/1)91%  (39/43)89%  (8/9)
userCommit (): void 100% (1/1)100% (7/7)100% (2/2)
userRollback (): void 100% (1/1)100% (5/5)100% (2/2)
validateStmtExecution (ConstantAction): void 100% (1/1)96%  (24/25)98%  (4.9/5)
verifyAllHeldResultSetsAreClosed (): boolean 100% (1/1)100% (95/95)100% (27/27)
verifyNoOpenResultSets (PreparedStatement, Provider, int): boolean 100% (1/1)95%  (95/100)89%  (25/28)
xaCommit (boolean): void 100% (1/1)100% (11/11)100% (2/2)
xaRollback (): void 100% (1/1)100% (5/5)100% (2/2)

1/*
2 
3   Derby - Class org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext
4 
5   Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable.
6 
7   Licensed under the Apache License, Version 2.0 (the "License");
8   you may not use this file except in compliance with the License.
9   You may obtain a copy of the License at
10 
11      http://www.apache.org/licenses/LICENSE-2.0
12 
13   Unless required by applicable law or agreed to in writing, software
14   distributed under the License is distributed on an "AS IS" BASIS,
15   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   See the License for the specific language governing permissions and
17   limitations under the License.
18 
19 */
20 
21package org.apache.derby.impl.sql.conn;
22 
23import org.apache.derby.iapi.services.context.ContextImpl;
24import org.apache.derby.iapi.services.cache.CacheManager;
25 
26import org.apache.derby.impl.sql.compile.CompilerContextImpl;
27import org.apache.derby.impl.sql.execute.InternalTriggerExecutionContext;
28import org.apache.derby.impl.sql.execute.AutoincrementCounter;
29import org.apache.derby.impl.sql.GenericPreparedStatement;
30import org.apache.derby.impl.sql.GenericStatement;
31import org.apache.derby.iapi.sql.Statement;
32import org.apache.derby.impl.sql.conn.CachedStatement;
33 
34import org.apache.derby.iapi.services.property.PropertyUtil;
35import org.apache.derby.iapi.services.context.Context;
36import org.apache.derby.iapi.services.context.ContextManager;
37import org.apache.derby.iapi.services.monitor.Monitor;
38import org.apache.derby.iapi.services.sanity.SanityManager;
39import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
40import org.apache.derby.iapi.services.loader.GeneratedClass;
41import org.apache.derby.iapi.services.cache.Cacheable;
42import org.apache.derby.iapi.db.Database;
43import org.apache.derby.iapi.error.StandardException;
44import org.apache.derby.iapi.sql.compile.CompilerContext;
45import org.apache.derby.iapi.sql.compile.OptimizerFactory;
46import org.apache.derby.iapi.sql.conn.Authorizer;
47import org.apache.derby.iapi.error.ExceptionSeverity;
48import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
49import org.apache.derby.iapi.sql.conn.LanguageConnectionFactory;
50import org.apache.derby.iapi.sql.conn.StatementContext;
51import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
52import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptorList;
53import org.apache.derby.iapi.sql.dictionary.DataDictionary;
54import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext;
55import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
56import        org.apache.derby.iapi.sql.dictionary.TableDescriptor;
57import org.apache.derby.iapi.types.DataValueFactory;
58import org.apache.derby.iapi.sql.compile.TypeCompilerFactory;
59import org.apache.derby.iapi.sql.depend.DependencyManager;
60import org.apache.derby.iapi.sql.depend.Provider;
61import org.apache.derby.iapi.reference.SQLState;
62import org.apache.derby.iapi.reference.Limits;
63import org.apache.derby.iapi.sql.execute.ConstantAction;
64import org.apache.derby.iapi.sql.execute.CursorActivation;
65import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;
66import org.apache.derby.iapi.sql.execute.ExecutionContext;
67import org.apache.derby.iapi.sql.execute.ExecutionStmtValidator;
68import org.apache.derby.iapi.sql.Activation;
69import org.apache.derby.iapi.sql.LanguageFactory;
70import org.apache.derby.iapi.sql.PreparedStatement;
71import org.apache.derby.iapi.sql.ResultSet;
72import org.apache.derby.iapi.sql.ParameterValueSet;
73 
74import org.apache.derby.iapi.store.access.TransactionController;
75import org.apache.derby.iapi.store.access.AccessFactory;
76import org.apache.derby.iapi.store.access.XATransactionController;
77import org.apache.derby.iapi.util.IdUtil;
78import org.apache.derby.iapi.util.StringUtil;
79 
80import org.apache.derby.catalog.UUID;
81import org.apache.derby.iapi.sql.execute.RunTimeStatistics;
82import org.apache.derby.iapi.db.TriggerExecutionContext;
83import org.apache.derby.iapi.reference.Property;
84 
85import java.util.List;
86import java.util.ArrayList;
87import java.util.Enumeration;
88import java.util.Hashtable;
89import java.util.Properties;
90import java.util.Vector;
91import java.util.Stack;
92import java.io.Serializable;
93 
94/**
95 * LanguageConnectionContext keeps the pool of prepared statements,
96 * activations, and cursors in use by the current connection.
97 * <p>
98 * The generic impl does not provide statement caching.
99 *
100 * @author ames
101 *
102 */
103public class GenericLanguageConnectionContext
104        extends ContextImpl 
105        implements LanguageConnectionContext
106{
107 
108        // make sure these are not zeros
109        private final static int NON_XA = 0;
110        private final static int XA_ONE_PHASE = 1;
111        private final static int XA_TWO_PHASE = 2;
112 
113        /*
114                fields
115         */
116 
117        private final Vector acts;
118        protected int bindCount;
119        private boolean ddWriteMode;
120        private boolean runTimeStatisticsSetting ;
121        private boolean statisticsTiming;
122 
123        //all the temporary tables declared for this connection
124        private ArrayList allDeclaredGlobalTempTables;
125        //The currentSavepointLevel is used to provide the rollback behavior of temporary tables.
126        //At any point, this variable has the total number of savepoints defined for the transaction.
127        private int currentSavepointLevel = 0;
128 
129        protected long        nextCursorId;
130 
131        protected int        nextSavepointId;
132 
133        private RunTimeStatistics runTimeStatisticsObject;
134        private StringBuffer sb;
135 
136        private Database db;
137 
138        private final int instanceNumber;
139        private String drdaID;
140        private String dbname;
141 
142    private int identifierCasing = UNKNOWN_CASING;
143    
144        /**
145        The transaction to use within this language connection context.  It may
146        be more appropriate to have it in a separate context (LanguageTransactionContext?).
147        REVISIT (nat): I shoehorned the transaction context that
148        the language uses into this class.  The main purpose is so
149        that the various language code can find out what its
150        transaction is.
151        **/
152        protected TransactionController tran;
153 
154        /**
155         * If non-null indicates that a nested user transaction is in progress.
156         */
157        protected TransactionController childTransaction;
158        
159        /**
160         * queryNestingDepth is a counter used to keep track of how many calls 
161         * have been made to begin nested transactions. Only the first call 
162         * actually starts a Nested User Transaction with the store. Subsequent
163         * calls simply increment this counter. commitNestedTransaction only
164         * decrements the counter and when it drops to 0 actually commits the 
165         * nested user transaction.
166         */
167        protected int queryNestingDepth;
168 
169        protected DataValueFactory dataFactory;
170        protected LanguageFactory langFactory;
171        protected TypeCompilerFactory tcf;
172        protected OptimizerFactory of;
173        protected LanguageConnectionFactory connFactory;
174        
175        /* 
176         * A statement context is "pushed" and "popped" at the beginning and
177     * end of every statement so that only that statement is cleaned up
178     * on a Statement Exception.  As a performance optimization, we only push
179     * the outermost statement context once, and never pop it.  Also, we
180         * save off a 2nd StatementContext for speeding server side method
181         * invocation, though we still push and pop it as needed.  All other
182     * statement contexts will allocated and pushed and popped on demand.
183     */
184        private final StatementContext[] statementContexts = new StatementContext[2];
185        private int     statementDepth;
186        protected int          outermostTrigger = -1;
187 
188    protected Authorizer authorizer;
189        protected String userName = null; //The name the user connects with.
190                                          //May still be quoted.
191        
192        protected SchemaDescriptor        sd;
193 
194        // RESOLVE - How do we want to set the default.
195    private int defaultIsolationLevel = ExecutionContext.READ_COMMITTED_ISOLATION_LEVEL;
196        protected int isolationLevel = defaultIsolationLevel;
197 
198        private boolean isolationLevelExplicitlySet = false;
199        // Isolation level can be changed using JDBC api Connection.setTransactionIsolation
200        // or it can be changed using SQL "set current isolation = NEWLEVEL".
201        // 
202        // In XA transactions, BrokeredConnection keeps isolation state information.
203        // When isolation is changed in XA transaction using JDBC, that state gets
204        // correctly set in BrokeredConnection.setTransactionIsolation method. But
205        // when SQL is used to set the isolation level, the code path is different
206        // and it does not go through BrokeredConnection's setTransactionIsolation
207        // method and hence the state is not maintained correctly when coming through
208        // SQL. To get around this, I am adding following flag which will get set
209        // everytime the isolation level is set using JDBC or SQL. This flag will be
210        // checked at global transaction start and end time. If the flag is set to true
211        // then BrokeredConnection's isolation level state will be brought upto date
212        // with Real Connection's isolation level and this flag will be set to false
213        // after that.
214        private boolean isolationLevelSetUsingSQLorJDBC = false;
215 
216        // isolation level to when preparing statements.
217        // if unspecified, the statement won't be prepared with a specific 
218        // scan isolationlevel
219        protected int prepareIsolationLevel = ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL;
220 
221        // Whether or not to write executing statement info to db2j.log
222        private boolean logStatementText;
223        private boolean logQueryPlan;
224        private HeaderPrintWriter istream;
225 
226        // this used to be computed in OptimizerFactoryContextImpl; i.e everytime a
227        // connection was made. To keep the semantics same I'm putting it out here
228        // instead of in the OptimizerFactory which is only initialized when the
229        // database is booted.
230        private int lockEscalationThreshold; 
231 
232        private Vector stmtValidators;
233        private Vector triggerExecutionContexts;
234        private Vector triggerTables;
235 
236        protected AccessFactory af;
237 
238        // OptimizerTrace
239        private boolean optimizerTrace;
240        private boolean optimizerTraceHtml;
241        private String lastOptimizerTraceOutput;
242        private String optimizerTraceOutput;
243 
244        //// Support for AUTOINCREMENT
245 
246        /**
247         * To support lastAutoincrementValue: This is a hashtable which maps
248         * schemaName,tableName,columnName to a Long value.
249         */
250        private Hashtable autoincrementHT;
251        /**
252         * whether to allow updates or not. 
253         */
254        private boolean autoincrementUpdate;
255        private long identityVal;        //support IDENTITY_VAL_LOCAL function
256        private boolean identityNotNull;        //frugal programmer
257 
258        // cache of ai being handled in memory (bulk insert + alter table).
259        private Hashtable autoincrementCacheHashtable;
260 
261        // temp public
262        public CacheManager statementCache;
263 
264        /*
265           constructor
266        */
267        public GenericLanguageConnectionContext
268        (
269         ContextManager cm,
270         TransactionController tranCtrl,
271 
272         LanguageFactory lf,
273         LanguageConnectionFactory lcf,
274         Database db,
275         String userName,
276         int instanceNumber,
277         String drdaID,
278         String dbname)
279                 throws StandardException
280        {
281                super(cm, org.apache.derby.iapi.reference.ContextId.LANG_CONNECTION);
282                acts = new Vector();
283                tran = tranCtrl;
284 
285                dataFactory = lcf.getDataValueFactory();
286                tcf = lcf.getTypeCompilerFactory();
287                of = lcf.getOptimizerFactory();
288                langFactory =  lf;
289                connFactory =  lcf;
290        this.db = db;
291                this.userName = userName;
292                this.instanceNumber = instanceNumber;
293                this.drdaID = drdaID;
294                this.dbname = dbname;
295 
296                /* Find out whether or not to log info on executing statements to error log
297                 */
298                String logStatementProperty = PropertyUtil.getServiceProperty(getTransactionCompile(),
299                                        "derby.language.logStatementText");
300                logStatementText = Boolean.valueOf(logStatementProperty).booleanValue();
301 
302                String logQueryPlanProperty = PropertyUtil.getServiceProperty(getTransactionCompile(),
303                                        "derby.language.logQueryPlan");
304                logQueryPlan = Boolean.valueOf(logQueryPlanProperty).booleanValue();
305 
306                setRunTimeStatisticsMode(logQueryPlan);
307 
308                lockEscalationThreshold = 
309                        PropertyUtil.getServiceInt(tranCtrl,
310                                                                           Property.LOCKS_ESCALATION_THRESHOLD,
311                                                                           Property.MIN_LOCKS_ESCALATION_THRESHOLD,
312                                                                           Integer.MAX_VALUE,
313                                                                           Property.DEFAULT_LOCKS_ESCALATION_THRESHOLD);                                                                                                                         
314                stmtValidators = new Vector();
315                triggerExecutionContexts = new Vector();
316                triggerTables = new Vector();
317                
318                af = lcf.getAccessFactory();
319                statementCache = lcf.getStatementCache();
320        }
321 
322        public void initialize(boolean sqlConnection) throws StandardException
323        {
324                //
325                //Creating the authorizer authorizes the connection.
326                authorizer = new GenericAuthorizer(IdUtil.getUserAuthorizationId(userName),this, sqlConnection);
327 
328                //we can ignore the following if this is a database connection
329                //associated with internal thread such as logSniffer and StageTrunc
330                if(!sqlConnection)
331                        return;
332 
333                /*
334                ** Set the authorization id.  User shouldn't
335                ** be null or else we are going to blow up trying
336                ** to create a schema for this user.
337                */
338                if (SanityManager.DEBUG)
339                {
340                        if (getAuthorizationId() == null)
341                        {
342                                SanityManager.THROWASSERT("User name is null," +
343                                        " check the connection manager to make sure it is set" +
344                                        " reasonably");
345                        }
346                }
347 
348 
349                setDefaultSchema(initDefaultSchemaDescriptor());
350        }
351 
352        protected SchemaDescriptor initDefaultSchemaDescriptor()
353                throws StandardException {
354                /*
355                ** - If the database supports schemas and a schema with the
356                ** same name as the user's name exists (has been created using
357                ** create schema already) the database will set the users
358                ** default schema to the the schema with the same name as the
359                ** user.
360        ** - Else Set the default schema to APP.
361        */
362                // SchemaDescriptor sd;
363 
364                DataDictionary dd = getDataDictionary();
365        String authorizationId = getAuthorizationId();
366        
367                if ( (sd = dd.getSchemaDescriptor(authorizationId, getTransactionCompile(), false)) == null )
368                {
369                        sd = new SchemaDescriptor(dd, authorizationId, authorizationId, (UUID) null, false);
370                }
371                return sd;
372        }
373 
374        //
375        // LanguageConnectionContext interface
376        //
377        /**
378         * @see LanguageConnectionContext#getLogStatementText
379         */
380        public boolean getLogStatementText()
381        {
382                return logStatementText;
383        }
384 
385        /**
386         * @see LanguageConnectionContext#setLogStatementText
387         */
388        public void setLogStatementText(boolean logStatementText)
389        {
390                this.logStatementText = logStatementText;
391        }
392 
393        /**
394         * @see LanguageConnectionContext#getLogQueryPlan
395         */
396        public boolean getLogQueryPlan()
397        {
398                return logQueryPlan;
399        }
400 
401        /**
402         * @see LanguageConnectionContext#usesSqlAuthorization
403         */
404        public boolean usesSqlAuthorization()
405        {
406                return getDataDictionary().usesSqlAuthorization();
407        }
408 
409        /**
410         * get the lock escalation threshold.
411         */
412        public int getLockEscalationThreshold()
413        {
414                return lockEscalationThreshold;
415        }
416 
417        /*
418                The methods that follow are for consistency checking purposes
419         */
420 
421        public int getCacheSize() {
422                if (statementCache != null)
423                        return statementCache.getNumberInUse();
424                else
425                        return 0;
426        }
427 
428        /**
429         * Add the activation to those known about by this connection.
430         */
431        public void addActivation(Activation a) {
432                acts.addElement(a);
433 
434                if (SanityManager.DEBUG) {
435 
436                        if (SanityManager.DEBUG_ON("memoryLeakTrace")) {
437 
438                                if (acts.size() > 20)
439                                        System.out.println("memoryLeakTrace:GenericLanguageContext:activations " + acts.size());
440                        }
441                }
442        }
443 
444        /**
445         * @see LanguageConnectionContext#checkIfAnyDeclaredGlobalTempTablesForThisConnection
446         */
447        public boolean checkIfAnyDeclaredGlobalTempTablesForThisConnection() {
448                return (allDeclaredGlobalTempTables == null ? false : true);
449        }
450 
451        /**
452         * @see LanguageConnectionContext#addDeclaredGlobalTempTable
453         */
454        public void addDeclaredGlobalTempTable(TableDescriptor td)
455                throws StandardException {
456 
457                if (findDeclaredGlobalTempTable(td.getName()) != null) //if table already declared, throw an exception
458                {
459                        throw
460                                StandardException.newException(
461                                                                                           SQLState.LANG_OBJECT_ALREADY_EXISTS_IN_OBJECT,
462                                                                                           "Declared global temporary table",
463                                                                                           td.getName(),
464                                                                                           "Schema",
465                                                                                           SchemaDescriptor.STD_DECLARED_GLOBAL_TEMPORARY_TABLES_SCHEMA_NAME);
466                }
467 
468                //save all the information about temp table in this special class
469                TempTableInfo tempTableInfo = new TempTableInfo(td, currentSavepointLevel);
470 
471                if (allDeclaredGlobalTempTables == null)
472                        allDeclaredGlobalTempTables = new ArrayList();
473 
474                allDeclaredGlobalTempTables.add(tempTableInfo);
475        }
476 
477        /**
478         * @see LanguageConnectionContext#dropDeclaredGlobalTempTable
479         */
480        public boolean dropDeclaredGlobalTempTable(String tableName) {
481    TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName);
482                if (tempTableInfo != null)
483                {
484                        if (SanityManager.DEBUG)
485                                if (tempTableInfo.getDeclaredInSavepointLevel() > currentSavepointLevel)
486                                        SanityManager.THROWASSERT("declared in savepoint level can not be higher than the current savepoint level");
487 
488                        //following checks if the table was declared in the current unit of work.
489                        if (tempTableInfo.getDeclaredInSavepointLevel() == currentSavepointLevel)
490                        {
491                                //since the table was declared in this unit of work,
492                                //the drop table method should remove it from the valid list of temp table for this unit of work
493                                allDeclaredGlobalTempTables.remove(allDeclaredGlobalTempTables.indexOf(tempTableInfo));
494                                if (allDeclaredGlobalTempTables.size() == 0)
495                                        allDeclaredGlobalTempTables = null;
496                        }
497                        else
498                        {
499                                //since the table was not declared in this unit of work, the drop table method will just mark the table as dropped
500                                //in the current unit of work. This information will be used at rollback time.
501                                tempTableInfo.setDroppedInSavepointLevel(currentSavepointLevel);
502                        }
503                        return true;
504                } else
505                        return false;
506        }
507 
508        /**
509         * After a release of a savepoint, we need to go through our temp tables list. If there are tables with their declare or drop
510         * or modified in savepoint levels set to savepoint levels higher than the current savepoint level, then we should change them
511         * to the current savepoint level
512         */
513        private void tempTablesReleaseSavepointLevels() {
514    //unlike rollback, here we check for dropped in / declared in / modified in savepoint levels > current savepoint level only.
515    //This is because the temp tables with their savepoint levels same as currentSavepointLevel have correct value assigned to them and
516    //do not need to be changed and hence no need to check for >=
517                for (int i = 0; i < allDeclaredGlobalTempTables.size(); i++) {
518                        TempTableInfo tempTableInfo = (TempTableInfo)allDeclaredGlobalTempTables.get(i);
519                        if (tempTableInfo.getDroppedInSavepointLevel() > currentSavepointLevel)
520                                tempTableInfo.setDroppedInSavepointLevel(currentSavepointLevel);
521 
522                        if (tempTableInfo.getDeclaredInSavepointLevel() > currentSavepointLevel)
523                                tempTableInfo.setDeclaredInSavepointLevel(currentSavepointLevel);
524 
525                        if (tempTableInfo.getModifiedInSavepointLevel() > currentSavepointLevel)
526                                tempTableInfo.setModifiedInSavepointLevel(currentSavepointLevel);
527                }
528        }
529 
530        /**
531         * do the necessary work at commit time for temporary tables
532         * 1)If a temporary table was marked as dropped in this transaction, then remove it from the list of temp tables for this connection
533         * 2)If a temporary table was not dropped in this transaction, then mark it's declared savepoint level and modified savepoint level as -1
534         */
535        private void tempTablesAndCommit() {
536                for (int i = allDeclaredGlobalTempTables.size()-1; i >= 0; i--) {
537                        TempTableInfo tempTableInfo = (TempTableInfo)allDeclaredGlobalTempTables.get(i);
538                        if (tempTableInfo.getDroppedInSavepointLevel() != -1)
539                        {
540                                //this means table was dropped in this unit of work and hence should be removed from valid list of temp tables
541                                allDeclaredGlobalTempTables.remove(i);
542                        } else //this table was not dropped in this unit of work, hence set its declaredInSavepointLevel as -1 and also mark it as not modified 
543                        {
544                                tempTableInfo.setDeclaredInSavepointLevel(-1);
545                                tempTableInfo.setModifiedInSavepointLevel(-1);
546                        }
547                }
548        }
549 
550        /**
551                Reset the connection before it is returned (indirectly) by
552                a PooledConnection object. See EmbeddedConnection.
553         */
554        public void resetFromPool()
555                 throws StandardException
556        {
557                // Reset IDENTITY_VAL_LOCAL
558                identityNotNull = false;
559 
560                // drop all temp tables.
561                dropAllDeclaredGlobalTempTables();
562        }
563 
564        /**
565         * Drop all the declared global temporary tables associated with this connection. This gets called
566         * when a getConnection() is done on a PooledConnection. This will ensure all the temporary tables
567         * declared on earlier connection handle associated with this physical database connection are dropped
568         * before a new connection handle is issued on that same physical database connection.
569         */
570        private void dropAllDeclaredGlobalTempTables() throws StandardException {
571                if (allDeclaredGlobalTempTables == null)
572                        return;
573    
574                DependencyManager dm = getDataDictionary().getDependencyManager();
575                StandardException topLevelStandardException = null;
576 
577                //collect all the exceptions we might receive while dropping the temporary tables and throw them as one chained exception at the end.
578                for (int i = 0; i < allDeclaredGlobalTempTables.size(); i++) {
579                        try {
580                                TempTableInfo tempTableInfo = (TempTableInfo)allDeclaredGlobalTempTables.get(i);
581                                TableDescriptor td = tempTableInfo.getTableDescriptor();
582                                //the following 2 lines of code has been copied from DropTableConstantAction. If there are any changes made there in future,
583                                //we should check if they need to be made here too.
584                                dm.invalidateFor(td, DependencyManager.DROP_TABLE, this);
585                                tran.dropConglomerate(td.getHeapConglomerateId());
586                        } catch (StandardException e) {
587                                e.setNestedException(topLevelStandardException);
588                                topLevelStandardException = e;
589                        }
590                }
591    
592                allDeclaredGlobalTempTables = null;
593                try {
594                        internalCommit(true);
595                } catch (StandardException e) {
596                        e.setNestedException(topLevelStandardException);
597                        topLevelStandardException = e;
598                }
599                if (topLevelStandardException != null) throw topLevelStandardException;
600        }
601 
602        //do the necessary work at rollback time for temporary tables
603        /**
604         * do the necessary work at rollback time for temporary tables
605         * 1)If a temp table was declared in the UOW, then drop it and remove it from list of temporary tables.
606         * 2)If a temp table was declared and dropped in the UOW, then remove it from list of temporary tables.
607         * 3)If an existing temp table was dropped in the UOW, then recreate it with no data.
608         * 4)If an existing temp table was modified in the UOW, then get rid of all the rows from the table.
609         */
610        private void tempTablesAndRollback()
611                throws StandardException {
612                for (int i = allDeclaredGlobalTempTables.size()-1; i >= 0; i--) {
613                        TempTableInfo tempTableInfo = (TempTableInfo)allDeclaredGlobalTempTables.get(i);
614                        if (tempTableInfo.getDeclaredInSavepointLevel() >= currentSavepointLevel)
615                        {
616                                if (tempTableInfo.getDroppedInSavepointLevel() == -1)
617                                {
618                                        //the table was declared but not dropped in the unit of work getting rolled back and hence we will remove
619                                        //it from valid list of temporary tables and drop the conglomerate associated with it
620                                        TableDescriptor td = tempTableInfo.getTableDescriptor();
621                                        tran.dropConglomerate(td.getHeapConglomerateId()); //remove the conglomerate created for this temp table
622                                        allDeclaredGlobalTempTables.remove(i); //remove it from the list of temp tables
623                                } else if (tempTableInfo.getDroppedInSavepointLevel() >= currentSavepointLevel)
624                                {
625                                        //the table was declared and dropped in the unit of work getting rolled back
626                                        allDeclaredGlobalTempTables.remove(i);
627                                }
628                        } else if (tempTableInfo.getDroppedInSavepointLevel() >= currentSavepointLevel) //this means the table was declared in an earlier savepoint unit / transaction and then dropped in current UOW 
629                        {
630                                //restore the old definition of temp table because drop is being rolledback
631                                TableDescriptor td = tempTableInfo.getTableDescriptor();
632                                td = cleanupTempTableOnCommitOrRollback(td, false);
633                                //In order to store the old conglomerate information for the temp table, we need to replace the
634                                //existing table descriptor with the old table descriptor which has the old conglomerate information
635                                tempTableInfo.setTableDescriptor(td);
636                                tempTableInfo.setDroppedInSavepointLevel(-1);
637                                //following will mark the table as not modified. This is because the table data has been deleted as part of the current rollback
638                                tempTableInfo.setModifiedInSavepointLevel(-1);
639                                allDeclaredGlobalTempTables.set(i, tempTableInfo);
640                        } else if (tempTableInfo.getModifiedInSavepointLevel() >= currentSavepointLevel) //this means the table was declared in an earlier savepoint unit / transaction and modified in current UOW
641                        {
642                                //following will mark the table as not modified. This is because the table data will be deleted as part of the current rollback
643                                tempTableInfo.setModifiedInSavepointLevel(-1);
644                                TableDescriptor td = tempTableInfo.getTableDescriptor();
645                                getDataDictionary().getDependencyManager().invalidateFor(td, DependencyManager.DROP_TABLE, this);
646                                cleanupTempTableOnCommitOrRollback(td, true);
647                        } // 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
648                }
649    
650                if (allDeclaredGlobalTempTables.size() == 0)
651                        allDeclaredGlobalTempTables = null;
652        }
653 
654        /**
655         * This is called at the commit time for temporary tables with ON COMMIT DELETE ROWS
656         * If a temp table with ON COMMIT DELETE ROWS doesn't have any held cursor open on them, we delete the data from
657         * them by dropping the conglomerate and recreating the conglomerate. In order to store the new conglomerate
658         * information for the temp table, we need to replace the existing table descriptor with the new table descriptor
659         * which has the new conglomerate information
660         * @param tableName Temporary table name whose table descriptor is getting changed
661         * @param td New table descriptor for the temporary table
662         */
663        private void replaceDeclaredGlobalTempTable(String tableName, TableDescriptor td) {
664    TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName);
665                tempTableInfo.setDroppedInSavepointLevel(-1);
666                tempTableInfo.setDeclaredInSavepointLevel(-1);
667                tempTableInfo.setTableDescriptor(td);
668                allDeclaredGlobalTempTables.set(allDeclaredGlobalTempTables.indexOf(tempTableInfo), tempTableInfo);
669  }
670 
671        /**
672         * @see LanguageConnectionContext#getTableDescriptorForDeclaredGlobalTempTable
673         */
674        public TableDescriptor getTableDescriptorForDeclaredGlobalTempTable(String tableName) {
675    TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName);
676                if (tempTableInfo == null)
677                        return null;
678                else
679                        return tempTableInfo.getTableDescriptor();
680        }
681 
682        /**
683         * Find the declared global temporary table in the list of temporary tables known by this connection.
684         * @param tableName look for this table name in the saved list
685         * @return data structure defining the temporary table if found. Else, return null 
686         *
687         */
688        private TempTableInfo findDeclaredGlobalTempTable(String tableName) {
689                if (allDeclaredGlobalTempTables == null)
690                        return null;
691 
692                for (int i = 0; i < allDeclaredGlobalTempTables.size(); i++) {
693                        if (((TempTableInfo)allDeclaredGlobalTempTables.get(i)).matches(tableName))
694                                return (TempTableInfo)allDeclaredGlobalTempTables.get(i);
695                }
696                return null;
697        }
698 
699        /**
700         * @see LanguageConnectionContext#markTempTableAsModifiedInUnitOfWork
701         */
702        public void markTempTableAsModifiedInUnitOfWork(String tableName) {
703    TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName);
704    tempTableInfo.setModifiedInSavepointLevel(currentSavepointLevel);
705        }
706 
707        /**
708         * @see LanguageConnectionContext#prepareInternalStatement
709         */
710        public PreparedStatement prepareInternalStatement(SchemaDescriptor compilationSchema, String sqlText, boolean isForReadOnly, boolean forMetaData) 
711            throws StandardException 
712        {
713            return connFactory.getStatement(compilationSchema, sqlText, isForReadOnly).prepare(this, forMetaData);
714            }
715 
716        /**
717             * @see LanguageConnectionContext#prepareInternalStatement
718             */
719        public PreparedStatement prepareInternalStatement(String sqlText) 
720            throws StandardException 
721        {
722                return connFactory.getStatement(sd, sqlText, true).prepare(this);
723            }      
724 
725        /**
726         * Remove the activation to those known about by this connection.
727         *
728         */
729        public void removeActivation(Activation a) 
730        {
731                if (SanityManager.DEBUG) {
732                        SanityManager.ASSERT(a.isClosed(), "Activation is not closed");
733                }
734 
735                acts.removeElement(a);
736 
737                int capacity = acts.capacity();
738 
739                if (capacity > 20 && (capacity > 2 * acts.size())) {
740                        acts.trimToSize();
741                }
742        }
743 
744        /**
745         * Return the number of activations known for this connection.
746         * Note that some of these activations may not be in use
747         * (when a prepared statement is finalized, its activations
748         * are marked as unused and later closed and removed on
749         * the next commit/rollback).
750         */
751        public int getActivationCount() {
752                return acts.size();
753        }
754 
755        /**
756         * See if a given cursor is available for use.
757         * if so return its activation. Returns null if not found.
758         * For use in execution.
759         *
760         * @return the activation for the given cursor, null
761         *        if none was found.
762         */
763        public CursorActivation lookupCursorActivation(String cursorName) {
764 
765                int size = acts.size();
766                if (size > 0)
767                {
768                        for (int i = 0; i < size; i++) {
769                                 Activation a = (Activation) acts.elementAt(i);
770 
771                                 if (!a.isInUse())
772                                 {
773                                        continue;
774                                 }
775 
776 
777 
778                                String executingCursorName = a.getCursorName();
779 
780                                 if (cursorName.equals(executingCursorName)) {
781 
782                                        ResultSet rs = a.getResultSet();
783                                        if (rs == null)
784                                                continue;
785 
786                                         // if the result set is closed, the the cursor doesn't exist
787                                         if (rs.isClosed()) {                                        
788                                                continue;
789                                         }
790 
791                                         return (CursorActivation)a;
792                                 }
793                        }
794                }
795                return null;
796        }
797 
798        /**
799        *  This method will remove a statement from the  statement cache.
800        *  It will be called,  for example, if there is an exception preparing
801        *  the statement.
802        *
803        *  @param statement Statement to remove
804        *  @exception StandardException thrown if lookup goes wrong.
805        */        
806        public void removeStatement(Statement statement)
807                throws StandardException {
808 
809                if (statementCache == null)
810                        return;
811 
812                        Cacheable cachedItem = statementCache.findCached(statement);
813                        if (cachedItem != null)
814                                statementCache.remove(cachedItem);
815        }
816 
817        /**
818         * See if a given statement has already been compiled for this user, and
819         * if so use its prepared statement. Returns null if not found.
820         *
821         * @exception StandardException thrown if lookup goes wrong.
822         * @return the prepared statement for the given string, null
823         *        if none was found.
824         */
825        public PreparedStatement lookupStatement(GenericStatement statement)
826                throws StandardException {
827 
828 
829                if (statementCache == null)
830                        return null;
831 
832                // statement caching disable when in DDL mode
833                if (dataDictionaryInWriteMode()) {
834                        return null;
835                }
836 
837                Cacheable cachedItem = statementCache.find(statement);
838 
839                CachedStatement cs = (CachedStatement) cachedItem;
840 
841 
842                GenericPreparedStatement ps = cs.getPreparedStatement();
843 
844                synchronized (ps) {
845                        if (ps.upToDate()) {
846                                GeneratedClass ac = ps.getActivationClass();
847 
848                                // Check to see if the statement was prepared before some change
849                                // in the class loading set. If this is the case then force it to be invalid
850                                int currentClasses =
851                                                getLanguageConnectionFactory().getClassFactory().getClassLoaderVersion();
852 
853                                if (ac.getClassLoaderVersion() != currentClasses) {
854                                        ps.makeInvalid(DependencyManager.INTERNAL_RECOMPILE_REQUEST, this);
855                                }
856 
857                                // note that the PreparedStatement is not kept in the cache. This is because
858                                // having items kept in the cache that ultimately are held onto by
859                                // user code is impossible to manage. E.g. an open ResultSet would hold onto
860                                // a PreparedStatement (through its activation) and the user can allow
861                                // this object to be garbage collected. Pushing a context stack is impossible
862                                // in garbage collection as it may deadlock with the open connection and
863                                // the context manager assumes a singel current thread per context stack
864                        }
865                }
866 
867                statementCache.release(cachedItem);
868                return ps;
869        }
870 
871        /**
872                Get a connection unique system generated name for a cursor.
873        */
874        public String getUniqueCursorName() 
875        {
876                return getNameString("SQLCUR", nextCursorId++);
877        }
878 
879        /**
880                Get a connection unique system generated name for an unnamed savepoint.
881        */
882        public String getUniqueSavepointName()
883        {
884                return getNameString("SAVEPT", nextSavepointId++);
885        }
886 
887        /**
888                Get a connection unique system generated id for an unnamed savepoint.
889        */
890        public int getUniqueSavepointID()
891        {
892                return nextSavepointId-1;
893        }
894 
895        /**
896         * Build a String for a statement name.
897         *
898         * @param prefix        The prefix for the statement name.
899         * @param number        The number to append for uniqueness
900         *
901         * @return        A unique String for a statement name.
902         */
903        private String getNameString(String prefix, long number)
904        {
905                if (sb != null)
906                {
907                        sb.setLength(0);
908                }
909                else
910                {
911                        sb = new StringBuffer();
912                }
913                sb.append(prefix).append(number);
914 
915                return sb.toString();
916        }
917 
918        /**
919         * Do a commit as appropriate for an internally generated
920         * commit (e.g. as needed by sync, or autocommit).
921         *
922         * @param        commitStore        true if we should commit the Store transaction
923         *
924         * @exception StandardException thrown on failure
925         */
926        public void internalCommit(boolean commitStore) throws StandardException
927        {
928                doCommit(commitStore,
929                                                                  true,
930                                                                  NON_XA,
931                                                                  false);
932        }
933 
934        /**
935         * Do a commmit as is appropriate for a user requested
936         * commit (e.g. a java.sql.Connection.commit() or a language
937         * 'COMMIT' statement.  Does some extra checking to make
938         * sure that users aren't doing anything bad.
939         *
940         * @exception StandardException thrown on failure
941         */
942        public void userCommit() throws StandardException
943        {
944                doCommit(true,
945                                                                  true,
946                                                                  NON_XA,
947                                                                  true);
948        }
949 
950 
951        /**
952                Commit the language transaction by doing a commitNoSync()
953                on the store's TransactionController.
954 
955                <p>
956                Do *NOT* tell the data dictionary that the transaction is
957                finished. The reason is that this would allow other transactions
958                to see comitted DDL that could be undone in the event of a
959                system crash.
960 
961                @param        commitflag        the flags to pass to commitNoSync in the store's
962                                                        TransactionController
963 
964                @exception StandardException thrown on failure
965         */
966        public final void internalCommitNoSync(int commitflag) throws StandardException
967        {
968                doCommit(true, false, commitflag, false);
969        }
970 
971 
972        /**
973                Same as userCommit except commit a distributed transaction.   
974                This commit always commit store and sync the commit.
975 
976                @param onePhase if true, allow it to commit without first going thru a
977                prepared state.
978 
979                @exception StandardException        thrown if something goes wrong
980         */
981        public final void xaCommit(boolean onePhase) throws StandardException
982        {
983                // further overload internalCommit to make it understand 2 phase commit
984                doCommit(true /* commit store */,
985                                                                  true /* sync */,
986                                                                  onePhase ? XA_ONE_PHASE : XA_TWO_PHASE,
987                                                                  true);
988        }
989 
990 
991        /**
992         * This is where the work on internalCommit(), userCOmmit() and 
993         * internalCommitNoSync() actually takes place.
994         * <p>
995         * When a commit happens, the language connection context
996         * will close all open activations/cursors and commit the
997         * Store transaction.
998         * <p>
999         * REVISIT: we talked about having a LanguageTransactionContext,
1000         * but since store transaction management is currently in flux
1001         * and our context might want to delegate to that context,
1002         * for now all commit/rollback actions are handled directly by
1003         * the language connection context.
1004         * REVISIT: this may need additional alterations when
1005         * RELEASE SAVEPOINT/ROLLBACK TO SAVEPOINT show up.
1006         * <P>
1007         * Since the access manager's own context takes care of its own
1008         * resources on commit, and the transaction stays open, there is
1009         * nothing that this context has to do with the transaction controller.
1010         * <p>
1011         * Also, tell the data dictionary that the transaction is finished,
1012         * if necessary (that is, if the data dictionary was put into
1013         * DDL mode in this transaction.
1014         *
1015         *
1016         * @param        commitStore        true if we should commit the Store transaction
1017         * @param        sync                true means do a synchronized commit,
1018         *                                                false means do an unsynchronized commit
1019         * @param        commitflag        if this is an unsynchronized commit, the flags to
1020         *                                                pass to commitNoSync in the store's
1021         *                                                TransactionController.  If this is a synchronized
1022         *                                                commit, this flag is overloaded for xacommit.
1023     * @param   requestedByUser    False iff the commit is for internal use and
1024         *                      we should ignore the check to prevent commits
1025         *                      in an atomic statement.
1026         *
1027         * @exception StandardException                Thrown on error
1028         */
1029 
1030        protected void doCommit(boolean commitStore,
1031                                                                                           boolean sync,
1032                                                                                           int commitflag,
1033                                                                                           boolean requestedByUser)
1034                 throws StandardException
1035        {
1036                StatementContext statementContext = getStatementContext();
1037                if (requestedByUser  &&
1038                        (statementContext != null) &&
1039                        statementContext.inUse() &&
1040                        statementContext.isAtomic())
1041                {
1042                        throw StandardException.newException(SQLState.LANG_NO_COMMIT_IN_NESTED_CONNECTION);
1043                }
1044 
1045                // Log commit to error log, if appropriate
1046                if (logStatementText)
1047                {
1048                        if (istream == null)
1049                        {
1050                                istream = Monitor.getStream();
1051                        }
1052                        String xactId = tran.getTransactionIdString();
1053                        istream.printlnWithHeader(LanguageConnectionContext.xidStr + 
1054                                                                          xactId + 
1055                                                                          "), " +
1056                                                                          LanguageConnectionContext.lccStr +
1057                                                                          instanceNumber +
1058                                                                          "), " + LanguageConnectionContext.dbnameStr +
1059                                                                                  dbname +
1060                                                                                  "), " +
1061                                                                                  LanguageConnectionContext.drdaStr +
1062                                                                                  drdaID +
1063                                                                          "), Committing");
1064                }
1065 
1066                resetActivations(false);
1067 
1068                //do the clean up work required for temporary tables at the commit time. This cleanup work
1069                //can possibly remove entries from allDeclaredGlobalTempTables and that's why we need to check
1070                //again later to see if we there are still any entries in allDeclaredGlobalTempTables
1071                if (allDeclaredGlobalTempTables != null)
1072                {
1073                        tempTablesAndCommit();
1074                        //at commit time, for all the temp tables declared with ON COMMIT DELETE ROWS, make sure there are no held cursor open on them.
1075                        //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
1076                        if (allDeclaredGlobalTempTables != null) {
1077                                for (int i=0; i<allDeclaredGlobalTempTables.size(); i++)
1078                                {
1079                                        TableDescriptor td = ((TempTableInfo)(allDeclaredGlobalTempTables.get(i))).getTableDescriptor();
1080                                        if (td.isOnCommitDeleteRows() == false) //do nothing for temp table with ON COMMIT PRESERVE ROWS
1081                                        {
1082                                                continue;
1083                                        }
1084                                        if (checkIfAnyActivationHasHoldCursor(td.getName()) == false)//temp tables with ON COMMIT DELETE ROWS and no open held cursors
1085                                        {
1086                                                getDataDictionary().getDependencyManager().invalidateFor(td, DependencyManager.DROP_TABLE, this);
1087                                                cleanupTempTableOnCommitOrRollback(td, true);
1088                                        }
1089                                }
1090                        }
1091                }
1092 
1093 
1094                currentSavepointLevel = 0; //reset the current savepoint level for the connection to 0 at the end of commit work for temp tables
1095 
1096                // Do *NOT* tell the DataDictionary to start using its cache again
1097                // if this is an unsynchronized commit. The reason is that it
1098                // would allow other transactions to see this transaction's DDL,
1099                // which could be rolled back in case of a system crash.
1100                if (sync)
1101                {
1102                        finishDDTransaction();
1103                }
1104 
1105                // now commit the Store transaction
1106                TransactionController tc = getTransactionExecute();
1107                if ( tc != null && commitStore ) 
1108                { 
1109                        if (sync)
1110                        {
1111                                if (commitflag == NON_XA)
1112                                {
1113                                        // regular commit
1114                                        tc.commit();
1115                                }
1116                                else
1117                                {
1118                                        // This may be a xa_commit, check overloaded commitflag.
1119 
1120                                        if (SanityManager.DEBUG)
1121                                                SanityManager.ASSERT(commitflag == XA_ONE_PHASE ||
1122                                                                                         commitflag == XA_TWO_PHASE,
1123                                                                                           "invalid commit flag");
1124 
1125                                        ((XATransactionController)tc).xa_commit(commitflag == XA_ONE_PHASE);
1126 
1127                                }
1128                        }
1129                        else
1130                        {
1131                                tc.commitNoSync(commitflag);
1132                        }
1133 
1134                        // reset the savepoints to the new
1135                        // location, since any outer nesting
1136                        // levels expect there to be a savepoint
1137                        resetSavepoints();
1138                }
1139        }
1140 
1141        /**
1142         * If dropAndRedeclare is true, that means we have come here for temp tables with on commit delete rows
1143         * and no held curosr open on them. We will drop the existing conglomerate and redeclare a new conglomerate
1144         * similar to old conglomerate. This is a more efficient way of deleting all rows from the table.
1145         *
1146         * If dropAndRedeclare is false, that means we have come here for the rollback cleanup work. We are trying
1147         * to restore old definition of the temp table (because the drop on it is being rolled back).
1148         */
1149        private TableDescriptor cleanupTempTableOnCommitOrRollback(TableDescriptor td, boolean dropAndRedeclare)
1150                 throws StandardException
1151        {
1152                //create new conglomerate with same properties as the old conglomerate and same row template as the old conglomerate
1153                long conglomId = tran.createConglomerate(
1154                        "heap", // we're requesting a heap conglomerate
1155                        td.getEmptyExecRow(getContextManager()).getRowArray(), // row template
1156                        null, //column sort order - not required for heap
1157                        null, // properties
1158                        (TransactionController.IS_TEMPORARY | TransactionController.IS_KEPT));
1159 
1160                long cid = td.getHeapConglomerateId();
1161 
1162                //remove the old conglomerate descriptor from the table descriptor
1163                ConglomerateDescriptor cgd = td.getConglomerateDescriptor(cid);
1164                td.getConglomerateDescriptorList().dropConglomerateDescriptorByUUID(cgd.getUUID());
1165                //add the new conglomerate descriptor to the table descriptor
1166                cgd = getDataDictionary().getDataDescriptorGenerator().newConglomerateDescriptor(conglomId, null, false, null, false, null, td.getUUID(),
1167                td.getSchemaDescriptor().getUUID());
1168                ConglomerateDescriptorList conglomList = td.getConglomerateDescriptorList();
1169                conglomList.add(cgd);
1170 
1171                //reset the heap conglomerate number in table descriptor to -1 so it will be refetched next time with the new value
1172                td.resetHeapConglomNumber();
1173 
1174                if(dropAndRedeclare)
1175                {
1176                        tran.dropConglomerate(cid); //remove the old conglomerate from the system
1177                        replaceDeclaredGlobalTempTable(td.getName(), td);
1178                }
1179 
1180                return(td);
1181        }
1182 
1183        /**
1184          Do a rollback as appropriate for an internally generated
1185          rollback (e.g. as needed by sync, or autocommit).
1186         
1187          When a rollback happens, we 
1188          close all open activations and invalidate their
1189          prepared statements.  We then tell the cache to
1190          age out everything else, which effectively invalidates
1191          them.  Thus, all prepared statements will be
1192          compiled anew on their 1st execution after
1193          a rollback.
1194          <p>
1195          The invalidated statements can revalidate themselves without
1196          a full recompile if they verify their dependencies' providers still
1197          exist unchanged. REVISIT when invalidation types are created.
1198          <p>
1199          REVISIT: this may need additional alterations when
1200          RELEASE SAVEPOINT/ROLLBACK TO SAVEPOINT show up.
1201          <p>
1202          Also, tell the data dictionary that the transaction is finished,
1203          if necessary (that is, if the data dictionary was put into
1204          DDL mode in this transaction.
1205 
1206          @exception StandardException thrown on failure
1207         */
1208 
1209        public void internalRollback() throws StandardException 
1210        {
1211                doRollback(false /* non-xa */, false);
1212        }
1213 
1214        /**
1215         * Do a rollback as is appropriate for a user requested
1216         * rollback (e.g. a java.sql.Connection.rollback() or a language
1217         * 'ROLLBACk' statement.  Does some extra checking to make
1218         * sure that users aren't doing anything bad.
1219         *
1220         * @exception StandardException thrown on failure
1221         */
1222        public void userRollback() throws StandardException
1223        {
1224                doRollback(false /* non-xa */, true);
1225        }
1226 
1227        /**
1228            Same as userRollback() except rolls back a distrubuted transaction.
1229 
1230                @exception StandardException        thrown if something goes wrong
1231         */
1232        public void xaRollback() throws StandardException
1233        {
1234                doRollback(true /* xa */, true);
1235        }
1236 
1237        /**
1238         * When a rollback happens, the language connection context
1239         * will close all open activations and invalidate
1240         * their prepared statements. Then the language will abort the
1241         * Store transaction.
1242         * <p>
1243         * The invalidated statements can revalidate themselves without
1244         * a full recompile if they verify their dependencies' providers still
1245         * exist unchanged. REVISIT when invalidation types are created.
1246         * <p>
1247         * REVISIT: this may need additional alterations when
1248         * RELEASE SAVEPOINT/ROLLBACK TO SAVEPOINT show up.
1249         * <p>
1250         * Also, tell the data dictionary that the transaction is finished,
1251         * if necessary (that is, if the data dictionary was put into
1252         * DDL mode in this transaction.
1253          *
1254          * @param xa        true if this is an xa rollback
1255          * @param requestedByUser        true if requested by user
1256          *
1257         * @exception StandardException thrown on failure
1258         */
1259        private void doRollback(boolean xa, boolean requestedByUser) throws StandardException
1260        {
1261                StatementContext statementContext = getStatementContext();
1262                if (requestedByUser &&
1263                        (statementContext != null) &&
1264                        statementContext.inUse() &&
1265                        statementContext.isAtomic())
1266                {
1267                        throw StandardException.newException(SQLState.LANG_NO_ROLLBACK_IN_NESTED_CONNECTION);
1268                }
1269 
1270                // Log rollback to error log, if appropriate
1271                if (logStatementText)
1272                {
1273                        if (istream == null)
1274                        {
1275                                istream = Monitor.getStream();
1276                        }
1277                        String xactId = tran.getTransactionIdString();
1278                        istream.printlnWithHeader(LanguageConnectionContext.xidStr +
1279                                                                          xactId + 
1280                                                                          "), " +
1281                                                                          LanguageConnectionContext.lccStr +
1282                                                                          instanceNumber +
1283                                                                          "), " + LanguageConnectionContext.dbnameStr +
1284                                                                                  dbname +
1285                                                                                  "), " +
1286                                                                                  LanguageConnectionContext.dbnameStr +
1287                                                                                  dbname +
1288                                                                                  "), " +
1289                                                                                  LanguageConnectionContext.drdaStr +
1290                                                                                  drdaID +
1291                                                                          "), Rolling back");
1292                }
1293 
1294                resetActivations(true);
1295 
1296                currentSavepointLevel = 0; //reset the current savepoint level for the connection to 0 at the beginning of rollback work for temp tables
1297                if (allDeclaredGlobalTempTables != null)
1298                        tempTablesAndRollback();
1299 
1300                finishDDTransaction();
1301 
1302                // now rollback the Store transaction
1303                TransactionController tc = getTransactionExecute();
1304                if (tc != null) 
1305                {        
1306                        if (xa)
1307                                ((XATransactionController)tc).xa_rollback();
1308                        else
1309                                tc.abort(); 
1310                        // reset the savepoints to the new
1311                        // location, since any outer nesting
1312                        // levels expet there to be a savepoint
1313                        resetSavepoints();
1314                }
1315        }
1316 
1317        /**
1318         * Reset all statement savepoints. Traverses the StatementContext
1319         * stack from bottom to top, calling resetSavePoint()
1320         * on each element.
1321         *
1322         * @exception StandardException thrown if something goes wrong
1323         */
1324        private void resetSavepoints() throws StandardException 
1325        {
1326                final ContextManager cm = getContextManager();
1327                final List stmts = cm.getContextStack(org.apache.derby.
1328                                                                                          iapi.reference.
1329                                                                                          ContextId.LANG_STATEMENT);
1330                final int end = stmts.size();
1331                for (int i = 0; i < end; ++i) {
1332                        ((StatementContext)stmts.get(i)).resetSavePoint();
1333                }
1334        }
1335 
1336        /**
1337         * Let the context deal with a rollback to savepoint
1338         *
1339         * @param        savepointName        Name of the savepoint that needs to be rolled back
1340         * @param        refreshStyle        boolean indicating whether or not the controller should close
1341         * open conglomerates and scans. Also used to determine if language should close
1342         * open activations.
1343         * @param        kindOfSavepoint         A NULL value means it is an internal savepoint (ie not a user defined savepoint)
1344         * Non NULL value means it is a user defined savepoint which can be a SQL savepoint or a JDBC savepoint
1345         *   A String value for kindOfSavepoint would mean it is SQL savepoint
1346         *   A JDBC Savepoint object value for kindOfSavepoint would mean it is JDBC savepoint
1347         *
1348         * @exception StandardException thrown if something goes wrong
1349         */
1350        public void internalRollbackToSavepoint( String savepointName, boolean refreshStyle, Object kindOfSavepoint )
1351                throws StandardException
1352        {
1353                // now rollback the Store transaction to the savepoint
1354                TransactionController tc = getTransactionExecute();
1355                if (tc != null)
1356                {
1357                        boolean                closeConglomerates;
1358 
1359                        if ( refreshStyle ) 
1360                        {
1361                                closeConglomerates = true;
1362                                // bug 5145 - don't forget to close the activations while rolling
1363                                // back to a savepoint
1364                                resetActivations(true);
1365                        }
1366                        else { closeConglomerates = false; }
1367 
1368                        currentSavepointLevel = tc.rollbackToSavePoint( savepointName, closeConglomerates, kindOfSavepoint );
1369                }
1370 
1371                if (tc != null && refreshStyle && allDeclaredGlobalTempTables != null)
1372                        tempTablesAndRollback();
1373        }
1374 
1375        /**
1376          Let the context deal with a release of a savepoint
1377 
1378          @param        savepointName        Name of the savepoint that needs to be released
1379          @param        kindOfSavepoint         A NULL value means it is an internal savepoint (ie not a user defined savepoint)
1380          Non NULL value means it is a user defined savepoint which can be a SQL savepoint or a JDBC savepoint
1381          A String value for kindOfSavepoint would mean it is SQL savepoint
1382          A JDBC Savepoint object value for kindOfSavepoint would mean it is JDBC savepoint
1383 
1384          @exception StandardException thrown if something goes wrong
1385         */
1386        public        void        releaseSavePoint( String savepointName, Object kindOfSavepoint )  throws StandardException
1387        {
1388                TransactionController tc = getTransactionExecute();
1389                if (tc != null)
1390                {
1391                        currentSavepointLevel = tc.releaseSavePoint( savepointName, kindOfSavepoint );
1392                        //after a release of a savepoint, we need to go through our temp tables list.
1393                        if (allDeclaredGlobalTempTables != null)
1394                                tempTablesReleaseSavepointLevels();
1395                }
1396        }
1397 
1398        /**
1399          Sets a savepoint. Causes the Store to set a savepoint.
1400 
1401          @param        savepointName        name of savepoint
1402          @param        kindOfSavepoint         A NULL value means it is an internal savepoint (ie not a user defined savepoint)
1403          Non NULL value means it is a user defined savepoint which can be a SQL savepoint or a JDBC savepoint
1404          A String value for kindOfSavepoint would mean it is SQL savepoint
1405          A JDBC Savepoint object value for kindOfSavepoint would mean it is JDBC savepoint
1406 
1407                @exception StandardException thrown if something goes wrong
1408          */
1409        public        void        languageSetSavePoint( String savepointName, Object kindOfSavepoint )  throws StandardException
1410        {
1411                TransactionController tc = getTransactionExecute();
1412                if (tc != null)
1413                {
1414                        currentSavepointLevel = tc.setSavePoint( savepointName, kindOfSavepoint );
1415                }
1416        }
1417 
1418        /**
1419         * Return true if any transaction is blocked, even if not by this one
1420         *
1421         */
1422        public boolean anyoneBlocked()
1423        {
1424                return getTransactionExecute().anyoneBlocked();
1425        }
1426 
1427        /**
1428                Sets the transaction controller to use with this language connection
1429                context.
1430 
1431                @param        tran        the transaction to use with this language connection context
1432         */
1433        public void setTransaction( TransactionController tran ) { this.tran = tran; }
1434 
1435 
1436        /**
1437         * Start a Nested User Transaction (NUT) with the store. If a NUT is 
1438         * already active simply increment a counter, queryNestingDepth, to keep
1439         * track of how many times we have tried to start a NUT.
1440         */
1441        public void beginNestedTransaction(boolean readOnly) throws StandardException
1442        {
1443                if (childTransaction == null)
1444                        childTransaction = tran.startNestedUserTransaction(readOnly);
1445                queryNestingDepth++;
1446                return;
1447        }
1448 
1449        public void commitNestedTransaction()
1450                throws StandardException
1451        {
1452                if (--queryNestingDepth == 0)
1453                {
1454                        childTransaction.commit();
1455                        childTransaction.destroy();
1456                        childTransaction = null;
1457                        return;
1458                }
1459        }
1460 
1461        /**
1462         * Get the transaction controller to use at compile time with this language
1463         * connection context. If a NUT is active then return NUT else return parent
1464         * transaction.
1465         */
1466        public TransactionController getTransactionCompile()
1467        {
1468                return (childTransaction != null) ? childTransaction : tran;
1469        }
1470 
1471        public TransactionController getTransactionExecute()
1472        {
1473                return tran;
1474        }
1475 
1476 /** Get the data value factory to use with this language connection
1477                context.
1478         */
1479        public DataValueFactory getDataValueFactory() {
1480                return dataFactory;
1481        }
1482        
1483        /**
1484                Get the language factory to use with this language connection
1485                context.
1486         */
1487        public LanguageFactory getLanguageFactory() {
1488                return langFactory;
1489        }
1490                
1491        public OptimizerFactory getOptimizerFactory() {
1492                return of;
1493        }
1494 
1495        /**
1496                Get the language connection factory to use with this language connection
1497                context.
1498         */
1499        public LanguageConnectionFactory getLanguageConnectionFactory() {
1500                return connFactory;
1501        }
1502 
1503        /**
1504         * check if there are any activations that reference this temporary table
1505         * @param tableName look for any activations referencing this table name
1506         * @return boolean  false if found no activations
1507         */
1508        private boolean checkIfAnyActivationHasHoldCursor(String tableName)
1509                        throws StandardException
1510        {
1511                for (int i = acts.size() - 1; i >= 0; i--) {
1512                        Activation a = (Activation) acts.elementAt(i);
1513                        if (a.checkIfThisActivationHasHoldCursor(tableName))
1514                                return true;
1515    }
1516    return false;
1517        }
1518 
1519 
1520        /**
1521         * Verify that there are no activations with open held result sets.
1522         *
1523         * @return boolean  Found no open (held) resultsets.
1524         *
1525         * @exception StandardException thrown on failure
1526         */
1527        /* This gets used in case of hold cursors. If there are any hold cursors open
1528         * then user can't change the isolation level without closing them. At the
1529         * execution time, set transaction isolation level calls this method before
1530         * changing the isolation level.
1531         */
1532        public boolean verifyAllHeldResultSetsAreClosed()
1533                        throws StandardException
1534        {
1535                boolean seenOpenResultSets = false;
1536 
1537                /* For every activation */
1538                for (int i = acts.size() - 1; i >= 0; i--) {
1539 
1540                        Activation a = (Activation) acts.elementAt(i);
1541 
1542                        if (SanityManager.DEBUG)
1543                        {
1544                                SanityManager.ASSERT(a instanceof CursorActivation, "a is not a CursorActivation");
1545                        }
1546 
1547                        if (!a.isInUse())
1548                        {
1549                                continue;
1550                        }
1551 
1552                        if (!a.getResultSetHoldability())
1553                        {
1554                                continue;
1555                        }
1556 
1557                        ResultSet rs = ((CursorActivation) a).getResultSet();
1558 
1559                        /* is there an open result set? */
1560                        if ((rs != null) && !rs.isClosed() && rs.returnsRows())
1561                        {
1562                                seenOpenResultSets = true;
1563                                break;
1564                        }
1565                }
1566 
1567                if (!seenOpenResultSets)
1568                        return(true);
1569 
1570                // There may be open ResultSet's that are yet to be garbage collected
1571                // let's try and force these out rather than throw an error
1572                System.gc();
1573                System.runFinalization();
1574 
1575 
1576                /* For every activation */
1577                for (int i = acts.size() - 1; i >= 0; i--) {
1578                                
1579                        Activation a = (Activation) acts.elementAt(i);
1580 
1581                        if (SanityManager.DEBUG)
1582                        {
1583                                SanityManager.ASSERT(a instanceof CursorActivation, "a is not a CursorActivation");
1584                        }
1585 
1586                        if (!a.isInUse())
1587                        {
1588                                continue;
1589                        }
1590 
1591                        if (!a.getResultSetHoldability())
1592                        {
1593                                continue;
1594                        }
1595 
1596                        ResultSet rs = ((CursorActivation) a).getResultSet();
1597 
1598                        /* is there an open held result set? */
1599                        if ((rs != null) && !rs.isClosed() && rs.returnsRows())
1600                        {
1601                                return(false);
1602                        }
1603                }
1604                return(true);
1605        }
1606 
1607        /**
1608         * Verify that there are no activations with open result sets
1609         * on the specified prepared statement.
1610         *
1611         * @param pStmt                The prepared Statement
1612         * @param provider        The object precipitating a possible invalidation
1613         * @param action        The action causing the possible invalidation
1614         *
1615         * @return Nothing.
1616         *
1617         * @exception StandardException thrown on failure
1618         */
1619        public boolean verifyNoOpenResultSets(PreparedStatement pStmt, Provider provider,
1620                                                                           int action)
1621                        throws StandardException
1622        {
1623                /*
1624                ** It is not a problem to create an index when there is an open
1625                ** result set, since it doesn't invalidate the access path that was
1626                ** chosen for the result set.
1627                */
1628                boolean seenOpenResultSets = false;
1629 
1630                /* For every activation */
1631 
1632                // synchronize on acts as other threads may be closing activations
1633                // in this list, thus invalidating the Enumeration
1634                for (int i = acts.size() - 1; i >= 0; i--) {
1635                                
1636                        Activation a = (Activation) acts.elementAt(i);
1637 
1638                        if (!a.isInUse())
1639                        {
1640                                continue;
1641                        }
1642                        
1643                        /* for this prepared statement */
1644                        if (pStmt == a.getPreparedStatement()) {
1645                                ResultSet rs = a.getResultSet();
1646 
1647                                /* is there an open result set? */
1648                                if (rs != null && ! rs.isClosed())
1649                                {
1650                                        if (!rs.returnsRows())
1651                                                continue;
1652                                        seenOpenResultSets = true;
1653                                        break;
1654                                }
1655                                
1656                        }
1657                }
1658 
1659                if (!seenOpenResultSets)
1660                        return false;
1661 
1662                // There may be open ResultSet's that are yet to be garbage collected
1663                // let's try and force these out rather than throw an error
1664                System.gc();
1665                System.runFinalization();
1666 
1667 
1668                /* For every activation */
1669                // synchronize on acts as other threads may be closing activations
1670                // in this list, thus invalidating the Enumeration
1671                for (int i = acts.size() - 1; i >= 0; i--) {
1672                                
1673                        Activation a = (Activation) acts.elementAt(i);
1674 
1675                        if (!a.isInUse())
1676                        {
1677                                continue;
1678                        }
1679 
1680                        /* for this prepared statement */
1681                        if (pStmt == a.getPreparedStatement()) {
1682                                ResultSet rs = a.getResultSet();
1683 
1684                                /* is there an open result set? */
1685                                if (rs != null && ! rs.isClosed())
1686                                {
1687                                        if ((provider != null) && rs.returnsRows()) {
1688                                        DependencyManager dmgr = getDataDictionary().getDependencyManager();
1689 
1690                                        throw StandardException.newException(SQLState.LANG_CANT_INVALIDATE_OPEN_RESULT_SET, 
1691                                                                        dmgr.getActionString(action), 
1692                                                                        provider.getObjectName());
1693 
1694                                        }
1695                                        return true;
1696                                }
1697                        }
1698                }
1699                return false;
1700        }
1701 
1702        /**
1703         *        Get the Authorization Id
1704         *
1705         * @return String        the authorization id
1706         */
1707        public String getAuthorizationId()
1708        { 
1709                return authorizer.getAuthorizationId();
1710        }
1711 
1712        /**
1713         *        Get the default schema
1714         *
1715         * @return SchemaDescriptor        the default schema
1716         */
1717        public SchemaDescriptor getDefaultSchema() 
1718        { 
1719                return sd; 
1720        }
1721        /**
1722         * Get the current schema name
1723         *
1724         * @return current schema name
1725         */
1726        public String getCurrentSchemaName()
1727        {
1728        if( null == sd)
1729            return null;
1730                return sd.getSchemaName();
1731        }
1732 
1733        /**
1734         * Set the default schema -- used by SET SCHEMA.
1735         * 
1736         * @param sd the new default schema.
1737         * If null, then the default schema descriptor is used.
1738         *
1739         * @exception StandardException thrown on failure
1740         */
1741        public void setDefaultSchema(SchemaDescriptor sd)
1742                throws StandardException
1743        {         
1744                if (sd == null)
1745                {        
1746                    sd = initDefaultSchemaDescriptor();
1747                }
1748                this.sd = sd;
1749                
1750        }
1751 
1752        /**
1753         * Get the identity column value most recently generated.
1754         *
1755         * @return the generated identity column value
1756         */
1757        public Long getIdentityValue()
1758        {
1759                return identityNotNull ? new Long(identityVal) : null;
1760        }
1761 
1762        /**
1763         * Set the field of most recently generated identity column value.
1764         *
1765         * @param val the generated identity column value
1766         */
1767        public void setIdentityValue(long val)
1768        {
1769                identityVal = val;
1770                identityNotNull = true;
1771        }
1772 
1773        /**
1774                Empty as much of the cache as possible. It is not guaranteed
1775                that the cache is empty after this call, as statements may be kept
1776                by currently executing queries, activations that are about to be garbage
1777                collected.
1778        */
1779        public void emptyCache() {
1780                /* We know prepared statements don't become dirty
1781                ** statementCache.cleanAll(); 
1782                */
1783                if (statementCache != null)
1784                        statementCache.ageOut(); 
1785        }
1786 
1787        /**
1788         * Push a CompilerContext on the context stack with
1789         * the current default schema as the default schema
1790         * which we compile against.
1791         *
1792         * @return the compiler context
1793         *
1794         * @exception StandardException thrown on failure
1795         */
1796        public        final CompilerContext pushCompilerContext()
1797        {
1798                return pushCompilerContext((SchemaDescriptor)null);
1799        }
1800 
1801        /**
1802         * Push a CompilerContext on the context stack with
1803         * the passed in default schema as the default schema
1804         * we compile against.
1805         *
1806         * @param sd the default schema 
1807         *
1808         * @return the compiler context
1809         *
1810         */
1811        public        CompilerContext pushCompilerContext(SchemaDescriptor sd)
1812        {
1813                CompilerContext cc;
1814                boolean                        firstCompilerContext = false;
1815 
1816                //        DEBUG        END
1817 
1818                cc = (CompilerContext) (getContextManager().getContext(CompilerContext.CONTEXT_ID));
1819 
1820                /*
1821                ** If there is no compiler context, this is the first one on the
1822                ** stack, so don't pop it when we're done (saves time).
1823                */
1824                if (cc == null) { firstCompilerContext = true; }
1825 
1826                if (cc == null || cc.getInUse())
1827                {
1828                        cc = new CompilerContextImpl(getContextManager(), this, tcf);
1829                        if (firstCompilerContext) { cc.firstOnStack(); }
1830                }
1831                else
1832                {
1833                        /* Reset the next column,table, subquery and ResultSet numbers at 
1834                         * the beginning of each statement 
1835                         */
1836                        cc.resetContext();
1837                }
1838 
1839                cc.setInUse(true);
1840 
1841                // Save off the current isolation level on entry so that it gets restored
1842                cc.setEntryIsolationLevel( getCurrentIsolationLevel());
1843 
1844                StatementContext sc = getStatementContext();
1845                if (sc.getSystemCode())
1846                        cc.setReliability(CompilerContext.INTERNAL_SQL_LEGAL);
1847 
1848                return        cc;
1849        }
1850 
1851 
1852        /**
1853         * Pop a CompilerContext off the context stack.
1854         *
1855         * @param cc  The compiler context.
1856         */
1857        public void popCompilerContext(CompilerContext cc)
1858        {
1859                cc.setCurrentDependent(null);
1860 
1861                cc.setInUse(false);
1862 
1863                // Restore the isolation level at the time of entry to CompilerContext
1864                isolationLevel = cc.getEntryIsolationLevel();
1865 
1866                /*
1867                ** Only pop the compiler context if it's not the first one
1868                ** on the stack.
1869                */
1870                if (! cc.isFirstOnStack()) 
1871                { 
1872                        cc.popMe(); 
1873                }
1874                else
1875                {
1876                        cc.setCompilationSchema((SchemaDescriptor)null);
1877                }
1878        }
1879 
1880        /**
1881         * Push a StatementContext on the context stack.
1882         *
1883         * @param isAtomic whether this statement is atomic or not
1884         * @param isForReadOnly whether this statement is for a read only resultset
1885         * @param stmtText the text of the statement.  Needed for any language
1886         *         statement (currently, for any statement that can cause a trigger
1887         *         to fire).  Please set this unless you are some funky jdbc setXXX
1888         *        method or something.
1889         * @param pvs parameter value set, if it has one
1890         * @param rollbackParentContext True if 1) the statement context is
1891         *         NOT a top-level context, AND 2) in the event of a statement-level
1892         *        exception, the parent context needs to be rolled back, too.
1893     * @param timeoutMillis timeout value for this statement, in milliseconds.
1894     *  The value 0 means that no timeout is set.
1895         *
1896         * @return StatementContext  The statement context.
1897         *
1898         */
1899        public StatementContext pushStatementContext (boolean isAtomic, boolean isForReadOnly, 
1900                                                      String stmtText, ParameterValueSet pvs, 
1901                                                      boolean rollbackParentContext, 
1902                                                      long timeoutMillis)
1903        {
1904                int                                        parentStatementDepth = statementDepth;
1905                boolean                                inTrigger = false;
1906                boolean                                parentIsAtomic = false;
1907 
1908                // by default, assume we are going to use the outermost statement context
1909                StatementContext        statementContext = statementContexts[0];
1910 
1911                /*
1912                ** If we haven't allocated any statement contexts yet, allocate
1913                ** the outermost stmt context now and push it.
1914                */
1915                if (statementContext == null)
1916                {
1917                        statementContext = statementContexts[0] = new GenericStatementContext(this, tran);
1918                }
1919                else if (statementDepth > 0)
1920                {
1921                        StatementContext        parentStatementContext;
1922                        /*
1923                        ** We also cache a 2nd statement context, though we still
1924                        ** push and pop it. Note, new contexts are automatically pushed.
1925                        */
1926                        if (statementDepth == 1)
1927                        {
1928                                statementContext = statementContexts[1];
1929 
1930                                if (statementContext == null)
1931                                        statementContext = statementContexts[1] = new GenericStatementContext(this, tran);
1932                                else
1933                                        statementContext.pushMe();
1934 
1935                                parentStatementContext = statementContexts[0];
1936                        }
1937                        else
1938                        {
1939                                parentStatementContext = getStatementContext();
1940                                statementContext = new GenericStatementContext(this, tran);
1941                        }
1942 
1943                        inTrigger = parentStatementContext.inTrigger() || (outermostTrigger == parentStatementDepth);
1944                        parentIsAtomic = parentStatementContext.isAtomic();
1945                        statementContext.setSQLAllowed(parentStatementContext.getSQLAllowed(), false);
1946                        if (parentStatementContext.getSystemCode())
1947                                statementContext.setSystemCode();
1948                }
1949 
1950                incrementStatementDepth();
1951 
1952                statementContext.setInUse(inTrigger, isAtomic || parentIsAtomic, isForReadOnly, stmtText, pvs, timeoutMillis);
1953                if (rollbackParentContext)
1954                        statementContext.setParentRollback();
1955                return statementContext;
1956        }
1957 
1958        /**
1959         * Pop a StatementContext of the context stack.
1960         *
1961         * @param statementContext  The statement context.
1962         * @param error                                The error, if any  (Only relevant for DEBUG)
1963         */
1964        public void popStatementContext(StatementContext statementContext,
1965                                                                        Throwable error) 
1966        {
1967                if ( statementContext != null ) 
1968                { 
1969                        /*
1970                        ** If someone beat us to the punch, then it is ok,
1971                        ** just silently ignore it.  We probably got here
1972                        ** because we had a try catch block around a push/pop
1973                        ** statement context, and we already got the context
1974                        ** on a cleanupOnError.
1975                        */
1976                        if (!statementContext.inUse())
1977                        {
1978                                return;
1979                        }
1980                        statementContext.clearInUse(); 
1981                }
1982 
1983                decrementStatementDepth();
1984                if (statementDepth == -1)
1985                {
1986                        /*
1987                         * Only ignore the pop request for an already
1988                         * empty stack when dealing with a session exception.
1989                         */
1990                        if (SanityManager.DEBUG)
1991                        {
1992                                int severity = (error instanceof StandardException) ?
1993                                                                        ((StandardException)error).getSeverity() :
1994                                                                0;
1995                                SanityManager.ASSERT(error != null,
1996                                        "Must have error to try popStatementContext with 0 depth");
1997                                SanityManager.ASSERT(
1998                                        (severity == ExceptionSeverity.SESSION_SEVERITY),
1999                                        "Must have session severity error to try popStatementContext with 0 depth");
2000                                SanityManager.ASSERT(statementContext == statementContexts[0],
2001                                        "statementContext is expected to equal statementContexts[0]");
2002                        }
2003                        resetStatementDepth(); // pretend we did nothing.
2004                }
2005                else if (statementDepth == 0)
2006                {
2007                        if (SanityManager.DEBUG)
2008                        {
2009                                /* Okay to pop last context on a session exception.
2010                                 * (We call clean up on error when exiting connection.)
2011                                 */
2012                                int severity = (error instanceof StandardException) ?
2013                                                                        ((StandardException)error).getSeverity() :
2014                                                                0;
2015                                if ((error == null) || 
2016                                        (severity != ExceptionSeverity.SESSION_SEVERITY))
2017                                {
2018                                        SanityManager.ASSERT(statementContext == statementContexts[0],
2019                                                "statementContext is expected to equal statementContexts[0]");
2020                                }
2021                        }
2022                }
2023                else
2024                {
2025                        if (SanityManager.DEBUG)
2026                        {
2027                                SanityManager.ASSERT(statementContext != statementContexts[0],
2028                                        "statementContext is not expected to equal statementContexts[0]");
2029                                if (statementDepth <= 0)
2030                                        SanityManager.THROWASSERT(
2031                                                "statement depth expected to be >0, was "+statementDepth);
2032                
2033                if (getContextManager().getContext(statementContext.getIdName()) != statementContext)
2034                {
2035                    SanityManager.THROWASSERT("trying to pop statement context from middle of stack");
2036                }
2037                        }
2038 
2039            statementContext.popMe();                
2040                }
2041 
2042        }
2043 
2044        /**
2045         * Push a new execution statement validator.  An execution statement 
2046         * validator is an object that validates the current statement to
2047         * ensure that it is permitted given the current execution context.
2048         * An example of a validator a trigger ExecutionStmtValidator that
2049         * doesn't allow ddl on the trigger target table.
2050         * <p>
2051         * Multiple ExecutionStmtValidators may be active at any given time.
2052         * This mirrors the way there can be multiple connection nestings
2053         * at a single time.  The validation is performed by calling each
2054         * validator's validateStatement() method.  This yields the union
2055         * of all validations.
2056         *
2057         * @param validator the validator to add
2058         */
2059        public void pushExecutionStmtValidator(ExecutionStmtValidator validator)
2060        {
2061                stmtValidators.addElement(validator);
2062        }
2063 
2064        /**
2065         * Remove the validator.  Does an object identity (validator == validator)
2066          * comparison.  Asserts that the validator is found.
2067         *
2068         * @param validator the validator to remove
2069         *
2070         * @exception StandardException on error
2071         */
2072        public void popExecutionStmtValidator(ExecutionStmtValidator validator)
2073                throws StandardException
2074        {
2075                boolean foundElement = stmtValidators.removeElement(validator);
2076                if (SanityManager.DEBUG)
2077                {
2078                        if (!foundElement)
2079                        {
2080                                SanityManager.THROWASSERT("statement validator "+validator+" not found");
2081                        }
2082                }
2083        }
2084 
2085        /**
2086         * Push a new trigger execution context.
2087         * <p>
2088         * Multiple TriggerExecutionContexts may be active at any given time.
2089         *
2090         * @param tec the trigger execution context
2091         *
2092         * @exception StandardException on trigger recursion error
2093         */
2094        public void pushTriggerExecutionContext(TriggerExecutionContext tec) throws StandardException
2095        {
2096                if (outermostTrigger == -1) 
2097                {
2098                        outermostTrigger = statementDepth; 
2099                }
2100 
2101                /* Maximum 16 nesting levels allowed */
2102                if (triggerExecutionContexts.size() >= Limits.DB2_MAX_TRIGGER_RECURSION)
2103                {
2104                        throw StandardException.newException(SQLState.LANG_TRIGGER_RECURSION_EXCEEDED);
2105                }
2106 
2107                triggerExecutionContexts.addElement(tec);
2108        }
2109 
2110        /**
2111         * Remove the tec.  Does an object identity (tec == tec)
2112          * comparison.  Asserts that the tec is found.
2113         *
2114         * @param tec the tec to remove
2115         *
2116         * @exception StandardException on error
2117         */
2118        public void popTriggerExecutionContext(TriggerExecutionContext tec)
2119                throws StandardException
2120        {
2121                if (outermostTrigger == statementDepth)
2122                {
2123                        outermostTrigger = -1; 
2124                }
2125 
2126                boolean foundElement = triggerExecutionContexts.removeElement(tec);
2127                if (SanityManager.DEBUG)
2128                {
2129                        if (!foundElement)
2130                        {
2131                                SanityManager.THROWASSERT("trigger execution context "+tec+" not found");
2132                        }
2133                }
2134        }
2135 
2136        /**
2137         * Get the topmost tec.  
2138         *
2139         * @return the tec
2140         */
2141        public TriggerExecutionContext getTriggerExecutionContext()
2142        {
2143                return triggerExecutionContexts.size() == 0 ? 
2144                                (TriggerExecutionContext)null :
2145                                (TriggerExecutionContext)triggerExecutionContexts.lastElement();        
2146        }
2147 
2148        /**
2149         * Validate a statement.  Does so by stepping through all the validators
2150         * and executing them.  If a validator throws and exception, then the
2151         * checking is stopped and the exception is passed up.
2152         *
2153         * @param constantAction the constantAction that is about to be executed (and
2154         *        should be validated
2155          *
2156         * @exception StandardException on validation failure
2157         */
2158        public void validateStmtExecution(ConstantAction constantAction)
2159                throws StandardException
2160        {
2161                if (SanityManager.DEBUG)
2162                {
2163                        SanityManager.ASSERT(constantAction!=null, "constantAction is null");
2164                }
2165 
2166                if (stmtValidators.size() > 0)
2167                {
2168                        for (Enumeration e = stmtValidators.elements(); e.hasMoreElements(); )
2169                        {
2170                                ((ExecutionStmtValidator)e.nextElement()).validateStatement(constantAction);
2171                        }
2172                }
2173        }
2174        
2175        /**
2176         * Set the trigger table descriptor.  Used to compile
2177         * statements that may special trigger pseudo tables.
2178         *
2179         * @param td the table that the trigger is 
2180         * defined upon
2181         *
2182         */
2183        public void pushTriggerTable(TableDescriptor td)
2184        {
2185                triggerTables.addElement(td);
2186        }
2187 
2188        /**
2189         * Remove the trigger table descriptor.
2190         *
2191         * @param td the table to remove from the stack.
2192         */
2193        public void popTriggerTable(TableDescriptor td)
2194        {
2195                boolean foundElement = triggerTables.removeElement(td);
2196                if (SanityManager.DEBUG)
2197                {
2198                        if (!foundElement)
2199                        {
2200                                SanityManager.THROWASSERT("trigger table not found: "+td);
2201                        }
2202                }
2203        }
2204 
2205        /**
2206         * Get the topmost trigger table descriptor
2207         *
2208         * @return the table descriptor, or null if we
2209         * aren't in the middle of compiling a create
2210         * trigger.
2211         */
2212        public TableDescriptor getTriggerTable()
2213        {
2214                return triggerTables.size() == 0 ? 
2215                        (TableDescriptor)null :
2216                        (TableDescriptor)triggerTables.lastElement();
2217        }
2218        /**
2219         * @see LanguageConnectionContext#getDatabase
2220         */
2221        public Database
2222        getDatabase()
2223        {
2224                return db;
2225        }
2226 
2227        /** @see LanguageConnectionContext#incrementBindCount */
2228        public int incrementBindCount()
2229        {
2230                bindCount++;
2231                return bindCount;
2232        }
2233 
2234        
2235        /** @see LanguageConnectionContext#decrementBindCount */
2236        public int decrementBindCount()
2237        {
2238                bindCount--;
2239 
2240                if (SanityManager.DEBUG)
2241                {
2242                        if (bindCount < 0)
2243                                SanityManager.THROWASSERT(
2244                                        "Level of nested binding == " + bindCount);
2245                }
2246 
2247                return bindCount;
2248        }
2249 
2250        /** @see LanguageConnectionContext#getBindCount */
2251        public int getBindCount()
2252        {
2253                return bindCount;
2254        }
2255 
2256        /** @see LanguageConnectionContext#setDataDictionaryWriteMode */
2257        public final void setDataDictionaryWriteMode()
2258        {
2259                ddWriteMode = true;
2260        }
2261 
2262        /** @see LanguageConnectionContext#dataDictionaryInWriteMode */
2263        public final boolean dataDictionaryInWriteMode()
2264        {
2265                return ddWriteMode;
2266        }
2267 
2268        /** @see LanguageConnectionContext#setRunTimeStatisticsMode */
2269        public void setRunTimeStatisticsMode(boolean onOrOff)
2270        {
2271                runTimeStatisticsSetting = onOrOff;
2272        }
2273 
2274        /** @see LanguageConnectionContext#getRunTimeStatisticsMode */
2275        public boolean getRunTimeStatisticsMode()
2276        {
2277                return runTimeStatisticsSetting;
2278        }
2279 
2280        /** @see LanguageConnectionContext#setStatisticsTiming */
2281        public void setStatisticsTiming(boolean onOrOff)
2282        {
2283                statisticsTiming = onOrOff;
2284        }
2285 
2286        /** @see LanguageConnectionContext#getStatisticsTiming */
2287        public boolean getStatisticsTiming()
2288        {
2289                return statisticsTiming;
2290        }
2291 
2292        /** @see LanguageConnectionContext#setRunTimeStatisticsObject */
2293        public void setRunTimeStatisticsObject(RunTimeStatistics runTimeStatisticsObject)
2294        {
2295                this.runTimeStatisticsObject = runTimeStatisticsObject;
2296        }
2297 
2298        /** @see LanguageConnectionContext#getRunTimeStatisticsObject */
2299        public RunTimeStatistics getRunTimeStatisticsObject()
2300        {
2301                return runTimeStatisticsObject;
2302        }
2303 
2304 
2305    /**
2306          *        Reports how many statement levels deep we are.
2307          *
2308          *        @return        a statement level >= OUTERMOST_STATEMENT
2309          */
2310        public        int                getStatementDepth()
2311        { return statementDepth; }
2312 
2313        /**
2314         * @see LanguageConnectionContext#isIsolationLevelSetUsingSQLorJDBC
2315         */
2316        public boolean isIsolationLevelSetUsingSQLorJDBC()
2317        {
2318                return isolationLevelSetUsingSQLorJDBC;
2319        }
2320 
2321        /**
2322         * @see LanguageConnectionContext#resetIsolationLevelFlagUsedForSQLandJDBC
2323         */
2324        public void resetIsolationLevelFlagUsedForSQLandJDBC()
2325        {
2326                isolationLevelSetUsingSQLorJDBC = false;
2327        }
2328 
2329        /**
2330         * @see LanguageConnectionContext#setIsolationLevel
2331         */
2332        public void setIsolationLevel(int isolationLevel) throws StandardException
2333        {
2334                StatementContext stmtCtxt = getStatementContext();
2335                if (stmtCtxt!= null && stmtCtxt.inTrigger())
2336                        throw StandardException.newException(SQLState.LANG_NO_XACT_IN_TRIGGER, getTriggerExecutionContext().toString());
2337 
2338                // find if there are any held cursors from previous isolation level.
2339                // if yes, then throw an exception that isolation change not allowed until
2340                // the held cursors are closed.
2341                // I had to move this check outside of transaction idle check because if a
2342                // transactions creates held cursors and commits the transaction, then
2343                // there still would be held cursors but the transaction state would be idle.
2344                // In order to check the above mentioned case, the held cursor check
2345                // shouldn't rely on transaction state.
2346                if (this.isolationLevel != isolationLevel)
2347                {
2348                        if (!verifyAllHeldResultSetsAreClosed())
2349                        {
2350                                throw StandardException.newException(SQLState.LANG_CANT_CHANGE_ISOLATION_HOLD_CURSOR);
2351                        }
2352                }
2353 
2354                /* Commit and set to new isolation level.
2355                 * NOTE: We commit first in case there's some kind
2356                 * of error, like can't commit within a server side jdbc call.
2357                 */
2358                TransactionController tc = getTransactionExecute();
2359                if (!tc.isIdle())
2360                {
2361                        // If this transaction is in progress, commit it.
2362                        // However, do not allow commit to happen if this is a global
2363                        // transaction.
2364                        if (tc.isGlobal())
2365                                throw StandardException.newException(SQLState.LANG_NO_SET_TRAN_ISO_IN_GLOBAL_CONNECTION);
2366 
2367                        userCommit();
2368                }
2369                this.isolationLevel = isolationLevel;
2370                this.isolationLevelExplicitlySet = true;
2371                this.isolationLevelSetUsingSQLorJDBC = true;
2372        }
2373 
2374        /**
2375         * @see LanguageConnectionContext#getCurrentIsolationLevel
2376         */
2377        public int getCurrentIsolationLevel()
2378        {
2379                return (isolationLevel == ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL) ? defaultIsolationLevel : isolationLevel;
2380        }
2381 
2382        /**
2383         * @see LanguageConnectionContext#getCurrentIsolationLevel
2384         */
2385        public String getCurrentIsolationLevelStr()
2386        {
2387        if( isolationLevel >= 0 && isolationLevel < ExecutionContext.CS_TO_SQL_ISOLATION_MAP.length)
2388            return ExecutionContext.CS_TO_SQL_ISOLATION_MAP[ isolationLevel][0];
2389        return ExecutionContext.CS_TO_SQL_ISOLATION_MAP[ ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL][0];
2390        }
2391 
2392        /**
2393         * @see LanguageConnectionContext#setPrepareIsolationLevel
2394         */
2395        public void setPrepareIsolationLevel(int level) 
2396        {
2397                        prepareIsolationLevel = level;
2398        }
2399 
2400        /**
2401         * @see LanguageConnectionContext#getPrepareIsolationLevel
2402         */
2403        public int getPrepareIsolationLevel()
2404        {
2405                if (!isolationLevelExplicitlySet)
2406                        return prepareIsolationLevel;
2407                else
2408                        return ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL;
2409        }
2410 
2411        /**
2412         * @see LanguageConnectionContext#getExecutionContext
2413         */
2414        public ExecutionContext getExecutionContext()
2415        {
2416                return (ExecutionContext) getContextManager().getContext(ExecutionContext.CONTEXT_ID);
2417        }
2418 
2419        /**
2420         * @see LanguageConnectionContext#getStatementContext
2421         */
2422        public StatementContext getStatementContext()
2423        {        
2424                return (StatementContext) getContextManager().getContext(org.apache.derby.iapi.reference.ContextId.LANG_STATEMENT);
2425        }
2426 
2427        /**
2428         * @see LanguageConnectionContext#setOptimizerTrace
2429         */
2430        public boolean setOptimizerTrace(boolean onOrOff)
2431        {
2432                if (of == null)
2433                {
2434                        return false;
2435                }
2436                if (! of.supportsOptimizerTrace())
2437                {
2438                        return false;
2439                }
2440                optimizerTrace = onOrOff;
2441                return true;
2442        }
2443 
2444        /**
2445         * @see LanguageConnectionContext#getOptimizerTrace
2446         */
2447        public boolean getOptimizerTrace()
2448        {
2449                return optimizerTrace;
2450        }
2451 
2452        /**
2453         * @see LanguageConnectionContext#setOptimizerTraceHtml
2454         */
2455        public boolean setOptimizerTraceHtml(boolean onOrOff)
2456        {
2457                if (of == null)
2458                {
2459                        return false;
2460                }
2461                if (! of.supportsOptimizerTrace())
2462                {
2463                        return false;
2464                }
2465                optimizerTraceHtml = onOrOff;
2466                return true;
2467        }
2468 
2469        /**
2470         * @see LanguageConnectionContext#getOptimizerTraceHtml
2471         */
2472        public boolean getOptimizerTraceHtml()
2473        {
2474                return optimizerTraceHtml;
2475        }
2476 
2477        /**
2478         * @see LanguageConnectionContext#setOptimizerTraceOutput
2479         */
2480        public void setOptimizerTraceOutput(String startingText)
2481        {
2482                if (optimizerTrace)
2483                {
2484                        lastOptimizerTraceOutput = optimizerTraceOutput;
2485                        optimizerTraceOutput = startingText;
2486                }
2487        }
2488 
2489        /**
2490         * @see LanguageConnectionContext#appendOptimizerTraceOutput
2491         */
2492        public void appendOptimizerTraceOutput(String output)
2493        {
2494                optimizerTraceOutput = 
2495                        (optimizerTraceOutput == null) ? output : optimizerTraceOutput + output;
2496        }
2497 
2498        /**
2499         * @see LanguageConnectionContext#getOptimizerTraceOutput
2500         */
2501        public String getOptimizerTraceOutput()
2502        {
2503                return lastOptimizerTraceOutput;
2504        }
2505 
2506    /**
2507          *        Reports whether there is any outstanding work in the transaction.
2508          *
2509          *        @return        true if there is outstanding work in the transaction
2510          *                                false otherwise
2511          */
2512        public        boolean        isTransactionPristine()
2513        {
2514                return getTransactionExecute().isPristine();
2515        }
2516 
2517    /**
2518          *        Get the lock handle for the current transaction.
2519          *
2520          *        @param        lockScope        SINGLE_TRANSACTION_LOCK or MULTI_TRANSACTION_LOCK
2521          *
2522          *        @return        the current lock handle
2523          *
2524          * @exception StandardException thrown if something goes wrong
2525          */
2526        public        Object        getLockObject( int lockScope ) throws StandardException
2527        {
2528                switch( lockScope )
2529                {
2530                    case SINGLE_TRANSACTION_LOCK:
2531                                return getTransactionExecute().getLockObject();
2532 
2533                    case MULTI_TRANSACTION_LOCK:
2534                                return new Object();
2535 
2536                    default:
2537                                throw StandardException.newException(SQLState.NOT_IMPLEMENTED);
2538                }
2539        }
2540 
2541    /**
2542     * Convert an identifier to the proper case for this connection. This method
2543     * is here to support the Plugin.
2544     *
2545     * @param id an identifier string
2546     * @return  the string converted to upper or lower case, as appropriate
2547     *
2548     * @exception StandardException thrown if something goes wrong
2549     */
2550    public        String convertIdentifierCase( String id) throws StandardException
2551    {
2552        if( ANTI_ANSI_CASING == getIdentifierCasing())
2553            return StringUtil.SQLToLowerCase(id);
2554        else
2555            return StringUtil.SQLToUpperCase(id);
2556    }
2557    
2558        /**
2559          *        Get casing for delimited identifiers. This feature is here to
2560          *        support the Plugin.
2561          *
2562          *        @return        ANSI_CASING or ANTI_ANSI_CASING.
2563          *
2564          * @exception StandardException thrown if something goes wrong
2565          */
2566    public        int        getIdentifierCasing() throws StandardException
2567        {
2568        if( UNKNOWN_CASING == identifierCasing)
2569        {
2570            identifierCasing = ANSI_CASING;
2571        }
2572        return identifierCasing;
2573    }
2574 
2575        //
2576        // Context interface
2577        //
2578        /**
2579                If worse than a transaction error, everything goes; we
2580                rely on other contexts to kill the context manager
2581                for this session.
2582                <p>
2583                If a transaction error, act like we saw a rollback.
2584                <p>
2585                If more severe or a java error, the outer cleanup
2586                will shutdown the connection, so we don't have to clean up.
2587                <p>
2588                REMIND: connection should throw out all contexts and start
2589                over when the connection is closed... perhaps by throwing
2590                out the context manager?
2591                <p>
2592                REVISIT: If statement error, should we do anything?
2593                <P>
2594                Since the access manager's own context takes care of its own
2595                resources on errors, there is nothing that this context has
2596                to do with the transaction controller.
2597 
2598                @exception StandardException thrown on error. REVISIT: don't want
2599                cleanupOnError's to throw exceptions.
2600         */
2601        public void cleanupOnError(Throwable error) throws StandardException {
2602 
2603                /*
2604                ** If it isn't a StandardException, then assume
2605                ** xact severity.  It is probably an unexpected
2606                ** java error somewhere in the language.
2607                */
2608                int severity = (error instanceof StandardException) ?
2609                        ((StandardException) error).getSeverity() :
2610                        ExceptionSeverity.TRANSACTION_SEVERITY;
2611 
2612                if (statementContexts[0] != null)
2613                {
2614                        statementContexts[0].clearInUse();
2615            
2616            // Force the StatementContext that's normally
2617            // left on the stack for optimization to be popped
2618            // when the session is closed. Ensures full cleanup
2619            // and no hanging refrences in the ContextManager.
2620            if (severity >= ExceptionSeverity.SESSION_SEVERITY)
2621                statementContexts[0].popMe();
2622                }
2623                if (statementContexts[1] != null)
2624                {
2625                        statementContexts[1].clearInUse();                
2626                }
2627 
2628                // closing the activations closes all the open cursors.
2629                // the activations are, for all intents and purposes, the
2630                // cursors.
2631                if (severity >= ExceptionSeverity.SESSION_SEVERITY) 
2632                {
2633                        for (int i = acts.size() - 1; i >= 0; i--) {
2634                                // it maybe the case that a reset()/close() ends up closing
2635                                // one or more activation leaving our index beyond
2636                                // the end of the array
2637                                if (i >= acts.size())
2638                                        continue;
2639                                Activation a = (Activation) acts.elementAt(i);
2640                                a.reset();
2641                                a.close();
2642                        }
2643                       
2644                        popMe();
2645                }
2646 
2647                /*
2648                ** We have some global state that we need
2649                ** to clean up no matter what.  Be sure
2650                ** to do so.
2651                */
2652                else if (severity >= ExceptionSeverity.TRANSACTION_SEVERITY) 
2653                {
2654                        internalRollback();
2655                }
2656        }
2657 
2658        /**
2659         * @see Context#isLastHandler
2660         */
2661        public boolean isLastHandler(int severity)
2662        {
2663                return false;
2664        }
2665 
2666        //
2667        // class implementation
2668        //
2669 
2670 
2671        /**
2672                resets all open activations, to close their result sets.
2673                Also cleans up (close()) activations that have been
2674                marked as unused during statement finalization.
2675 
2676                @exception StandardException thrown on failure
2677         */
2678        private void resetActivations(boolean andClose) throws StandardException {
2679 
2680                // don't use an enumeration as the activation may remove
2681                // itself from the list, thus invalidating the Enumeration
2682                for (int i = acts.size() - 1; i >= 0; i--) {
2683 
2684                        // it maybe the case that a reset() ends up closing
2685                        // one or more activation leaving our index beyond
2686                        // the end of the array
2687                        if (i >= acts.size())
2688                                continue;
2689 
2690                        Activation a = (Activation) acts.elementAt(i);
2691                        /*
2692                        ** andClose true means we are here for rollback.
2693                        ** In case of rollback, we don't care for holding
2694                        ** cursors and that's why I am resetting holdability
2695                        ** to false for all activations just before rollback
2696                        */        
2697                        if (andClose)
2698                                a.setResultSetHoldability(false);
2699 
2700                        /*
2701                        ** Look for stale activations.  Activations are
2702                        ** marked as unused during statement finalization.
2703                        ** Here, we sweep and remove this inactive ones.
2704                        */        
2705                        if (!a.isInUse())
2706                        {
2707                                a.close();
2708                                continue;
2709                        }
2710 
2711                        a.reset();
2712 
2713                        // Only invalidate statements if we performed DDL.
2714                        if (andClose && dataDictionaryInWriteMode()) {
2715                                ExecPreparedStatement ps = a.getPreparedStatement();
2716                                if (ps != null) {
2717                                        ps.makeInvalid(DependencyManager.ROLLBACK, this);
2718                                }
2719                        }
2720                }
2721        }
2722 
2723        /**
2724                Finish the data dictionary transaction, if any.
2725 
2726                @exception StandardException        Thrown on error
2727         */
2728        private void finishDDTransaction() throws StandardException {
2729 
2730                /* Was the data dictionary put into write mode? */
2731                if (ddWriteMode) {
2732                        DataDictionary dd = getDataDictionary();
2733 
2734                        /* Tell the data dictionary that the transaction is finished */
2735                        dd.transactionFinished();
2736 
2737                        /* The data dictionary isn't in write mode any more */
2738                        ddWriteMode = false;
2739                }
2740        }
2741 
2742        ////////////////////////////////////////////////////////////////////
2743        //
2744        //        MINIONS
2745        //
2746        ////////////////////////////////////////////////////////////////////
2747 
2748        /**
2749          *        Increments the statement depth.
2750          */
2751    private        void        incrementStatementDepth() { statementDepth++; }
2752 
2753    /**
2754          * Decrements the statement depth
2755          */
2756        private        void        decrementStatementDepth()
2757        {
2758                statementDepth--;
2759        }
2760 
2761        /**
2762          *        Resets the statementDepth.
2763          */
2764        protected        void        resetStatementDepth()
2765        {
2766                statementDepth = 0;
2767        }
2768 
2769    /**
2770     * Get the name of the system schema.
2771     *
2772     * @return        A String containing the name of the system schema.
2773     * @throws StandardException
2774     */
2775    public String getSystemSchemaName() throws StandardException
2776    {
2777        return convertIdentifierCase( SchemaDescriptor.STD_SYSTEM_SCHEMA_NAME);
2778    }
2779    
2780    /**
2781     * Get the name of the SYSIBM schema.
2782     *
2783     * @return        A String containing the name of the SYSIBM schema.
2784     * @throws StandardException
2785     */
2786    public String getSysIBMSchemaName() throws StandardException
2787    {
2788        return convertIdentifierCase( SchemaDescriptor.IBM_SYSTEM_SCHEMA_NAME);
2789    }
2790 
2791    /**
2792     * Get the name of the SYSCS_DIAG schema.
2793     *
2794     * @return        A String containing the name of the SYSIBM schema.
2795     * @throws StandardException
2796     */
2797    public String getSystemDiagSchemaName() throws StandardException
2798    {
2799        return(
2800            convertIdentifierCase(
2801                SchemaDescriptor.STD_SYSTEM_DIAG_SCHEMA_NAME));
2802    }
2803 
2804    /**
2805     * Get the name of the SYSCS_UTIL schema.
2806     *
2807     * @return        A String containing the name of the SYSIBM schema.
2808     * @throws StandardException
2809     */
2810    public String getSystemUtilSchemaName() throws StandardException
2811    {
2812        return(
2813            convertIdentifierCase(
2814                SchemaDescriptor.STD_SYSTEM_UTIL_SCHEMA_NAME));
2815    }
2816    
2817    /**
2818     * Get the declared global temporary tables schema name.
2819     *
2820     * @return        a String containing the declared global temporary tables schema name.
2821     * @throws StandardException
2822     */
2823    public String getDeclaredGlobalTemporaryTablesSchemaName() throws StandardException
2824    {
2825        return convertIdentifierCase( SchemaDescriptor.STD_DECLARED_GLOBAL_TEMPORARY_TABLES_SCHEMA_NAME);
2826    }
2827 
2828        public DataDictionary getDataDictionary()
2829        {
2830                DataDictionaryContext ddc =
2831                        (DataDictionaryContext) getContextManager().getContext(DataDictionaryContext.CONTEXT_ID);
2832 
2833                if (ddc != null)
2834                {
2835                        return ddc.getDataDictionary();
2836                }
2837                else 
2838                {
2839                        return null;
2840                }
2841        }
2842 
2843        /**
2844          @see LanguageConnectionContext#setReadOnly
2845          @exception StandardException The operation is disallowed.
2846          */
2847        public void setReadOnly(boolean on) throws StandardException
2848        {
2849                if (!tran.isPristine())
2850                        throw StandardException.newException(SQLState.AUTH_SET_CONNECTION_READ_ONLY_IN_ACTIVE_XACT);
2851                authorizer.setReadOnlyConnection(on,true);
2852        }
2853 
2854        /**
2855          @see LanguageConnectionContext#isReadOnly
2856          */
2857        public boolean isReadOnly()
2858        {
2859                return authorizer.isReadOnlyConnection();
2860        }
2861 
2862        /**
2863          @see LanguageConnectionContext#getAuthorizer
2864         */
2865        public Authorizer getAuthorizer()
2866        {
2867                return authorizer;
2868        }
2869 
2870        /** @see LanguageConnectionContext#getAccessFactory */
2871        public AccessFactory getAccessFactory()
2872        {
2873                return af;
2874        }
2875 
2876        /**
2877         * Implements ConnectionInfo.lastAutoincrementValue.
2878         * lastAutoincrementValue searches for the last autoincrement value inserted
2879         * into a column specified by the user. The search for the "last" value
2880         * supports nesting levels caused by triggers (Only triggers cause nesting,
2881         * not server side JDBC). 
2882         * If lastAutoincrementValue is called from within a trigger, the search
2883         * space for ai-values are those values that are inserted by this trigger as
2884         * well as previous triggers; 
2885         * i.e if a SQL statement fires trigger T1, which in turn does something
2886         * that fires trigger t2, and if lastAutoincrementValue is called from
2887         * within t2, then autoincrement values genereated by t1 are visible to
2888         * it. By the same logic, if it is called from within t1, then it does not
2889         * see values inserted by t2.
2890         *
2891         * @see LanguageConnectionContext#lastAutoincrementValue
2892         * @see org.apache.derby.iapi.db.ConnectionInfo#lastAutoincrementValue
2893         */
2894        public Long lastAutoincrementValue(String schemaName, String tableName,
2895                                                                           String columnName)
2896        {
2897                String aiKey = AutoincrementCounter.makeIdentity(schemaName, tableName, columnName);
2898                
2899                int size = triggerExecutionContexts.size();
2900                //                System.out.println(" searching for " + aiKey);
2901                for (int i = size - 1; i >= 0; i--)
2902                {
2903                        // first loop through triggers.
2904                        InternalTriggerExecutionContext itec = 
2905                                (InternalTriggerExecutionContext)triggerExecutionContexts.elementAt(i);
2906                        Long value = itec.getAutoincrementValue(aiKey);
2907                        if (value == null)
2908                                continue;
2909 
2910                        return value;
2911                }
2912                if (autoincrementHT == null)
2913                        return null;
2914                return (Long)autoincrementHT.get(aiKey);
2915        }        
2916 
2917        /**
2918         * @see LanguageConnectionContext#setAutoincrementUpdate
2919         */
2920        public void setAutoincrementUpdate(boolean flag)
2921        {
2922                autoincrementUpdate = flag;
2923        }
2924        
2925        /**
2926         * @see LanguageConnectionContext#getAutoincrementUpdate
2927         */
2928        public boolean getAutoincrementUpdate()
2929        {
2930                return autoincrementUpdate;
2931        }
2932        
2933        /**
2934         * @see LanguageConnectionContext#autoincrementCreateCounter
2935         */
2936        public void autoincrementCreateCounter(String s, String t, String c,
2937                                                                                   Long initialValue, long increment,
2938                                                                                   int position)
2939        {
2940                String key = AutoincrementCounter.makeIdentity(s,t,c);
2941                
2942                if (autoincrementCacheHashtable == null)
2943                {
2944                        autoincrementCacheHashtable = new Hashtable();
2945                }
2946 
2947                AutoincrementCounter aic = 
2948                        (AutoincrementCounter)autoincrementCacheHashtable.get(key);
2949                if (aic != null)
2950                {
2951                        if (SanityManager.DEBUG)                        
2952                        {
2953                                SanityManager.THROWASSERT(
2954                                                          "Autoincrement Counter already exists:" + key);
2955                        }
2956                        return;
2957                }
2958                
2959                aic = new AutoincrementCounter(initialValue, 
2960                                                                           increment, 0, s, t, c, position);
2961                autoincrementCacheHashtable.put(key, aic);
2962        }
2963 
2964        /**
2965         * returns the <b>next</b> value to be inserted into an autoincrement col.
2966         * This is used internally by the system to generate autoincrement values
2967         * which are going to be inserted into a autoincrement column. This is
2968         * used when as autoincrement column is added to a table by an alter 
2969         * table statemenet and during bulk insert.
2970         *
2971         * @param schemaName
2972         * @param tableName
2973         * @param columnName identify the column uniquely in the system.
2974         */
2975        public long nextAutoincrementValue(String schemaName, String tableName,
2976                                                                           String columnName)
2977                        throws StandardException                                                   
2978        {
2979                String key = AutoincrementCounter.makeIdentity(schemaName,tableName,
2980                                                                                                           columnName);
2981                
2982                AutoincrementCounter aic = 
2983                        (AutoincrementCounter)autoincrementCacheHashtable.get(key);
2984 
2985                if (aic == null)
2986                {
2987                        if (SanityManager.DEBUG)                        
2988                        {
2989                                SanityManager.THROWASSERT("counter doesn't exist:" + key);
2990                        }
2991                        return 0;
2992                }
2993                else
2994                {
2995                        return aic.update();
2996                }
2997        }
2998        
2999        /**
3000         * Flush the cache of autoincrement values being kept by the lcc.
3001         * This will result in the autoincrement values being written to the
3002         * SYSCOLUMNS table as well as the mapping used by lastAutoincrementValue
3003         * 
3004         * @exception StandardException thrown on error.
3005         * @see LanguageConnectionContext#lastAutoincrementValue
3006         * @see GenericLanguageConnectionContext#lastAutoincrementValue
3007         * @see org.apache.derby.iapi.db.ConnectionInfo#lastAutoincrementValue
3008         */
3009        public void autoincrementFlushCache(UUID tableUUID)
3010                throws StandardException
3011        {
3012                if (autoincrementCacheHashtable == null)
3013                        return;
3014 
3015                if (autoincrementHT == null)
3016                        autoincrementHT = new Hashtable();
3017 
3018                DataDictionary dd = getDataDictionary();
3019                for (Enumeration e = autoincrementCacheHashtable.keys(); 
3020                         e.hasMoreElements(); )
3021                {
3022                        Object key = e.nextElement();
3023                        AutoincrementCounter aic = 
3024                                (AutoincrementCounter)autoincrementCacheHashtable.get(key);
3025                        Long value = aic.getCurrentValue();
3026                        aic.flushToDisk(getTransactionExecute(), dd, tableUUID);
3027                        if (value != null)
3028                        {
3029                                autoincrementHT.put(key, value);
3030                        }
3031                }
3032                autoincrementCacheHashtable.clear();
3033        }
3034 
3035        /**
3036         * Copies an existing hashtable of autoincrement mappings 
3037         * into autoincrementHT, the cache of autoincrement values 
3038         * kept in the languageconnectioncontext.
3039         */
3040        public void copyHashtableToAIHT(Hashtable from)
3041        {
3042                if (from.isEmpty())
3043                        return;
3044                if (autoincrementHT == null)
3045                        autoincrementHT = new Hashtable();
3046                
3047                for (Enumeration e = from.keys(); e.hasMoreElements(); )
3048                {
3049                        Object key = e.nextElement();
3050                        Object value = from.get(key);
3051                        autoincrementHT.put(key, value);
3052                }
3053        }
3054        
3055        /**
3056         * @see LanguageConnectionContext#getInstanceNumber
3057         */
3058        public int getInstanceNumber()
3059        {
3060                return instanceNumber;
3061        }
3062 
3063        /**
3064         * @see LanguageConnectionContext#getDrdaID
3065         */
3066        public String getDrdaID()
3067        {
3068                return drdaID;
3069        }
3070 
3071        /**
3072         * @see LanguageConnectionContext#setDrdaID
3073         */
3074        public void setDrdaID(String drdaID)
3075        {
3076                this.drdaID = drdaID;
3077        }
3078 
3079        /**
3080         * @see LanguageConnectionContext#getDbname
3081         */
3082        public String getDbname()
3083        {
3084                return dbname;
3085        }
3086 
3087        /**
3088         * @see LanguageConnectionContext#getLastActivation
3089         */
3090        public Activation getLastActivation()
3091        {
3092                return (Activation)acts.lastElement();
3093        }
3094 
3095        public StringBuffer appendErrorInfo() {
3096 
3097                TransactionController tc = getTransactionExecute();
3098                if (tc == null)
3099                        return null;
3100 
3101                StringBuffer sb = new StringBuffer(200);
3102 
3103                sb.append(LanguageConnectionContext.xidStr);
3104                sb.append(tc.getTransactionIdString());
3105                sb.append("), ");
3106 
3107                sb.append(LanguageConnectionContext.lccStr);
3108                sb.append(Integer.toString(getInstanceNumber()));
3109                sb.append("), ");
3110 
3111                sb.append(LanguageConnectionContext.dbnameStr);
3112                sb.append(getDbname());
3113                sb.append("), ");
3114 
3115                sb.append(LanguageConnectionContext.drdaStr);
3116                sb.append(getDrdaID());
3117                sb.append("), ");
3118 
3119                return sb;
3120        }
3121}

[all classes][org.apache.derby.impl.sql.conn]
EMMA 2.0.5312 (C) Vladimir Roubtsov