mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-18 11:45:11 +08:00
Allow EXPLAIN in read-only mode
Using `EXPLAIN` when `transaction_read_only` is set to `on` fails with an error. This is fixed by explicitly setting the `check_read_only` flag.
This commit is contained in:
parent
65b8151af3
commit
39049feba6
2
.unreleased/pr_7637
Normal file
2
.unreleased/pr_7637
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Fixes: #7637 Allow EXPLAIN in read-only mode
|
||||||
|
Thanks: @ikalafat for reporting the error
|
@ -4859,6 +4859,7 @@ process_ddl_command_start(ProcessUtilityArgs *args)
|
|||||||
handler = preprocess_execute;
|
handler = preprocess_execute;
|
||||||
break;
|
break;
|
||||||
case T_ExplainStmt:
|
case T_ExplainStmt:
|
||||||
|
check_read_only = false;
|
||||||
handler = process_explain_start;
|
handler = process_explain_start;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -8,7 +8,84 @@
|
|||||||
-- create_hypertable()
|
-- create_hypertable()
|
||||||
--
|
--
|
||||||
CREATE TABLE test_table(time bigint NOT NULL, device int);
|
CREATE TABLE test_table(time bigint NOT NULL, device int);
|
||||||
|
-- EXPLAIN should work in read-only mode, when enabling in transaction.
|
||||||
|
START TRANSACTION;
|
||||||
|
SET transaction_read_only TO on;
|
||||||
|
EXPLAIN (COSTS OFF) SELECT * FROM test_table;
|
||||||
|
QUERY PLAN
|
||||||
|
------------------------
|
||||||
|
Seq Scan on test_table
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
ROLLBACK;
|
||||||
|
START TRANSACTION;
|
||||||
|
SET transaction_read_only TO on;
|
||||||
|
EXPLAIN (ANALYZE ON, COSTS OFF, TIMING OFF, SUMMARY OFF) SELECT * FROM test_table;
|
||||||
|
QUERY PLAN
|
||||||
|
------------------------------------------------
|
||||||
|
Seq Scan on test_table (actual rows=0 loops=1)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
ROLLBACK;
|
||||||
|
START TRANSACTION;
|
||||||
|
SET transaction_read_only TO on;
|
||||||
|
EXPLAIN (COSTS OFF) INSERT INTO test_table VALUES (1, 1);
|
||||||
|
QUERY PLAN
|
||||||
|
----------------------
|
||||||
|
Insert on test_table
|
||||||
|
-> Result
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
ROLLBACK;
|
||||||
|
-- This should give an error since we are using ANALYZE and a DML. The
|
||||||
|
-- read-only is checked when executing the actual INSERT statement,
|
||||||
|
-- not inside our code.
|
||||||
|
\set ON_ERROR_STOP 0
|
||||||
|
START TRANSACTION;
|
||||||
|
SET transaction_read_only TO on;
|
||||||
|
EXPLAIN (ANALYZE ON, COSTS OFF, TIMING OFF, SUMMARY OFF) INSERT INTO test_table VALUES (1, 1);
|
||||||
|
ERROR: cannot execute INSERT in a read-only transaction
|
||||||
|
ROLLBACK;
|
||||||
|
\set ON_ERROR_STOP 1
|
||||||
SET default_transaction_read_only TO on;
|
SET default_transaction_read_only TO on;
|
||||||
|
-- EXPLAIN should work in read-only mode, even when using the default.
|
||||||
|
START TRANSACTION;
|
||||||
|
EXPLAIN (COSTS OFF) SELECT * FROM test_table;
|
||||||
|
QUERY PLAN
|
||||||
|
------------------------
|
||||||
|
Seq Scan on test_table
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
ROLLBACK;
|
||||||
|
START TRANSACTION;
|
||||||
|
SET transaction_read_only TO on;
|
||||||
|
EXPLAIN (ANALYZE ON, COSTS OFF, TIMING OFF, SUMMARY OFF) SELECT * FROM test_table;
|
||||||
|
QUERY PLAN
|
||||||
|
------------------------------------------------
|
||||||
|
Seq Scan on test_table (actual rows=0 loops=1)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
ROLLBACK;
|
||||||
|
START TRANSACTION;
|
||||||
|
SET transaction_read_only TO on;
|
||||||
|
EXPLAIN (COSTS OFF) INSERT INTO test_table VALUES (1, 1);
|
||||||
|
QUERY PLAN
|
||||||
|
----------------------
|
||||||
|
Insert on test_table
|
||||||
|
-> Result
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
ROLLBACK;
|
||||||
|
-- This should give an error since we are using ANALYZE and a DML. The
|
||||||
|
-- read-only is checked when executing the actual INSERT statement,
|
||||||
|
-- not inside our code.
|
||||||
|
\set ON_ERROR_STOP 0
|
||||||
|
START TRANSACTION;
|
||||||
|
SET transaction_read_only TO on;
|
||||||
|
EXPLAIN (ANALYZE ON, COSTS OFF, TIMING OFF, SUMMARY OFF) INSERT INTO test_table VALUES (1, 1);
|
||||||
|
ERROR: cannot execute INSERT in a read-only transaction
|
||||||
|
ROLLBACK;
|
||||||
|
\set ON_ERROR_STOP 1
|
||||||
\set ON_ERROR_STOP 0
|
\set ON_ERROR_STOP 0
|
||||||
SELECT * FROM create_hypertable('test_table', 'time');
|
SELECT * FROM create_hypertable('test_table', 'time');
|
||||||
ERROR: cannot execute create_hypertable() in a read-only transaction
|
ERROR: cannot execute create_hypertable() in a read-only transaction
|
||||||
|
@ -12,8 +12,59 @@
|
|||||||
--
|
--
|
||||||
CREATE TABLE test_table(time bigint NOT NULL, device int);
|
CREATE TABLE test_table(time bigint NOT NULL, device int);
|
||||||
|
|
||||||
|
-- EXPLAIN should work in read-only mode, when enabling in transaction.
|
||||||
|
START TRANSACTION;
|
||||||
|
SET transaction_read_only TO on;
|
||||||
|
EXPLAIN (COSTS OFF) SELECT * FROM test_table;
|
||||||
|
ROLLBACK;
|
||||||
|
|
||||||
|
START TRANSACTION;
|
||||||
|
SET transaction_read_only TO on;
|
||||||
|
EXPLAIN (ANALYZE ON, COSTS OFF, TIMING OFF, SUMMARY OFF) SELECT * FROM test_table;
|
||||||
|
ROLLBACK;
|
||||||
|
|
||||||
|
START TRANSACTION;
|
||||||
|
SET transaction_read_only TO on;
|
||||||
|
EXPLAIN (COSTS OFF) INSERT INTO test_table VALUES (1, 1);
|
||||||
|
ROLLBACK;
|
||||||
|
|
||||||
|
-- This should give an error since we are using ANALYZE and a DML. The
|
||||||
|
-- read-only is checked when executing the actual INSERT statement,
|
||||||
|
-- not inside our code.
|
||||||
|
\set ON_ERROR_STOP 0
|
||||||
|
START TRANSACTION;
|
||||||
|
SET transaction_read_only TO on;
|
||||||
|
EXPLAIN (ANALYZE ON, COSTS OFF, TIMING OFF, SUMMARY OFF) INSERT INTO test_table VALUES (1, 1);
|
||||||
|
ROLLBACK;
|
||||||
|
\set ON_ERROR_STOP 1
|
||||||
|
|
||||||
SET default_transaction_read_only TO on;
|
SET default_transaction_read_only TO on;
|
||||||
|
|
||||||
|
-- EXPLAIN should work in read-only mode, even when using the default.
|
||||||
|
START TRANSACTION;
|
||||||
|
EXPLAIN (COSTS OFF) SELECT * FROM test_table;
|
||||||
|
ROLLBACK;
|
||||||
|
|
||||||
|
START TRANSACTION;
|
||||||
|
SET transaction_read_only TO on;
|
||||||
|
EXPLAIN (ANALYZE ON, COSTS OFF, TIMING OFF, SUMMARY OFF) SELECT * FROM test_table;
|
||||||
|
ROLLBACK;
|
||||||
|
|
||||||
|
START TRANSACTION;
|
||||||
|
SET transaction_read_only TO on;
|
||||||
|
EXPLAIN (COSTS OFF) INSERT INTO test_table VALUES (1, 1);
|
||||||
|
ROLLBACK;
|
||||||
|
|
||||||
|
-- This should give an error since we are using ANALYZE and a DML. The
|
||||||
|
-- read-only is checked when executing the actual INSERT statement,
|
||||||
|
-- not inside our code.
|
||||||
|
\set ON_ERROR_STOP 0
|
||||||
|
START TRANSACTION;
|
||||||
|
SET transaction_read_only TO on;
|
||||||
|
EXPLAIN (ANALYZE ON, COSTS OFF, TIMING OFF, SUMMARY OFF) INSERT INTO test_table VALUES (1, 1);
|
||||||
|
ROLLBACK;
|
||||||
|
\set ON_ERROR_STOP 1
|
||||||
|
|
||||||
\set ON_ERROR_STOP 0
|
\set ON_ERROR_STOP 0
|
||||||
SELECT * FROM create_hypertable('test_table', 'time');
|
SELECT * FROM create_hypertable('test_table', 'time');
|
||||||
\set ON_ERROR_STOP 1
|
\set ON_ERROR_STOP 1
|
||||||
@ -213,3 +264,4 @@ SELECT remove_retention_policy('test_table');
|
|||||||
SELECT add_job('now','12h');
|
SELECT add_job('now','12h');
|
||||||
SELECT alter_job(1,scheduled:=false);
|
SELECT alter_job(1,scheduled:=false);
|
||||||
SELECT delete_job(1);
|
SELECT delete_job(1);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user