/*-------------------------------------------------------------------------
*
- * spi.c--
+ * spi.c
* Server Programming Interface
*
+ * $Id: spi.c,v 1.48 2000/10/26 21:35:15 tgl Exp $
+ *
*-------------------------------------------------------------------------
*/
-#include "executor/spi.h"
-#include "catalog/pg_type.h"
+#include "executor/spi_priv.h"
#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;
static _SPI_connection *_SPI_stack = NULL;
static _SPI_connection *_SPI_current = NULL;
static int _SPI_connected = -1;
static int _SPI_curid = -1;
-uint32 SPI_processed = 0;
-SPITupleTable *SPI_tuptable;
-int SPI_result;
-
-void spi_printtup(HeapTuple tuple, TupleDesc tupdesc);
-
-typedef struct
-{
- QueryTreeList *qtlist;
- List *ptlist;
- int nargs;
- Oid *argtypes;
-} _SPI_plan;
+DLLIMPORT uint32 SPI_processed = 0;
+DLLIMPORT SPITupleTable *SPI_tuptable = NULL;
+DLLIMPORT int SPI_result;
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);
-
-#endif
-static int
-_SPI_execute_plan(_SPI_plan *plan,
+static int _SPI_execute_plan(_SPI_plan *plan,
Datum *Values, char *Nulls, int tcount);
-#define _SPI_CPLAN_CURCXT 0
-#define _SPI_CPLAN_PROCXT 1
-#define _SPI_CPLAN_TOPCXT 2
-
static _SPI_plan *_SPI_copy_plan(_SPI_plan *plan, int location);
static int _SPI_begin_call(bool execmem);
int
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);
+ return SPI_ERROR_CONNECT;
if (_SPI_stack == 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);
+ /* Create memory contexts for this procedure */
+ _SPI_current->procCxt = AllocSetContextCreate(TopTransactionContext,
+ "SPI Proc",
+ ALLOCSET_DEFAULT_MINSIZE,
+ ALLOCSET_DEFAULT_INITSIZE,
+ ALLOCSET_DEFAULT_MAXSIZE);
+ _SPI_current->execCxt = AllocSetContextCreate(TopTransactionContext,
+ "SPI Exec",
+ ALLOCSET_DEFAULT_MINSIZE,
+ ALLOCSET_DEFAULT_INITSIZE,
+ ALLOCSET_DEFAULT_MAXSIZE);
+ /* ... and switch to procedure's context */
+ _SPI_current->savedcxt = MemoryContextSwitchTo(_SPI_current->procCxt);
_SPI_current->savedId = GetScanCommandId();
SetScanCommandId(GetCurrentCommandId());
- return (SPI_OK_CONNECT);
+ return SPI_OK_CONNECT;
}
res = _SPI_begin_call(false); /* live in procedure memory */
if (res < 0)
- return (res);
+ return res;
/* Restore memory context as it was before procedure call */
MemoryContextSwitchTo(_SPI_current->savedcxt);
- PortalDestroy(&(_SPI_current->portal));
+
+ /* Release memory used in procedure call */
+ MemoryContextDelete(_SPI_current->execCxt);
+ MemoryContextDelete(_SPI_current->procCxt);
SetScanCommandId(_SPI_current->savedId);
{
free(_SPI_stack);
_SPI_stack = NULL;
+ _SPI_current = NULL;
}
else
{
_SPI_current = &(_SPI_stack[_SPI_connected]);
}
- return (SPI_OK_FINISH);
+ return SPI_OK_FINISH;
}
+/*
+ * Clean up SPI state at transaction commit or abort (we don't care which).
+ */
+void
+AtEOXact_SPI(void)
+{
+ /*
+ * Note that memory contexts belonging to SPI stack entries will be
+ * freed automatically, so we can ignore them here. We just need to
+ * restore our static variables to initial state.
+ */
+ 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;
+}
+
+void
+SPI_push(void)
+{
+ _SPI_curid++;
+}
+
+void
+SPI_pop(void)
+{
+ _SPI_curid--;
+}
+
int
SPI_exec(char *src, int tcount)
{
int res;
if (src == NULL || tcount < 0)
- return (SPI_ERROR_ARGUMENT);
+ return SPI_ERROR_ARGUMENT;
res = _SPI_begin_call(true);
if (res < 0)
- return (res);
+ return res;
res = _SPI_execute(src, tcount, NULL);
_SPI_end_call(true);
- return (res);
+ return res;
}
int
int res;
if (plan == NULL || tcount < 0)
- return (SPI_ERROR_ARGUMENT);
+ return SPI_ERROR_ARGUMENT;
if (((_SPI_plan *) plan)->nargs > 0 && Values == NULL)
- return (SPI_ERROR_PARAM);
+ return SPI_ERROR_PARAM;
res = _SPI_begin_call(true);
if (res < 0)
- return (res);
+ return res;
/* copy plan to current (executor) context */
plan = (void *) _SPI_copy_plan(plan, _SPI_CPLAN_CURCXT);
res = _SPI_execute_plan((_SPI_plan *) plan, Values, Nulls, tcount);
_SPI_end_call(true);
- return (res);
+ return res;
}
void *
if (src == NULL || nargs < 0 || (nargs > 0 && argtypes == NULL))
{
SPI_result = SPI_ERROR_ARGUMENT;
- return (NULL);
+ return NULL;
}
SPI_result = _SPI_begin_call(true);
if (SPI_result < 0)
- return (NULL);
+ return NULL;
plan = (_SPI_plan *) palloc(sizeof(_SPI_plan)); /* Executor context */
plan->argtypes = argtypes;
_SPI_end_call(true);
- return ((void *) plan);
+ return (void *) plan;
}
if (plan == NULL)
{
SPI_result = SPI_ERROR_ARGUMENT;
- return (NULL);
+ return NULL;
}
SPI_result = _SPI_begin_call(false); /* don't change context */
if (SPI_result < 0)
- return (NULL);
+ return NULL;
newplan = _SPI_copy_plan((_SPI_plan *) plan, _SPI_CPLAN_TOPCXT);
_SPI_curid--;
SPI_result = 0;
- return ((void *) newplan);
+ return (void *) newplan;
}
if (tuple == NULL)
{
SPI_result = SPI_ERROR_ARGUMENT;
- return (NULL);
+ return NULL;
}
if (_SPI_curid + 1 == _SPI_connected) /* connected */
if (oldcxt)
MemoryContextSwitchTo(oldcxt);
- return (ctuple);
+ return ctuple;
}
HeapTuple
if (rel == NULL || tuple == NULL || natts <= 0 || attnum == NULL || Values == NULL)
{
SPI_result = SPI_ERROR_ARGUMENT;
- return (NULL);
+ return NULL;
}
if (_SPI_curid + 1 == _SPI_connected) /* connected */
n[attnum[i] - 1] = (Nulls && Nulls[i] == 'n') ? 'n' : ' ';
}
- if (i == natts) /* no errors in attnum[] */
+ if (i == natts) /* no errors in *attnum */
{
mtuple = heap_formtuple(rel->rd_att, v, n);
- infomask = mtuple->t_infomask;
- memmove(&(mtuple->t_ctid), &(tuple->t_ctid),
- ((char *) &(tuple->t_hoff) - (char *) &(tuple->t_ctid)));
- mtuple->t_infomask = infomask;
- mtuple->t_natts = numberOfAttributes;
+ infomask = mtuple->t_data->t_infomask;
+ memmove(&(mtuple->t_data->t_oid), &(tuple->t_data->t_oid),
+ ((char *) &(tuple->t_data->t_hoff) -
+ (char *) &(tuple->t_data->t_oid)));
+ mtuple->t_data->t_infomask = infomask;
+ mtuple->t_data->t_natts = numberOfAttributes;
}
else
{
if (oldcxt)
MemoryContextSwitchTo(oldcxt);
- return (mtuple);
+ return mtuple;
}
int
for (res = 0; res < tupdesc->natts; res++)
{
- if (strcasecmp(tupdesc->attrs[res]->attname.data, fname) == 0)
- return (res + 1);
+ if (strcasecmp(NameStr(tupdesc->attrs[res]->attname), fname) == 0)
+ return res + 1;
}
- return (SPI_ERROR_NOATTRIBUTE);
+ return SPI_ERROR_NOATTRIBUTE;
}
char *
if (tupdesc->natts < fnumber || fnumber <= 0)
{
SPI_result = SPI_ERROR_NOATTRIBUTE;
- return (NULL);
+ return NULL;
}
- return (nameout(&(tupdesc->attrs[fnumber - 1]->attname)));
+ return pstrdup(NameStr(tupdesc->attrs[fnumber - 1]->attname));
}
char *
{
Datum val;
bool isnull;
- Oid foutoid;
+ Oid foutoid,
+ typelem;
SPI_result = 0;
- if (tuple->t_natts < fnumber || fnumber <= 0)
+ if (tuple->t_data->t_natts < fnumber || fnumber <= 0)
{
SPI_result = SPI_ERROR_NOATTRIBUTE;
- return (NULL);
+ return NULL;
}
val = heap_getattr(tuple, fnumber, tupdesc, &isnull);
if (isnull)
- return (NULL);
- foutoid = typtoout((Oid) tupdesc->attrs[fnumber - 1]->atttypid);
- if (!OidIsValid(foutoid))
+ return NULL;
+ if (!getTypeOutAndElem((Oid) tupdesc->attrs[fnumber - 1]->atttypid,
+ &foutoid, &typelem))
{
SPI_result = SPI_ERROR_NOOUTFUNC;
- return (NULL);
+ return NULL;
}
- return (fmgr(foutoid, val,
- gettypelem(tupdesc->attrs[fnumber - 1]->atttypid),
- tupdesc->attrs[fnumber - 1]->atttypmod));
+ return DatumGetCString(OidFunctionCall3(foutoid,
+ val,
+ ObjectIdGetDatum(typelem),
+ Int32GetDatum(tupdesc->attrs[fnumber - 1]->atttypmod)));
}
Datum
*isnull = true;
SPI_result = 0;
- if (tuple->t_natts < fnumber || fnumber <= 0)
+ if (tuple->t_data->t_natts < fnumber || fnumber <= 0)
{
SPI_result = SPI_ERROR_NOATTRIBUTE;
- return ((Datum) NULL);
+ return (Datum) NULL;
}
val = heap_getattr(tuple, fnumber, tupdesc, isnull);
- return (val);
+ return val;
}
char *
if (tupdesc->natts < fnumber || fnumber <= 0)
{
SPI_result = SPI_ERROR_NOATTRIBUTE;
- return (NULL);
+ return NULL;
}
- typeTuple = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(tupdesc->attrs[fnumber - 1]->atttypid),
+ typeTuple = SearchSysCacheTuple(TYPEOID,
+ ObjectIdGetDatum(tupdesc->attrs[fnumber - 1]->atttypid),
0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
{
SPI_result = SPI_ERROR_TYPUNKNOWN;
- return (NULL);
+ return NULL;
}
- return (pstrdup(((TypeTupleForm) GETSTRUCT(typeTuple))->typname.data));
+ return pstrdup(NameStr(((Form_pg_type) GETSTRUCT(typeTuple))->typname));
}
Oid
if (tupdesc->natts < fnumber || fnumber <= 0)
{
SPI_result = SPI_ERROR_NOATTRIBUTE;
- return (InvalidOid);
+ return InvalidOid;
}
- return (tupdesc->attrs[fnumber - 1]->atttypid);
+ return tupdesc->attrs[fnumber - 1]->atttypid;
}
char *
SPI_getrelname(Relation rel)
{
- return (pstrdup(rel->rd_rel->relname.data));
+ return pstrdup(RelationGetRelationName(rel));
}
void *
if (oldcxt)
MemoryContextSwitchTo(oldcxt);
- return (pointer);
+ return pointer;
}
void *
SPI_repalloc(void *pointer, Size size)
{
- MemoryContext oldcxt = NULL;
-
- if (_SPI_curid + 1 == _SPI_connected) /* connected */
- {
- if (_SPI_current != &(_SPI_stack[_SPI_curid + 1]))
- elog(FATAL, "SPI: stack corrupted");
- oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt);
- }
-
- pointer = repalloc(pointer, size);
-
- if (oldcxt)
- MemoryContextSwitchTo(oldcxt);
-
- return (pointer);
+ /* No longer need to worry which context chunk was in... */
+ return repalloc(pointer, size);
}
void
SPI_pfree(void *pointer)
{
- MemoryContext oldcxt = NULL;
-
- if (_SPI_curid + 1 == _SPI_connected) /* connected */
- {
- if (_SPI_current != &(_SPI_stack[_SPI_curid + 1]))
- elog(FATAL, "SPI: stack corrupted");
- oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt);
- }
-
+ /* No longer need to worry which context chunk was in... */
pfree(pointer);
+}
- if (oldcxt)
- MemoryContextSwitchTo(oldcxt);
-
- return;
+void
+SPI_freetuple(HeapTuple tuple)
+{
+ /* No longer need to worry which context tuple was in... */
+ heap_freetuple(tuple);
}
/* =================== private functions =================== */
/*
- * spi_printtup --
+ * spi_printtup
* store tuple retrieved by Executor into SPITupleTable
* of current SPI procedure
*
*/
void
-spi_printtup(HeapTuple tuple, TupleDesc tupdesc)
+spi_printtup(HeapTuple tuple, TupleDesc tupdesc, DestReceiver *self)
{
SPITupleTable *tuptable;
MemoryContext oldcxt;
static int
_SPI_execute(char *src, int tcount, _SPI_plan *plan)
{
- QueryTreeList *queryTree_list;
+ List *queryTree_list;
List *planTree_list;
- List *ptlist;
+ List *queryTree_list_item;
QueryDesc *qdesc;
Query *queryTree;
Plan *planTree;
EState *state;
- int qlen;
int nargs = 0;
Oid *argtypes = NULL;
- int res;
- int i;
+ int res = 0;
+ bool islastquery;
/* Increment CommandCounter to see changes made by now */
CommandCounterIncrement();
nargs = plan->nargs;
argtypes = plan->argtypes;
}
- ptlist = planTree_list = (List *)
- pg_parse_and_plan(src, argtypes, nargs, &queryTree_list, None);
+
+ queryTree_list = pg_parse_and_rewrite(src, argtypes, nargs);
_SPI_current->qtlist = queryTree_list;
- qlen = queryTree_list->len;
- for (i = 0;; i++)
+ planTree_list = NIL;
+
+ foreach(queryTree_list_item, queryTree_list)
{
- queryTree = (Query *) (queryTree_list->qtrees[i]);
- planTree = lfirst(planTree_list);
+ queryTree = (Query *) lfirst(queryTree_list_item);
+ islastquery = (lnext(queryTree_list_item) == NIL);
- planTree_list = lnext(planTree_list);
+ planTree = pg_plan_query(queryTree);
+ planTree_list = lappend(planTree_list, planTree);
if (queryTree->commandType == CMD_UTILITY)
{
CopyStmt *stmt = (CopyStmt *) (queryTree->utilityStmt);
if (stmt->filename == NULL)
- return (SPI_ERROR_COPY);
+ return SPI_ERROR_COPY;
}
else if (nodeTag(queryTree->utilityStmt) == T_ClosePortalStmt ||
nodeTag(queryTree->utilityStmt) == T_FetchStmt)
- return (SPI_ERROR_CURSOR);
+ return SPI_ERROR_CURSOR;
else if (nodeTag(queryTree->utilityStmt) == T_TransactionStmt)
- return (SPI_ERROR_TRANSACTION);
+ return SPI_ERROR_TRANSACTION;
res = SPI_OK_UTILITY;
if (plan == NULL)
{
ProcessUtility(queryTree->utilityStmt, None);
- if (i < qlen - 1)
+ if (!islastquery)
CommandCounterIncrement();
else
- return (res);
+ return res;
}
- else if (i >= qlen - 1)
+ else if (islastquery)
break;
}
else if (plan == NULL)
{
qdesc = CreateQueryDesc(queryTree, planTree,
- (i < qlen - 1) ? None : SPI);
+ islastquery ? SPI : None);
state = CreateExecutorState();
- res = _SPI_pquery(qdesc, state, (i < qlen - 1) ? 0 : tcount);
- if (res < 0 || i >= qlen - 1)
- return (res);
+ res = _SPI_pquery(qdesc, state, islastquery ? tcount : 0);
+ if (res < 0 || islastquery)
+ return res;
CommandCounterIncrement();
}
else
{
qdesc = CreateQueryDesc(queryTree, planTree,
- (i < qlen - 1) ? None : SPI);
- res = _SPI_pquery(qdesc, NULL, (i < qlen - 1) ? 0 : tcount);
+ islastquery ? SPI : None);
+ res = _SPI_pquery(qdesc, NULL, islastquery ? tcount : 0);
if (res < 0)
- return (res);
- if (i >= qlen - 1)
+ return res;
+ if (islastquery)
break;
}
}
plan->qtlist = queryTree_list;
- plan->ptlist = ptlist;
-
- return (res);
+ plan->ptlist = planTree_list;
+ return res;
}
static int
_SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount)
{
- QueryTreeList *queryTree_list = plan->qtlist;
+ List *queryTree_list = plan->qtlist;
List *planTree_list = plan->ptlist;
+ List *queryTree_list_item;
QueryDesc *qdesc;
Query *queryTree;
Plan *planTree;
EState *state;
int nargs = plan->nargs;
- int qlen = queryTree_list->len;
- int res;
- int i,
- k;
+ int res = 0;
+ bool islastquery;
+ int k;
/* Increment CommandCounter to see changes made by now */
CommandCounterIncrement();
_SPI_current->tuptable = NULL;
_SPI_current->qtlist = NULL;
- for (i = 0;; i++)
+ foreach(queryTree_list_item, queryTree_list)
{
- queryTree = (Query *) (queryTree_list->qtrees[i]);
+ queryTree = (Query *) lfirst(queryTree_list_item);
planTree = lfirst(planTree_list);
-
planTree_list = lnext(planTree_list);
+ islastquery = (planTree_list == NIL); /* assume lists are same
+ * len */
if (queryTree->commandType == CMD_UTILITY)
{
ProcessUtility(queryTree->utilityStmt, None);
- if (i < qlen - 1)
+ if (!islastquery)
CommandCounterIncrement();
else
- return (SPI_OK_UTILITY);
+ return SPI_OK_UTILITY;
}
else
{
qdesc = CreateQueryDesc(queryTree, planTree,
- (i < qlen - 1) ? None : SPI);
+ islastquery ? SPI : None);
state = CreateExecutorState();
if (nargs > 0)
{
}
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);
+ res = _SPI_pquery(qdesc, state, islastquery ? tcount : 0);
+ if (res < 0 || islastquery)
+ return res;
CommandCounterIncrement();
}
}
- return (res);
-
+ return res;
}
static int
_SPI_pquery(QueryDesc *queryDesc, EState *state, int tcount)
{
Query *parseTree = queryDesc->parsetree;
- Plan *plan = queryDesc->plantree;
int operation = queryDesc->operation;
CommandDest dest = queryDesc->dest;
TupleDesc tupdesc;
intoName = parseTree->into;
parseTree->isBinary = false; /* */
- return (SPI_ERROR_CURSOR);
+ return SPI_ERROR_CURSOR;
}
else if (parseTree->into != NULL) /* select into table */
res = SPI_OK_UPDATE;
break;
default:
- return (SPI_ERROR_OPUNKNOWN);
+ return SPI_ERROR_OPUNKNOWN;
}
if (state == NULL) /* plan preparation */
- return (res);
+ return res;
#ifdef SPI_EXECUTOR_STATS
if (ShowExecutorStats)
ResetUsage();
#endif
tupdesc = ExecutorStart(queryDesc, state);
- /* Don't work currently */
+ /* Don't work currently --- need to rearrange callers so that
+ * we prepare the portal before doing CreateExecutorState() etc.
+ * See pquery.c for the correct order of operations.
+ */
if (isRetrieveIntoPortal)
{
- ProcessPortal(intoName,
- parseTree,
- plan,
- state,
- tupdesc,
- None);
- return (SPI_OK_CURSOR);
+ elog(FATAL, "SPI_select: retrieve into portal not implemented");
}
- ExecutorRun(queryDesc, state, EXEC_FOR, tcount);
+ ExecutorRun(queryDesc, state, EXEC_FOR, (long) tcount);
_SPI_current->processed = state->es_processed;
if (operation == CMD_SELECT && queryDesc->dest == SPI)
}
queryDesc->dest = dest;
- return (res);
+ return res;
}
-#if 0
-static void
-_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())
- elog(FATAL, "SPI_fetch: # of processed tuples check failed");
-
- SPI_processed = _SPI_current->processed;
- SPI_tuptable = _SPI_current->tuptable;
-
-}
-
-#endif
-
static MemoryContext
_SPI_execmem()
{
- MemoryContext oldcxt;
- PortalHeapMemory phmem;
-
- phmem = PortalGetHeapMemory(_SPI_current->portal);
- oldcxt = MemoryContextSwitchTo((MemoryContext) phmem);
-
- return (oldcxt);
-
+ return MemoryContextSwitchTo(_SPI_current->execCxt);
}
static MemoryContext
_SPI_procmem()
{
- MemoryContext oldcxt;
- PortalVariableMemory pvmem;
-
- pvmem = PortalGetVariableMemory(_SPI_current->portal);
- oldcxt = MemoryContextSwitchTo((MemoryContext) pvmem);
-
- return (oldcxt);
-
+ return MemoryContextSwitchTo(_SPI_current->procCxt);
}
/*
- * _SPI_begin_call --
+ * _SPI_begin_call
*
*/
static int
_SPI_begin_call(bool execmem)
{
if (_SPI_curid + 1 != _SPI_connected)
- return (SPI_ERROR_UNCONNECTED);
+ 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);
+ return 0;
}
static int
*/
_SPI_curid--;
- if (_SPI_current->qtlist) /* free _SPI_plan allocations */
- {
- free(_SPI_current->qtlist->qtrees);
- free(_SPI_current->qtlist);
- _SPI_current->qtlist = NULL;
- }
+ _SPI_current->qtlist = NULL;
if (procmem) /* switch to the procedure memory context */
- { /* but free Executor memory before */
- EndPortalAllocMode();
+ {
_SPI_procmem();
+ /* and free Executor memory */
+ MemoryContextResetAndDeleteChildren(_SPI_current->execCxt);
}
- return (0);
+ return 0;
}
static bool
failed = true;
}
- return (failed);
+ return failed;
}
static _SPI_plan *
{
_SPI_plan *newplan;
MemoryContext oldcxt = NULL;
- int i;
if (location == _SPI_CPLAN_PROCXT)
- oldcxt = MemoryContextSwitchTo((MemoryContext)
- PortalGetVariableMemory(_SPI_current->portal));
+ oldcxt = MemoryContextSwitchTo(_SPI_current->procCxt);
else if (location == _SPI_CPLAN_TOPCXT)
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->qtlist = (List *) copyObject(plan->qtlist);
newplan->ptlist = (List *) copyObject(plan->ptlist);
newplan->nargs = plan->nargs;
if (plan->nargs > 0)
else
newplan->argtypes = NULL;
- if (location != _SPI_CPLAN_CURCXT)
+ if (oldcxt != NULL)
MemoryContextSwitchTo(oldcxt);
- return (newplan);
+ return newplan;
}