On Tue, May 5, 2026 at 15:37 Amul Sul <[email protected]> wrote: > Hi, > > The crash occurs when the per-query firing loop in > AfterTriggerEndQuery() exits via the "all fired" path. If > afterTriggerInvokeEvents() reallocated query_stack while firing, the > loop's local qs pointer is left dangling, and the subsequent > FireAfterTriggerBatchCallbacks(qs->batch_callbacks) reads > batch_callbacks from the freed memory and crashes. > > Here is the reproducible test that has an AFTER INSERT trigger on a > referenced table that recursively inserts rows into itself: > > -- > create table trigger_recursive_pk (id int primary key); > create table trigger_recursive_fk (id int references > trigger_recursive_pk(id)); > insert into trigger_recursive_pk select g from generate_series(1, 15) g; > > create function trigger_recursive_fn() returns trigger language plpgsql as > $$ > begin > if new.id < 10 then > insert into trigger_recursive_fk values (new.id + 1); > end if; > return new; > end$$; > > create trigger trigger_recursive after insert on trigger_recursive_fk > for each row execute function trigger_recursive_fn(); > > insert into trigger_recursive_fk values (1); > -- > > The attached patch fixes the reported issue by recomputing qs > immediately before calling FireAfterTriggerBatchCallbacks().
Thanks Amul for the report. I'll look at this on Thursday when I'm back at work. - Amit >
