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 <[email protected]> Co-authored-by: Peter Geoghegan <[email protected]> Discussion: https://postgr.es/m/CAH2-WznQjX3GByh_Ju7unuzMcik_5PJ5D7i_=qhwk=gpekh...@mail.gmail.com Backpatch-through: 19 Branch ------ REL_19_STABLE Details ------- https://git.postgresql.org/pg/commitdiff/3b70fa6f3d32ac832ed9ddd566c11b05e575f2c7 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(-)
