diff options
| author | Tom Lane | 2004-07-17 03:32:14 +0000 |
|---|---|---|
| committer | Tom Lane | 2004-07-17 03:32:14 +0000 |
| commit | fe548629c50b753e96515ba2cfd8a85e8fba10de (patch) | |
| tree | e80b54f71cb7868db3f9f9c97bccf4c48859951a /src/backend/commands | |
| parent | f4c069ca8fc80640bd1bff510697371ffaf45267 (diff) | |
Invent ResourceOwner mechanism as per my recent proposal, and use it to
keep track of portal-related resources separately from transaction-related
resources. This allows cursors to work in a somewhat sane fashion with
nested transactions. For now, cursor behavior is non-subtransactional,
that is a cursor's state does not roll back if you abort a subtransaction
that fetched from the cursor. We might want to change that later.
Diffstat (limited to 'src/backend/commands')
| -rw-r--r-- | src/backend/commands/portalcmds.c | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c index 9cb8febd31..b176a6c0c7 100644 --- a/src/backend/commands/portalcmds.c +++ b/src/backend/commands/portalcmds.c @@ -14,7 +14,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/portalcmds.c,v 1.28 2004/06/11 01:08:37 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/portalcmds.c,v 1.29 2004/07/17 03:28:47 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -233,7 +233,7 @@ PerformPortalClose(const char *name) * for portals. */ void -PortalCleanup(Portal portal, bool isError) +PortalCleanup(Portal portal) { QueryDesc *queryDesc; @@ -253,8 +253,16 @@ PortalCleanup(Portal portal, bool isError) if (queryDesc) { portal->queryDesc = NULL; - if (!isError) + if (portal->status != PORTAL_FAILED) + { + ResourceOwner saveResourceOwner; + + /* We must make the portal's resource owner current */ + saveResourceOwner = CurrentResourceOwner; + CurrentResourceOwner = portal->resowner; ExecutorEnd(queryDesc); + CurrentResourceOwner = saveResourceOwner; + } } } @@ -271,6 +279,7 @@ PersistHoldablePortal(Portal portal) { QueryDesc *queryDesc = PortalGetQueryDesc(portal); Portal saveActivePortal; + ResourceOwner saveResourceOwner; MemoryContext savePortalContext; MemoryContext saveQueryContext; MemoryContext oldcxt; @@ -281,8 +290,6 @@ PersistHoldablePortal(Portal portal) */ Assert(portal->createXact == GetCurrentTransactionId()); Assert(queryDesc != NULL); - Assert(portal->portalReady); - Assert(!portal->portalDone); /* * Caller must have created the tuplestore already. @@ -303,17 +310,19 @@ PersistHoldablePortal(Portal portal) /* * Check for improper portal use, and mark portal active. */ - if (portal->portalActive) + if (portal->status != PORTAL_READY) ereport(ERROR, - (errcode(ERRCODE_OBJECT_IN_USE), - errmsg("portal \"%s\" already active", portal->name))); - portal->portalActive = true; + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("portal \"%s\" cannot be run", portal->name))); + portal->status = PORTAL_ACTIVE; /* * Set global portal context pointers. */ saveActivePortal = ActivePortal; ActivePortal = portal; + saveResourceOwner = CurrentResourceOwner; + CurrentResourceOwner = portal->resowner; savePortalContext = PortalContext; PortalContext = PortalGetHeapMemory(portal); saveQueryContext = QueryContext; @@ -342,13 +351,6 @@ PersistHoldablePortal(Portal portal) portal->queryDesc = NULL; /* prevent double shutdown */ ExecutorEnd(queryDesc); - /* Mark portal not active */ - portal->portalActive = false; - - ActivePortal = saveActivePortal; - PortalContext = savePortalContext; - QueryContext = saveQueryContext; - /* * Reset the position in the result set: ideally, this could be * implemented by just skipping straight to the tuple # that we need @@ -394,4 +396,12 @@ PersistHoldablePortal(Portal portal) * portal's heap via PortalContext. */ MemoryContextDeleteChildren(PortalGetHeapMemory(portal)); + + /* Mark portal not active */ + portal->status = PORTAL_READY; + + ActivePortal = saveActivePortal; + CurrentResourceOwner = saveResourceOwner; + PortalContext = savePortalContext; + QueryContext = saveQueryContext; } |
