-- validate lock tuple trigger \set ON_ERROR_STOP 1 CREATE EXTENSION tuplock; -- test in a distinct schema... CREATE SCHEMA test_tuplock; SET search_path TO test_tuplock,public; CREATE TABLE test( tid SERIAL PRIMARY KEY, data TEXT NOT NULL, -- locking attribute lock BOOLEAN NOT NULL DEFAULT FALSE ); CREATE TRIGGER testlock BEFORE UPDATE OR DELETE ON test FOR EACH ROW EXECUTE PROCEDURE tuplock(lock); SELECT COUNT(*) FROM test; -- 0 count ------- 0 (1 row) -- first insert new values INSERT INTO test(data) VALUES('hello'); INSERT INTO test(data) VALUES('world'); INSERT INTO test(data) VALUES('!'); INSERT INTO test(data) VALUES('foo'); INSERT INTO test(data) VALUES('bla'); -- show all SELECT * FROM test ORDER BY tid; tid | data | lock -----+-------+------ 1 | hello | f 2 | world | f 3 | ! | f 4 | foo | f 5 | bla | f (5 rows) -- update is fine UPDATE test SET data='HELLO' WHERE data='hello'; -- delete is fine DELETE FROM test WHERE data='!'; -- then lock UPDATE test SET lock=TRUE WHERE lock=FALSE AND length(data)<>3; -- errors are fine, now: \set ON_ERROR_STOP 0 -- now updates are not ok UPDATE test SET data='WORLD' WHERE data='world'; -- fails ERROR: trigger "testlock" on "test": item locked by attribute "lock" UPDATE test SET lock=FALSE; -- fails ERROR: trigger "testlock" on "test": item locked by attribute "lock" -- now deletes are not ok DELETE FROM test WHERE data='HELLO'; -- fails ERROR: trigger "testlock" on "test": item locked by attribute "lock" -- back to normal \set ON_ERROR_STOP 1 -- this update is ok UPDATE test SET data='FOO' WHERE data='foo'; -- this delete is ok DELETE FROM test WHERE data='bla'; -- show all SELECT * FROM test ORDER BY tid; tid | data | lock -----+-------+------ 1 | HELLO | t 2 | world | t 4 | FOO | f (3 rows) -- clean DROP SCHEMA test_tuplock CASCADE;