Track RI fast-path FK-check batches per firing cycle Commit 34a30786293 fixed an RI fast-path crash under nested C-level SPI by keeping batch-callback lists per after-trigger query depth. That fix was incomplete: the RI fast path still tracked callback registration with one global flag. Once an outer firing cycle had registered its callback, the flag suppressed registration for a nested cycle, leaving the nested batch to be handled by the outer callback, too late and with the wrong snapshot, potentially after the ResourceOwner holding its relations had gone away.
Nor is per-depth callback registration sufficient while the cache is keyed only by constraint OID. If nested firing checks the same constraint, it reuses the outer entry, combining rows that must be checked in separate firing cycles. Key the cache by both constraint OID and query depth. Register a callback for each depth that creates an entry, and make ri_FastPathEndBatch() flush and release only entries belonging to the ending depth. Add AfterTriggerCurrentQueryDepth() so ri_triggers.c can obtain the current depth; depth -1 represents deferred firing. Add regression coverage for nested firing through a cursor portal, whose resources must not outlive the nested cycle, nested firing of the same constraint at different query depths, and deferred firing at query depth -1. Reported-by: Noah Misch <[email protected]> Reported-by: Peter Geoghegan <[email protected]> Discussion: https://postgr.es/m/[email protected] Discussion: https://postgr.es/m/CAH2-Wz=D533JbF_ak_Pc8kP0FKse-ju8DnMxtjvY==yhsp4...@mail.gmail.com Backpatch-through: 19 Branch ------ master Details ------- https://git.postgresql.org/pg/commitdiff/6fc2a486417d07f45ad47bc70d90a18902c304e5 Modified Files -------------- src/backend/commands/trigger.c | 14 ++++ src/backend/utils/adt/ri_triggers.c | 106 +++++++++++++++++++++++------- src/include/commands/trigger.h | 1 + src/test/regress/expected/foreign_key.out | 92 ++++++++++++++++++++++++++ src/test/regress/sql/foreign_key.sql | 78 ++++++++++++++++++++++ src/tools/pgindent/typedefs.list | 1 + 6 files changed, 269 insertions(+), 23 deletions(-)
