aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/portalcmds.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-02-15 16:18:34 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2012-02-15 16:19:01 -0500
commit4bfe68dfab009ce8fcaea79dc0832eadf3380051 (patch)
treea3cfddf505fa6b8136b2fc26324ee930bdb390e1 /src/backend/commands/portalcmds.c
parentedec8c8e00e3f2a9305ab92e2c81293457cf959a (diff)
downloadpostgresql-4bfe68dfab009ce8fcaea79dc0832eadf3380051.tar.gz
postgresql-4bfe68dfab009ce8fcaea79dc0832eadf3380051.zip
Run a portal's cleanup hook immediately when pushing it to FAILED state.
This extends the changes of commit 6252c4f9e201f619e5eebda12fa867acd4e4200e so that we run the cleanup hook earlier for failure cases as well as success cases. As before, the point is to avoid an assertion failure from an Assert I added in commit a874fe7b4c890d1fe3455215a83ca777867beadd, which was meant to check that no user-written code can be called during portal cleanup. This fixes a case reported by Pavan Deolasee in which the Assert could be triggered during backend exit (see the new regression test case), and also prevents the possibility that the cleanup hook is run after portions of the portal's state have already been recycled. That doesn't really matter in current usage, but it foreseeably could matter in the future. Back-patch to 9.1 where the Assert in question was added.
Diffstat (limited to 'src/backend/commands/portalcmds.c')
-rw-r--r--src/backend/commands/portalcmds.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c
index ab8b55c1d2e..1c7a1c3a33f 100644
--- a/src/backend/commands/portalcmds.c
+++ b/src/backend/commands/portalcmds.c
@@ -224,7 +224,7 @@ PerformPortalClose(const char *name)
}
/*
- * Note: PortalCleanup is called as a side-effect
+ * Note: PortalCleanup is called as a side-effect, if not already done.
*/
PortalDrop(portal, false);
}
@@ -234,6 +234,10 @@ PerformPortalClose(const char *name)
*
* Clean up a portal when it's dropped. This is the standard cleanup hook
* for portals.
+ *
+ * Note: if portal->status is PORTAL_FAILED, we are probably being called
+ * during error abort, and must be careful to avoid doing anything that
+ * is likely to fail again.
*/
void
PortalCleanup(Portal portal)
@@ -420,7 +424,7 @@ PersistHoldablePortal(Portal portal)
PG_CATCH();
{
/* Uncaught error while executing portal: mark it dead */
- portal->status = PORTAL_FAILED;
+ MarkPortalFailed(portal);
/* Restore global vars and propagate error */
ActivePortal = saveActivePortal;