1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Fix behavior of AND CHAIN outside of explicit transaction blocks

When using COMMIT AND CHAIN or ROLLBACK AND CHAIN not in an explicit
transaction block, the previous implementation would leave a
transaction block active in the ROLLBACK case but not the COMMIT case.
To fix for now, error out when using these commands not in an explicit
transaction block.  This restriction could be lifted if a sensible
definition and implementation is found.

Bug: #15977
Author: fn ln <emuser20140816@gmail.com>
Reviewed-by: Fabien COELHO <coelho@cri.ensmp.fr>
This commit is contained in:
Peter Eisentraut
2019-09-08 16:11:21 +02:00
parent 422910423b
commit b6d72ddd5f
5 changed files with 166 additions and 19 deletions

View File

@ -839,6 +839,11 @@ SHOW transaction_deferrable;
(1 row)
ROLLBACK;
-- not allowed outside a transaction block
COMMIT AND CHAIN; -- error
ERROR: COMMIT AND CHAIN can only be used in transaction blocks
ROLLBACK AND CHAIN; -- error
ERROR: ROLLBACK AND CHAIN can only be used in transaction blocks
SELECT * FROM abc ORDER BY 1;
a
---
@ -934,6 +939,79 @@ SELECT 2\; RELEASE SAVEPOINT sp\; SELECT 3;
ERROR: RELEASE SAVEPOINT can only be used in transaction blocks
-- but this is OK, because the BEGIN converts it to a regular xact
SELECT 1\; BEGIN\; SAVEPOINT sp\; ROLLBACK TO SAVEPOINT sp\; COMMIT;
-- Tests for AND CHAIN in implicit transaction blocks
SET TRANSACTION READ WRITE\; COMMIT AND CHAIN; -- error
ERROR: COMMIT AND CHAIN can only be used in transaction blocks
SHOW transaction_read_only;
transaction_read_only
-----------------------
off
(1 row)
SET TRANSACTION READ WRITE\; ROLLBACK AND CHAIN; -- error
ERROR: ROLLBACK AND CHAIN can only be used in transaction blocks
SHOW transaction_read_only;
transaction_read_only
-----------------------
off
(1 row)
CREATE TABLE abc (a int);
-- COMMIT/ROLLBACK + COMMIT/ROLLBACK AND CHAIN
INSERT INTO abc VALUES (7)\; COMMIT\; INSERT INTO abc VALUES (8)\; COMMIT AND CHAIN; -- 7 commit, 8 error
WARNING: there is no transaction in progress
ERROR: COMMIT AND CHAIN can only be used in transaction blocks
INSERT INTO abc VALUES (9)\; ROLLBACK\; INSERT INTO abc VALUES (10)\; ROLLBACK AND CHAIN; -- 9 rollback, 10 error
WARNING: there is no transaction in progress
ERROR: ROLLBACK AND CHAIN can only be used in transaction blocks
-- COMMIT/ROLLBACK AND CHAIN + COMMIT/ROLLBACK
INSERT INTO abc VALUES (11)\; COMMIT AND CHAIN\; INSERT INTO abc VALUES (12)\; COMMIT; -- 11 error, 12 not reached
ERROR: COMMIT AND CHAIN can only be used in transaction blocks
INSERT INTO abc VALUES (13)\; ROLLBACK AND CHAIN\; INSERT INTO abc VALUES (14)\; ROLLBACK; -- 13 error, 14 not reached
ERROR: ROLLBACK AND CHAIN can only be used in transaction blocks
-- START TRANSACTION + COMMIT/ROLLBACK AND CHAIN
START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (15)\; COMMIT AND CHAIN; -- 15 ok
SHOW transaction_isolation; -- transaction is active at this point
transaction_isolation
-----------------------
repeatable read
(1 row)
COMMIT;
START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (16)\; ROLLBACK AND CHAIN; -- 16 ok
SHOW transaction_isolation; -- transaction is active at this point
transaction_isolation
-----------------------
repeatable read
(1 row)
ROLLBACK;
-- START TRANSACTION + COMMIT/ROLLBACK + COMMIT/ROLLBACK AND CHAIN
START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (17)\; COMMIT\; INSERT INTO abc VALUES (18)\; COMMIT AND CHAIN; -- 17 commit, 18 error
ERROR: COMMIT AND CHAIN can only be used in transaction blocks
SHOW transaction_isolation; -- out of transaction block
transaction_isolation
-----------------------
read committed
(1 row)
START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (19)\; ROLLBACK\; INSERT INTO abc VALUES (20)\; ROLLBACK AND CHAIN; -- 19 rollback, 20 error
ERROR: ROLLBACK AND CHAIN can only be used in transaction blocks
SHOW transaction_isolation; -- out of transaction block
transaction_isolation
-----------------------
read committed
(1 row)
SELECT * FROM abc ORDER BY 1;
a
----
7
15
17
(3 rows)
DROP TABLE abc;
-- Test for successful cleanup of an aborted transaction at session exit.
-- THIS MUST BE THE LAST TEST IN THIS FILE.
begin;

View File

@ -475,6 +475,10 @@ SHOW transaction_read_only;
SHOW transaction_deferrable;
ROLLBACK;
-- not allowed outside a transaction block
COMMIT AND CHAIN; -- error
ROLLBACK AND CHAIN; -- error
SELECT * FROM abc ORDER BY 1;
RESET default_transaction_read_only;
@ -536,6 +540,45 @@ SELECT 2\; RELEASE SAVEPOINT sp\; SELECT 3;
SELECT 1\; BEGIN\; SAVEPOINT sp\; ROLLBACK TO SAVEPOINT sp\; COMMIT;
-- Tests for AND CHAIN in implicit transaction blocks
SET TRANSACTION READ WRITE\; COMMIT AND CHAIN; -- error
SHOW transaction_read_only;
SET TRANSACTION READ WRITE\; ROLLBACK AND CHAIN; -- error
SHOW transaction_read_only;
CREATE TABLE abc (a int);
-- COMMIT/ROLLBACK + COMMIT/ROLLBACK AND CHAIN
INSERT INTO abc VALUES (7)\; COMMIT\; INSERT INTO abc VALUES (8)\; COMMIT AND CHAIN; -- 7 commit, 8 error
INSERT INTO abc VALUES (9)\; ROLLBACK\; INSERT INTO abc VALUES (10)\; ROLLBACK AND CHAIN; -- 9 rollback, 10 error
-- COMMIT/ROLLBACK AND CHAIN + COMMIT/ROLLBACK
INSERT INTO abc VALUES (11)\; COMMIT AND CHAIN\; INSERT INTO abc VALUES (12)\; COMMIT; -- 11 error, 12 not reached
INSERT INTO abc VALUES (13)\; ROLLBACK AND CHAIN\; INSERT INTO abc VALUES (14)\; ROLLBACK; -- 13 error, 14 not reached
-- START TRANSACTION + COMMIT/ROLLBACK AND CHAIN
START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (15)\; COMMIT AND CHAIN; -- 15 ok
SHOW transaction_isolation; -- transaction is active at this point
COMMIT;
START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (16)\; ROLLBACK AND CHAIN; -- 16 ok
SHOW transaction_isolation; -- transaction is active at this point
ROLLBACK;
-- START TRANSACTION + COMMIT/ROLLBACK + COMMIT/ROLLBACK AND CHAIN
START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (17)\; COMMIT\; INSERT INTO abc VALUES (18)\; COMMIT AND CHAIN; -- 17 commit, 18 error
SHOW transaction_isolation; -- out of transaction block
START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (19)\; ROLLBACK\; INSERT INTO abc VALUES (20)\; ROLLBACK AND CHAIN; -- 19 rollback, 20 error
SHOW transaction_isolation; -- out of transaction block
SELECT * FROM abc ORDER BY 1;
DROP TABLE abc;
-- Test for successful cleanup of an aborted transaction at session exit.
-- THIS MUST BE THE LAST TEST IN THIS FILE.