]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Cleanups.
authorVadim B. Mikheev <vadim4o@yahoo.com>
Sat, 6 Sep 1997 11:23:05 +0000 (11:23 +0000)
committerVadim B. Mikheev <vadim4o@yahoo.com>
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);