// Here we get the trigger action sql and use the parser to build
// the parse tree for it.
SchemaDescriptor compSchema;
compSchema = dd.getSchemaDescriptor(trd.getSchemaDescriptor().getUUID(), null);
CompilerContext newCC = lcc.pushCompilerContext(compSchema);
Parser pa = newCC.getParser();
StatementNode stmtnode = (StatementNode)pa.parseStatement(trd.getTriggerDefinition());
lcc.popCompilerContext(newCC);
// Do not delete following. We use this in finally clause to
// determine if the CompilerContext needs to be popped.
newCC = null;
try {
// We are interested in ColumnReference classes in the parse tree
CollectNodesVisitor visitor = new CollectNodesVisitor(ColumnReference.class);
stmtnode.accept(visitor);
Vector refs = visitor.getList();
// Regenerate the internal representation for the trigger action
// sql using the ColumnReference classes in the parse tree. It
// will catch dropped column getting used in trigger action sql
// through the REFERENCING clause(this can happen only for the
// the triggers created prior to 10.7. Trigger created with
// 10.7 and higher keep track of trigger action column used
// through the REFERENCING clause in system table and hence
// use of dropped column will be detected earlier in this
// method for such triggers).
//
// We might catch errors like following during this step.
// Say that following pre-10.7 trigger exists in the system and
// user is dropping column c11. During the regeneration of the
// internal trigger action sql format, we will catch that
// column oldt.c11 does not exist anymore
// CREATE TRIGGER DERBY4998_SOFT_UPGRADE_RESTRICT_tr1
// AFTER UPDATE OF c12
// ON DERBY4998_SOFT_UPGRADE_RESTRICT REFERENCING OLD AS oldt
// FOR EACH ROW
// SELECT oldt.c11 from DERBY4998_SOFT_UPGRADE_RESTRICT
SPSDescriptor triggerActionSPSD = trd.getActionSPS(lcc);
int[] referencedColsInTriggerAction = new int[td.getNumberOfColumns()];
java.util.Arrays.fill(referencedColsInTriggerAction, -1);
triggerActionSPSD.setText(dd.getTriggerActionString(stmtnode,
trd.getOldReferencingName(),
trd.getNewReferencingName(),
trd.getTriggerDefinition(),
trd.getReferencedCols(),
referencedColsInTriggerAction,
0,
trd.getTableDescriptor(),
trd.getTriggerEventMask(),
true
));
// Now that we have the internal format of the trigger action sql,
// bind that sql to make sure that we are not using colunm being
// dropped in the trigger action sql directly (ie not through
// REFERENCING clause.
// eg
// create table atdc_12 (a integer, b integer);
// create trigger atdc_12_trigger_1 after update of a
// on atdc_12 for each row select a,b from atdc_12
// Drop one of the columns used in the trigger action
// alter table atdc_12 drop column b
// Following rebinding of the trigger action sql will catch the use
// of column b in trigger atdc_12_trigger_1
compSchema = dd.getSchemaDescriptor(trd.getSchemaDescriptor().getUUID(), null);
newCC = lcc.pushCompilerContext(compSchema);
newCC.setReliability(CompilerContext.INTERNAL_SQL_LEGAL);
pa = newCC.getParser();
stmtnode = (StatementNode)pa.parseStatement(triggerActionSPSD.getText());
// need a current dependent for bind
newCC.setCurrentDependent(triggerActionSPSD.getPreparedStatement());
stmtnode.bindStatement();
//Register the dependency between trigger table and trigger
// action SPS