cc.setCurrentDependent(preparedStmt);
//Only top level statements go through here, nested statement
//will invoke this method from other places
QueryTreeNode qt = p.parseStatement(statementText, paramDefaults);
parseTime = getCurrentTimeMillis(lcc);
if (SanityManager.DEBUG)
{
if (SanityManager.DEBUG_ON("DumpParseTree"))
{
qt.treePrint();
}
if (SanityManager.DEBUG_ON("StopAfterParsing"))
{
throw StandardException.newException(SQLState.LANG_STOP_AFTER_PARSING);
}
}
/*
** Tell the data dictionary that we are about to do
** a bunch of "get" operations that must be consistent with
** each other.
*/
DataDictionary dataDictionary = lcc.getDataDictionary();
int ddMode = dataDictionary == null ? 0 : dataDictionary.startReading(lcc);
try
{
// start a nested transaction -- all locks acquired by bind
// and optimize will be released when we end the nested
// transaction.
lcc.beginNestedTransaction(true);
qt = qt.bind();
bindTime = getCurrentTimeMillis(lcc);
if (SanityManager.DEBUG)
{
if (SanityManager.DEBUG_ON("DumpBindTree"))
{
qt.treePrint();
}
if (SanityManager.DEBUG_ON("StopAfterBinding")) {
throw StandardException.newException(SQLState.LANG_STOP_AFTER_BINDING);
}
}
qt = qt.optimize();
optimizeTime = getCurrentTimeMillis(lcc);
// Statement logging if lcc.getLogStatementText() is true
if (istream != null)
{
String xactId = lcc.getTransactionExecute().getActiveStateTxIdString();
istream.printlnWithHeader(LanguageConnectionContext.xidStr +
xactId +
"), " +
LanguageConnectionContext.lccStr +
lcc.getInstanceNumber() +
"), " +
LanguageConnectionContext.dbnameStr +
lcc.getDbname() +
"), " +
LanguageConnectionContext.drdaStr +
lcc.getDrdaID() +
"), End compiling prepared statement: " +
getSource() +
" :End prepared statement");
}
}
catch (StandardException se)
{
lcc.commitNestedTransaction();
if (foundInCache)
((GenericLanguageConnectionContext)lcc).removeStatement(this);
// Statement logging if lcc.getLogStatementText() is true
if (istream != null)
{
String xactId = lcc.getTransactionExecute().getActiveStateTxIdString();
istream.printlnWithHeader(LanguageConnectionContext.xidStr +
xactId +
"), " +
LanguageConnectionContext.lccStr +
lcc.getInstanceNumber() +
"), " +
LanguageConnectionContext.dbnameStr +
lcc.getDbname() +
"), " +
LanguageConnectionContext.drdaStr +
lcc.getDrdaID() +
"), Error compiling prepared statement: " +
getSource() +
" :End prepared statement");
}
throw se;
}
finally
{
/* Tell the data dictionary that we are done reading */
if (dataDictionary != null)
dataDictionary.doneReading(ddMode, lcc);
}
/* we need to move the commit of nested sub-transaction
* after we mark PS valid, during compilation, we might need
* to get some lock to synchronize with another thread's DDL
* execution, in particular, the compilation of insert/update/
* delete vs. create index/constraint (see Beetle 3976). We
* can't release such lock until after we mark the PS valid.
* Otherwise we would just erase the DDL's invalidation when
* we mark it valid.
*/
try // put in try block, commit sub-transaction if bad
{
if (SanityManager.DEBUG)
{
if (SanityManager.DEBUG_ON("DumpOptimizedTree"))
{
qt.treePrint();
}
if (SanityManager.DEBUG_ON("StopAfterOptimizing"))
{
throw StandardException.newException(SQLState.LANG_STOP_AFTER_OPTIMIZING);
}
}
GeneratedClass ac = qt.generate(preparedStmt.getByteCodeSaver());
generateTime = getCurrentTimeMillis(lcc);
/* endTimestamp only meaningful if generateTime is meaningful.
* generateTime is meaningful if STATISTICS TIMING is ON.
*/
if (generateTime != 0)
{
endTimestamp = new Timestamp(generateTime);
}
if (SanityManager.DEBUG)
{
if (SanityManager.DEBUG_ON("StopAfterGenerating"))
{
throw StandardException.newException(SQLState.LANG_STOP_AFTER_GENERATING);
}
}
/*
copy over the compile-time created objects
to the prepared statement. This always happens
at the end of a compile, so there is no need
to erase the previous entries on a re-compile --
this erases as it replaces. Set the activation
class in case it came from a StorablePreparedStatement
*/
preparedStmt.setConstantAction( qt.makeConstantAction() );
preparedStmt.setSavedObjects( cc.getSavedObjects() );
preparedStmt.setActivationClass(ac);
preparedStmt.setParams(cc.getParams());
preparedStmt.setNeedsSavepoint(qt.needsSavepoint());
preparedStmt.setCursorInfo((CursorInfo)cc.getCursorInfo());
preparedStmt.setIsAtomic(qt.isAtomic());
preparedStmt.setExecuteStatementNameAndSchema(
qt.executeStatementName(),
qt.executeSchemaName()
);
preparedStmt.setSPSName(qt.getSPSName());
//if this statement is referencing session schema tables, then we do not want cache it. Following will remove the
//entry that was made into the cache for this statement at the beginning of the compile phase
if (preparedStmt.completeCompile(qt)) {
if (foundInCache)