Commit 183e8b91 authored by Tom Lane's avatar Tom Lane

While fixing plperl and pltcl, I realized plpgsql wasn't doing

subtransactions quite right either: the ReleaseCurrentSubTransaction
call should occur inside the PG_TRY, so that the proper path is taken
if an error occurs during subtransaction commit.  This assumes that
AbortSubTransaction can cope with the state left behind if
CommitSubTransaction fails partway through, but we were already
requiring that.
parent 32c97fd5
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* procedural language * procedural language
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.121 2004/11/16 18:10:14 tgl Exp $ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.122 2004/11/21 22:27:34 tgl Exp $
* *
* This software is copyrighted by Jan Wieck - Hamburg. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -898,7 +898,6 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block) ...@@ -898,7 +898,6 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
*/ */
MemoryContext oldcontext = CurrentMemoryContext; MemoryContext oldcontext = CurrentMemoryContext;
ResourceOwner oldowner = CurrentResourceOwner; ResourceOwner oldowner = CurrentResourceOwner;
volatile bool caught = false;
BeginInternalSubTransaction(NULL); BeginInternalSubTransaction(NULL);
/* Want to run statements inside function's memory context */ /* Want to run statements inside function's memory context */
...@@ -907,6 +906,17 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block) ...@@ -907,6 +906,17 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
PG_TRY(); PG_TRY();
{ {
rc = exec_stmts(estate, block->body); rc = exec_stmts(estate, block->body);
/* Commit the inner transaction, return to outer xact context */
ReleaseCurrentSubTransaction();
MemoryContextSwitchTo(oldcontext);
CurrentResourceOwner = oldowner;
/*
* AtEOSubXact_SPI() should not have popped any SPI context,
* but just in case it did, make sure we remain connected.
*/
SPI_restore_connection();
} }
PG_CATCH(); PG_CATCH();
{ {
...@@ -949,22 +959,8 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block) ...@@ -949,22 +959,8 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
ReThrowError(edata); ReThrowError(edata);
else else
FreeErrorData(edata); FreeErrorData(edata);
caught = true;
} }
PG_END_TRY(); PG_END_TRY();
/* Commit the inner transaction, return to outer xact context */
if (!caught)
{
ReleaseCurrentSubTransaction();
MemoryContextSwitchTo(oldcontext);
CurrentResourceOwner = oldowner;
/*
* AtEOSubXact_SPI() should not have popped any SPI context,
* but just in case it did, make sure we remain connected.
*/
SPI_restore_connection();
}
} }
else else
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment