Re: Re-read conindid under the referenced table's lock in the RI fast path

From: Amit Langote <amitlangote09(at)gmail(dot)com>
To: Mihail Nikalayeu <mihailnikalayeu(at)gmail(dot)com>
Cc: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: Re-read conindid under the referenced table's lock in the RI fast path
Date: 2026-08-31 13:53:34
Message-ID: CA+HiwqEhm+_=bs=2wavAJz-UqC+1KebD31++mapJQQGweE8iQQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Tue, Aug 18, 2026 at 5:34 PM Amit Langote <amitlangote09(at)gmail(dot)com> wrote:
> On Mon, Aug 17, 2026 at 10:17 PM Mihail Nikalayeu
> <mihailnikalayeu(at)gmail(dot)com> wrote:
> > On Mon, Aug 17, 2026 at 3:07 PM Amit Langote <amitlangote09(at)gmail(dot)com> wrote:
> > > Thanks. Attached is v2 of the patch posted here. I adjusted the commit
> > > message and comments, kept you credited as Author, and replaced the
> > > Opus co-author trailer with a disclosure sentence, which I can remove
> > > if you so prefer.
> >
> > I'm not sure it's required, I think using some AI tool is the new
> > default now, at least for some phases.
>
> Ok, removed.
>
> > > I will push this tomorrow.
>
> Done.

While testing the fastpath code with the batching layer reverted, I
hit a case where ri_FastPathCheck() , the per-row path taken when a
batch isn't in play, rejects a valid row. It registers the snapshot
for its index scan before table_open() on the referenced relation, so
anything committed while it waits for that lock is invisible. If the
referenced row commits, the check reports a violation for a key that
exists.

The fastpath is meant to be semantically equivalent to the SPI path,
so I checked what that does here. RI_FKey_check() passes
detectNewRows = false, so ri_PerformCheck() passes InvalidSnapshot
rather than an explicit snapshot. _SPI_execute_plan() then calls
GetCachedPlan(), which locks the relations, before it reaches
PushActiveSnapshot(GetTransactionSnapshot()). ri_FastPathCheck() does
its own opening and scanning, so there is no plan cache to force that
ordering; the snapshot is acquired directly, and it was placed before
the table_open() rather than after.

Patch attached, moving the acquisition after table_open() and the
constraint re-read.

Will add an open item once this hits the archive.

--
Thanks, Amit Langote

Attachment Content-Type Size
v1-0001-Take-the-RI-fast-path-snapshot-after-locking-the-.patch application/octet-stream 6.6 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Amit Langote 2026-08-31 13:57:35 Re: Re-read conindid under the referenced table's lock in the RI fast path
Previous Message Zsolt Parragi 2026-08-31 13:44:40 Prevent foreign key references to unlogged partitions