--- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -3729,6 +3729,7 @@ (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION), errmsg("there is no transaction in progress"))); s->blockState = TBLOCK_END; + chain = false; /* Do not chain the implicit transaction */ result = true; break; @@ -3798,6 +3799,7 @@ ereport(WARNING, (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION), errmsg("there is no transaction in progress"))); + chain = false; /* Do not chain the implicit transaction */ result = true; break; @@ -3915,6 +3917,7 @@ (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION), errmsg("there is no transaction in progress"))); s->blockState = TBLOCK_ABORT_PENDING; + chain = false; /* Do not chain the implicit transaction */ break; /* --- a/src/test/regress/expected/transactions.out +++ b/src/test/regress/expected/transactions.out @@ -839,6 +839,36 @@ (1 row) ROLLBACK; +-- transaction cannot be chained outside a transaction block +COMMIT AND CHAIN; -- TBLOCK_STARTED +WARNING: there is no transaction in progress +COMMIT; -- TBLOCK_STARTED +WARNING: there is no transaction in progress +ROLLBACK AND CHAIN; -- TBLOCK_ABORT_PENDING +WARNING: there is no transaction in progress +ROLLBACK; -- TBLOCK_ABORT_PENDING +WARNING: there is no transaction in progress +-- implicit transaction cannot be chained as well +SET TRANSACTION READ WRITE\; COMMIT AND CHAIN; -- TBLOCK_END +WARNING: there is no transaction in progress +SHOW transaction_read_only; + transaction_read_only +----------------------- + on +(1 row) + +COMMIT; +WARNING: there is no transaction in progress +SET TRANSACTION READ WRITE\; ROLLBACK AND CHAIN; -- TBLOCK_ABORT_PENDING +WARNING: there is no transaction in progress +SHOW transaction_read_only; + transaction_read_only +----------------------- + on +(1 row) + +ROLLBACK; +WARNING: there is no transaction in progress SELECT * FROM abc ORDER BY 1; a --- --- a/src/test/regress/sql/transactions.sql +++ b/src/test/regress/sql/transactions.sql @@ -475,6 +475,22 @@ SHOW transaction_deferrable; ROLLBACK; +-- transaction cannot be chained outside a transaction block +COMMIT AND CHAIN; -- TBLOCK_STARTED +COMMIT; -- TBLOCK_STARTED + +ROLLBACK AND CHAIN; -- TBLOCK_ABORT_PENDING +ROLLBACK; -- TBLOCK_ABORT_PENDING + +-- implicit transaction cannot be chained as well +SET TRANSACTION READ WRITE\; COMMIT AND CHAIN; -- TBLOCK_END +SHOW transaction_read_only; +COMMIT; + +SET TRANSACTION READ WRITE\; ROLLBACK AND CHAIN; -- TBLOCK_ABORT_PENDING +SHOW transaction_read_only; +ROLLBACK; + SELECT * FROM abc ORDER BY 1; RESET default_transaction_read_only;