pg.ddx.io  pgsql-committers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Amit Langote <amitlan@postgresql.org>
To: pgsql-committers@lists.postgresql.org
Subject: pgsql: Track RI fast-path FK-check batches per firing cycle
Date: Thu, 20 Aug 2026 08:22:32 +0000
Message-ID: <E1wwy2h-00000001L08-3M2y@gemulon.postgresql.org> (raw)

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 <noah@leadboat.com>
Reported-by: Peter Geoghegan <pg@bowt.ie>
Discussion: https://postgr.es/m/20260705222115.be.noahmisch@microsoft.com
Discussion: https://postgr.es/m/CAH2-Wz=D533JbF_ak_Pc8kP0FKse-ju8DnMxtjvY==yHsP4xgw@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(-)



view thread (4+ messages)  latest in thread

Message-ID: <E1wwy2h-00000001L08-3M2y@gemulon.postgresql.org>
Permalink:  ../E1wwy2h-00000001L08-3M2y@gemulon.postgresql.org/
Also on:    postgresql.org/message-id/E1wwy2h-00000001L08-3M2y@gemulon.postgresql.org

 · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-committers@postgresql.org
  Cc: amitlan@postgresql.org, pgsql-committers@lists.postgresql.org
  Subject: Re: pgsql: Track RI fast-path FK-check batches per firing cycle
  In-Reply-To: <E1wwy2h-00000001L08-3M2y@gemulon.postgresql.org>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox