aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/spi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/spi.c')
-rw-r--r--src/backend/executor/spi.c1537
1 files changed, 775 insertions, 762 deletions
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 74ace81171a..1d05a752d24 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -1,7 +1,7 @@
/*-------------------------------------------------------------------------
*
* spi.c--
- * Server Programming Interface
+ * Server Programming Interface
*
*-------------------------------------------------------------------------
*/
@@ -9,440 +9,447 @@
#include "access/printtup.h"
#include "fmgr.h"
-typedef struct {
- QueryTreeList *qtlist; /* malloced */
- uint32 processed; /* by Executor */
- SPITupleTable *tuptable;
- Portal portal; /* portal per procedure */
- MemoryContext savedcxt;
- CommandId savedId;
-} _SPI_connection;
-
-static Portal _SPI_portal = (Portal) NULL;
+typedef struct
+{
+ QueryTreeList *qtlist; /* malloced */
+ uint32 processed; /* by Executor */
+ SPITupleTable *tuptable;
+ Portal portal; /* portal per procedure */
+ MemoryContext savedcxt;
+ CommandId savedId;
+} _SPI_connection;
+
+static Portal _SPI_portal = (Portal) NULL;
static _SPI_connection *_SPI_stack = NULL;
static _SPI_connection *_SPI_current = NULL;
-static int _SPI_connected = -1;
-static int _SPI_curid = -1;
+static int _SPI_connected = -1;
+static int _SPI_curid = -1;
+
+uint32 SPI_processed = 0;
+SPITupleTable *SPI_tuptable;
+int SPI_result;
-uint32 SPI_processed = 0;
-SPITupleTable *SPI_tuptable;
-int SPI_result;
+void spi_printtup(HeapTuple tuple, TupleDesc tupdesc);
-void spi_printtup (HeapTuple tuple, TupleDesc tupdesc);
+typedef struct
+{
+ QueryTreeList *qtlist;
+ List *ptlist;
+ int nargs;
+ Oid *argtypes;
+} _SPI_plan;
-typedef struct {
- QueryTreeList *qtlist;
- List *ptlist;
- int nargs;
- Oid *argtypes;
-} _SPI_plan;
+static int _SPI_execute(char *src, int tcount, _SPI_plan * plan);
+static int _SPI_pquery(QueryDesc * queryDesc, EState * state, int tcount);
-static int _SPI_execute (char *src, int tcount, _SPI_plan *plan);
-static int _SPI_pquery (QueryDesc *queryDesc, EState *state, int tcount);
#if 0
-static void _SPI_fetch (FetchStmt *stmt);
+static void _SPI_fetch(FetchStmt * stmt);
+
#endif
-static int _SPI_execute_plan (_SPI_plan *plan,
- char **Values, char *Nulls, int tcount);
+static int
+_SPI_execute_plan(_SPI_plan * plan,
+ char **Values, char *Nulls, int tcount);
-static _SPI_plan *_SPI_copy_plan (_SPI_plan *plan, bool local);
+static _SPI_plan *_SPI_copy_plan(_SPI_plan * plan, bool local);
-static int _SPI_begin_call (bool execmem);
-static int _SPI_end_call (bool procmem);
-static MemoryContext _SPI_execmem (void);
-static MemoryContext _SPI_procmem (void);
-static bool _SPI_checktuples (bool isRetrieveIntoRelation);
+static int _SPI_begin_call(bool execmem);
+static int _SPI_end_call(bool procmem);
+static MemoryContext _SPI_execmem(void);
+static MemoryContext _SPI_procmem(void);
+static bool _SPI_checktuples(bool isRetrieveIntoRelation);
#ifdef SPI_EXECUTOR_STATS
-extern int ShowExecutorStats;
-extern void ResetUsage (void);
-extern void ShowUsage (void);
+extern int ShowExecutorStats;
+extern void ResetUsage(void);
+extern void ShowUsage(void);
+
#endif
int
-SPI_connect ()
+SPI_connect()
{
- char pname[64];
- PortalVariableMemory pvmem;
-
- /*
- * It's possible on startup and after commit/abort.
- * In future we'll catch commit/abort in some way...
- */
- strcpy (pname, "<SPI manager>");
- _SPI_portal = GetPortalByName (pname);
- if ( !PortalIsValid (_SPI_portal) )
- {
- if ( _SPI_stack != NULL ) /* there was abort */
- free (_SPI_stack);
- _SPI_current = _SPI_stack = NULL;
- _SPI_connected = _SPI_curid = -1;
- SPI_processed = 0;
- SPI_tuptable = NULL;
- _SPI_portal = CreatePortal (pname);
- if ( !PortalIsValid (_SPI_portal) )
- elog (FATAL, "SPI_connect: global initialization failed");
- }
-
- /*
- * When procedure called by Executor _SPI_curid expected to be
- * equal to _SPI_connected
- */
- if ( _SPI_curid != _SPI_connected )
- return (SPI_ERROR_CONNECT);
-
- if ( _SPI_stack == NULL )
- {
- if ( _SPI_connected != -1 )
- elog (FATAL, "SPI_connect: no connection(s) expected");
- _SPI_stack = (_SPI_connection *) malloc (sizeof (_SPI_connection));
- }
- else
- {
- if ( _SPI_connected <= -1 )
- elog (FATAL, "SPI_connect: some connection(s) expected");
- _SPI_stack = (_SPI_connection *) realloc (_SPI_stack,
- (_SPI_connected + 1) * sizeof (_SPI_connection));
- }
- /*
- * We' returning to procedure where _SPI_curid == _SPI_connected - 1
- */
- _SPI_connected++;
-
- _SPI_current = &(_SPI_stack[_SPI_connected]);
- _SPI_current->qtlist = NULL;
- _SPI_current->processed = 0;
- _SPI_current->tuptable = NULL;
-
- /* Create Portal for this procedure ... */
- sprintf (pname, "<SPI %d>", _SPI_connected);
- _SPI_current->portal = CreatePortal (pname);
- if ( !PortalIsValid (_SPI_current->portal) )
- elog (FATAL, "SPI_connect: initialization failed");
-
- /* ... and switch to Portal' Variable memory - procedure' context */
- pvmem = PortalGetVariableMemory (_SPI_current->portal);
- _SPI_current->savedcxt = MemoryContextSwitchTo ((MemoryContext)pvmem);
-
- _SPI_current->savedId = GetScanCommandId ();
- SetScanCommandId (GetCurrentCommandId ());
-
- return (SPI_OK_CONNECT);
-
+ char pname[64];
+ PortalVariableMemory pvmem;
+
+ /*
+ * It's possible on startup and after commit/abort. In future we'll
+ * catch commit/abort in some way...
+ */
+ strcpy(pname, "<SPI manager>");
+ _SPI_portal = GetPortalByName(pname);
+ if (!PortalIsValid(_SPI_portal))
+ {
+ if (_SPI_stack != NULL) /* there was abort */
+ free(_SPI_stack);
+ _SPI_current = _SPI_stack = NULL;
+ _SPI_connected = _SPI_curid = -1;
+ SPI_processed = 0;
+ SPI_tuptable = NULL;
+ _SPI_portal = CreatePortal(pname);
+ if (!PortalIsValid(_SPI_portal))
+ elog(FATAL, "SPI_connect: global initialization failed");
+ }
+
+ /*
+ * When procedure called by Executor _SPI_curid expected to be equal
+ * to _SPI_connected
+ */
+ if (_SPI_curid != _SPI_connected)
+ return (SPI_ERROR_CONNECT);
+
+ if (_SPI_stack == NULL)
+ {
+ if (_SPI_connected != -1)
+ elog(FATAL, "SPI_connect: no connection(s) expected");
+ _SPI_stack = (_SPI_connection *) malloc(sizeof(_SPI_connection));
+ }
+ else
+ {
+ if (_SPI_connected <= -1)
+ elog(FATAL, "SPI_connect: some connection(s) expected");
+ _SPI_stack = (_SPI_connection *) realloc(_SPI_stack,
+ (_SPI_connected + 1) * sizeof(_SPI_connection));
+ }
+
+ /*
+ * We' returning to procedure where _SPI_curid == _SPI_connected - 1
+ */
+ _SPI_connected++;
+
+ _SPI_current = &(_SPI_stack[_SPI_connected]);
+ _SPI_current->qtlist = NULL;
+ _SPI_current->processed = 0;
+ _SPI_current->tuptable = NULL;
+
+ /* Create Portal for this procedure ... */
+ sprintf(pname, "<SPI %d>", _SPI_connected);
+ _SPI_current->portal = CreatePortal(pname);
+ if (!PortalIsValid(_SPI_current->portal))
+ elog(FATAL, "SPI_connect: initialization failed");
+
+ /* ... and switch to Portal' Variable memory - procedure' context */
+ pvmem = PortalGetVariableMemory(_SPI_current->portal);
+ _SPI_current->savedcxt = MemoryContextSwitchTo((MemoryContext) pvmem);
+
+ _SPI_current->savedId = GetScanCommandId();
+ SetScanCommandId(GetCurrentCommandId());
+
+ return (SPI_OK_CONNECT);
+
}
int
-SPI_finish ()
+SPI_finish()
{
- int res;
-
- res = _SPI_begin_call (false); /* live in procedure memory */
- if ( res < 0 )
- return (res);
-
- /* Restore memory context as it was before procedure call */
- MemoryContextSwitchTo (_SPI_current->savedcxt);
- PortalDestroy (&(_SPI_current->portal));
-
- SetScanCommandId (_SPI_current->savedId);
-
- /*
- * After _SPI_begin_call _SPI_connected == _SPI_curid.
- * Now we are closing connection to SPI and returning to upper
- * Executor and so _SPI_connected must be equal to _SPI_curid.
- */
- _SPI_connected--;
- _SPI_curid--;
- if ( _SPI_connected == -1 )
- {
- free (_SPI_stack);
- _SPI_stack = NULL;
- }
- else
- {
- _SPI_stack = (_SPI_connection *) realloc (_SPI_stack,
- (_SPI_connected + 1) * sizeof (_SPI_connection));
- _SPI_current = &(_SPI_stack[_SPI_connected]);
- }
-
- return (SPI_OK_FINISH);
-
+ int res;
+
+ res = _SPI_begin_call(false); /* live in procedure memory */
+ if (res < 0)
+ return (res);
+
+ /* Restore memory context as it was before procedure call */
+ MemoryContextSwitchTo(_SPI_current->savedcxt);
+ PortalDestroy(&(_SPI_current->portal));
+
+ SetScanCommandId(_SPI_current->savedId);
+
+ /*
+ * After _SPI_begin_call _SPI_connected == _SPI_curid. Now we are
+ * closing connection to SPI and returning to upper Executor and so
+ * _SPI_connected must be equal to _SPI_curid.
+ */
+ _SPI_connected--;
+ _SPI_curid--;
+ if (_SPI_connected == -1)
+ {
+ free(_SPI_stack);
+ _SPI_stack = NULL;
+ }
+ else
+ {
+ _SPI_stack = (_SPI_connection *) realloc(_SPI_stack,
+ (_SPI_connected + 1) * sizeof(_SPI_connection));
+ _SPI_current = &(_SPI_stack[_SPI_connected]);
+ }
+
+ return (SPI_OK_FINISH);
+
}
int
-SPI_exec (char *src, int tcount)
+SPI_exec(char *src, int tcount)
{
- int res;
-
- if ( src == NULL || tcount < 0 )
- return (SPI_ERROR_ARGUMENT);
-
- res = _SPI_begin_call (true);
- if ( res < 0 )
- return (res);
-
- res = _SPI_execute (src, tcount, NULL);
-
- _SPI_end_call (true);
- return (res);
+ int res;
+
+ if (src == NULL || tcount < 0)
+ return (SPI_ERROR_ARGUMENT);
+
+ res = _SPI_begin_call(true);
+ if (res < 0)
+ return (res);
+
+ res = _SPI_execute(src, tcount, NULL);
+
+ _SPI_end_call(true);
+ return (res);
}
-int
-SPI_execp (void *plan, char **Values, char *Nulls, int tcount)
+int
+SPI_execp(void *plan, char **Values, char *Nulls, int tcount)
{
- int res;
-
- if ( plan == NULL || tcount < 0 )
- return (SPI_ERROR_ARGUMENT);
-
- if ( ((_SPI_plan *)plan)->nargs > 0 &&
- ( Values == NULL || Nulls == NULL ) )
- return (SPI_ERROR_PARAM);
-
- res = _SPI_begin_call (true);
- if ( res < 0 )
- return (res);
-
- res = _SPI_execute_plan ((_SPI_plan *)plan, Values, Nulls, tcount);
-
- _SPI_end_call (true);
- return (res);
+ int res;
+
+ if (plan == NULL || tcount < 0)
+ return (SPI_ERROR_ARGUMENT);
+
+ if (((_SPI_plan *) plan)->nargs > 0 &&
+ (Values == NULL || Nulls == NULL))
+ return (SPI_ERROR_PARAM);
+
+ res = _SPI_begin_call(true);
+ if (res < 0)
+ return (res);
+
+ res = _SPI_execute_plan((_SPI_plan *) plan, Values, Nulls, tcount);
+
+ _SPI_end_call(true);
+ return (res);
}
-void *
-SPI_prepare (char *src, int nargs, Oid *argtypes)
+void *
+SPI_prepare(char *src, int nargs, Oid * argtypes)
{
- _SPI_plan *plan;
-
- if ( nargs < 0 || ( nargs > 0 && argtypes == NULL ) )
- {
- SPI_result = SPI_ERROR_ARGUMENT;
- return (NULL);
- }
-
- SPI_result = _SPI_begin_call (true);
- if ( SPI_result < 0 )
- return (NULL);
-
- plan = (_SPI_plan *) palloc (sizeof (_SPI_plan)); /* Executor context */
- plan->argtypes = argtypes;
- plan->nargs = nargs;
-
- SPI_result = _SPI_execute (src, 0, plan);
-
- if ( SPI_result >= 0 ) /* copy plan to local space */
- plan = _SPI_copy_plan (plan, true);
- else
- plan = NULL;
-
- _SPI_end_call (true);
-
- return ((void *)plan);
-
+ _SPI_plan *plan;
+
+ if (nargs < 0 || (nargs > 0 && argtypes == NULL))
+ {
+ SPI_result = SPI_ERROR_ARGUMENT;
+ return (NULL);
+ }
+
+ SPI_result = _SPI_begin_call(true);
+ if (SPI_result < 0)
+ return (NULL);
+
+ plan = (_SPI_plan *) palloc(sizeof(_SPI_plan)); /* Executor context */
+ plan->argtypes = argtypes;
+ plan->nargs = nargs;
+
+ SPI_result = _SPI_execute(src, 0, plan);
+
+ if (SPI_result >= 0) /* copy plan to local space */
+ plan = _SPI_copy_plan(plan, true);
+ else
+ plan = NULL;
+
+ _SPI_end_call(true);
+
+ return ((void *) plan);
+
}
-void *
-SPI_saveplan (void *plan)
+void *
+SPI_saveplan(void *plan)
{
- _SPI_plan *newplan;
-
- if ( plan == NULL )
- {
- SPI_result = SPI_ERROR_ARGUMENT;
- return (NULL);
- }
-
- SPI_result = _SPI_begin_call (false); /* don't change context */
- if ( SPI_result < 0 )
- return (NULL);
-
- newplan = _SPI_copy_plan ((_SPI_plan *)plan, false);
-
- _SPI_curid--;
- SPI_result = 0;
-
- return ((void *)newplan);
-
+ _SPI_plan *newplan;
+
+ if (plan == NULL)
+ {
+ SPI_result = SPI_ERROR_ARGUMENT;
+ return (NULL);
+ }
+
+ SPI_result = _SPI_begin_call(false); /* don't change context */
+ if (SPI_result < 0)
+ return (NULL);
+
+ newplan = _SPI_copy_plan((_SPI_plan *) plan, false);
+
+ _SPI_curid--;
+ SPI_result = 0;
+
+ return ((void *) newplan);
+
}
int
-SPI_fnumber (TupleDesc tupdesc, char *fname)
+SPI_fnumber(TupleDesc tupdesc, char *fname)
{
- int res;
-
- if ( _SPI_curid + 1 != _SPI_connected )
- return (SPI_ERROR_UNCONNECTED);
-
- for (res = 0; res < tupdesc->natts; res++)
- {
- if ( strcmp (tupdesc->attrs[res]->attname.data, fname) == 0 )
- return (res + 1);
- }
-
- return (SPI_ERROR_NOATTRIBUTE);
+ int res;
+
+ if (_SPI_curid + 1 != _SPI_connected)
+ return (SPI_ERROR_UNCONNECTED);
+
+ for (res = 0; res < tupdesc->natts; res++)
+ {
+ if (strcmp(tupdesc->attrs[res]->attname.data, fname) == 0)
+ return (res + 1);
+ }
+
+ return (SPI_ERROR_NOATTRIBUTE);
}
-char *
-SPI_getvalue (HeapTuple tuple, TupleDesc tupdesc, int fnumber)
+char *
+SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
{
- char *val;
- bool isnull;
- Oid foutoid;
-
- SPI_result = 0;
- if ( _SPI_curid + 1 != _SPI_connected )
- {
- SPI_result = SPI_ERROR_UNCONNECTED;
- return (NULL);
- }
-
- if ( tuple->t_natts < fnumber || fnumber <= 0 )
- return (NULL);
-
- val = heap_getattr (tuple, InvalidBuffer, fnumber, tupdesc, &isnull);
- if ( isnull )
- return (NULL);
- foutoid = typtoout ((Oid) tupdesc->attrs[fnumber - 1]->atttypid);
- if ( !OidIsValid (foutoid) )
- {
- SPI_result = SPI_ERROR_NOOUTFUNC;
- return (NULL);
- }
-
- return (fmgr (foutoid, val, gettypelem (tupdesc->attrs[fnumber - 1]->atttypid)));
+ char *val;
+ bool isnull;
+ Oid foutoid;
+
+ SPI_result = 0;
+ if (_SPI_curid + 1 != _SPI_connected)
+ {
+ SPI_result = SPI_ERROR_UNCONNECTED;
+ return (NULL);
+ }
+
+ if (tuple->t_natts < fnumber || fnumber <= 0)
+ return (NULL);
+
+ val = heap_getattr(tuple, InvalidBuffer, fnumber, tupdesc, &isnull);
+ if (isnull)
+ return (NULL);
+ foutoid = typtoout((Oid) tupdesc->attrs[fnumber - 1]->atttypid);
+ if (!OidIsValid(foutoid))
+ {
+ SPI_result = SPI_ERROR_NOOUTFUNC;
+ return (NULL);
+ }
+
+ return (fmgr(foutoid, val, gettypelem(tupdesc->attrs[fnumber - 1]->atttypid)));
}
-char *
-SPI_getbinval (HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
+char *
+SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool * isnull)
{
- char *val;
-
- *isnull = true;
- SPI_result = 0;
- if ( _SPI_curid + 1 != _SPI_connected )
- {
- SPI_result = SPI_ERROR_UNCONNECTED;
- return (NULL);
- }
-
- if ( tuple->t_natts < fnumber || fnumber <= 0 )
- return (NULL);
-
- val = heap_getattr (tuple, InvalidBuffer, fnumber, tupdesc, isnull);
-
- return (val);
+ char *val;
+
+ *isnull = true;
+ SPI_result = 0;
+ if (_SPI_curid + 1 != _SPI_connected)
+ {
+ SPI_result = SPI_ERROR_UNCONNECTED;
+ return (NULL);
+ }
+
+ if (tuple->t_natts < fnumber || fnumber <= 0)
+ return (NULL);
+
+ val = heap_getattr(tuple, InvalidBuffer, fnumber, tupdesc, isnull);
+
+ return (val);
}
-char *
-SPI_gettype (TupleDesc tupdesc, int fnumber)
+char *
+SPI_gettype(TupleDesc tupdesc, int fnumber)
{
- HeapTuple typeTuple;
-
- SPI_result = 0;
- if ( _SPI_curid + 1 != _SPI_connected )
- {
- SPI_result = SPI_ERROR_UNCONNECTED;
- return (NULL);
- }
-
- if ( tupdesc->natts < fnumber || fnumber <= 0 )
- {
- SPI_result = SPI_ERROR_NOATTRIBUTE;
- return (NULL);
- }
-
- typeTuple = SearchSysCacheTuple (TYPOID,
- ObjectIdGetDatum (tupdesc->attrs[fnumber - 1]->atttypid),
- 0, 0, 0);
-
- if ( !HeapTupleIsValid (typeTuple) )
- {
- SPI_result = SPI_ERROR_TYPUNKNOWN;
- return (NULL);
- }
-
- return (pstrdup (((TypeTupleForm) GETSTRUCT (typeTuple))->typname.data));
+ HeapTuple typeTuple;
+
+ SPI_result = 0;
+ if (_SPI_curid + 1 != _SPI_connected)
+ {
+ SPI_result = SPI_ERROR_UNCONNECTED;
+ return (NULL);
+ }
+
+ if (tupdesc->natts < fnumber || fnumber <= 0)
+ {
+ SPI_result = SPI_ERROR_NOATTRIBUTE;
+ return (NULL);
+ }
+
+ typeTuple = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(tupdesc->attrs[fnumber - 1]->atttypid),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(typeTuple))
+ {
+ SPI_result = SPI_ERROR_TYPUNKNOWN;
+ return (NULL);
+ }
+
+ return (pstrdup(((TypeTupleForm) GETSTRUCT(typeTuple))->typname.data));
}
Oid
-SPI_gettypeid (TupleDesc tupdesc, int fnumber)
+SPI_gettypeid(TupleDesc tupdesc, int fnumber)
{
-
- SPI_result = 0;
- if ( _SPI_curid + 1 != _SPI_connected )
- {
- SPI_result = SPI_ERROR_UNCONNECTED;
- return (InvalidOid);
- }
-
- if ( tupdesc->natts < fnumber || fnumber <= 0 )
- {
- SPI_result = SPI_ERROR_NOATTRIBUTE;
- return (InvalidOid);
- }
-
- return (tupdesc->attrs[fnumber - 1]->atttypid);
+
+ SPI_result = 0;
+ if (_SPI_curid + 1 != _SPI_connected)
+ {
+ SPI_result = SPI_ERROR_UNCONNECTED;
+ return (InvalidOid);
+ }
+
+ if (tupdesc->natts < fnumber || fnumber <= 0)
+ {
+ SPI_result = SPI_ERROR_NOATTRIBUTE;
+ return (InvalidOid);
+ }
+
+ return (tupdesc->attrs[fnumber - 1]->atttypid);
}
-char *
-SPI_getrelname (Relation rel)
+char *
+SPI_getrelname(Relation rel)
{
-
- SPI_result = 0;
- if ( _SPI_curid + 1 != _SPI_connected )
- {
- SPI_result = SPI_ERROR_UNCONNECTED;
- return (NULL);
- }
-
- return (pstrdup (rel->rd_rel->relname.data));
+
+ SPI_result = 0;
+ if (_SPI_curid + 1 != _SPI_connected)
+ {
+ SPI_result = SPI_ERROR_UNCONNECTED;
+ return (NULL);
+ }
+
+ return (pstrdup(rel->rd_rel->relname.data));
}
/*
* spi_printtup --
- * store tuple retrieved by Executor into SPITupleTable
- * of current SPI procedure
+ * store tuple retrieved by Executor into SPITupleTable
+ * of current SPI procedure
*
*/
void
-spi_printtup (HeapTuple tuple, TupleDesc tupdesc)
+spi_printtup(HeapTuple tuple, TupleDesc tupdesc)
{
- SPITupleTable *tuptable;
- MemoryContext oldcxt;
-
- /*
- * When called by Executor _SPI_curid expected to be
- * equal to _SPI_connected
- */
- if ( _SPI_curid != _SPI_connected || _SPI_connected < 0 )
- elog (FATAL, "SPI: improper call to spi_printtup");
- if ( _SPI_current != &(_SPI_stack[_SPI_curid]) )
- elog (FATAL, "SPI: stack corrupted in spi_printtup");
-
- oldcxt = _SPI_procmem (); /* switch to procedure memory context */
-
- tuptable = _SPI_current->tuptable;
- if ( tuptable == NULL )
- {
- _SPI_current->tuptable = tuptable = (SPITupleTable *)
- palloc (sizeof (SPITupleTable));
- tuptable->alloced = tuptable->free = 128;
- tuptable->vals = (HeapTuple *) palloc (tuptable->alloced * sizeof (HeapTuple));
- tuptable->tupdesc = CreateTupleDescCopy (tupdesc);
- }
- else if ( tuptable->free == 0 )
- {
- tuptable->free = 256;
- tuptable->alloced += tuptable->free;
- tuptable->vals = (HeapTuple *) repalloc (tuptable->vals,
- tuptable->alloced * sizeof (HeapTuple));
- }
-
- tuptable->vals[tuptable->alloced - tuptable->free] = heap_copytuple (tuple);
- (tuptable->free)--;
-
- MemoryContextSwitchTo (oldcxt);
- return;
+ SPITupleTable *tuptable;
+ MemoryContext oldcxt;
+
+ /*
+ * When called by Executor _SPI_curid expected to be equal to
+ * _SPI_connected
+ */
+ if (_SPI_curid != _SPI_connected || _SPI_connected < 0)
+ elog(FATAL, "SPI: improper call to spi_printtup");
+ if (_SPI_current != &(_SPI_stack[_SPI_curid]))
+ elog(FATAL, "SPI: stack corrupted in spi_printtup");
+
+ oldcxt = _SPI_procmem(); /* switch to procedure memory context */
+
+ tuptable = _SPI_current->tuptable;
+ if (tuptable == NULL)
+ {
+ _SPI_current->tuptable = tuptable = (SPITupleTable *)
+ palloc(sizeof(SPITupleTable));
+ tuptable->alloced = tuptable->free = 128;
+ tuptable->vals = (HeapTuple *) palloc(tuptable->alloced * sizeof(HeapTuple));
+ tuptable->tupdesc = CreateTupleDescCopy(tupdesc);
+ }
+ else if (tuptable->free == 0)
+ {
+ tuptable->free = 256;
+ tuptable->alloced += tuptable->free;
+ tuptable->vals = (HeapTuple *) repalloc(tuptable->vals,
+ tuptable->alloced * sizeof(HeapTuple));
+ }
+
+ tuptable->vals[tuptable->alloced - tuptable->free] = heap_copytuple(tuple);
+ (tuptable->free)--;
+
+ MemoryContextSwitchTo(oldcxt);
+ return;
}
/*
@@ -450,330 +457,334 @@ spi_printtup (HeapTuple tuple, TupleDesc tupdesc)
*/
static int
-_SPI_execute (char *src, int tcount, _SPI_plan *plan)
+_SPI_execute(char *src, int tcount, _SPI_plan * plan)
{
- QueryTreeList *queryTree_list;
- List *planTree_list;
- List *ptlist;
- QueryDesc *qdesc;
- Query *queryTree;
- Plan *planTree;
- EState *state;
- int qlen;
- int nargs = 0;
- Oid *argtypes = NULL;
- int res;
- int i;
-
- /* Increment CommandCounter to see changes made by now */
- CommandCounterIncrement ();
-
- SPI_processed = 0;
- SPI_tuptable = NULL;
- _SPI_current->tuptable = NULL;
- _SPI_current->qtlist = NULL;
-
- if ( plan )
- {
- nargs = plan->nargs;
- argtypes = plan->argtypes;
- }
- ptlist = planTree_list = (List *)
- pg_plan (src, argtypes, nargs, &queryTree_list, None);
-
- _SPI_current->qtlist = queryTree_list;
-
- qlen = queryTree_list->len;
- for (i=0; ;i++)
- {
- queryTree = (Query*) (queryTree_list->qtrees[i]);
- planTree = lfirst(planTree_list);
-
- planTree_list = lnext (planTree_list);
-
- if ( queryTree->commandType == CMD_UTILITY )
- {
- if ( nodeTag (queryTree->utilityStmt ) == T_CopyStmt )
- {
- CopyStmt *stmt = (CopyStmt *)(queryTree->utilityStmt);
-
- if ( stmt->filename == NULL )
- return (SPI_ERROR_COPY);
- }
- else if ( nodeTag (queryTree->utilityStmt ) == T_ClosePortalStmt ||
- nodeTag (queryTree->utilityStmt ) == T_FetchStmt )
- return (SPI_ERROR_CURSOR);
- else if ( nodeTag (queryTree->utilityStmt ) == T_TransactionStmt )
- return (SPI_ERROR_TRANSACTION);
- res = SPI_OK_UTILITY;
- if ( plan == NULL )
- {
- ProcessUtility (queryTree->utilityStmt, None);
- if ( i < qlen - 1 )
- CommandCounterIncrement ();
- else
- return (res);
- }
- else if ( i >= qlen - 1 )
- break;
- }
- else if ( plan == NULL )
- {
- qdesc = CreateQueryDesc (queryTree, planTree,
- ( i < qlen - 1 ) ? None : SPI);
- state = CreateExecutorState();
- res = _SPI_pquery (qdesc, state, ( i < qlen - 1 ) ? 0 : tcount);
- if ( res < 0 || i >= qlen - 1 )
- return (res);
- CommandCounterIncrement ();
+ QueryTreeList *queryTree_list;
+ List *planTree_list;
+ List *ptlist;
+ QueryDesc *qdesc;
+ Query *queryTree;
+ Plan *planTree;
+ EState *state;
+ int qlen;
+ int nargs = 0;
+ Oid *argtypes = NULL;
+ int res;
+ int i;
+
+ /* Increment CommandCounter to see changes made by now */
+ CommandCounterIncrement();
+
+ SPI_processed = 0;
+ SPI_tuptable = NULL;
+ _SPI_current->tuptable = NULL;
+ _SPI_current->qtlist = NULL;
+
+ if (plan)
+ {
+ nargs = plan->nargs;
+ argtypes = plan->argtypes;
}
- else
+ ptlist = planTree_list = (List *)
+ pg_plan(src, argtypes, nargs, &queryTree_list, None);
+
+ _SPI_current->qtlist = queryTree_list;
+
+ qlen = queryTree_list->len;
+ for (i = 0;; i++)
{
- qdesc = CreateQueryDesc (queryTree, planTree,
- ( i < qlen - 1 ) ? None : SPI);
- res = _SPI_pquery (qdesc, NULL, ( i < qlen - 1 ) ? 0 : tcount);
- if ( res < 0 )
- return (res);
- if ( i >= qlen - 1 )
- break;
- }
- }
-
- plan->qtlist = queryTree_list;
- plan->ptlist = ptlist;
-
- return (res);
-
+ queryTree = (Query *) (queryTree_list->qtrees[i]);
+ planTree = lfirst(planTree_list);
+
+ planTree_list = lnext(planTree_list);
+
+ if (queryTree->commandType == CMD_UTILITY)
+ {
+ if (nodeTag(queryTree->utilityStmt) == T_CopyStmt)
+ {
+ CopyStmt *stmt = (CopyStmt *) (queryTree->utilityStmt);
+
+ if (stmt->filename == NULL)
+ return (SPI_ERROR_COPY);
+ }
+ else if (nodeTag(queryTree->utilityStmt) == T_ClosePortalStmt ||
+ nodeTag(queryTree->utilityStmt) == T_FetchStmt)
+ return (SPI_ERROR_CURSOR);
+ else if (nodeTag(queryTree->utilityStmt) == T_TransactionStmt)
+ return (SPI_ERROR_TRANSACTION);
+ res = SPI_OK_UTILITY;
+ if (plan == NULL)
+ {
+ ProcessUtility(queryTree->utilityStmt, None);
+ if (i < qlen - 1)
+ CommandCounterIncrement();
+ else
+ return (res);
+ }
+ else if (i >= qlen - 1)
+ break;
+ }
+ else if (plan == NULL)
+ {
+ qdesc = CreateQueryDesc(queryTree, planTree,
+ (i < qlen - 1) ? None : SPI);
+ state = CreateExecutorState();
+ res = _SPI_pquery(qdesc, state, (i < qlen - 1) ? 0 : tcount);
+ if (res < 0 || i >= qlen - 1)
+ return (res);
+ CommandCounterIncrement();
+ }
+ else
+ {
+ qdesc = CreateQueryDesc(queryTree, planTree,
+ (i < qlen - 1) ? None : SPI);
+ res = _SPI_pquery(qdesc, NULL, (i < qlen - 1) ? 0 : tcount);
+ if (res < 0)
+ return (res);
+ if (i >= qlen - 1)
+ break;
+ }
+ }
+
+ plan->qtlist = queryTree_list;
+ plan->ptlist = ptlist;
+
+ return (res);
+
}
static int
-_SPI_execute_plan (_SPI_plan *plan, char **Values, char *Nulls, int tcount)
+_SPI_execute_plan(_SPI_plan * plan, char **Values, char *Nulls, int tcount)
{
- QueryTreeList *queryTree_list = plan->qtlist;
- List *planTree_list = plan->ptlist;
- QueryDesc *qdesc;
- Query *queryTree;
- Plan *planTree;
- EState *state;
- int nargs = plan->nargs;
- int qlen = queryTree_list->len;
- int res;
- int i, k;
-
- /* Increment CommandCounter to see changes made by now */
- CommandCounterIncrement ();
-
- SPI_processed = 0;
- SPI_tuptable = NULL;
- _SPI_current->tuptable = NULL;
- _SPI_current->qtlist = NULL;
-
- for (i=0; ;i++)
- {
- queryTree = (Query*) (queryTree_list->qtrees[i]);
- planTree = lfirst(planTree_list);
-
- planTree_list = lnext (planTree_list);
-
- if ( queryTree->commandType == CMD_UTILITY )
- {
- ProcessUtility (queryTree->utilityStmt, None);
- if ( i < qlen - 1 )
- CommandCounterIncrement ();
- else
- return (SPI_OK_UTILITY);
- }
- else
+ QueryTreeList *queryTree_list = plan->qtlist;
+ List *planTree_list = plan->ptlist;
+ QueryDesc *qdesc;
+ Query *queryTree;
+ Plan *planTree;
+ EState *state;
+ int nargs = plan->nargs;
+ int qlen = queryTree_list->len;
+ int res;
+ int i,
+ k;
+
+ /* Increment CommandCounter to see changes made by now */
+ CommandCounterIncrement();
+
+ SPI_processed = 0;
+ SPI_tuptable = NULL;
+ _SPI_current->tuptable = NULL;
+ _SPI_current->qtlist = NULL;
+
+ for (i = 0;; i++)
{
- qdesc = CreateQueryDesc (queryTree, planTree,
- ( i < qlen - 1 ) ? None : SPI);
- state = CreateExecutorState();
- if ( nargs > 0 )
- {
- ParamListInfo paramLI = (ParamListInfo) palloc ((nargs + 1) *
- sizeof (ParamListInfoData));
- state->es_param_list_info = paramLI;
- for (k = 0; k < plan->nargs; paramLI++, k++)
- {
- paramLI->kind = PARAM_NUM;
- paramLI->id = k+1;
- paramLI->isnull = (Nulls[k] != 0);
- paramLI->value = (Datum) Values[k];
- }
- paramLI->kind = PARAM_INVALID;
- }
- else
- state->es_param_list_info = NULL;
- res = _SPI_pquery (qdesc, state, ( i < qlen - 1 ) ? 0 : tcount);
- if ( res < 0 || i >= qlen - 1 )
- return (res);
- CommandCounterIncrement ();
- }
- }
-
- return (res);
-
+ queryTree = (Query *) (queryTree_list->qtrees[i]);
+ planTree = lfirst(planTree_list);
+
+ planTree_list = lnext(planTree_list);
+
+ if (queryTree->commandType == CMD_UTILITY)
+ {
+ ProcessUtility(queryTree->utilityStmt, None);
+ if (i < qlen - 1)
+ CommandCounterIncrement();
+ else
+ return (SPI_OK_UTILITY);
+ }
+ else
+ {
+ qdesc = CreateQueryDesc(queryTree, planTree,
+ (i < qlen - 1) ? None : SPI);
+ state = CreateExecutorState();
+ if (nargs > 0)
+ {
+ ParamListInfo paramLI = (ParamListInfo) palloc((nargs + 1) *
+ sizeof(ParamListInfoData));
+
+ state->es_param_list_info = paramLI;
+ for (k = 0; k < plan->nargs; paramLI++, k++)
+ {
+ paramLI->kind = PARAM_NUM;
+ paramLI->id = k + 1;
+ paramLI->isnull = (Nulls[k] != 0);
+ paramLI->value = (Datum) Values[k];
+ }
+ paramLI->kind = PARAM_INVALID;
+ }
+ else
+ state->es_param_list_info = NULL;
+ res = _SPI_pquery(qdesc, state, (i < qlen - 1) ? 0 : tcount);
+ if (res < 0 || i >= qlen - 1)
+ return (res);
+ CommandCounterIncrement();
+ }
+ }
+
+ return (res);
+
}
static int
-_SPI_pquery (QueryDesc *queryDesc, EState *state, int tcount)
+_SPI_pquery(QueryDesc * queryDesc, EState * state, int tcount)
{
- Query *parseTree;
- Plan *plan;
- int operation;
- TupleDesc tupdesc;
- bool isRetrieveIntoPortal = false;
- bool isRetrieveIntoRelation = false;
- char* intoName = NULL;
- int res;
-
- parseTree = queryDesc->parsetree;
- plan = queryDesc->plantree;
- operation = queryDesc->operation;
-
- switch (operation)
- {
- case CMD_SELECT:
- res = SPI_OK_SELECT;
- if (parseTree->isPortal)
- {
- isRetrieveIntoPortal = true;
- intoName = parseTree->into;
- parseTree->isBinary = false; /* */
-
- return (SPI_ERROR_CURSOR);
-
- }
- else if (parseTree->into != NULL) /* select into table */
- {
- res = SPI_OK_SELINTO;
- isRetrieveIntoRelation = true;
- }
- break;
- case CMD_INSERT:
- res = SPI_OK_INSERT;
- break;
- case CMD_DELETE:
- res = SPI_OK_DELETE;
- break;
- case CMD_UPDATE:
- res = SPI_OK_UPDATE;
- break;
- default:
- return (SPI_ERROR_OPUNKNOWN);
- }
-
- if ( state == NULL ) /* plan preparation */
- return (res);
+ Query *parseTree;
+ Plan *plan;
+ int operation;
+ TupleDesc tupdesc;
+ bool isRetrieveIntoPortal = false;
+ bool isRetrieveIntoRelation = false;
+ char *intoName = NULL;
+ int res;
+
+ parseTree = queryDesc->parsetree;
+ plan = queryDesc->plantree;
+ operation = queryDesc->operation;
+
+ switch (operation)
+ {
+ case CMD_SELECT:
+ res = SPI_OK_SELECT;
+ if (parseTree->isPortal)
+ {
+ isRetrieveIntoPortal = true;
+ intoName = parseTree->into;
+ parseTree->isBinary = false; /* */
+
+ return (SPI_ERROR_CURSOR);
+
+ }
+ else if (parseTree->into != NULL) /* select into table */
+ {
+ res = SPI_OK_SELINTO;
+ isRetrieveIntoRelation = true;
+ }
+ break;
+ case CMD_INSERT:
+ res = SPI_OK_INSERT;
+ break;
+ case CMD_DELETE:
+ res = SPI_OK_DELETE;
+ break;
+ case CMD_UPDATE:
+ res = SPI_OK_UPDATE;
+ break;
+ default:
+ return (SPI_ERROR_OPUNKNOWN);
+ }
+
+ if (state == NULL) /* plan preparation */
+ return (res);
#ifdef SPI_EXECUTOR_STATS
- if ( ShowExecutorStats )
- ResetUsage ();
+ if (ShowExecutorStats)
+ ResetUsage();
#endif
- tupdesc = ExecutorStart (queryDesc, state);
-
- /* Don't work currently */
- if (isRetrieveIntoPortal)
- {
- ProcessPortal(intoName,
- parseTree,
- plan,
- state,
- tupdesc,
- None);
- return (SPI_OK_CURSOR);
- }
-
- ExecutorRun (queryDesc, state, EXEC_RUN, tcount);
-
- _SPI_current->processed = state->es_processed;
- if ( operation == CMD_SELECT && queryDesc->dest == SPI )
- {
- if ( _SPI_checktuples (isRetrieveIntoRelation) )
- elog (FATAL, "SPI_select: # of processed tuples check failed");
- }
-
- ExecutorEnd (queryDesc, state);
-
+ tupdesc = ExecutorStart(queryDesc, state);
+
+ /* Don't work currently */
+ if (isRetrieveIntoPortal)
+ {
+ ProcessPortal(intoName,
+ parseTree,
+ plan,
+ state,
+ tupdesc,
+ None);
+ return (SPI_OK_CURSOR);
+ }
+
+ ExecutorRun(queryDesc, state, EXEC_RUN, tcount);
+
+ _SPI_current->processed = state->es_processed;
+ if (operation == CMD_SELECT && queryDesc->dest == SPI)
+ {
+ if (_SPI_checktuples(isRetrieveIntoRelation))
+ elog(FATAL, "SPI_select: # of processed tuples check failed");
+ }
+
+ ExecutorEnd(queryDesc, state);
+
#ifdef SPI_EXECUTOR_STATS
- if ( ShowExecutorStats )
- {
- fprintf (stderr, "! Executor Stats:\n");
- ShowUsage ();
- }
+ if (ShowExecutorStats)
+ {
+ fprintf(stderr, "! Executor Stats:\n");
+ ShowUsage();
+ }
#endif
-
- if ( queryDesc->dest == SPI )
- {
- SPI_processed = _SPI_current->processed;
- SPI_tuptable = _SPI_current->tuptable;
- }
-
- return (res);
+
+ if (queryDesc->dest == SPI)
+ {
+ SPI_processed = _SPI_current->processed;
+ SPI_tuptable = _SPI_current->tuptable;
+ }
+
+ return (res);
}
#if 0
static void
-_SPI_fetch (FetchStmt *stmt)
+_SPI_fetch(FetchStmt * stmt)
{
- char *name = stmt->portalname;
- int feature = ( stmt->direction == FORWARD ) ? EXEC_FOR : EXEC_BACK;
- int count = stmt->howMany;
- Portal portal;
- QueryDesc *queryDesc;
- EState *state;
- MemoryContext context;
-
- if ( name == NULL)
- elog (FATAL, "SPI_fetch from blank portal unsupported");
-
- portal = GetPortalByName (name);
- if ( !PortalIsValid (portal) )
- elog (FATAL, "SPI_fetch: portal \"%s\" not found", name);
-
- context = MemoryContextSwitchTo((MemoryContext)PortalGetHeapMemory(portal));
-
- queryDesc = PortalGetQueryDesc(portal);
- state = PortalGetState(portal);
-
- ExecutorRun(queryDesc, state, feature, count);
-
- MemoryContextSwitchTo (context); /* switch to the normal Executor context */
-
- _SPI_current->processed = state->es_processed;
- if ( _SPI_checktuples (false) )
- elog (FATAL, "SPI_fetch: # of processed tuples check failed");
-
- SPI_processed = _SPI_current->processed;
- SPI_tuptable = _SPI_current->tuptable;
-
+ char *name = stmt->portalname;
+ int feature = (stmt->direction == FORWARD) ? EXEC_FOR : EXEC_BACK;
+ int count = stmt->howMany;
+ Portal portal;
+ QueryDesc *queryDesc;
+ EState *state;
+ MemoryContext context;
+
+ if (name == NULL)
+ elog(FATAL, "SPI_fetch from blank portal unsupported");
+
+ portal = GetPortalByName(name);
+ if (!PortalIsValid(portal))
+ elog(FATAL, "SPI_fetch: portal \"%s\" not found", name);
+
+ context = MemoryContextSwitchTo((MemoryContext) PortalGetHeapMemory(portal));
+
+ queryDesc = PortalGetQueryDesc(portal);
+ state = PortalGetState(portal);
+
+ ExecutorRun(queryDesc, state, feature, count);
+
+ MemoryContextSwitchTo(context); /* switch to the normal Executor
+ * context */
+
+ _SPI_current->processed = state->es_processed;
+ if (_SPI_checktuples(false))
+ elog(FATAL, "SPI_fetch: # of processed tuples check failed");
+
+ SPI_processed = _SPI_current->processed;
+ SPI_tuptable = _SPI_current->tuptable;
+
}
+
#endif
-static MemoryContext
-_SPI_execmem ()
+static MemoryContext
+_SPI_execmem()
{
- MemoryContext oldcxt;
- PortalHeapMemory phmem;
-
- phmem = PortalGetHeapMemory (_SPI_current->portal);
- oldcxt = MemoryContextSwitchTo ((MemoryContext)phmem);
-
- return (oldcxt);
-
+ MemoryContext oldcxt;
+ PortalHeapMemory phmem;
+
+ phmem = PortalGetHeapMemory(_SPI_current->portal);
+ oldcxt = MemoryContextSwitchTo((MemoryContext) phmem);
+
+ return (oldcxt);
+
}
-static MemoryContext
-_SPI_procmem ()
+static MemoryContext
+_SPI_procmem()
{
- MemoryContext oldcxt;
- PortalVariableMemory pvmem;
-
- pvmem = PortalGetVariableMemory (_SPI_current->portal);
- oldcxt = MemoryContextSwitchTo ((MemoryContext)pvmem);
-
- return (oldcxt);
-
+ MemoryContext oldcxt;
+ PortalVariableMemory pvmem;
+
+ pvmem = PortalGetVariableMemory(_SPI_current->portal);
+ oldcxt = MemoryContextSwitchTo((MemoryContext) pvmem);
+
+ return (oldcxt);
+
}
/*
@@ -781,108 +792,110 @@ _SPI_procmem ()
*
*/
static int
-_SPI_begin_call (bool execmem)
+_SPI_begin_call(bool execmem)
{
- if ( _SPI_curid + 1 != _SPI_connected )
- return (SPI_ERROR_UNCONNECTED);
- _SPI_curid++;
- if ( _SPI_current != &(_SPI_stack[_SPI_curid]) )
- elog (FATAL, "SPI: stack corrupted");
-
- if ( execmem ) /* switch to the Executor memory context */
- {
- _SPI_execmem ();
- StartPortalAllocMode (DefaultAllocMode, 0);
- }
-
- return (0);
+ if (_SPI_curid + 1 != _SPI_connected)
+ return (SPI_ERROR_UNCONNECTED);
+ _SPI_curid++;
+ if (_SPI_current != &(_SPI_stack[_SPI_curid]))
+ elog(FATAL, "SPI: stack corrupted");
+
+ if (execmem) /* switch to the Executor memory context */
+ {
+ _SPI_execmem();
+ StartPortalAllocMode(DefaultAllocMode, 0);
+ }
+
+ return (0);
}
static int
-_SPI_end_call (bool procmem)
+_SPI_end_call(bool procmem)
{
- /*
- * We' returning to procedure where _SPI_curid == _SPI_connected - 1
- */
- _SPI_curid--;
-
- if ( _SPI_current->qtlist) /* free _SPI_plan allocations */
- {
- free (_SPI_current->qtlist->qtrees);
- free (_SPI_current->qtlist);
- _SPI_current->qtlist = NULL;
- }
-
- if ( procmem ) /* switch to the procedure memory context */
- { /* but free Executor memory before */
- EndPortalAllocMode ();
- _SPI_procmem ();
- }
-
- return (0);
+
+ /*
+ * We' returning to procedure where _SPI_curid == _SPI_connected - 1
+ */
+ _SPI_curid--;
+
+ if (_SPI_current->qtlist) /* free _SPI_plan allocations */
+ {
+ free(_SPI_current->qtlist->qtrees);
+ free(_SPI_current->qtlist);
+ _SPI_current->qtlist = NULL;
+ }
+
+ if (procmem) /* switch to the procedure memory context */
+ { /* but free Executor memory before */
+ EndPortalAllocMode();
+ _SPI_procmem();
+ }
+
+ return (0);
}
-static bool
-_SPI_checktuples (bool isRetrieveIntoRelation)
+static bool
+_SPI_checktuples(bool isRetrieveIntoRelation)
{
- uint32 processed = _SPI_current->processed;
- SPITupleTable *tuptable = _SPI_current->tuptable;
- bool failed = false;
-
- if ( processed == 0 )
- {
- if ( tuptable != NULL )
- failed = true;
- }
- else /* some tuples were processed */
- {
- if ( tuptable == NULL ) /* spi_printtup was not called */
- {
- if ( !isRetrieveIntoRelation )
- failed = true;
- }
- else if ( isRetrieveIntoRelation )
- failed = true;
- else if ( processed != ( tuptable->alloced - tuptable->free ) )
- failed = true;
- }
-
- return (failed);
+ uint32 processed = _SPI_current->processed;
+ SPITupleTable *tuptable = _SPI_current->tuptable;
+ bool failed = false;
+
+ if (processed == 0)
+ {
+ if (tuptable != NULL)
+ failed = true;
+ }
+ else
+/* some tuples were processed */
+ {
+ if (tuptable == NULL) /* spi_printtup was not called */
+ {
+ if (!isRetrieveIntoRelation)
+ failed = true;
+ }
+ else if (isRetrieveIntoRelation)
+ failed = true;
+ else if (processed != (tuptable->alloced - tuptable->free))
+ failed = true;
+ }
+
+ return (failed);
}
-
+
static _SPI_plan *
-_SPI_copy_plan (_SPI_plan *plan, bool local)
+_SPI_copy_plan(_SPI_plan * plan, bool local)
{
- _SPI_plan *newplan;
- MemoryContext oldcxt;
- int i;
-
- if ( local )
- oldcxt = MemoryContextSwitchTo ((MemoryContext)
- PortalGetVariableMemory (_SPI_current->portal));
- else
- oldcxt = MemoryContextSwitchTo (TopMemoryContext);
-
- newplan = (_SPI_plan *) palloc (sizeof (_SPI_plan));
- newplan->qtlist = (QueryTreeList*) palloc (sizeof (QueryTreeList));
- newplan->qtlist->len = plan->qtlist->len;
- newplan->qtlist->qtrees = (Query**) palloc (plan->qtlist->len *
- sizeof (Query*));
- for (i = 0; i < plan->qtlist->len; i++)
- newplan->qtlist->qtrees[i] = (Query *)
- copyObject (plan->qtlist->qtrees[i]);
-
- newplan->ptlist = (List *) copyObject (plan->ptlist);
- newplan->nargs = plan->nargs;
- if ( plan->nargs > 0 )
- {
- newplan->argtypes = (Oid *) palloc (plan->nargs * sizeof (Oid));
- memcpy (newplan->argtypes, plan->argtypes, plan->nargs * sizeof (Oid));
- }
- else
- newplan->argtypes = NULL;
-
- MemoryContextSwitchTo (oldcxt);
-
- return (newplan);
+ _SPI_plan *newplan;
+ MemoryContext oldcxt;
+ int i;
+
+ if (local)
+ oldcxt = MemoryContextSwitchTo((MemoryContext)
+ PortalGetVariableMemory(_SPI_current->portal));
+ else
+ oldcxt = MemoryContextSwitchTo(TopMemoryContext);
+
+ newplan = (_SPI_plan *) palloc(sizeof(_SPI_plan));
+ newplan->qtlist = (QueryTreeList *) palloc(sizeof(QueryTreeList));
+ newplan->qtlist->len = plan->qtlist->len;
+ newplan->qtlist->qtrees = (Query **) palloc(plan->qtlist->len *
+ sizeof(Query *));
+ for (i = 0; i < plan->qtlist->len; i++)
+ newplan->qtlist->qtrees[i] = (Query *)
+ copyObject(plan->qtlist->qtrees[i]);
+
+ newplan->ptlist = (List *) copyObject(plan->ptlist);
+ newplan->nargs = plan->nargs;
+ if (plan->nargs > 0)
+ {
+ newplan->argtypes = (Oid *) palloc(plan->nargs * sizeof(Oid));
+ memcpy(newplan->argtypes, plan->argtypes, plan->nargs * sizeof(Oid));
+ }
+ else
+ newplan->argtypes = NULL;
+
+ MemoryContextSwitchTo(oldcxt);
+
+ return (newplan);
}