Added: SPI_copytuple() & SPI_modifytuple()
authorVadim B. Mikheev <vadim4o@yahoo.com>
Fri, 12 Sep 1997 08:37:52 +0000 (08:37 +0000)
committerVadim B. Mikheev <vadim4o@yahoo.com>
Fri, 12 Sep 1997 08:37:52 +0000 (08:37 +0000)
src/backend/executor/spi.c
src/include/executor/spi.h

index f3aae45ce2a0dfd53075f837150d9e0be215582d..186c0f0313ef145e066d27d3397e3974f6872301 100644 (file)
@@ -48,7 +48,7 @@ static void _SPI_fetch(FetchStmt * stmt);
 #endif
 static int
 _SPI_execute_plan(_SPI_plan * plan,
-                                 Datum *Values, char *Nulls, int tcount);
+                                 Datum * Values, char *Nulls, int tcount);
 
 #define _SPI_CPLAN_CURCXT      0
 #define _SPI_CPLAN_PROCXT      1
@@ -199,7 +199,7 @@ SPI_exec(char *src, int tcount)
 }
 
 int
-SPI_execp(void *plan, Datum *Values, char *Nulls, int tcount)
+SPI_execp(void *plan, Datum * Values, char *Nulls, int tcount)
 {
        int                     res;
 
@@ -278,11 +278,108 @@ SPI_saveplan(void *plan)
 
 }
 
+HeapTuple
+SPI_copytuple(HeapTuple tuple)
+{
+       MemoryContext oldcxt = NULL;
+       HeapTuple       ctuple;
+
+       if (tuple == NULL)
+       {
+               SPI_result = SPI_ERROR_ARGUMENT;
+               return (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);
+       }
+
+       ctuple = heap_copytuple(tuple);
+
+       if (oldcxt)
+               MemoryContextSwitchTo(oldcxt);
+
+       return (ctuple);
+}
+
+HeapTuple
+SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum,
+                               Datum * Values, char *Nulls)
+{
+       MemoryContext oldcxt = NULL;
+       HeapTuple       mtuple;
+       int                     numberOfAttributes;
+       uint8           infomask;
+       Datum      *v;
+       char       *n;
+       bool            isnull;
+       int                     i;
+
+       if (rel == NULL || tuple == NULL || natts <= 0 || attnum == NULL || Values == NULL)
+       {
+               SPI_result = SPI_ERROR_ARGUMENT;
+               return (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);
+       }
+       SPI_result = 0;
+       numberOfAttributes = rel->rd_att->natts;
+       v = (Datum *) palloc(numberOfAttributes * sizeof(Datum));
+       n = (char *) palloc(numberOfAttributes * sizeof(char));
+
+       /* fetch old values and nulls */
+       for (i = 0; i < numberOfAttributes; i++)
+       {
+               v[i] = heap_getattr(tuple, InvalidBuffer, i + 1, rel->rd_att, &isnull);
+               n[i] = (isnull) ? 'n' : ' ';
+       }
+
+       /* replace values and nulls */
+       for (i = 0; i < natts; i++)
+       {
+               if (attnum[i] <= 0 || attnum[i] > numberOfAttributes)
+                       break;
+               v[attnum[i] - 1] = Values[i];
+               n[attnum[i] - 1] = (Nulls && Nulls[i] == 'n') ? 'n' : ' ';
+       }
+
+       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;
+       }
+       else
+       {
+               mtuple = NULL;
+               SPI_result = SPI_ERROR_NOATTRIBUTE;
+       }
+
+       pfree(v);
+       pfree(n);
+
+       if (oldcxt)
+               MemoryContextSwitchTo(oldcxt);
+
+       return (mtuple);
+}
+
 int
 SPI_fnumber(TupleDesc tupdesc, char *fname)
 {
        int                     res;
-       
+
        for (res = 0; res < tupdesc->natts; res++)
        {
                if (strcasecmp(tupdesc->attrs[res]->attname.data, fname) == 0)
@@ -333,7 +430,7 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
 Datum
 SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool * isnull)
 {
-       Datum   val;
+       Datum           val;
 
        *isnull = true;
        SPI_result = 0;
@@ -539,7 +636,7 @@ _SPI_execute(char *src, int tcount, _SPI_plan * plan)
 }
 
 static int
-_SPI_execute_plan(_SPI_plan * plan, Datum *Values, char *Nulls, int tcount)
+_SPI_execute_plan(_SPI_plan * plan, Datum * Values, char *Nulls, int tcount)
 {
        QueryTreeList *queryTree_list = plan->qtlist;
        List       *planTree_list = plan->ptlist;
@@ -591,7 +688,7 @@ _SPI_execute_plan(_SPI_plan * plan, Datum *Values, char *Nulls, int tcount)
                                {
                                        paramLI->kind = PARAM_NUM;
                                        paramLI->id = k + 1;
-                                       paramLI->isnull = (Nulls != NULL && Nulls[k] != 'n');
+                                       paramLI->isnull = (Nulls && Nulls[k] == 'n');
                                        paramLI->value = Values[k];
                                }
                                paramLI->kind = PARAM_INVALID;
index 6eab4b8544fce19073a92d4a217cf1c92d17f997..58346be4921786f171254237fec69e0fbb46b73f 100644 (file)
@@ -73,10 +73,14 @@ extern int  SPI_result;
 extern int     SPI_connect(void);
 extern int     SPI_finish(void);
 extern int     SPI_exec(char *src, int tcount);
-extern int     SPI_execp(void *plan, Datum *values, char *Nulls, int tcount);
+extern int     SPI_execp(void *plan, Datum * values, char *Nulls, int tcount);
 extern void *SPI_prepare(char *src, int nargs, Oid * argtypes);
 extern void *SPI_saveplan(void *plan);
 
+extern HeapTuple SPI_copytuple(HeapTuple tuple);
+extern HeapTuple
+SPI_modifytuple(Relation rel, HeapTuple tuple, int natts,
+                               int *attnum, Datum * Values, char *Nulls);
 extern int     SPI_fnumber(TupleDesc tupdesc, char *fname);
 extern char *SPI_fname(TupleDesc tupdesc, int fnumber);
 extern char *SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber);