aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/spi.c
diff options
context:
space:
mode:
authorVadim B. Mikheev <vadim4o@yahoo.com>1997-09-12 08:37:52 +0000
committerVadim B. Mikheev <vadim4o@yahoo.com>1997-09-12 08:37:52 +0000
commit4587547f1382b125fb8835eace3ba3f5f7980db4 (patch)
tree591b33b830c838f8694cfc2a253f57f50c0ca58d /src/backend/executor/spi.c
parenta40a546e47efb43e070ee4cfe89ecf4b627ade64 (diff)
downloadpostgresql-4587547f1382b125fb8835eace3ba3f5f7980db4.tar.gz
postgresql-4587547f1382b125fb8835eace3ba3f5f7980db4.zip
Added: SPI_copytuple() & SPI_modifytuple()
Diffstat (limited to 'src/backend/executor/spi.c')
-rw-r--r--src/backend/executor/spi.c109
1 files changed, 103 insertions, 6 deletions
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index f3aae45ce2a..186c0f0313e 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -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;