ps.setSource(sps.getText());
ps.setSPSAction();
}
// save the active statement context for exception handling purpose
StatementContext active_sc = lcc.getStatementContext();
/*
** Execute the activation. If we have an error, we
** are going to go to some extra work to pop off
** our statement context. This is because we are
** a nested statement (we have 2 activations), but
** we aren't a nested connection, so we have to
** pop off our statementcontext to get error handling
** to work correctly. This is normally a no-no, but
** we are an unusual case.
*/
try
{
// This is a substatement; for now, we do not set any timeout
// for it. We might change this behaviour later, by linking
// timeout to its parent statement's timeout settings.
ResultSet rs = ps.executeSubStatement
(activation, spsActivation, false, 0L);
if( rs.returnsRows())
{
// Fetch all the data to ensure that functions in the select list or values statement will
// be evaluated and side effects will happen. Why else would the trigger action return
// rows, but for side effects?
// The result set was opened in ps.execute()
while( rs.getNextRow() != null)
{
}
}
rs.close();
}
catch (StandardException e)
{
/*
** When a trigger SPS action is executed and results in
** an exception, the system needs to clean up the active
** statement context(SC) and the trigger execution context
** (TEC) in language connection context(LCC) properly (e.g.:
** "Maximum depth triggers exceeded" exception); otherwise,
** this will leave old TECs lingering and may result in
** subsequent statements within the same connection to throw
** the same exception again prematurely.
**
** A new statement context will be created for the SPS before
** it is executed. However, it is possible for some
** StandardException to be thrown before a new statement
** context is pushed down to the context stack; hence, the
** trigger executor needs to ensure that the current active SC
** is associated with the SPS, so that it is cleaning up the
** right statement context in LCC.
**
** When the active SC is cleaned up, the TEC will be removed
** from LCC and the SC object will be popped off from the LCC
** as part of cleanupOnError logic.
*/
/* retrieve the current active SC */
StatementContext sc = lcc.getStatementContext();
/* make sure that the cleanup is on the new SC */
if (active_sc != sc)
{
sc.cleanupOnError(e);
}
/* Handle dynamic recompiles */
if (e.getMessageId().equals(SQLState.LANG_STATEMENT_NEEDS_RECOMPILE))
{