aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execMain.c35
-rw-r--r--src/backend/executor/execTuples.c64
-rw-r--r--src/backend/executor/functions.c4
-rw-r--r--src/backend/executor/spi.c50
-rw-r--r--src/backend/executor/tstoreReceiver.c60
5 files changed, 125 insertions, 88 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 719c9456562..3d1b950e210 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -26,7 +26,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.207 2003/05/06 00:20:31 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.208 2003/05/06 20:26:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -72,9 +72,9 @@ static TupleTableSlot *ExecutePlan(EState *estate, PlanState *planstate,
CmdType operation,
long numberTuples,
ScanDirection direction,
- DestReceiver *destfunc);
+ DestReceiver *dest);
static void ExecSelect(TupleTableSlot *slot,
- DestReceiver *destfunc,
+ DestReceiver *dest,
EState *estate);
static void ExecInsert(TupleTableSlot *slot, ItemPointer tupleid,
EState *estate);
@@ -188,8 +188,7 @@ ExecutorRun(QueryDesc *queryDesc,
{
EState *estate;
CmdType operation;
- CommandDest dest;
- DestReceiver *destfunc;
+ DestReceiver *dest;
TupleTableSlot *result;
MemoryContext oldcontext;
@@ -218,11 +217,10 @@ ExecutorRun(QueryDesc *queryDesc,
estate->es_processed = 0;
estate->es_lastoid = InvalidOid;
- destfunc = DestToFunction(dest);
- (*destfunc->setup) (destfunc, operation,
- queryDesc->portalName,
- queryDesc->tupDesc,
- queryDesc->planstate->plan->targetlist);
+ (*dest->startup) (dest, operation,
+ queryDesc->portalName,
+ queryDesc->tupDesc,
+ queryDesc->planstate->plan->targetlist);
/*
* run plan
@@ -235,12 +233,12 @@ ExecutorRun(QueryDesc *queryDesc,
operation,
count,
direction,
- destfunc);
+ dest);
/*
* shutdown receiver
*/
- (*destfunc->cleanup) (destfunc);
+ (*dest->shutdown) (dest);
MemoryContextSwitchTo(oldcontext);
@@ -962,7 +960,7 @@ ExecutePlan(EState *estate,
CmdType operation,
long numberTuples,
ScanDirection direction,
- DestReceiver *destfunc)
+ DestReceiver *dest)
{
JunkFilter *junkfilter;
TupleTableSlot *slot;
@@ -1162,8 +1160,7 @@ lnext: ;
{
case CMD_SELECT:
ExecSelect(slot, /* slot containing tuple */
- destfunc, /* destination's tuple-receiver
- * obj */
+ dest, /* destination's tuple-receiver obj */
estate);
result = slot;
break;
@@ -1237,7 +1234,7 @@ lnext: ;
*/
static void
ExecSelect(TupleTableSlot *slot,
- DestReceiver *destfunc,
+ DestReceiver *dest,
EState *estate)
{
HeapTuple tuple;
@@ -1251,6 +1248,8 @@ ExecSelect(TupleTableSlot *slot,
/*
* insert the tuple into the "into relation"
+ *
+ * XXX this probably ought to be replaced by a separate destination
*/
if (estate->es_into_relation_descriptor != NULL)
{
@@ -1260,9 +1259,9 @@ ExecSelect(TupleTableSlot *slot,
}
/*
- * send the tuple to the front end (or the screen)
+ * send the tuple to the destination
*/
- (*destfunc->receiveTuple) (tuple, attrtype, destfunc);
+ (*dest->receiveTuple) (tuple, attrtype, dest);
IncrRetrieved();
(estate->es_processed)++;
}
diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c
index c81dd33d36a..2e040f78903 100644
--- a/src/backend/executor/execTuples.c
+++ b/src/backend/executor/execTuples.c
@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.64 2003/05/06 00:20:31 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.65 2003/05/06 20:26:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -591,6 +591,49 @@ ExecTypeFromTL(List *targetList, bool hasoid)
return typeInfo;
}
+/* ----------------------------------------------------------------
+ * ExecCleanTypeFromTL
+ *
+ * Same as above, but resjunk columns are omitted from the result.
+ * ----------------------------------------------------------------
+ */
+TupleDesc
+ExecCleanTypeFromTL(List *targetList, bool hasoid)
+{
+ TupleDesc typeInfo;
+ List *tlitem;
+ int len;
+ int cleanresno;
+
+ /*
+ * allocate a new typeInfo
+ */
+ len = ExecCleanTargetListLength(targetList);
+ typeInfo = CreateTemplateTupleDesc(len, hasoid);
+
+ /*
+ * scan list, generate type info for each entry
+ */
+ cleanresno = 1;
+ foreach(tlitem, targetList)
+ {
+ TargetEntry *tle = lfirst(tlitem);
+ Resdom *resdom = tle->resdom;
+
+ if (resdom->resjunk)
+ continue;
+ TupleDescInitEntry(typeInfo,
+ cleanresno++,
+ resdom->resname,
+ resdom->restype,
+ resdom->restypmod,
+ 0,
+ false);
+ }
+
+ return typeInfo;
+}
+
/*
* TupleDescGetSlot - Initialize a slot based on the supplied tupledesc
*/
@@ -713,17 +756,17 @@ BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
* Table Function capability. Currently used by EXPLAIN and SHOW ALL
*/
TupOutputState *
-begin_tup_output_tupdesc(CommandDest dest, TupleDesc tupdesc)
+begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc)
{
TupOutputState *tstate;
tstate = (TupOutputState *) palloc(sizeof(TupOutputState));
tstate->metadata = TupleDescGetAttInMetadata(tupdesc);
- tstate->destfunc = DestToFunction(dest);
+ tstate->dest = dest;
- (*tstate->destfunc->setup) (tstate->destfunc, (int) CMD_SELECT,
- NULL, tupdesc, NIL);
+ (*tstate->dest->startup) (tstate->dest, (int) CMD_SELECT,
+ NULL, tupdesc, NIL);
return tstate;
}
@@ -741,9 +784,9 @@ do_tup_output(TupOutputState *tstate, char **values)
HeapTuple tuple = BuildTupleFromCStrings(tstate->metadata, values);
/* send the tuple to the receiver */
- (*tstate->destfunc->receiveTuple) (tuple,
- tstate->metadata->tupdesc,
- tstate->destfunc);
+ (*tstate->dest->receiveTuple) (tuple,
+ tstate->metadata->tupdesc,
+ tstate->dest);
/* clean up */
heap_freetuple(tuple);
}
@@ -766,7 +809,7 @@ do_text_output_multiline(TupOutputState *tstate, char *text)
if (eol)
*eol++ = '\0';
else
- eol = text +strlen(text);
+ eol = text + strlen(text);
do_tup_output(tstate, &text);
text = eol;
@@ -776,7 +819,8 @@ do_text_output_multiline(TupOutputState *tstate, char *text)
void
end_tup_output(TupOutputState *tstate)
{
- (*tstate->destfunc->cleanup) (tstate->destfunc);
+ (*tstate->dest->shutdown) (tstate->dest);
+ /* note that destroying the dest is not ours to do */
/* XXX worth cleaning up the attinmetadata? */
pfree(tstate);
}
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index ba41828be34..e89e5f32d64 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.63 2003/05/06 00:20:31 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.64 2003/05/06 20:26:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -245,7 +245,7 @@ postquel_start(execution_state *es, SQLFunctionCachePtr fcache)
{
Assert(es->qd == NULL);
es->qd = CreateQueryDesc(es->query, es->plan,
- None, NULL,
+ None_Receiver, NULL,
fcache->paramLI, false);
/* Utility commands don't need Executor. */
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 74299ddf3ea..c3b3ec3530a 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.95 2003/05/06 00:20:31 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.96 2003/05/06 20:26:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -38,7 +38,7 @@ static int _SPI_execute_plan(_SPI_plan *plan,
Datum *Values, const char *Nulls, int tcount);
static void _SPI_cursor_operation(Portal portal, bool forward, int count,
- CommandDest dest);
+ DestReceiver *dest);
static _SPI_plan *_SPI_copy_plan(_SPI_plan *plan, int location);
@@ -841,7 +841,8 @@ SPI_cursor_find(const char *name)
void
SPI_cursor_fetch(Portal portal, bool forward, int count)
{
- _SPI_cursor_operation(portal, forward, count, SPI);
+ _SPI_cursor_operation(portal, forward, count, CreateDestReceiver(SPI));
+ /* we know that the SPI receiver doesn't need a destroy call */
}
@@ -853,7 +854,7 @@ SPI_cursor_fetch(Portal portal, bool forward, int count)
void
SPI_cursor_move(Portal portal, bool forward, int count)
{
- _SPI_cursor_operation(portal, forward, count, None);
+ _SPI_cursor_operation(portal, forward, count, None_Receiver);
}
@@ -874,13 +875,13 @@ SPI_cursor_close(Portal portal)
/* =================== private functions =================== */
/*
- * spi_dest_setup
+ * spi_dest_startup
* Initialize to receive tuples from Executor into SPITupleTable
* of current SPI procedure
*/
void
-spi_dest_setup(DestReceiver *self, int operation,
- const char *portalName, TupleDesc typeinfo, List *targetlist)
+spi_dest_startup(DestReceiver *self, int operation,
+ const char *portalName, TupleDesc typeinfo, List *targetlist)
{
SPITupleTable *tuptable;
MemoryContext oldcxt;
@@ -891,12 +892,12 @@ spi_dest_setup(DestReceiver *self, int operation,
* _SPI_connected
*/
if (_SPI_curid != _SPI_connected || _SPI_connected < 0)
- elog(FATAL, "SPI: improper call to spi_dest_setup");
+ elog(FATAL, "SPI: improper call to spi_dest_startup");
if (_SPI_current != &(_SPI_stack[_SPI_curid]))
- elog(FATAL, "SPI: stack corrupted in spi_dest_setup");
+ elog(FATAL, "SPI: stack corrupted in spi_dest_startup");
if (_SPI_current->tuptable != NULL)
- elog(FATAL, "SPI: improper call to spi_dest_setup");
+ elog(FATAL, "SPI: improper call to spi_dest_startup");
oldcxt = _SPI_procmem(); /* switch to procedure memory context */
@@ -1029,10 +1030,12 @@ _SPI_execute(const char *src, int tcount, _SPI_plan *plan)
Query *queryTree = (Query *) lfirst(query_list_item);
Plan *planTree;
QueryDesc *qdesc;
+ DestReceiver *dest;
planTree = pg_plan_query(queryTree);
plan_list = lappend(plan_list, planTree);
+ dest = CreateDestReceiver(queryTree->canSetTag ? SPI : None);
if (queryTree->commandType == CMD_UTILITY)
{
if (IsA(queryTree->utilityStmt, CopyStmt))
@@ -1051,14 +1054,13 @@ _SPI_execute(const char *src, int tcount, _SPI_plan *plan)
res = SPI_OK_UTILITY;
if (plan == NULL)
{
- ProcessUtility(queryTree->utilityStmt, None, NULL);
+ ProcessUtility(queryTree->utilityStmt, dest, NULL);
CommandCounterIncrement();
}
}
else if (plan == NULL)
{
- qdesc = CreateQueryDesc(queryTree, planTree,
- queryTree->canSetTag ? SPI : None,
+ qdesc = CreateQueryDesc(queryTree, planTree, dest,
NULL, NULL, false);
res = _SPI_pquery(qdesc, true,
queryTree->canSetTag ? tcount : 0);
@@ -1068,8 +1070,7 @@ _SPI_execute(const char *src, int tcount, _SPI_plan *plan)
}
else
{
- qdesc = CreateQueryDesc(queryTree, planTree,
- queryTree->canSetTag ? SPI : None,
+ qdesc = CreateQueryDesc(queryTree, planTree, dest,
NULL, NULL, false);
res = _SPI_pquery(qdesc, false, 0);
if (res < 0)
@@ -1144,20 +1145,21 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
Query *queryTree = (Query *) lfirst(query_list_item);
Plan *planTree;
QueryDesc *qdesc;
+ DestReceiver *dest;
planTree = lfirst(plan_list);
plan_list = lnext(plan_list);
+ dest = CreateDestReceiver(queryTree->canSetTag ? SPI : None);
if (queryTree->commandType == CMD_UTILITY)
{
- ProcessUtility(queryTree->utilityStmt, None, NULL);
+ ProcessUtility(queryTree->utilityStmt, dest, NULL);
res = SPI_OK_UTILITY;
CommandCounterIncrement();
}
else
{
- qdesc = CreateQueryDesc(queryTree, planTree,
- queryTree->canSetTag ? SPI : None,
+ qdesc = CreateQueryDesc(queryTree, planTree, dest,
NULL, paramLI, false);
res = _SPI_pquery(qdesc, true,
queryTree->canSetTag ? tcount : 0);
@@ -1185,7 +1187,7 @@ _SPI_pquery(QueryDesc *queryDesc, bool runit, int tcount)
if (queryDesc->parsetree->into != NULL) /* select into table */
{
res = SPI_OK_SELINTO;
- queryDesc->dest = None; /* don't output results anywhere */
+ queryDesc->dest = None_Receiver; /* don't output results */
}
break;
case CMD_INSERT:
@@ -1216,13 +1218,13 @@ _SPI_pquery(QueryDesc *queryDesc, bool runit, int tcount)
_SPI_current->processed = queryDesc->estate->es_processed;
save_lastoid = queryDesc->estate->es_lastoid;
- if (operation == CMD_SELECT && queryDesc->dest == SPI)
+ if (operation == CMD_SELECT && queryDesc->dest->mydest == SPI)
{
if (_SPI_checktuples())
elog(FATAL, "SPI_select: # of processed tuples check failed");
}
- if (queryDesc->dest == SPI)
+ if (queryDesc->dest->mydest == SPI)
{
SPI_processed = _SPI_current->processed;
SPI_lastoid = save_lastoid;
@@ -1253,7 +1255,7 @@ _SPI_pquery(QueryDesc *queryDesc, bool runit, int tcount)
*/
static void
_SPI_cursor_operation(Portal portal, bool forward, int count,
- CommandDest dest)
+ DestReceiver *dest)
{
/* Check that the portal is valid */
if (!PortalIsValid(portal))
@@ -1275,7 +1277,7 @@ _SPI_cursor_operation(Portal portal, bool forward, int count,
(long) count,
dest);
- if (dest == SPI && _SPI_checktuples())
+ if (dest->mydest == SPI && _SPI_checktuples())
elog(FATAL, "SPI_fetch: # of processed tuples check failed");
/* Put the result into place for access by caller */
@@ -1343,7 +1345,7 @@ _SPI_checktuples(void)
SPITupleTable *tuptable = _SPI_current->tuptable;
bool failed = false;
- if (tuptable == NULL) /* spi_dest_setup was not called */
+ if (tuptable == NULL) /* spi_dest_startup was not called */
failed = true;
else if (processed != (tuptable->alloced - tuptable->free))
failed = true;
diff --git a/src/backend/executor/tstoreReceiver.c b/src/backend/executor/tstoreReceiver.c
index 05b0c1f2397..bcab8154a32 100644
--- a/src/backend/executor/tstoreReceiver.c
+++ b/src/backend/executor/tstoreReceiver.c
@@ -1,6 +1,6 @@
/*-------------------------------------------------------------------------
*
- * tstore_receiver.c
+ * tstoreReceiver.c
* an implementation of DestReceiver that stores the result tuples in
* a Tuplestore
*
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/tstoreReceiver.c,v 1.4 2003/05/06 00:20:31 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/tstoreReceiver.c,v 1.5 2003/05/06 20:26:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,8 +17,7 @@
#include "postgres.h"
#include "executor/tstoreReceiver.h"
-#include "utils/memutils.h"
-#include "utils/portal.h"
+
typedef struct
{
@@ -30,32 +29,13 @@ typedef struct
/*
* Prepare to receive tuples from executor.
- *
- * XXX: As currently implemented, this routine is a hack: there should
- * be no tie between this code and the portal system. Instead, the
- * receiver function that is part of DestFunction should be passed a
- * QueryDesc, so that the call site of ExecutorRun can "sub-class"
- * QueryDesc and pass in any necessary addition information (in this
- * case, the Tuplestore to use).
*/
static void
-tstoreSetupReceiver(DestReceiver *self, int operation,
- const char *portalname,
- TupleDesc typeinfo, List *targetlist)
+tstoreStartupReceiver(DestReceiver *self, int operation,
+ const char *portalname,
+ TupleDesc typeinfo, List *targetlist)
{
- TStoreState *myState = (TStoreState *) self;
-
- /* Should only be called within a suitably-prepped portal */
- if (CurrentPortal == NULL ||
- CurrentPortal->holdStore == NULL)
- elog(ERROR, "Tuplestore destination used in wrong context");
-
- /* Debug check: make sure portal's result tuple desc is correct */
- Assert(CurrentPortal->tupDesc != NULL);
- Assert(equalTupleDescs(CurrentPortal->tupDesc, typeinfo));
-
- myState->tstore = CurrentPortal->holdStore;
- myState->cxt = CurrentPortal->holdContext;
+ /* do nothing */
}
/*
@@ -73,28 +53,40 @@ tstoreReceiveTuple(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
}
/*
- * Clean up
+ * Clean up at end of an executor run
*/
static void
-tstoreCleanupReceiver(DestReceiver *self)
+tstoreShutdownReceiver(DestReceiver *self)
{
/* do nothing */
}
/*
+ * Destroy receiver when done with it
+ */
+static void
+tstoreDestroyReceiver(DestReceiver *self)
+{
+ pfree(self);
+}
+
+/*
* Initially create a DestReceiver object.
*/
DestReceiver *
-tstoreReceiverCreateDR(void)
+CreateTuplestoreDestReceiver(Tuplestorestate *tStore,
+ MemoryContext tContext)
{
TStoreState *self = (TStoreState *) palloc(sizeof(TStoreState));
self->pub.receiveTuple = tstoreReceiveTuple;
- self->pub.setup = tstoreSetupReceiver;
- self->pub.cleanup = tstoreCleanupReceiver;
+ self->pub.startup = tstoreStartupReceiver;
+ self->pub.shutdown = tstoreShutdownReceiver;
+ self->pub.destroy = tstoreDestroyReceiver;
+ self->pub.mydest = Tuplestore;
- self->tstore = NULL;
- self->cxt = NULL;
+ self->tstore = tStore;
+ self->cxt = tContext;
return (DestReceiver *) self;
}