Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9ce8ee9

Browse files
committed
Don't throw an error if a queued AFTER trigger no longer exists.
afterTriggerInvokeEvents and AfterTriggerExecute have alwaystreated it as an error if the trigger OID mentioned in a queuedafter-trigger event can't be found. However, that fails toaccount for the edge case where the trigger's been dropped inthe current transaction since queueing the event. There seemsno very good reason to disallow that case, so instead silentlydo nothing if the trigger OID can't be found.This does give up a little bit of bug-detection ability, but I don'trecall that these error messages have ever actually revealed a bug,so it seems mostly theoretical. Alternatives such as markingpending events DONE at the time of dropping a trigger would becomplicated and perhaps introduce bugs of their own.Per bug #18517 from Alexander Lakhin. Back-patch to allsupported branches.Discussion:https://postgr.es/m/18517-af2d19882240902c@postgresql.org
1 parent507a900 commit9ce8ee9

File tree

3 files changed

+32
-5
lines changed

3 files changed

+32
-5
lines changed

‎src/backend/commands/trigger.c‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3900,8 +3900,12 @@ AfterTriggerExecute(EState *estate,
39003900
boolshould_free_new= false;
39013901

39023902
/*
3903-
* Locate trigger in trigdesc.
3903+
* Locate trigger in trigdesc. It might not be present, and in fact the
3904+
* trigdesc could be NULL, if the trigger was dropped since the event was
3905+
* queued. In that case, silently do nothing.
39043906
*/
3907+
if (trigdesc==NULL)
3908+
return;
39053909
for (tgindx=0;tgindx<trigdesc->numtriggers;tgindx++)
39063910
{
39073911
if (trigdesc->triggers[tgindx].tgoid==tgoid)
@@ -3911,7 +3915,7 @@ AfterTriggerExecute(EState *estate,
39113915
}
39123916
}
39133917
if (LocTriggerData.tg_trigger==NULL)
3914-
elog(ERROR,"could not find trigger %u",tgoid);
3918+
return;
39153919

39163920
/*
39173921
* If doing EXPLAIN ANALYZE, start charging time to this trigger. We want
@@ -4235,6 +4239,7 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events,
42354239
/* Catch calls with insufficient relcache refcounting */
42364240
Assert(!RelationHasReferenceCountZero(rel));
42374241
trigdesc=rInfo->ri_TrigDesc;
4242+
/* caution: trigdesc could be NULL here */
42384243
finfo=rInfo->ri_TrigFunctions;
42394244
instr=rInfo->ri_TrigInstrument;
42404245
if (slot1!=NULL)
@@ -4250,9 +4255,6 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events,
42504255
slot2=MakeSingleTupleTableSlot(rel->rd_att,
42514256
&TTSOpsMinimalTuple);
42524257
}
4253-
if (trigdesc==NULL)/* should not happen */
4254-
elog(ERROR,"relation %u has no triggers",
4255-
evtshared->ats_relid);
42564258
}
42574259

42584260
/*

‎src/test/regress/expected/triggers.out‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3286,6 +3286,17 @@ select * from trig_table;
32863286

32873287
drop table refd_table, trig_table;
32883288
--
3289+
-- Test that we can drop a not-yet-fired deferred trigger
3290+
--
3291+
create table refd_table (id int primary key);
3292+
create table trig_table (fk int references refd_table initially deferred);
3293+
begin;
3294+
insert into trig_table values (1);
3295+
drop table refd_table cascade;
3296+
NOTICE: drop cascades to constraint trig_table_fk_fkey on table trig_table
3297+
commit;
3298+
drop table trig_table;
3299+
--
32893300
-- self-referential FKs are even more fun
32903301
--
32913302
create table self_ref (a int primary key,

‎src/test/regress/sql/triggers.sql‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2406,6 +2406,20 @@ select * from trig_table;
24062406

24072407
droptable refd_table, trig_table;
24082408

2409+
--
2410+
-- Test that we can drop a not-yet-fired deferred trigger
2411+
--
2412+
2413+
createtablerefd_table (idintprimary key);
2414+
createtabletrig_table (fkintreferences refd_table initially deferred);
2415+
2416+
begin;
2417+
insert into trig_tablevalues (1);
2418+
droptable refd_table cascade;
2419+
commit;
2420+
2421+
droptable trig_table;
2422+
24092423
--
24102424
-- self-referential FKs are even more fun
24112425
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp