diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/commands/trigger.c | 16 | ||||
-rw-r--r-- | src/test/regress/expected/triggers.out | 11 | ||||
-rw-r--r-- | src/test/regress/sql/triggers.sql | 14 |
3 files changed, 34 insertions, 7 deletions
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 794bfe1f149..7f3285b0718 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -4239,13 +4239,17 @@ AfterTriggerExecute(EState *estate, bool should_free_trig = false; bool should_free_new = false; - /* - * Locate trigger in trigdesc. - */ LocTriggerData.tg_trigger = NULL; LocTriggerData.tg_trigslot = NULL; LocTriggerData.tg_newslot = NULL; + /* + * Locate trigger in trigdesc. It might not be present, and in fact the + * trigdesc could be NULL, if the trigger was dropped since the event was + * queued. In that case, silently do nothing. + */ + if (trigdesc == NULL) + return; for (tgindx = 0; tgindx < trigdesc->numtriggers; tgindx++) { if (trigdesc->triggers[tgindx].tgoid == tgoid) @@ -4255,7 +4259,7 @@ AfterTriggerExecute(EState *estate, } } if (LocTriggerData.tg_trigger == NULL) - elog(ERROR, "could not find trigger %u", tgoid); + return; /* * If doing EXPLAIN ANALYZE, start charging time to this trigger. We want @@ -4575,6 +4579,7 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events, rInfo = ExecGetTriggerResultRel(estate, evtshared->ats_relid); rel = rInfo->ri_RelationDesc; trigdesc = rInfo->ri_TrigDesc; + /* caution: trigdesc could be NULL here */ finfo = rInfo->ri_TrigFunctions; instr = rInfo->ri_TrigInstrument; if (slot1 != NULL) @@ -4590,9 +4595,6 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events, slot2 = MakeSingleTupleTableSlot(rel->rd_att, &TTSOpsMinimalTuple); } - if (trigdesc == NULL) /* should not happen */ - elog(ERROR, "relation %u has no triggers", - evtshared->ats_relid); } /* diff --git a/src/test/regress/expected/triggers.out b/src/test/regress/expected/triggers.out index 79e5e4b3533..58ee950b57e 100644 --- a/src/test/regress/expected/triggers.out +++ b/src/test/regress/expected/triggers.out @@ -3124,6 +3124,17 @@ select * from trig_table; drop table refd_table, trig_table; -- +-- Test that we can drop a not-yet-fired deferred trigger +-- +create table refd_table (id int primary key); +create table trig_table (fk int references refd_table initially deferred); +begin; +insert into trig_table values (1); +drop table refd_table cascade; +NOTICE: drop cascades to constraint trig_table_fk_fkey on table trig_table +commit; +drop table trig_table; +-- -- self-referential FKs are even more fun -- create table self_ref (a int primary key, diff --git a/src/test/regress/sql/triggers.sql b/src/test/regress/sql/triggers.sql index d1d6f9974ca..f889d251429 100644 --- a/src/test/regress/sql/triggers.sql +++ b/src/test/regress/sql/triggers.sql @@ -2304,6 +2304,20 @@ select * from trig_table; drop table refd_table, trig_table; -- +-- Test that we can drop a not-yet-fired deferred trigger +-- + +create table refd_table (id int primary key); +create table trig_table (fk int references refd_table initially deferred); + +begin; +insert into trig_table values (1); +drop table refd_table cascade; +commit; + +drop table trig_table; + +-- -- self-referential FKs are even more fun -- |