Cleanups.
authorVadim B. Mikheev
Sat, 6 Sep 1997 11:23:05 +0000 (11:23 +0000)
committerVadim B. Mikheev
Sat, 6 Sep 1997 11:23:05 +0000 (11:23 +0000)
src/backend/executor/spi.c
src/include/executor/spi.h

index 6cf4ec8c36fd543bf249b6fbb9440272cabab90d..74ace81171aa2e0106cccd4650840376c6c17eff 100644 (file)
@@ -9,31 +9,6 @@
 #include "access/printtup.h"
 #include "fmgr.h"
 
-typedef struct {
-    QueryTreeList  *qtlist;
-    List       *ptlist;
-    int            nargs;
-    Oid            *argtypes;
-} _SPI_plan;
-
-typedef struct {
-    int        len;
-    void   *data;
-} _SPI_data;
-
-typedef struct {
-    char       *ident;
-    int            plcnt;
-    _SPI_plan      **plan;
-    int            dtcnt;
-    _SPI_data      *data;
-} _SPI_entry;
-
-static _SPI_entry  *_SPI_xtab = NULL;
-static int     _SPI_xtabsz = 0;
-static _SPI_entry  *_SPI_stab = NULL;
-static int     _SPI_stabsz = 0;
-
 typedef struct {
     QueryTreeList  *qtlist;    /* malloced */
     uint32     processed;  /* by Executor */
@@ -41,7 +16,6 @@ typedef struct {
     Portal     portal;     /* portal per procedure */
     MemoryContext  savedcxt;
     CommandId      savedId;
-    _SPI_entry     ltab;
 } _SPI_connection;
 
 static Portal _SPI_portal = (Portal) NULL;
@@ -52,10 +26,17 @@ static int _SPI_curid = -1;
 
 uint32 SPI_processed = 0;
 SPITupleTable *SPI_tuptable;
-int SPI_error;
+int SPI_result;
 
 void spi_printtup (HeapTuple tuple, TupleDesc tupdesc);
 
+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);
 #if 0
@@ -64,7 +45,7 @@ static void _SPI_fetch (FetchStmt *stmt);
 static int _SPI_execute_plan (_SPI_plan *plan, 
                char **Values, char *Nulls, int tcount);
 
-static int _SPI_copy_plan (int dspace, _SPI_plan *plan);
+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);
@@ -79,14 +60,11 @@ extern void ShowUsage (void);
 #endif
 
 int
-SPI_connect (char *ident)
+SPI_connect ()
 {
     char pname[64];
     PortalVariableMemory pvmem;
     
-    if ( !ident || *ident == 0 )
-       return (SPI_ERROR_ARGUMENT);
-    
     /*
      * It's possible on startup and after commit/abort.
      * In future we'll catch commit/abort in some way...
@@ -99,8 +77,6 @@ SPI_connect (char *ident)
            free (_SPI_stack);
        _SPI_current = _SPI_stack = NULL;
        _SPI_connected = _SPI_curid = -1;
-       _SPI_xtab = NULL;
-       _SPI_xtabsz = 0;
        SPI_processed = 0;
        SPI_tuptable = NULL;
        _SPI_portal = CreatePortal (pname);
@@ -151,10 +127,6 @@ SPI_connect (char *ident)
     _SPI_current->savedId = GetScanCommandId ();
     SetScanCommandId (GetCurrentCommandId ());
     
-    _SPI_current->ltab.ident = pstrdup (ident);
-    _SPI_current->ltab.plcnt = 0;
-    _SPI_current->ltab.dtcnt = 0;
-    
     return (SPI_OK_CONNECT);
     
 }
@@ -198,65 +170,285 @@ SPI_finish ()
 }
 
 int
-SPI_exec (char *src)
+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, 0, NULL);
+    res = _SPI_execute (src, tcount, NULL);
     
     _SPI_end_call (true);
     return (res);
 }
 
-int
-SPI_execn (char *src, int tcount)
+int 
+SPI_execp (void *plan, char **Values, char *Nulls, int tcount)
 {
     int res;
     
-    if ( tcount < 0 )
+    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 (src, tcount, NULL);
+    res = _SPI_execute_plan ((_SPI_plan *)plan, Values, Nulls, tcount);
     
     _SPI_end_call (true);
     return (res);
 }
 
-int
+void *
 SPI_prepare (char *src, int nargs, Oid *argtypes)
 {
     _SPI_plan *plan;
-    int res;
     
     if ( nargs < 0 || ( nargs > 0 && argtypes == NULL ) )
-       return (SPI_ERROR_ARGUMENT);
+    {
+       SPI_result = SPI_ERROR_ARGUMENT;
+       return (NULL);
+    }
     
-    res = _SPI_begin_call (true);
-    if ( res < 0 )
-       return (res);
+    SPI_result = _SPI_begin_call (true);
+    if ( SPI_result < 0 )
+       return (NULL);
     
-    plan = (_SPI_plan *) palloc (sizeof (_SPI_plan));
+    plan = (_SPI_plan *) palloc (sizeof (_SPI_plan));  /* Executor context */
     plan->argtypes = argtypes;
     plan->nargs = nargs;
     
-    res = _SPI_execute (src, 0, plan);
+    SPI_result = _SPI_execute (src, 0, plan);
     
-    if ( res >= 0 )    /* copy plan to local data space */
-       res = _SPI_copy_plan (SPI_DSPACE_LOCAL, plan);
+    if ( SPI_result >= 0 ) /* copy plan to local space */
+       plan = _SPI_copy_plan (plan, true);
+    else
+       plan = NULL;
     
     _SPI_end_call (true);
-    return (res);
     
+    return ((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);
+    
+}
+
+int
+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);
+}
+
+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 *
+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 *
+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));
+}
+
+Oid
+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);
+}
+
+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_printtup --
+ * store tuple retrieved by Executor into SPITupleTable
+ * of current SPI procedure
+ *
+ */
+void
+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;
 }
 
+/*
+ * Static functions
+ */
+
 static int
 _SPI_execute (char *src, int tcount, _SPI_plan *plan)
 {
@@ -355,31 +547,100 @@ _SPI_execute (char *src, int tcount, _SPI_plan *plan)
 }
 
 static int
-_SPI_pquery (QueryDesc *queryDesc, EState *state, int tcount)
+_SPI_execute_plan (_SPI_plan *plan, char **Values, char *Nulls, int tcount)
 {
-    Query  *parseTree;
-    Plan   *plan;
-    int        operation;
-    TupleDesc   tupdesc;
-    bool   isRetrieveIntoPortal = false;
-    bool   isRetrieveIntoRelation = false;
-    char*  intoName = NULL;
-    int        res;
+    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;
     
-    parseTree = queryDesc->parsetree;
-    plan = queryDesc->plantree;
-    operation = queryDesc->operation;
+    /* Increment CommandCounter to see changes made by now */
+    CommandCounterIncrement ();
     
-    switch (operation)
+    SPI_processed = 0;
+    SPI_tuptable = NULL;
+    _SPI_current->tuptable = NULL;
+    _SPI_current->qtlist = NULL;
+    
+    for (i=0; ;i++)
     {
-       case CMD_SELECT:
-           res = SPI_OK_SELECT;
-       if (parseTree->isPortal)
-       {
-           isRetrieveIntoPortal = true;
-           intoName = parseTree->into;
-           parseTree->isBinary = false;    /* */
-           
+       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)
+{
+    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);
            
        }
@@ -489,53 +750,6 @@ _SPI_fetch (FetchStmt *stmt)
 }
 #endif
 
-/*
- * spi_printtup --
- * store tuple retrieved by Executor into SPITupleTable
- * of current SPI procedure
- *
- */
-void
-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;
-}
-
 static MemoryContext
 _SPI_execmem ()
 {
@@ -635,210 +849,21 @@ _SPI_checktuples (bool isRetrieveIntoRelation)
     
     return (failed);
 }
-
-int
-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);
-    }
-    
-    return (SPI_ERROR_NOATTRIBUTE);
-}
-
-char *
-SPI_getvalue (HeapTuple tuple, TupleDesc tupdesc, int fnumber)
-{
-    char *val;
-    bool isnull;
-    Oid foutoid;
-    
-    SPI_error = 0;
-    if ( _SPI_curid + 1 != _SPI_connected )
-    {
-       SPI_error = SPI_ERROR_UNCONNECTED;
-       return (NULL);
-    }
     
-    if ( tuple->t_natts <= fnumber || fnumber < 0 )
-       return (NULL);
-    
-    val = heap_getattr (tuple, InvalidBuffer, fnumber + 1, tupdesc, &isnull);
-    if ( isnull )
-       return (NULL);
-    foutoid = typtoout ((Oid) tupdesc->attrs[fnumber]->atttypid);
-    if ( !OidIsValid (foutoid) )
-    {
-       SPI_error = SPI_ERROR_NOOUTFUNC;
-       return (NULL);
-    }
-    
-    return (fmgr (foutoid, val, gettypelem (tupdesc->attrs[fnumber]->atttypid)));
-}
-
-char *
-SPI_getbinval (HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
+static _SPI_plan *
+_SPI_copy_plan (_SPI_plan *plan, bool local)
 {
-    char *val;
-    
-    *isnull = true;
-    SPI_error = 0;
-    if ( _SPI_curid + 1 != _SPI_connected )
-    {
-       SPI_error = SPI_ERROR_UNCONNECTED;
-       return (NULL);
-    }
-    
-    if ( tuple->t_natts <= fnumber || fnumber < 0 )
-       return (NULL);
-    
-    val = heap_getattr (tuple, InvalidBuffer, fnumber + 1, tupdesc, isnull);
-    
-    return (val);
-}
-
-char *
-SPI_gettype (TupleDesc tupdesc, int fnumber)
-{
-    HeapTuple typeTuple;
-    
-    SPI_error = 0;
-    if ( _SPI_curid + 1 != _SPI_connected )
-    {
-       SPI_error = SPI_ERROR_UNCONNECTED;
-       return (NULL);
-    }
-    
-    if ( tupdesc->natts <= fnumber || fnumber < 0 )
-       return (NULL);
-    
-    typeTuple = SearchSysCacheTuple (TYPOID, 
-               ObjectIdGetDatum (tupdesc->attrs[fnumber]->atttypid),
-               0, 0, 0);
-    
-    if ( !HeapTupleIsValid (typeTuple) )
-    {
-       SPI_error = SPI_ERROR_TYPUNKNOWN;
-       return (NULL);
-    }
-    
-    return (pstrdup (((TypeTupleForm) GETSTRUCT (typeTuple))->typname.data));
-}
-
-Oid
-SPI_gettypeid (TupleDesc tupdesc, int fnumber)
-{
-    
-    SPI_error = 0;
-    if ( _SPI_curid + 1 != _SPI_connected )
-    {
-       SPI_error = SPI_ERROR_UNCONNECTED;
-       return (InvalidOid);
-    }
-    
-    if ( tupdesc->natts <= fnumber || fnumber < 0 )
-       return (InvalidOid);
-    
-    return (tupdesc->attrs[fnumber]->atttypid);
-}
-
-char *
-SPI_getrelname (Relation rel)
-{
-    
-    SPI_error = 0;
-    if ( _SPI_curid + 1 != _SPI_connected )
-    {
-       SPI_error = SPI_ERROR_UNCONNECTED;
-       return (NULL);
-    }
-    
-    return (pstrdup (rel->rd_rel->relname.data));
-}
-    
-static _SPI_entry *
-_SPI_fnentry (int dspace, int **tabsz, MemoryContext *oldcxt)
-{
-    char *ident = _SPI_current->ltab.ident;
-    int *size = NULL;
-    _SPI_entry **ep = NULL;
-    _SPI_entry *entry;
-    int i;
-    
-    switch (dspace)
-    {
-       case SPI_DSPACE_SESSION :
-           if ( tabsz != NULL )
-               *oldcxt = MemoryContextSwitchTo (TopMemoryContext);
-           ep = &(_SPI_stab);
-           size = &(_SPI_stabsz);
-           break;
-       case SPI_DSPACE_XACT :
-           if ( tabsz != NULL )
-               *oldcxt = MemoryContextSwitchTo ((MemoryContext) 
-                       PortalGetVariableMemory (_SPI_portal));
-           ep = &(_SPI_xtab);
-           size = &(_SPI_xtabsz);
-           break;
-    }
-    
-    for (i = 0; i < *size; i++, ep++)
-    {
-       if ( strcmp ((*ep)->ident, ident) == 0 )
-           break;
-    }
-    if ( i == *size )
-    {
-       if ( tabsz == NULL )        /* don't expand table */
-           return (NULL);
-       *tabsz = size;
-       if ( *size == 0 )
-           *ep = (_SPI_entry *) palloc (sizeof (_SPI_entry));
-       else
-           *ep = (_SPI_entry *) repalloc (*ep, 
-               (*size + 1) * sizeof (_SPI_entry));
-       entry = (*ep) + *size;
-       entry->ident = pstrdup (ident);
-       entry->plcnt = entry->dtcnt = 0;
-    }
-    else
-       entry = *ep;
-    
-    return (entry);
-}
-
-static int 
-_SPI_copy_plan (int dspace, _SPI_plan *plan)
-{
-    _SPI_entry *entry;
     _SPI_plan *newplan;
-    int *tabsz = NULL;
     MemoryContext oldcxt;
     int i;
     
-    if ( dspace == SPI_DSPACE_LOCAL )
-    {
+    if ( local )
        oldcxt = MemoryContextSwitchTo ((MemoryContext)
                PortalGetVariableMemory (_SPI_current->portal));
-       entry = &(_SPI_current->ltab);
-    }
     else
-       entry = _SPI_fnentry (dspace, &tabsz, &oldcxt);
+       oldcxt = MemoryContextSwitchTo (TopMemoryContext);
     
-    if ( entry->plcnt == 0 )
-       entry->plan = (_SPI_plan **) palloc (sizeof (_SPI_plan *));
-    else
-       entry->plan = (_SPI_plan **) repalloc (entry->plan,
-                   (entry->plcnt + 1) * sizeof (_SPI_plan *));
     newplan = (_SPI_plan *) palloc (sizeof (_SPI_plan));
-    entry->plan[entry->plcnt] = newplan;
     newplan->qtlist = (QueryTreeList*) palloc (sizeof (QueryTreeList));
     newplan->qtlist->len = plan->qtlist->len;
     newplan->qtlist->qtrees = (Query**) palloc (plan->qtlist->len * 
@@ -856,278 +881,8 @@ _SPI_copy_plan (int dspace, _SPI_plan *plan)
     }
     else
        newplan->argtypes = NULL;
-    (entry->plcnt)++;
-    
-    if ( tabsz != NULL )       /* table expanded */
-       (*tabsz)++;
     
     MemoryContextSwitchTo (oldcxt);
     
-    return (entry->plcnt - 1);
-}
-
-int 
-SPI_expdata (int dspace, int count, void **data, int *len)
-{
-    _SPI_entry *entry;
-    _SPI_data *newdata;
-    int *tabsz = NULL;
-    MemoryContext oldcxt;
-    int res;
-    int i;
-    
-    if ( ( dspace != SPI_DSPACE_XACT && 
-           dspace != SPI_DSPACE_SESSION ) || 
-               count <= 0 || data == NULL || len == NULL )
-       return (SPI_ERROR_ARGUMENT);
-    
-    res = _SPI_begin_call (false); /* don't change context */
-    if ( res < 0 )
-       return (res);
-    
-    entry = _SPI_fnentry (dspace, &tabsz, &oldcxt);
-    
-    if ( entry->dtcnt == 0 )
-       entry->data = (_SPI_data *) palloc (count * sizeof (_SPI_data));
-    else
-       entry->data = (_SPI_data *) repalloc (entry->data,
-                   (entry->dtcnt + count) * sizeof (_SPI_data));
-    for (i = 0, newdata = &(entry->data[entry->dtcnt]); i < count; i++, newdata++)
-    {
-       if ( len[i] <= 0 || data[i] == NULL )
-           break;
-       newdata->data = (void *) palloc (len[i]);
-       memcpy (newdata->data, data[i], len[i]);
-       newdata->len = len[i];
-    }
-    entry->dtcnt += i;
-    res = i;
-    
-    if ( tabsz != NULL )       /* table expanded */
-       (*tabsz)++;
-    
-    MemoryContextSwitchTo (oldcxt);
-    
-    _SPI_curid--;
-    return (res);
-}
-
-int
-SPI_impdata (int dspace, int start, int count, void **data, int **len)
-{
-    _SPI_entry *entry;
-    int *dl;
-    int res;
-    int i;
-    
-    if ( ( dspace != SPI_DSPACE_XACT && 
-           dspace != SPI_DSPACE_SESSION ) || 
-               start < 0 || count < 0 ||
-               (count > 0 && (data == NULL || len == NULL) ) )
-       return (SPI_ERROR_ARGUMENT);
-    
-    res = _SPI_begin_call (false); /* don't change context */
-    if ( res < 0 )
-       return (res);
-    
-    entry = _SPI_fnentry (dspace, NULL, NULL);
-    
-    _SPI_curid--;
-    
-    if ( entry == NULL || entry->dtcnt == 0 )
-           return (0);
-    if ( count == 0 )
-       return (entry->dtcnt);
-    if ( start >= entry->dtcnt )
-       return (0);
-    
-    i = ( entry->dtcnt - start >= count ) ? count : entry->dtcnt - start;
-    data = (void **) palloc (i * sizeof (void *));
-    dl = *len = (int *) palloc (i * sizeof (int));
-    
-    for (i = start, res = 0; i < entry->dtcnt && res < count; i++, res++)
-    {
-       dl[res] = entry->data[i].len;
-       data[res] = (void *) palloc (dl[res]);
-       memcpy (data[res], entry->data[i].data, dl[res]);
-    }
-    
-    return (res);
-}
-
-int 
-SPI_expplan (int dspace, int start, int count)
-{
-    _SPI_entry *entry = &(_SPI_current->ltab);
-    int res;
-    int i;
-    
-    if ( ( dspace != SPI_DSPACE_XACT && 
-           dspace != SPI_DSPACE_SESSION ) || 
-               start < 0 || count <= 0 )
-       return (SPI_ERROR_ARGUMENT);
-    
-    res = _SPI_begin_call (false); /* don't change context */
-    if ( res < 0 )
-       return (res);
-    
-    if ( start >= entry->plcnt )
-    {
-       _SPI_curid--;
-       return (0);
-    }
-    
-    for (i = start, res = 0; i < entry->plcnt && res < count; i++, res++)
-    {
-       _SPI_copy_plan (dspace, entry->plan[i]);
-    }
-    
-    _SPI_curid--;
-    
-    return (res);
-}
-
-int 
-SPI_impplan (int dspace, int start, int count)
-{
-    _SPI_entry *to = &(_SPI_current->ltab);
-    _SPI_entry *from;
-    int res;
-    int i;
-    
-    if ( ( dspace != SPI_DSPACE_XACT && 
-           dspace != SPI_DSPACE_SESSION ) || 
-                   start < 0 || count < 0 )
-       return (SPI_ERROR_ARGUMENT);
-    
-    res = _SPI_begin_call (false);     /* don't change context */
-    if ( res < 0 )
-       return (res);
-    
-    from = _SPI_fnentry (dspace, NULL, NULL);  /* don't expand table */
-    
-    _SPI_curid--;
-    
-    if ( from == NULL || from->plcnt == 0 )
-           return (0);
-    if ( count == 0 )
-       return (from->plcnt);
-    if ( start >= from->plcnt )
-       return (0);
-    
-    i = ( from->plcnt - start >= count ) ? count : from->plcnt - start;
-    if ( to->plcnt == 0 )
-       to->plan = (_SPI_plan **) palloc (i * sizeof (_SPI_plan *));
-    else
-       to->plan = (_SPI_plan **) repalloc (to->plan, 
-                   (to->plcnt + i) * sizeof (_SPI_plan *));
-    
-    for (i = start, res = 0; i < from->plcnt && res < count; i++, res++)
-    {
-       to->plan[res] = from->plan[i];
-    }
-    
-    return (res);
-}
-
-int 
-SPI_execp (int pid, char **Values, char *Nulls)
-{
-    _SPI_entry *entry = &(_SPI_current->ltab);
-    int res;
-    
-    if ( pid < 0 )
-       return (SPI_ERROR_ARGUMENT);
-    
-    res = _SPI_begin_call (false);
-    if ( res < 0 )
-       return (res);
-    
-    if ( entry->plcnt < pid )
-    {
-       _SPI_curid--;
-       return (SPI_ERROR_NOENTRY);
-    }
-    else if ( entry->plan[pid]->nargs > 0 && ( Values == NULL || Nulls == NULL ) )
-    {
-       _SPI_curid--;
-       return (SPI_ERROR_PARAM);
-    }
-    
-    _SPI_execmem();
-    StartPortalAllocMode (DefaultAllocMode, 0);
-    
-    res = _SPI_execute_plan (entry->plan[pid], Values, Nulls, 0);
-    
-    _SPI_end_call (true);
-    return (res);
-}
-
-static int
-_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
-   {
-           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 = i+1;
-                   paramLI->isnull = (Nulls[i] != 0);
-                   paramLI->value = (Datum) Values[i];
-           }
-           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);
-    
+    return (newplan);
 }
index 31d9ecc8e27dc4dd98cce5dd8e52b5f90aee60b0..8ab7b34b0c842d9abd59ce6d6f86bfeaf3d85c75 100644 (file)
@@ -52,7 +52,6 @@ typedef struct {
 #define SPI_ERROR_NOATTRIBUTE  -9
 #define SPI_ERROR_NOOUTFUNC    -10
 #define SPI_ERROR_TYPUNKNOWN   -11
-#define SPI_ERROR_NOENTRY  -12
 
 #define SPI_OK_CONNECT     1
 #define SPI_OK_FINISH      2
@@ -65,24 +64,16 @@ typedef struct {
 #define SPI_OK_UPDATE      9
 #define SPI_OK_CURSOR      10
 
-#define SPI_DSPACE_LOCAL   0
-#define SPI_DSPACE_XACT        1
-#define SPI_DSPACE_SESSION 2
-
 extern uint32 SPI_processed;
 extern SPITupleTable *SPI_tuptable;
-extern int SPI_error;
+extern int SPI_result;
 
-extern int SPI_connect (char *ident);
+extern int SPI_connect (void);
 extern int SPI_finish (void);
-extern int SPI_exec (char *src);
-extern int SPI_execn (char *src, int tcount);
-extern int SPI_execp (int pid, char **values, char *Nulls);
-extern int SPI_prepare (char *src, int nargs, Oid *argtypes);
-extern int SPI_expplan (int dspace, int start, int count);
-extern int SPI_impplan (int dspace, int start, int count);
-extern int SPI_expdata (int dspace, int count, void **data, int *len);
-extern int SPI_impdata (int dspace, int start, int count, void **data, int **len);
+extern int SPI_exec (char *src, int tcount);
+extern int SPI_execp (void *plan, char **values, char *Nulls, int tcount);
+extern void *SPI_prepare (char *src, int nargs, Oid *argtypes);
+extern void *SPI_saveplan (void *plan);
 
 extern int SPI_fnumber (TupleDesc tupdesc, char *fname);
 extern char *SPI_getvalue (HeapTuple tuple, TupleDesc tupdesc, int fnumber);