Commit 4587547f authored by Vadim B. Mikheev's avatar Vadim B. Mikheev

Added: SPI_copytuple() & SPI_modifytuple()

parent a40a546e
...@@ -48,7 +48,7 @@ static void _SPI_fetch(FetchStmt * stmt); ...@@ -48,7 +48,7 @@ static void _SPI_fetch(FetchStmt * stmt);
#endif #endif
static int static int
_SPI_execute_plan(_SPI_plan * plan, _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_CURCXT 0
#define _SPI_CPLAN_PROCXT 1 #define _SPI_CPLAN_PROCXT 1
...@@ -199,7 +199,7 @@ SPI_exec(char *src, int tcount) ...@@ -199,7 +199,7 @@ SPI_exec(char *src, int tcount)
} }
int int
SPI_execp(void *plan, Datum *Values, char *Nulls, int tcount) SPI_execp(void *plan, Datum * Values, char *Nulls, int tcount)
{ {
int res; int res;
...@@ -278,11 +278,108 @@ SPI_saveplan(void *plan) ...@@ -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 int
SPI_fnumber(TupleDesc tupdesc, char *fname) SPI_fnumber(TupleDesc tupdesc, char *fname)
{ {
int res; int res;
for (res = 0; res < tupdesc->natts; res++) for (res = 0; res < tupdesc->natts; res++)
{ {
if (strcasecmp(tupdesc->attrs[res]->attname.data, fname) == 0) if (strcasecmp(tupdesc->attrs[res]->attname.data, fname) == 0)
...@@ -333,7 +430,7 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber) ...@@ -333,7 +430,7 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
Datum Datum
SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool * isnull) SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool * isnull)
{ {
Datum val; Datum val;
*isnull = true; *isnull = true;
SPI_result = 0; SPI_result = 0;
...@@ -539,7 +636,7 @@ _SPI_execute(char *src, int tcount, _SPI_plan * plan) ...@@ -539,7 +636,7 @@ _SPI_execute(char *src, int tcount, _SPI_plan * plan)
} }
static int 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; QueryTreeList *queryTree_list = plan->qtlist;
List *planTree_list = plan->ptlist; List *planTree_list = plan->ptlist;
...@@ -591,7 +688,7 @@ _SPI_execute_plan(_SPI_plan * plan, Datum *Values, char *Nulls, int tcount) ...@@ -591,7 +688,7 @@ _SPI_execute_plan(_SPI_plan * plan, Datum *Values, char *Nulls, int tcount)
{ {
paramLI->kind = PARAM_NUM; paramLI->kind = PARAM_NUM;
paramLI->id = k + 1; paramLI->id = k + 1;
paramLI->isnull = (Nulls != NULL && Nulls[k] != 'n'); paramLI->isnull = (Nulls && Nulls[k] == 'n');
paramLI->value = Values[k]; paramLI->value = Values[k];
} }
paramLI->kind = PARAM_INVALID; paramLI->kind = PARAM_INVALID;
......
...@@ -73,10 +73,14 @@ extern int SPI_result; ...@@ -73,10 +73,14 @@ extern int SPI_result;
extern int SPI_connect(void); extern int SPI_connect(void);
extern int SPI_finish(void); extern int SPI_finish(void);
extern int SPI_exec(char *src, int tcount); 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_prepare(char *src, int nargs, Oid * argtypes);
extern void *SPI_saveplan(void *plan); 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 int SPI_fnumber(TupleDesc tupdesc, char *fname);
extern char *SPI_fname(TupleDesc tupdesc, int fnumber); extern char *SPI_fname(TupleDesc tupdesc, int fnumber);
extern char *SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber); extern char *SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment