Hello!

While testing the new INSERT...ON CONFLICT DO SELECT feature I found a
possible serialization violation: the row returned back by DO SELECT
is not covered by any SIREAD lock, so a concurrent transaction can
modify it.

s1: INSERT INTO a VALUES (1,99) ON CONFLICT (key) DO SELECT RETURNING val;
s2: SELECT count(*) FROM b;
s2: UPDATE a SET val = 1 WHERE key = 1;
s1: INSERT INTO b VALUES (1,10);
s1: COMMIT;
s2: COMMIT;

And both transactions commit. If you replace the DO SELECT with a
plain SELECT, or SELECT FOR UPDATE s2 fails with a serialization
error, as expected.

The attached patch takes a predicate lock to fix the issue and adds an
isolation test covering the above example.

Attachment: 0001-Take-SIREAD-lock-on-rows-read-by-ON-CONFLICT-DO-SELE.patch
Description: Binary data

Reply via email to