CREATE SCHEMA propagate_set_commands; SET search_path TO propagate_set_commands; CREATE TABLE test (id int, value int); SELECT create_distributed_table('test', 'id'); create_distributed_table --------------------------------------------------------------------- (1 row) INSERT INTO test VALUES (1,1), (3,3); -- test set local propagation SET citus.propagate_set_commands TO 'local'; -- make sure we send BEGIN before a SELECT SET citus.select_opens_transaction_block TO on; BEGIN; SELECT current_setting('enable_hashagg') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- on (1 row) -- triggers an error on the worker SET LOCAL TRANSACTION ISOLATION LEVEL REPEATABLE READ; WARNING: SET TRANSACTION ISOLATION LEVEL must be called before any query CONTEXT: while executing command on localhost:xxxxx ERROR: failure on connection marked as essential: localhost:xxxxx END; BEGIN; SET TRANSACTION READ ONLY; -- should fail after setting transaction to read only INSERT INTO test VALUES (2,2); ERROR: cannot execute INSERT in a read-only transaction END; BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED; -- should reflect isolation level of current transaction SELECT current_setting('transaction_isolation') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- read committed (1 row) END; START TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- should reflect isolation level of current transaction SELECT current_setting('transaction_isolation') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- repeatable read (1 row) END; BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; -- should reflect isolation level of current transaction SELECT current_setting('transaction_isolation') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- serializable (1 row) END; BEGIN READ ONLY; -- should reflect read-only status of current transaction SELECT current_setting('transaction_read_only') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- on (1 row) END; BEGIN READ WRITE; -- should reflect read-only status of current transaction SELECT current_setting('transaction_read_only') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- off (1 row) SET TRANSACTION READ ONLY; -- should reflect writable status of current transaction SELECT current_setting('transaction_read_only') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- on (1 row) END; BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE DEFERRABLE; -- should reflect deferrable status of the current transaction SELECT current_setting('transaction_deferrable') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- on (1 row) END; BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE DEFERRABLE READ ONLY; SELECT current_setting('transaction_read_only') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- on (1 row) SELECT current_setting('transaction_deferrable') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- on (1 row) END; -- postgres warns against, but does not disallow multiple BEGIN BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED; WARNING: there is already a transaction in progress SELECT current_setting('transaction_isolation') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- read committed (1 row) -- but not after a query (SET TRANSACTION error is consistent with postgres) BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; WARNING: there is already a transaction in progress ERROR: SET TRANSACTION ISOLATION LEVEL must be called before any query END; BEGIN READ WRITE; SAVEPOINT goback; SET TRANSACTION READ ONLY; SELECT current_setting('transaction_read_only') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- on (1 row) ROLLBACK TO SAVEPOINT goback; SELECT current_setting('transaction_read_only') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- off (1 row) END; SET default_transaction_isolation TO 'repeatable read'; BEGIN; -- should reflect isolation level of local session SELECT current_setting('transaction_isolation') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- repeatable read (1 row) END; -- SET is not propagated and plain SELECT does not use transaction blocks SELECT DISTINCT current_setting('transaction_isolation') FROM test; current_setting --------------------------------------------------------------------- read committed (1 row) -- the CTE will trigger transaction blocks WITH cte AS MATERIALIZED ( SELECT DISTINCT current_setting('transaction_isolation') iso FROM test ) SELECT iso FROM cte; iso --------------------------------------------------------------------- repeatable read (1 row) RESET default_transaction_isolation; BEGIN; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- should reflect new isolation level SELECT current_setting('transaction_isolation') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- repeatable read (1 row) END; BEGIN; SET TRANSACTION READ ONLY; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; SELECT current_setting('transaction_read_only') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- on (1 row) SELECT current_setting('transaction_isolation') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- repeatable read (1 row) END; BEGIN; SET LOCAL transaction_read_only TO on; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; SELECT current_setting('transaction_read_only') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- on (1 row) SELECT current_setting('transaction_isolation') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- repeatable read (1 row) END; BEGIN; SET TRANSACTION READ ONLY; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; SELECT current_setting('transaction_read_only') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- on (1 row) SELECT current_setting('transaction_isolation') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- repeatable read (1 row) END; BEGIN; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; SAVEPOINT goback; SET TRANSACTION READ ONLY; SELECT current_setting('transaction_read_only') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- on (1 row) ROLLBACK TO SAVEPOINT goback; SELECT current_setting('transaction_read_only') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- off (1 row) END; BEGIN; -- set session commands are not propagated SET enable_hashagg TO false; SELECT current_setting('enable_hashagg') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- on (1 row) ABORT; BEGIN; -- should not propagate exit_on_error SET LOCAL exit_on_error TO on; SELECT current_setting('exit_on_error') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- off (1 row) END; BEGIN; -- should be off on worker SET LOCAL enable_hashagg TO false; SELECT current_setting('enable_hashagg') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- off (1 row) -- expand to new node, set should still apply SELECT current_setting('enable_hashagg') FROM test WHERE id = 3; current_setting --------------------------------------------------------------------- off (1 row) END; BEGIN; -- should be off on worker SET LOCAL enable_hashagg TO false; SELECT current_setting('enable_hashagg') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- off (1 row) -- should be back on after set to default SET LOCAL enable_hashagg TO DEFAULT; SELECT current_setting('enable_hashagg') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- on (1 row) -- expand to new node, set to default should still apply SELECT current_setting('enable_hashagg') FROM test WHERE id = 3; current_setting --------------------------------------------------------------------- on (1 row) END; BEGIN; -- should be off on worker SET LOCAL enable_hashagg TO false; SELECT current_setting('enable_hashagg') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- off (1 row) -- does not have the LOCAL keyword, not propagated SET enable_hashagg TO DEFAULT; SELECT current_setting('enable_hashagg') FROM test WHERE id = 3; current_setting --------------------------------------------------------------------- off (1 row) END; BEGIN; -- should be off on worker SET LOCAL enable_hashagg TO false; SELECT current_setting('enable_hashagg') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- off (1 row) -- should be back on after reset RESET enable_hashagg; SELECT current_setting('enable_hashagg') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- on (1 row) -- expand to new node, reset should still apply SELECT current_setting('enable_hashagg') FROM test WHERE id = 3; current_setting --------------------------------------------------------------------- on (1 row) END; BEGIN; -- should be off on worker SET LOCAL enable_hashagg TO false; SELECT current_setting('enable_hashagg') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- off (1 row) -- should be back on after reset all RESET ALL; SET search_path = 'propagate_set_commands'; SELECT current_setting('enable_hashagg') FROM test WHERE id = 1; current_setting --------------------------------------------------------------------- on (1 row) -- funky case, we reset citus.propagate_set_commands, so not set again SET LOCAL enable_hashagg TO false; SELECT current_setting('enable_hashagg') FROM test WHERE id = 3; current_setting --------------------------------------------------------------------- on (1 row) ABORT; DROP SCHEMA propagate_set_commands CASCADE; NOTICE: drop cascades to table test