# INSERT...ON CONFLICT DO UPDATE test # # This test tries to expose problems with the interaction between concurrent # sessions. setup { CREATE TABLE upsert (key int primary key, val text); } teardown { DROP TABLE upsert; } session s1 setup { BEGIN ISOLATION LEVEL READ COMMITTED; } step insert1 { INSERT INTO upsert(key, val) VALUES(1, 'insert1') ON CONFLICT (key) DO UPDATE set val = upsert.val || ' updated by insert1'; } step c1 { COMMIT; } step a1 { ABORT; } session s2 setup { BEGIN ISOLATION LEVEL READ COMMITTED; } step insert2 { INSERT INTO upsert(key, val) VALUES(1, 'insert2') ON CONFLICT (key) DO UPDATE set val = upsert.val || ' updated by insert2'; } step select2 { SELECT * FROM upsert; } step c2 { COMMIT; } # One session (session 2) block-waits on another (session 1) to determine if it # should proceed with an insert or update. Notably, this entails updating a # tuple while there is no version of that tuple visible to the updating # session's snapshot. This is permitted only in READ COMMITTED mode. permutation insert1 insert2 c1 select2 c2 permutation insert1 insert2 a1 select2 c2