While fixing plperl and pltcl, I realized plpgsql wasn't doing
authorTom Lane <[email protected]>
Sun, 21 Nov 2004 22:27:34 +0000 (22:27 +0000)
committerTom Lane <[email protected]>
Sun, 21 Nov 2004 22:27:34 +0000 (22:27 +0000)
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.

src/pl/plpgsql/src/pl_exec.c

index b2b9ff97ee89bb753c431d20a64c4282ebdc8afe..1e77951375c7b6212f82862dcced62b46fc5d26a 100644 (file)
@@ -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
        {