aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/commands/trigger.c16
-rw-r--r--src/test/regress/expected/triggers.out11
-rw-r--r--src/test/regress/sql/triggers.sql14
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
--