aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/portalcmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/portalcmds.c')
-rw-r--r--src/backend/commands/portalcmds.c69
1 files changed, 28 insertions, 41 deletions
diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c
index 82058ff5d10..1c51a1bb89f 100644
--- a/src/backend/commands/portalcmds.c
+++ b/src/backend/commands/portalcmds.c
@@ -14,7 +14,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/portalcmds.c,v 1.14 2003/05/05 00:44:55 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/portalcmds.c,v 1.15 2003/05/06 20:26:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,9 +23,9 @@
#include <limits.h>
-#include "miscadmin.h"
#include "commands/portalcmds.h"
#include "executor/executor.h"
+#include "executor/tstoreReceiver.h"
#include "optimizer/planner.h"
#include "rewrite/rewriteHandler.h"
#include "tcop/pquery.h"
@@ -37,7 +37,7 @@
* Execute SQL DECLARE CURSOR command.
*/
void
-PerformCursorOpen(DeclareCursorStmt *stmt, CommandDest dest)
+PerformCursorOpen(DeclareCursorStmt *stmt)
{
List *rewritten;
Query *query;
@@ -142,9 +142,10 @@ PerformCursorOpen(DeclareCursorStmt *stmt, CommandDest dest)
*/
void
PerformPortalFetch(FetchStmt *stmt,
- CommandDest dest,
+ DestReceiver *dest,
char *completionTag)
{
+ DestReceiver *mydest = dest;
Portal portal;
long nprocessed;
@@ -168,7 +169,7 @@ PerformPortalFetch(FetchStmt *stmt,
}
/*
- * Adjust dest if needed. MOVE wants dest = None.
+ * Adjust dest if needed. MOVE wants destination None.
*
* If fetching from a binary cursor and the requested destination is
* Remote, change it to RemoteInternal. Note we do NOT change if the
@@ -176,21 +177,26 @@ PerformPortalFetch(FetchStmt *stmt,
* specification wins out over the cursor's type.
*/
if (stmt->ismove)
- dest = None;
- else if (dest == Remote && (portal->cursorOptions & CURSOR_OPT_BINARY))
- dest = RemoteInternal;
+ mydest = CreateDestReceiver(None);
+ else if (dest->mydest == Remote &&
+ (portal->cursorOptions & CURSOR_OPT_BINARY))
+ mydest = CreateDestReceiver(RemoteInternal);
/* Do it */
nprocessed = PortalRunFetch(portal,
stmt->direction,
stmt->howMany,
- dest);
+ mydest);
/* Return command status if wanted */
if (completionTag)
snprintf(completionTag, COMPLETION_TAG_BUFSIZE, "%s %ld",
stmt->ismove ? "MOVE" : "FETCH",
nprocessed);
+
+ /* Clean up if we created a local destination */
+ if (mydest != dest)
+ (mydest->destroy) (mydest);
}
/*
@@ -244,21 +250,6 @@ PortalCleanup(Portal portal, bool isError)
AssertArg(portal->cleanup == PortalCleanup);
/*
- * Delete tuplestore if present. (Note: portalmem.c is responsible
- * for removing holdContext.) We should do this even under error
- * conditions; since the tuplestore would have been using cross-
- * transaction storage, its temp files need to be explicitly deleted.
- */
- if (portal->holdStore)
- {
- MemoryContext oldcontext;
-
- oldcontext = MemoryContextSwitchTo(portal->holdContext);
- tuplestore_end(portal->holdStore);
- MemoryContextSwitchTo(oldcontext);
- portal->holdStore = NULL;
- }
- /*
* Shut down executor, if still running. We skip this during error
* abort, since other mechanisms will take care of releasing executor
* resources, and we can't be sure that ExecutorEnd itself wouldn't fail.
@@ -284,7 +275,6 @@ void
PersistHoldablePortal(Portal portal)
{
QueryDesc *queryDesc = PortalGetQueryDesc(portal);
- Portal saveCurrentPortal;
MemoryContext savePortalContext;
MemoryContext saveQueryContext;
MemoryContext oldcxt;
@@ -294,26 +284,22 @@ PersistHoldablePortal(Portal portal)
* inside the transaction that originally created it.
*/
Assert(portal->createXact == GetCurrentTransactionId());
- Assert(portal->holdStore == NULL);
Assert(queryDesc != NULL);
Assert(portal->portalReady);
Assert(!portal->portalDone);
/*
- * This context is used to store the tuple set.
- * Caller must have created it already.
+ * Caller must have created the tuplestore already.
*/
Assert(portal->holdContext != NULL);
- oldcxt = MemoryContextSwitchTo(portal->holdContext);
-
- /* XXX: Should SortMem be used for this? */
- portal->holdStore = tuplestore_begin_heap(true, true, SortMem);
+ Assert(portal->holdStore != NULL);
/*
- * Before closing down the executor, we must copy the tupdesc, since
- * it was created in executor memory. Note we are copying it into
- * the holdContext.
+ * Before closing down the executor, we must copy the tupdesc into
+ * long-term memory, since it was created in executor memory.
*/
+ oldcxt = MemoryContextSwitchTo(portal->holdContext);
+
portal->tupDesc = CreateTupleDescCopy(portal->tupDesc);
MemoryContextSwitchTo(oldcxt);
@@ -326,10 +312,8 @@ PersistHoldablePortal(Portal portal)
portal->portalActive = true;
/*
- * Set global portal and context pointers.
+ * Set global portal context pointers.
*/
- saveCurrentPortal = CurrentPortal;
- CurrentPortal = portal;
savePortalContext = PortalContext;
PortalContext = PortalGetHeapMemory(portal);
saveQueryContext = QueryContext;
@@ -344,12 +328,16 @@ PersistHoldablePortal(Portal portal)
*/
ExecutorRewind(queryDesc);
- /* Set the destination to output to the tuplestore */
- queryDesc->dest = Tuplestore;
+ /* Change the destination to output to the tuplestore */
+ queryDesc->dest = CreateTuplestoreDestReceiver(portal->holdStore,
+ portal->holdContext);
/* Fetch the result set into the tuplestore */
ExecutorRun(queryDesc, ForwardScanDirection, 0L);
+ (*queryDesc->dest->destroy) (queryDesc->dest);
+ queryDesc->dest = NULL;
+
/*
* Now shut down the inner executor.
*/
@@ -359,7 +347,6 @@ PersistHoldablePortal(Portal portal)
/* Mark portal not active */
portal->portalActive = false;
- CurrentPortal = saveCurrentPortal;
PortalContext = savePortalContext;
QueryContext = saveQueryContext;