summaryrefslogtreecommitdiffstats
path: root/src/test/regress/expected/transactions.out
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/regress/expected/transactions.out')
-rw-r--r--src/test/regress/expected/transactions.out1064
1 files changed, 1064 insertions, 0 deletions
diff --git a/src/test/regress/expected/transactions.out b/src/test/regress/expected/transactions.out
new file mode 100644
index 0000000..61862d5
--- /dev/null
+++ b/src/test/regress/expected/transactions.out
@@ -0,0 +1,1064 @@
+--
+-- TRANSACTIONS
+--
+BEGIN;
+SELECT *
+ INTO TABLE xacttest
+ FROM aggtest;
+INSERT INTO xacttest (a, b) VALUES (777, 777.777);
+END;
+-- should retrieve one value--
+SELECT a FROM xacttest WHERE a > 100;
+ a
+-----
+ 777
+(1 row)
+
+BEGIN;
+CREATE TABLE disappear (a int4);
+DELETE FROM aggtest;
+-- should be empty
+SELECT * FROM aggtest;
+ a | b
+---+---
+(0 rows)
+
+ABORT;
+-- should not exist
+SELECT oid FROM pg_class WHERE relname = 'disappear';
+ oid
+-----
+(0 rows)
+
+-- should have members again
+SELECT * FROM aggtest;
+ a | b
+-----+---------
+ 56 | 7.8
+ 100 | 99.097
+ 0 | 0.09561
+ 42 | 324.78
+(4 rows)
+
+-- Read-only tests
+CREATE TABLE writetest (a int);
+CREATE TEMPORARY TABLE temptest (a int);
+BEGIN;
+SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ ONLY, DEFERRABLE; -- ok
+SELECT * FROM writetest; -- ok
+ a
+---
+(0 rows)
+
+SET TRANSACTION READ WRITE; --fail
+ERROR: transaction read-write mode must be set before any query
+COMMIT;
+BEGIN;
+SET TRANSACTION READ ONLY; -- ok
+SET TRANSACTION READ WRITE; -- ok
+SET TRANSACTION READ ONLY; -- ok
+SELECT * FROM writetest; -- ok
+ a
+---
+(0 rows)
+
+SAVEPOINT x;
+SET TRANSACTION READ ONLY; -- ok
+SELECT * FROM writetest; -- ok
+ a
+---
+(0 rows)
+
+SET TRANSACTION READ ONLY; -- ok
+SET TRANSACTION READ WRITE; --fail
+ERROR: cannot set transaction read-write mode inside a read-only transaction
+COMMIT;
+BEGIN;
+SET TRANSACTION READ WRITE; -- ok
+SAVEPOINT x;
+SET TRANSACTION READ WRITE; -- ok
+SET TRANSACTION READ ONLY; -- ok
+SELECT * FROM writetest; -- ok
+ a
+---
+(0 rows)
+
+SET TRANSACTION READ ONLY; -- ok
+SET TRANSACTION READ WRITE; --fail
+ERROR: cannot set transaction read-write mode inside a read-only transaction
+COMMIT;
+BEGIN;
+SET TRANSACTION READ WRITE; -- ok
+SAVEPOINT x;
+SET TRANSACTION READ ONLY; -- ok
+SELECT * FROM writetest; -- ok
+ a
+---
+(0 rows)
+
+ROLLBACK TO SAVEPOINT x;
+SHOW transaction_read_only; -- off
+ transaction_read_only
+-----------------------
+ off
+(1 row)
+
+SAVEPOINT y;
+SET TRANSACTION READ ONLY; -- ok
+SELECT * FROM writetest; -- ok
+ a
+---
+(0 rows)
+
+RELEASE SAVEPOINT y;
+SHOW transaction_read_only; -- off
+ transaction_read_only
+-----------------------
+ off
+(1 row)
+
+COMMIT;
+SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY;
+DROP TABLE writetest; -- fail
+ERROR: cannot execute DROP TABLE in a read-only transaction
+INSERT INTO writetest VALUES (1); -- fail
+ERROR: cannot execute INSERT in a read-only transaction
+SELECT * FROM writetest; -- ok
+ a
+---
+(0 rows)
+
+DELETE FROM temptest; -- ok
+UPDATE temptest SET a = 0 FROM writetest WHERE temptest.a = 1 AND writetest.a = temptest.a; -- ok
+PREPARE test AS UPDATE writetest SET a = 0; -- ok
+EXECUTE test; -- fail
+ERROR: cannot execute UPDATE in a read-only transaction
+SELECT * FROM writetest, temptest; -- ok
+ a | a
+---+---
+(0 rows)
+
+CREATE TABLE test AS SELECT * FROM writetest; -- fail
+ERROR: cannot execute CREATE TABLE AS in a read-only transaction
+START TRANSACTION READ WRITE;
+DROP TABLE writetest; -- ok
+COMMIT;
+-- Subtransactions, basic tests
+-- create & drop tables
+SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE;
+CREATE TABLE trans_foobar (a int);
+BEGIN;
+ CREATE TABLE trans_foo (a int);
+ SAVEPOINT one;
+ DROP TABLE trans_foo;
+ CREATE TABLE trans_bar (a int);
+ ROLLBACK TO SAVEPOINT one;
+ RELEASE SAVEPOINT one;
+ SAVEPOINT two;
+ CREATE TABLE trans_baz (a int);
+ RELEASE SAVEPOINT two;
+ drop TABLE trans_foobar;
+ CREATE TABLE trans_barbaz (a int);
+COMMIT;
+-- should exist: trans_barbaz, trans_baz, trans_foo
+SELECT * FROM trans_foo; -- should be empty
+ a
+---
+(0 rows)
+
+SELECT * FROM trans_bar; -- shouldn't exist
+ERROR: relation "trans_bar" does not exist
+LINE 1: SELECT * FROM trans_bar;
+ ^
+SELECT * FROM trans_barbaz; -- should be empty
+ a
+---
+(0 rows)
+
+SELECT * FROM trans_baz; -- should be empty
+ a
+---
+(0 rows)
+
+-- inserts
+BEGIN;
+ INSERT INTO trans_foo VALUES (1);
+ SAVEPOINT one;
+ INSERT into trans_bar VALUES (1);
+ERROR: relation "trans_bar" does not exist
+LINE 1: INSERT into trans_bar VALUES (1);
+ ^
+ ROLLBACK TO one;
+ RELEASE SAVEPOINT one;
+ SAVEPOINT two;
+ INSERT into trans_barbaz VALUES (1);
+ RELEASE two;
+ SAVEPOINT three;
+ SAVEPOINT four;
+ INSERT INTO trans_foo VALUES (2);
+ RELEASE SAVEPOINT four;
+ ROLLBACK TO SAVEPOINT three;
+ RELEASE SAVEPOINT three;
+ INSERT INTO trans_foo VALUES (3);
+COMMIT;
+SELECT * FROM trans_foo; -- should have 1 and 3
+ a
+---
+ 1
+ 3
+(2 rows)
+
+SELECT * FROM trans_barbaz; -- should have 1
+ a
+---
+ 1
+(1 row)
+
+-- test whole-tree commit
+BEGIN;
+ SAVEPOINT one;
+ SELECT trans_foo;
+ERROR: column "trans_foo" does not exist
+LINE 1: SELECT trans_foo;
+ ^
+ ROLLBACK TO SAVEPOINT one;
+ RELEASE SAVEPOINT one;
+ SAVEPOINT two;
+ CREATE TABLE savepoints (a int);
+ SAVEPOINT three;
+ INSERT INTO savepoints VALUES (1);
+ SAVEPOINT four;
+ INSERT INTO savepoints VALUES (2);
+ SAVEPOINT five;
+ INSERT INTO savepoints VALUES (3);
+ ROLLBACK TO SAVEPOINT five;
+COMMIT;
+COMMIT; -- should not be in a transaction block
+WARNING: there is no transaction in progress
+SELECT * FROM savepoints;
+ a
+---
+ 1
+ 2
+(2 rows)
+
+-- test whole-tree rollback
+BEGIN;
+ SAVEPOINT one;
+ DELETE FROM savepoints WHERE a=1;
+ RELEASE SAVEPOINT one;
+ SAVEPOINT two;
+ DELETE FROM savepoints WHERE a=1;
+ SAVEPOINT three;
+ DELETE FROM savepoints WHERE a=2;
+ROLLBACK;
+COMMIT; -- should not be in a transaction block
+WARNING: there is no transaction in progress
+SELECT * FROM savepoints;
+ a
+---
+ 1
+ 2
+(2 rows)
+
+-- test whole-tree commit on an aborted subtransaction
+BEGIN;
+ INSERT INTO savepoints VALUES (4);
+ SAVEPOINT one;
+ INSERT INTO savepoints VALUES (5);
+ SELECT trans_foo;
+ERROR: column "trans_foo" does not exist
+LINE 1: SELECT trans_foo;
+ ^
+COMMIT;
+SELECT * FROM savepoints;
+ a
+---
+ 1
+ 2
+(2 rows)
+
+BEGIN;
+ INSERT INTO savepoints VALUES (6);
+ SAVEPOINT one;
+ INSERT INTO savepoints VALUES (7);
+ RELEASE SAVEPOINT one;
+ INSERT INTO savepoints VALUES (8);
+COMMIT;
+-- rows 6 and 8 should have been created by the same xact
+SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=6 AND b.a=8;
+ ?column?
+----------
+ t
+(1 row)
+
+-- rows 6 and 7 should have been created by different xacts
+SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=6 AND b.a=7;
+ ?column?
+----------
+ f
+(1 row)
+
+BEGIN;
+ INSERT INTO savepoints VALUES (9);
+ SAVEPOINT one;
+ INSERT INTO savepoints VALUES (10);
+ ROLLBACK TO SAVEPOINT one;
+ INSERT INTO savepoints VALUES (11);
+COMMIT;
+SELECT a FROM savepoints WHERE a in (9, 10, 11);
+ a
+----
+ 9
+ 11
+(2 rows)
+
+-- rows 9 and 11 should have been created by different xacts
+SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=9 AND b.a=11;
+ ?column?
+----------
+ f
+(1 row)
+
+BEGIN;
+ INSERT INTO savepoints VALUES (12);
+ SAVEPOINT one;
+ INSERT INTO savepoints VALUES (13);
+ SAVEPOINT two;
+ INSERT INTO savepoints VALUES (14);
+ ROLLBACK TO SAVEPOINT one;
+ INSERT INTO savepoints VALUES (15);
+ SAVEPOINT two;
+ INSERT INTO savepoints VALUES (16);
+ SAVEPOINT three;
+ INSERT INTO savepoints VALUES (17);
+COMMIT;
+SELECT a FROM savepoints WHERE a BETWEEN 12 AND 17;
+ a
+----
+ 12
+ 15
+ 16
+ 17
+(4 rows)
+
+BEGIN;
+ INSERT INTO savepoints VALUES (18);
+ SAVEPOINT one;
+ INSERT INTO savepoints VALUES (19);
+ SAVEPOINT two;
+ INSERT INTO savepoints VALUES (20);
+ ROLLBACK TO SAVEPOINT one;
+ INSERT INTO savepoints VALUES (21);
+ ROLLBACK TO SAVEPOINT one;
+ INSERT INTO savepoints VALUES (22);
+COMMIT;
+SELECT a FROM savepoints WHERE a BETWEEN 18 AND 22;
+ a
+----
+ 18
+ 22
+(2 rows)
+
+DROP TABLE savepoints;
+-- only in a transaction block:
+SAVEPOINT one;
+ERROR: SAVEPOINT can only be used in transaction blocks
+ROLLBACK TO SAVEPOINT one;
+ERROR: ROLLBACK TO SAVEPOINT can only be used in transaction blocks
+RELEASE SAVEPOINT one;
+ERROR: RELEASE SAVEPOINT can only be used in transaction blocks
+-- Only "rollback to" allowed in aborted state
+BEGIN;
+ SAVEPOINT one;
+ SELECT 0/0;
+ERROR: division by zero
+ SAVEPOINT two; -- ignored till the end of ...
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+ RELEASE SAVEPOINT one; -- ignored till the end of ...
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+ ROLLBACK TO SAVEPOINT one;
+ SELECT 1;
+ ?column?
+----------
+ 1
+(1 row)
+
+COMMIT;
+SELECT 1; -- this should work
+ ?column?
+----------
+ 1
+(1 row)
+
+-- check non-transactional behavior of cursors
+BEGIN;
+ DECLARE c CURSOR FOR SELECT unique2 FROM tenk1 ORDER BY unique2;
+ SAVEPOINT one;
+ FETCH 10 FROM c;
+ unique2
+---------
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+(10 rows)
+
+ ROLLBACK TO SAVEPOINT one;
+ FETCH 10 FROM c;
+ unique2
+---------
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+(10 rows)
+
+ RELEASE SAVEPOINT one;
+ FETCH 10 FROM c;
+ unique2
+---------
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+(10 rows)
+
+ CLOSE c;
+ DECLARE c CURSOR FOR SELECT unique2/0 FROM tenk1 ORDER BY unique2;
+ SAVEPOINT two;
+ FETCH 10 FROM c;
+ERROR: division by zero
+ ROLLBACK TO SAVEPOINT two;
+ -- c is now dead to the world ...
+ FETCH 10 FROM c;
+ERROR: portal "c" cannot be run
+ ROLLBACK TO SAVEPOINT two;
+ RELEASE SAVEPOINT two;
+ FETCH 10 FROM c;
+ERROR: portal "c" cannot be run
+COMMIT;
+--
+-- Check that "stable" functions are really stable. They should not be
+-- able to see the partial results of the calling query. (Ideally we would
+-- also check that they don't see commits of concurrent transactions, but
+-- that's a mite hard to do within the limitations of pg_regress.)
+--
+select * from xacttest;
+ a | b
+-----+---------
+ 56 | 7.8
+ 100 | 99.097
+ 0 | 0.09561
+ 42 | 324.78
+ 777 | 777.777
+(5 rows)
+
+create or replace function max_xacttest() returns smallint language sql as
+'select max(a) from xacttest' stable;
+begin;
+update xacttest set a = max_xacttest() + 10 where a > 0;
+select * from xacttest;
+ a | b
+-----+---------
+ 0 | 0.09561
+ 787 | 7.8
+ 787 | 99.097
+ 787 | 324.78
+ 787 | 777.777
+(5 rows)
+
+rollback;
+-- But a volatile function can see the partial results of the calling query
+create or replace function max_xacttest() returns smallint language sql as
+'select max(a) from xacttest' volatile;
+begin;
+update xacttest set a = max_xacttest() + 10 where a > 0;
+select * from xacttest;
+ a | b
+-----+---------
+ 0 | 0.09561
+ 787 | 7.8
+ 797 | 99.097
+ 807 | 324.78
+ 817 | 777.777
+(5 rows)
+
+rollback;
+-- Now the same test with plpgsql (since it depends on SPI which is different)
+create or replace function max_xacttest() returns smallint language plpgsql as
+'begin return max(a) from xacttest; end' stable;
+begin;
+update xacttest set a = max_xacttest() + 10 where a > 0;
+select * from xacttest;
+ a | b
+-----+---------
+ 0 | 0.09561
+ 787 | 7.8
+ 787 | 99.097
+ 787 | 324.78
+ 787 | 777.777
+(5 rows)
+
+rollback;
+create or replace function max_xacttest() returns smallint language plpgsql as
+'begin return max(a) from xacttest; end' volatile;
+begin;
+update xacttest set a = max_xacttest() + 10 where a > 0;
+select * from xacttest;
+ a | b
+-----+---------
+ 0 | 0.09561
+ 787 | 7.8
+ 797 | 99.097
+ 807 | 324.78
+ 817 | 777.777
+(5 rows)
+
+rollback;
+-- test case for problems with dropping an open relation during abort
+BEGIN;
+ savepoint x;
+ CREATE TABLE koju (a INT UNIQUE);
+ INSERT INTO koju VALUES (1);
+ INSERT INTO koju VALUES (1);
+ERROR: duplicate key value violates unique constraint "koju_a_key"
+DETAIL: Key (a)=(1) already exists.
+ rollback to x;
+ CREATE TABLE koju (a INT UNIQUE);
+ INSERT INTO koju VALUES (1);
+ INSERT INTO koju VALUES (1);
+ERROR: duplicate key value violates unique constraint "koju_a_key"
+DETAIL: Key (a)=(1) already exists.
+ROLLBACK;
+DROP TABLE trans_foo;
+DROP TABLE trans_baz;
+DROP TABLE trans_barbaz;
+-- test case for problems with revalidating an open relation during abort
+create function inverse(int) returns float8 as
+$$
+begin
+ analyze revalidate_bug;
+ return 1::float8/$1;
+exception
+ when division_by_zero then return 0;
+end$$ language plpgsql volatile;
+create table revalidate_bug (c float8 unique);
+insert into revalidate_bug values (1);
+insert into revalidate_bug values (inverse(0));
+drop table revalidate_bug;
+drop function inverse(int);
+-- verify that cursors created during an aborted subtransaction are
+-- closed, but that we do not rollback the effect of any FETCHs
+-- performed in the aborted subtransaction
+begin;
+savepoint x;
+create table abc (a int);
+insert into abc values (5);
+insert into abc values (10);
+declare foo cursor for select * from abc;
+fetch from foo;
+ a
+---
+ 5
+(1 row)
+
+rollback to x;
+-- should fail
+fetch from foo;
+ERROR: cursor "foo" does not exist
+commit;
+begin;
+create table abc (a int);
+insert into abc values (5);
+insert into abc values (10);
+insert into abc values (15);
+declare foo cursor for select * from abc;
+fetch from foo;
+ a
+---
+ 5
+(1 row)
+
+savepoint x;
+fetch from foo;
+ a
+----
+ 10
+(1 row)
+
+rollback to x;
+fetch from foo;
+ a
+----
+ 15
+(1 row)
+
+abort;
+-- Test for proper cleanup after a failure in a cursor portal
+-- that was created in an outer subtransaction
+CREATE FUNCTION invert(x float8) RETURNS float8 LANGUAGE plpgsql AS
+$$ begin return 1/x; end $$;
+CREATE FUNCTION create_temp_tab() RETURNS text
+LANGUAGE plpgsql AS $$
+BEGIN
+ CREATE TEMP TABLE new_table (f1 float8);
+ -- case of interest is that we fail while holding an open
+ -- relcache reference to new_table
+ INSERT INTO new_table SELECT invert(0.0);
+ RETURN 'foo';
+END $$;
+BEGIN;
+DECLARE ok CURSOR FOR SELECT * FROM int8_tbl;
+DECLARE ctt CURSOR FOR SELECT create_temp_tab();
+FETCH ok;
+ q1 | q2
+-----+-----
+ 123 | 456
+(1 row)
+
+SAVEPOINT s1;
+FETCH ok; -- should work
+ q1 | q2
+-----+------------------
+ 123 | 4567890123456789
+(1 row)
+
+FETCH ctt; -- error occurs here
+ERROR: division by zero
+CONTEXT: PL/pgSQL function invert(double precision) line 1 at RETURN
+SQL statement "INSERT INTO new_table SELECT invert(0.0)"
+PL/pgSQL function create_temp_tab() line 6 at SQL statement
+ROLLBACK TO s1;
+FETCH ok; -- should work
+ q1 | q2
+------------------+-----
+ 4567890123456789 | 123
+(1 row)
+
+FETCH ctt; -- must be rejected
+ERROR: portal "ctt" cannot be run
+COMMIT;
+DROP FUNCTION create_temp_tab();
+DROP FUNCTION invert(x float8);
+-- Tests for AND CHAIN
+CREATE TABLE abc (a int);
+-- set nondefault value so we have something to override below
+SET default_transaction_read_only = on;
+START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE;
+SHOW transaction_isolation;
+ transaction_isolation
+-----------------------
+ repeatable read
+(1 row)
+
+SHOW transaction_read_only;
+ transaction_read_only
+-----------------------
+ off
+(1 row)
+
+SHOW transaction_deferrable;
+ transaction_deferrable
+------------------------
+ on
+(1 row)
+
+INSERT INTO abc VALUES (1);
+INSERT INTO abc VALUES (2);
+COMMIT AND CHAIN; -- TBLOCK_END
+SHOW transaction_isolation;
+ transaction_isolation
+-----------------------
+ repeatable read
+(1 row)
+
+SHOW transaction_read_only;
+ transaction_read_only
+-----------------------
+ off
+(1 row)
+
+SHOW transaction_deferrable;
+ transaction_deferrable
+------------------------
+ on
+(1 row)
+
+INSERT INTO abc VALUES ('error');
+ERROR: invalid input syntax for type integer: "error"
+LINE 1: INSERT INTO abc VALUES ('error');
+ ^
+INSERT INTO abc VALUES (3); -- check it's really aborted
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+COMMIT AND CHAIN; -- TBLOCK_ABORT_END
+SHOW transaction_isolation;
+ transaction_isolation
+-----------------------
+ repeatable read
+(1 row)
+
+SHOW transaction_read_only;
+ transaction_read_only
+-----------------------
+ off
+(1 row)
+
+SHOW transaction_deferrable;
+ transaction_deferrable
+------------------------
+ on
+(1 row)
+
+INSERT INTO abc VALUES (4);
+COMMIT;
+START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE;
+SHOW transaction_isolation;
+ transaction_isolation
+-----------------------
+ repeatable read
+(1 row)
+
+SHOW transaction_read_only;
+ transaction_read_only
+-----------------------
+ off
+(1 row)
+
+SHOW transaction_deferrable;
+ transaction_deferrable
+------------------------
+ on
+(1 row)
+
+SAVEPOINT x;
+INSERT INTO abc VALUES ('error');
+ERROR: invalid input syntax for type integer: "error"
+LINE 1: INSERT INTO abc VALUES ('error');
+ ^
+COMMIT AND CHAIN; -- TBLOCK_ABORT_PENDING
+SHOW transaction_isolation;
+ transaction_isolation
+-----------------------
+ repeatable read
+(1 row)
+
+SHOW transaction_read_only;
+ transaction_read_only
+-----------------------
+ off
+(1 row)
+
+SHOW transaction_deferrable;
+ transaction_deferrable
+------------------------
+ on
+(1 row)
+
+INSERT INTO abc VALUES (5);
+COMMIT;
+START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE;
+SHOW transaction_isolation;
+ transaction_isolation
+-----------------------
+ repeatable read
+(1 row)
+
+SHOW transaction_read_only;
+ transaction_read_only
+-----------------------
+ off
+(1 row)
+
+SHOW transaction_deferrable;
+ transaction_deferrable
+------------------------
+ on
+(1 row)
+
+SAVEPOINT x;
+COMMIT AND CHAIN; -- TBLOCK_SUBCOMMIT
+SHOW transaction_isolation;
+ transaction_isolation
+-----------------------
+ repeatable read
+(1 row)
+
+SHOW transaction_read_only;
+ transaction_read_only
+-----------------------
+ off
+(1 row)
+
+SHOW transaction_deferrable;
+ transaction_deferrable
+------------------------
+ on
+(1 row)
+
+COMMIT;
+-- different mix of options just for fun
+START TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ WRITE, NOT DEFERRABLE;
+SHOW transaction_isolation;
+ transaction_isolation
+-----------------------
+ serializable
+(1 row)
+
+SHOW transaction_read_only;
+ transaction_read_only
+-----------------------
+ off
+(1 row)
+
+SHOW transaction_deferrable;
+ transaction_deferrable
+------------------------
+ off
+(1 row)
+
+INSERT INTO abc VALUES (6);
+ROLLBACK AND CHAIN; -- TBLOCK_ABORT_PENDING
+SHOW transaction_isolation;
+ transaction_isolation
+-----------------------
+ serializable
+(1 row)
+
+SHOW transaction_read_only;
+ transaction_read_only
+-----------------------
+ off
+(1 row)
+
+SHOW transaction_deferrable;
+ transaction_deferrable
+------------------------
+ off
+(1 row)
+
+INSERT INTO abc VALUES ('error');
+ERROR: invalid input syntax for type integer: "error"
+LINE 1: INSERT INTO abc VALUES ('error');
+ ^
+ROLLBACK AND CHAIN; -- TBLOCK_ABORT_END
+SHOW transaction_isolation;
+ transaction_isolation
+-----------------------
+ serializable
+(1 row)
+
+SHOW transaction_read_only;
+ transaction_read_only
+-----------------------
+ off
+(1 row)
+
+SHOW transaction_deferrable;
+ transaction_deferrable
+------------------------
+ off
+(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
+---
+ 1
+ 2
+ 4
+ 5
+(4 rows)
+
+RESET default_transaction_read_only;
+DROP TABLE abc;
+-- Test assorted behaviors around the implicit transaction block created
+-- when multiple SQL commands are sent in a single Query message. These
+-- tests rely on the fact that psql will not break SQL commands apart at a
+-- backslash-quoted semicolon, but will send them as one Query.
+create temp table i_table (f1 int);
+-- psql will show only the last result in a multi-statement Query
+SELECT 1\; SELECT 2\; SELECT 3;
+ ?column?
+----------
+ 3
+(1 row)
+
+-- this implicitly commits:
+insert into i_table values(1)\; select * from i_table;
+ f1
+----
+ 1
+(1 row)
+
+-- 1/0 error will cause rolling back the whole implicit transaction
+insert into i_table values(2)\; select * from i_table\; select 1/0;
+ERROR: division by zero
+select * from i_table;
+ f1
+----
+ 1
+(1 row)
+
+rollback; -- we are not in a transaction at this point
+WARNING: there is no transaction in progress
+-- can use regular begin/commit/rollback within a single Query
+begin\; insert into i_table values(3)\; commit;
+rollback; -- we are not in a transaction at this point
+WARNING: there is no transaction in progress
+begin\; insert into i_table values(4)\; rollback;
+rollback; -- we are not in a transaction at this point
+WARNING: there is no transaction in progress
+-- begin converts implicit transaction into a regular one that
+-- can extend past the end of the Query
+select 1\; begin\; insert into i_table values(5);
+commit;
+select 1\; begin\; insert into i_table values(6);
+rollback;
+-- commit in implicit-transaction state commits but issues a warning.
+insert into i_table values(7)\; commit\; insert into i_table values(8)\; select 1/0;
+WARNING: there is no transaction in progress
+ERROR: division by zero
+-- similarly, rollback aborts but issues a warning.
+insert into i_table values(9)\; rollback\; select 2;
+WARNING: there is no transaction in progress
+ ?column?
+----------
+ 2
+(1 row)
+
+select * from i_table;
+ f1
+----
+ 1
+ 3
+ 5
+ 7
+(4 rows)
+
+rollback; -- we are not in a transaction at this point
+WARNING: there is no transaction in progress
+-- implicit transaction block is still a transaction block, for e.g. VACUUM
+SELECT 1\; VACUUM;
+ERROR: VACUUM cannot run inside a transaction block
+SELECT 1\; COMMIT\; VACUUM;
+WARNING: there is no transaction in progress
+ERROR: VACUUM cannot run inside a transaction block
+-- we disallow savepoint-related commands in implicit-transaction state
+SELECT 1\; SAVEPOINT sp;
+ERROR: SAVEPOINT can only be used in transaction blocks
+SELECT 1\; COMMIT\; SAVEPOINT sp;
+WARNING: there is no transaction in progress
+ERROR: SAVEPOINT can only be used in transaction blocks
+ROLLBACK TO SAVEPOINT sp\; SELECT 2;
+ERROR: ROLLBACK TO SAVEPOINT can only be used in transaction blocks
+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 ONLY\; 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 ONLY\; 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;
+SET default_transaction_isolation = 'read committed';
+-- 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)
+
+RESET default_transaction_isolation;
+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;
+select 1/0;
+ERROR: division by zero
+rollback to X;
+ERROR: savepoint "x" does not exist
+-- DO NOT ADD ANYTHING HERE.