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: Fix cross-type foreign keys in the batched fast-path FK check
Date: Tue, 18 Aug 2026 03:42:01 +0000
Message-ID: <E1wwAi7-000000010NE-41n2@gemulon.postgresql.org> (raw)

Fix cross-type foreign keys in the batched fast-path FK check

ri_FastPathFlushArray() rechecked a concurrently updated PK tuple with a
scan key it built itself, putting found_val, the key of the tuple it had
just locked, into sk_argument, and passing that same slot to
recheck_matched_pk_tuple().  Both operands therefore came from the locked
tuple, and since sk_argument is the operator's right-hand input, the PK
value was read as an FK value.  For a foreign key using a cross-type
equality operator, such as a "date" primary key referenced by a "timestamp"
column, that compares days against microseconds, so the recheck always
failed and a batch that had to follow an update chain reported a violation
even though the version it locked still had the key.

Remove the recheck.  For a same-type key it compared the tuple against
itself and so never rejected anything, which was harmless only because the
loop a few lines below does the real work: it already compares found_val,
read after the chain has been followed, against every buffered FK value,
with the arguments in the order the operator expects.  That makes the
recheck redundant as well as wrong.  Detection is not weakened by dropping
it, since the buffered value that led the scan to a tuple can be matched by
no other row visible to our snapshot.

ri_FastPathProbeOne() passes its original scan key, with the FK value still
in sk_argument, and was never affected; nor were single-row statements or
multi-column foreign keys, which go through it.

Add an isolation test covering the cross-type case, a permutation where
the key really does move away, and a same-type permutation that should
behave identically.

Reported-by: Peter Geoghegan <pg@bowt.ie>
Co-authored-by: Peter Geoghegan <pg@bowt.ie>
Discussion: https://postgr.es/m/CAH2-WznQjX3GByh_Ju7unuzMcik_5PJ5D7i_=qhwk=gPEkhfVQ@mail.gmail.com
Backpatch-through: 19

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/cc449a504bfe50c91854727844b6fb1782a29417

Modified Files
--------------
src/backend/utils/adt/ri_triggers.c                | 43 ++++++++---------
.../isolation/expected/fk-crosstype-recheck.out    | 37 +++++++++++++++
src/test/isolation/isolation_schedule              |  1 +
src/test/isolation/specs/fk-crosstype-recheck.spec | 54 ++++++++++++++++++++++
4 files changed, 111 insertions(+), 24 deletions(-)



view thread (2+ messages)

Message-ID: <E1wwAi7-000000010NE-41n2@gemulon.postgresql.org>
Permalink:  ../E1wwAi7-000000010NE-41n2@gemulon.postgresql.org/
Also on:    postgresql.org/message-id/E1wwAi7-000000010NE-41n2@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: Fix cross-type foreign keys in the batched fast-path FK check
  In-Reply-To: <E1wwAi7-000000010NE-41n2@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