diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 775477c6cf..ef309c7ff6 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -472,7 +472,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, ListCell *cell; char *name = NULL; - RequireTransactionChain(isTopLevel, "SAVEPOINT"); + RequireTransactionChain(!IsTransactionBlock(), "SAVEPOINT"); foreach(cell, stmt->options) { @@ -489,12 +489,12 @@ standard_ProcessUtility(PlannedStmt *pstmt, break; case TRANS_STMT_RELEASE: - RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT"); + RequireTransactionChain(!IsTransactionBlock(), "RELEASE SAVEPOINT"); ReleaseSavepoint(stmt->options); break; case TRANS_STMT_ROLLBACK_TO: - RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT"); + RequireTransactionChain(!IsTransactionBlock(), "ROLLBACK TO SAVEPOINT"); RollbackToSavepoint(stmt->options); /* diff --git a/src/test/regress/expected/transactions.out b/src/test/regress/expected/transactions.out index d9b702d016..c848e0660f 100644 --- a/src/test/regress/expected/transactions.out +++ b/src/test/regress/expected/transactions.out @@ -657,6 +657,20 @@ FETCH ok; -- should work FETCH ctt; -- must be rejected ERROR: portal "ctt" cannot be run COMMIT; +-- Test SAVEPOINTs in multi-statement requests +SELECT 1 "1"; SAVEPOINT sp; + 1 +--- + 1 +(1 row) + +ERROR: SAVEPOINT can only be used in transaction blocks +SELECT 1 "1"; BEGIN; SAVEPOINT sp; ROLLBACK TO SAVEPOint sp; COMMIT; + 1 +--- + 1 +(1 row) + DROP FUNCTION create_temp_tab(); DROP FUNCTION invert(x float8); -- Test for successful cleanup of an aborted transaction at session exit. diff --git a/src/test/regress/sql/transactions.sql b/src/test/regress/sql/transactions.sql index bf9cb05971..53a2c12a91 100644 --- a/src/test/regress/sql/transactions.sql +++ b/src/test/regress/sql/transactions.sql @@ -415,6 +415,10 @@ FETCH ok; -- should work FETCH ctt; -- must be rejected COMMIT; +-- Test SAVEPOINTs in multi-statement requests +SELECT 1 "1"; SAVEPOINT sp; +SELECT 1 "1"; BEGIN; SAVEPOINT sp; ROLLBACK TO SAVEPOint sp; COMMIT; + DROP FUNCTION create_temp_tab(); DROP FUNCTION invert(x float8);