1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-14 18:42:34 +03:00

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.
This commit is contained in:
Tom Lane
2004-07-17 03:32:14 +00:00
parent f4c069ca8f
commit fe548629c5
41 changed files with 2086 additions and 1192 deletions

View File

@ -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;
}