aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/explain.c30
-rw-r--r--src/backend/commands/portalcmds.c69
-rw-r--r--src/backend/commands/prepare.c20
-rw-r--r--src/backend/commands/schemacmds.c4
4 files changed, 61 insertions, 62 deletions
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 2504d69fd06..28a6e0378c8 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994-5, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.107 2003/05/06 00:20:31 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.108 2003/05/06 20:26:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -67,21 +67,15 @@ static Node *make_ors_ands_explicit(List *orclauses);
* execute an EXPLAIN command
*/
void
-ExplainQuery(ExplainStmt *stmt, CommandDest dest)
+ExplainQuery(ExplainStmt *stmt, DestReceiver *dest)
{
Query *query = stmt->query;
TupOutputState *tstate;
- TupleDesc tupdesc;
List *rewritten;
List *l;
- /* need a tuple descriptor representing a single TEXT column */
- tupdesc = CreateTemplateTupleDesc(1, false);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "QUERY PLAN",
- TEXTOID, -1, 0, false);
-
/* prepare for projection of tuples */
- tstate = begin_tup_output_tupdesc(dest, tupdesc);
+ tstate = begin_tup_output_tupdesc(dest, ExplainResultDesc(stmt));
if (query->commandType == CMD_UTILITY)
{
@@ -120,6 +114,22 @@ ExplainQuery(ExplainStmt *stmt, CommandDest dest)
}
/*
+ * ExplainResultDesc -
+ * construct the result tupledesc for an EXPLAIN
+ */
+TupleDesc
+ExplainResultDesc(ExplainStmt *stmt)
+{
+ TupleDesc tupdesc;
+
+ /* need a tuple descriptor representing a single TEXT column */
+ tupdesc = CreateTemplateTupleDesc(1, false);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 1, "QUERY PLAN",
+ TEXTOID, -1, 0, false);
+ return tupdesc;
+}
+
+/*
* ExplainOneQuery -
* print out the execution plan for one query
*/
@@ -169,7 +179,7 @@ ExplainOneQuery(Query *query, ExplainStmt *stmt, TupOutputState *tstate)
plan = planner(query, isCursor, cursorOptions);
/* Create a QueryDesc requesting no output */
- queryDesc = CreateQueryDesc(query, plan, None, NULL, NULL,
+ queryDesc = CreateQueryDesc(query, plan, None_Receiver, NULL, NULL,
stmt->analyze);
ExplainOnePlan(queryDesc, stmt, tstate);
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;
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 3f8beac53c1..c317494f6fa 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -10,7 +10,7 @@
* Copyright (c) 2002-2003, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/prepare.c,v 1.15 2003/05/05 00:44:55 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/prepare.c,v 1.16 2003/05/06 20:26:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -102,7 +102,7 @@ PrepareQuery(PrepareStmt *stmt)
* Implements the 'EXECUTE' utility statement.
*/
void
-ExecuteQuery(ExecuteStmt *stmt, CommandDest outputDest)
+ExecuteQuery(ExecuteStmt *stmt, DestReceiver *dest)
{
PreparedStatement *entry;
char *query_string;
@@ -180,7 +180,7 @@ ExecuteQuery(ExecuteStmt *stmt, CommandDest outputDest)
*/
PortalStart(portal, paramLI);
- (void) PortalRun(portal, FETCH_ALL, outputDest, outputDest, NULL);
+ (void) PortalRun(portal, FETCH_ALL, dest, dest, NULL);
PortalDrop(portal, false);
@@ -488,19 +488,21 @@ ExplainExecuteQuery(ExplainStmt *stmt, TupOutputState *tstate)
{
QueryDesc *qdesc;
- /* Create a QueryDesc requesting no output */
- qdesc = CreateQueryDesc(query, plan, None, NULL,
- paramLI, stmt->analyze);
-
if (execstmt->into)
{
- if (qdesc->operation != CMD_SELECT)
+ if (query->commandType != CMD_SELECT)
elog(ERROR, "INTO clause specified for non-SELECT query");
+ /* Copy the query so we can modify it */
+ query = copyObject(query);
+
query->into = execstmt->into;
- qdesc->dest = None;
}
+ /* Create a QueryDesc requesting no output */
+ qdesc = CreateQueryDesc(query, plan, None_Receiver, NULL,
+ paramLI, stmt->analyze);
+
ExplainOnePlan(qdesc, stmt, tstate);
}
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index 4e2224e189b..282fb19a85b 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/schemacmds.c,v 1.8 2003/04/29 22:13:08 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/schemacmds.c,v 1.9 2003/05/06 20:26:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -133,7 +133,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
/* schemas should contain only utility stmts */
Assert(querytree->commandType == CMD_UTILITY);
/* do this step */
- ProcessUtility(querytree->utilityStmt, None, NULL);
+ ProcessUtility(querytree->utilityStmt, None_Receiver, NULL);
/* make sure later steps can see the object created here */
CommandCounterIncrement();
}