ri_FastPathCheck() acquired its scan snapshot before opening the referenced relation. If it then waited for the relation lock in READ COMMITTED mode, a referenced row committed during the wait would not be visible to the old snapshot. The check could consequently report a foreign key violation even though the referenced row existed. The batched path acquires its scan snapshot after opening the relations, so it does not have the lock-wait problem. The per-row path remains reachable during constraint validation and checks re-entered from a batch flush. Take the snapshot after opening the referenced relation and reloading the constraint information. This also agrees with the SPI path, which acquires the referenced-relation lock before selecting the snapshot used for the check. Also make the scan snapshot active for the duration of the check, so STABLE cast and equality functions use the same snapshot as the index scan. Otherwise, a STABLE cast can miss rows inserted by earlier AFTER triggers and cause a valid foreign key to be rejected. Add a regression test comparing this case with the SPI path. Finally, also advance the command counter after acquiring the referenced-relation lock and before reloading the constraint information, so local invalidations are processed under the lock, as in the SPI path. Add an injection-point test that pauses a per-row check before locking the referenced relation, commits the missing referenced row in another session, and verifies that validation succeeds. Force per-row validation by using a role without SELECT privilege on the referenced table, so the test exercises this path even with batching enabled. Add isolation-test coverage for the visibility of a referenced row committed after the referencing transaction has executed an earlier command. A later command can see such a row in READ COMMITTED, but not in REPEATABLE READ or SERIALIZABLE. Reviewed-by: Chao Li <li.evan.chao@gmail.com> Reviewed-by: Amit Kapila <amit.kapila16@gmail.com> Discussion: https://postgr.es/m/CA+HiwqEhm+_=bs=2wavAJz-UqC+1KebD31++mapJQQGweE8iQQ@mail.gmail.com Backpatch-through: 19
PostgreSQL Database Management System
This directory contains the source code distribution of the PostgreSQL database management system.
PostgreSQL is an advanced object-relational database management system that supports an extended subset of the SQL standard, including transactions, foreign keys, subqueries, triggers, user-defined types and functions. This distribution also contains C language bindings.
Copyright and license information can be found in the file COPYRIGHT.
General documentation about this version of PostgreSQL can be found at https://www.postgresql.org/docs/devel/. In particular, information about building PostgreSQL from the source code can be found at https://www.postgresql.org/docs/devel/installation.html.
The latest version of this software, and related software, may be obtained at https://www.postgresql.org/download/. For more information look at our web site located at https://www.postgresql.org/.