@@ -560,35 +560,49 @@ void EXE_execute_ddl_triggers(thread_db* tdbb, jrd_tra* transaction, bool preTri
560
560
{
561
561
TrigVector triggers;
562
562
TrigVector* triggersPtr = &triggers;
563
+ HalfStaticArray<Trigger*, 4 > cachedTriggers;
563
564
564
- for (const auto & trigger : *attachment->att_ddl_triggers )
565
+ for (auto & trigger : *attachment->att_ddl_triggers )
565
566
{
566
567
const auto type = trigger.type & ~TRIGGER_TYPE_MASK;
567
568
const bool preTrigger = ((type & 1 ) == 0 );
568
569
569
570
if ((type & (1LL << action)) && (preTriggers == preTrigger))
570
571
{
571
572
triggers.add () = trigger;
573
+ cachedTriggers.add (&trigger);
572
574
}
573
575
}
574
576
575
577
if (triggers.hasData ())
576
578
{
579
+ FbLocalStatus tempStatus;
580
+
577
581
jrd_tra* const oldTransaction = tdbb->getTransaction ();
578
582
tdbb->setTransaction (transaction);
579
583
580
584
try
581
585
{
582
586
EXE_execute_triggers (tdbb, &triggersPtr, NULL , NULL , TRIGGER_DDL,
583
587
preTriggers ? StmtNode::PRE_TRIG : StmtNode::POST_TRIG);
584
-
585
- tdbb->setTransaction (oldTransaction);
586
588
}
587
- catch (const Exception&)
589
+ catch (const Exception& ex )
588
590
{
589
- tdbb->setTransaction (oldTransaction);
590
- throw ;
591
+ ex.stuffException (&tempStatus);
591
592
}
593
+
594
+ tdbb->setTransaction (oldTransaction);
595
+
596
+ // Triggers could be compiled inside EXE_execute_triggers(),
597
+ // so ensure the new pointers are copied back to the cache
598
+ fb_assert (triggers.getCount () == cachedTriggers.getCount ());
599
+ for (unsigned i = 0 ; i < triggers.getCount (); i++)
600
+ {
601
+ *cachedTriggers[i] = triggers[i];
602
+ triggers[i].extTrigger = nullptr ; // avoid deletion inside d'tor
603
+ }
604
+
605
+ tempStatus.check ();
592
606
}
593
607
}
594
608
}
0 commit comments