From: Tom Lane Date: Sun, 21 Nov 2004 22:27:34 +0000 (+0000) Subject: While fixing plperl and pltcl, I realized plpgsql wasn't doing X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=334c59253a96f1f7f7e37df3ada376e05ece2a92;p=users%2Fbernd%2Fpostgres.git 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. --- diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index b2b9ff97ee..1e77951375 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -898,7 +898,6 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block) */ MemoryContext oldcontext = CurrentMemoryContext; ResourceOwner oldowner = CurrentResourceOwner; - volatile bool caught = false; BeginInternalSubTransaction(NULL); /* Want to run statements inside function's memory context */ @@ -907,6 +906,17 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block) PG_TRY(); { 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(); { @@ -949,22 +959,8 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block) ReThrowError(edata); else FreeErrorData(edata); - caught = true; } 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 {