Fix ExecCheckIndexConstraints() crash when es_snapshot is invalid.

At transaction level SERIALIZABLE, commit fb60892f403 made
check_exclusion_or_unique_constraint() read the conflicting tuple
again using estate->es_snapshot when violationOK is true and
conflictTid is non-NULL, to ensure that INSERT ... ON CONFLICT takes
an SIREAD lock. This can only happen from ExecCheckIndexConstraints(),
but not all callers of ExecCheckIndexConstraints() initialize
estate->es_snapshot, and the re-fetch crashes if it's invalid.

In core Postgres, this only affects the logical replication apply
worker which, starting from v18, uses ExecCheckIndexConstraints() to
log conflicts while applying changes, without initializing es_snapshot
in the EState that it builds. However, there is also extension code
that does the same, so the problem affects all versions that
fb60892f403 was applied to.

Fix by skipping the re-fetch in check_exclusion_or_unique_constraint()
if the snapshot is invalid.

Reported-by: Zsolt Parragi <[email protected]>
Author: Zsolt Parragi <[email protected]>
Reviewed-by: Andrey Borodin <[email protected]>
Discussion: 
https://postgr.es/m/CAN4CZFPz4ysPyo1ahD-5n0iyKxmuo2Wvn%3DPgEZTyW63_Tu7Eaw%40mail.gmail.com
Backpatch-through: 14

Branch
------
REL_14_STABLE

Details
-------
https://git.postgresql.org/pg/commitdiff/83efe9602ecdad32ffe766ba0deab02b5fb0da93

Modified Files
--------------
src/backend/executor/execIndexing.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

Reply via email to