| From: | Amit Langote <amitlangote09(at)gmail(dot)com> |
|---|---|
| To: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: Two more RI fast-path issues |
| Date: | 2026-10-06 06:20:07 |
| Message-ID: | CA+HiwqFKTWCO9+33EypNcjMaiMzku8s5RCYx0B90v03=tD8DoQ@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Tue, Oct 6, 2026 at 3:13 PM Amit Langote <amitlangote09(at)gmail(dot)com> wrote:
>
> Hi,
>
> While reviewing the RI fast path after removing batching from master,
> with help from Claude Opus 5.5, I found two more places where it
> behaves differently from the SPI path, apart from the cast issues
> discussed in [1].
>
> 1. Fast-path doesn't refuse to take row locks in a read-only
> transaction, whereas the SPI path does. In the SPI path, the executor
> calls PreventCommandIfReadOnly(), but the fast-path continues without
> checking. With pk as a plain table and ppk as a partitioned one
> (whose checks use SPI), and both foreign keys deferred:
>
> CREATE TABLE pk (a int PRIMARY KEY); INSERT INTO pk VALUES (1);
> CREATE TABLE ppk (a int PRIMARY KEY) PARTITION BY LIST (a);
> CREATE TABLE ppk1 PARTITION OF ppk DEFAULT; INSERT INTO ppk VALUES (1);
> CREATE TABLE fk (a int REFERENCES pk DEFERRABLE INITIALLY DEFERRED);
> CREATE TABLE pfk (a int REFERENCES ppk DEFERRABLE INITIALLY DEFERRED);
>
> -- SPI
> BEGIN; INSERT INTO pfk VALUES (1); SET TRANSACTION READ ONLY;
> COMMIT;
> ERROR: cannot execute SELECT FOR KEY SHARE in a read-only transaction
> CONTEXT: SQL statement "SELECT 1 FROM "public"."ppk" x WHERE "a"
> OPERATOR(pg_catalog.=) $1 FOR KEY SHARE OF x"
>
> -- fast -path
> BEGIN; INSERT INTO fk VALUES (1); SET TRANSACTION READ ONLY;
> COMMIT;
> COMMIT
>
> 2. Fast-path can produce "attempted to lock invisible tuple" error
> due to a bug in how it calls table_tuple_lock(). In the SPI path the
> ExecLockRows() calls table_tuple_lock() with es_output_cid, whereas
> the fast-path uses GetCurrentCommandId(), which can result in the
> latter case using a command ID that is different from when the initial
> snapshot was taken. If user code running during the scan advances it,
> and if that code also updated the referenced row, the fast path can
> fail with "attempt to lock invisible tuple" when it should report an
> FK violation (). In this case, user code is the index's equality
> operator as shown in the test case added in 0002.
>
> Attached patches to fix both, which I'd like to get in before RC1 freeze.
I have added an open item for this.
--
Thanks, Amit Langote
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Narayanan Venkateswaran | 2026-10-06 06:20:18 | Re: Proposal: Conflict log history table for Logical Replication |
| Previous Message | Amit Langote | 2026-10-06 06:13:50 | Two more RI fast-path issues |