aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/trigger.c12
-rw-r--r--src/test/regress/expected/triggers.out11
-rw-r--r--src/test/regress/sql/triggers.sql14
3 files changed, 32 insertions, 5 deletions
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 95de402fa65..58b7fc5bbd5 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -4289,8 +4289,12 @@ AfterTriggerExecute(EState *estate,
bool should_free_new = false;
/*
- * Locate trigger in trigdesc.
+ * 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)
@@ -4300,7 +4304,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
@@ -4681,6 +4685,7 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events,
/* Catch calls with insufficient relcache refcounting */
Assert(!RelationHasReferenceCountZero(rel));
trigdesc = rInfo->ri_TrigDesc;
+ /* caution: trigdesc could be NULL here */
finfo = rInfo->ri_TrigFunctions;
instr = rInfo->ri_TrigInstrument;
if (slot1 != NULL)
@@ -4696,9 +4701,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 7f774e5e177..a044d6afe27 100644
--- a/src/test/regress/expected/triggers.out
+++ b/src/test/regress/expected/triggers.out
@@ -3372,6 +3372,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 6c9e066397f..51610788b21 100644
--- a/src/test/regress/sql/triggers.sql
+++ b/src/test/regress/sql/triggers.sql
@@ -2479,6 +2479,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
--