-- -- test.sql -- create extension pg_readonly; -- select unset_cluster_readonly(); unset_cluster_readonly ------------------------ t (1 row) select get_cluster_readonly(); get_cluster_readonly ---------------------- f (1 row) -- drop table t; ERROR: table "t" does not exist drop function f; ERROR: could not find a function named "f" -- create table t(i int); create function f(IN p int, OUT i int) returns int as $$ begin insert into t(i) values (f.p) returning t.i into f.i; end$$ language plpgsql; select set_cluster_readonly(); set_cluster_readonly ---------------------- t (1 row) select * from t; i --- (0 rows) insert into t values (1); ERROR: cannot execute INSERT in a read-only transaction select f(1); ERROR: pg_readonly: cannot execute query containing volatile functions because cluster is read-only -- However, in this same session, if you call f() before entering in read only mode, -- it is then able to write during read only mode: select unset_cluster_readonly(); unset_cluster_readonly ------------------------ t (1 row) select f(1); f --- 1 (1 row) select set_cluster_readonly(); set_cluster_readonly ---------------------- t (1 row) insert into t values (2); ERROR: cannot execute INSERT in a read-only transaction select f(2); ERROR: pg_readonly: cannot execute query containing volatile functions because cluster is read-only select get_cluster_readonly(); get_cluster_readonly ---------------------- t (1 row) select f(3); ERROR: pg_readonly: cannot execute query containing volatile functions because cluster is read-only select * from t; i --- 1 (1 row) with inserted as (insert into t values(3) returning 3) select * from inserted; ERROR: cannot execute SELECT in a read-only transaction select * from t; i --- 1 (1 row) -- DDL is also blocked via ProcessUtility hook CREATE TABLE t2(i int); ERROR: cannot execute CREATE TABLE in a read-only transaction -- DO block: INSERT inside a DO block should be blocked by the executor hook DO $$ BEGIN INSERT INTO t VALUES (99); END $$; ERROR: cannot execute INSERT in a read-only transaction CONTEXT: SQL statement "INSERT INTO t VALUES (99)" PL/pgSQL function inline_code_block line 1 at SQL statement select * from t; i --- 1 (1 row) -- Large object creation: lo_create() is a SELECT-callable function that -- writes to the pg_largeobject catalog internally. SELECT lo_create(0); ERROR: pg_readonly: cannot execute query containing volatile functions because cluster is read-only