summaryrefslogtreecommitdiff
path: root/contrib/spi
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/spi')
-rw-r--r--contrib/spi/autoinc.c17
-rw-r--r--contrib/spi/insert_username.c14
-rw-r--r--contrib/spi/moddatetime.c27
-rw-r--r--contrib/spi/refint.c7
-rw-r--r--contrib/spi/timetravel.c31
5 files changed, 46 insertions, 50 deletions
diff --git a/contrib/spi/autoinc.c b/contrib/spi/autoinc.c
index 41eae4fdc4..8bf742230e 100644
--- a/contrib/spi/autoinc.c
+++ b/contrib/spi/autoinc.c
@@ -3,6 +3,7 @@
*/
#include "postgres.h"
+#include "access/htup_details.h"
#include "catalog/pg_type.h"
#include "commands/sequence.h"
#include "commands/trigger.h"
@@ -23,6 +24,7 @@ autoinc(PG_FUNCTION_ARGS)
int *chattrs; /* attnums of attributes to change */
int chnattrs = 0; /* # of above */
Datum *newvals; /* vals of above */
+ bool *newnulls; /* null flags for above */
char **args; /* arguments */
char *relname; /* triggered relation name */
Relation rel; /* triggered relation */
@@ -64,6 +66,7 @@ autoinc(PG_FUNCTION_ARGS)
chattrs = (int *) palloc(nargs / 2 * sizeof(int));
newvals = (Datum *) palloc(nargs / 2 * sizeof(Datum));
+ newnulls = (bool *) palloc(nargs / 2 * sizeof(bool));
for (i = 0; i < nargs;)
{
@@ -71,7 +74,7 @@ autoinc(PG_FUNCTION_ARGS)
int32 val;
Datum seqname;
- if (attnum < 0)
+ if (attnum <= 0)
ereport(ERROR,
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
errmsg("\"%s\" has no attribute \"%s\"",
@@ -102,23 +105,23 @@ autoinc(PG_FUNCTION_ARGS)
newvals[chnattrs] = DirectFunctionCall1(nextval, seqname);
newvals[chnattrs] = Int32GetDatum((int32) DatumGetInt64(newvals[chnattrs]));
}
- pfree(DatumGetTextP(seqname));
+ newnulls[chnattrs] = false;
+ pfree(DatumGetTextPP(seqname));
chnattrs++;
i++;
}
if (chnattrs > 0)
{
- rettuple = SPI_modifytuple(rel, rettuple, chnattrs, chattrs, newvals, NULL);
- if (rettuple == NULL)
- /* internal error */
- elog(ERROR, "autoinc (%s): %d returned by SPI_modifytuple",
- relname, SPI_result);
+ rettuple = heap_modify_tuple_by_cols(rettuple, tupdesc,
+ chnattrs, chattrs,
+ newvals, newnulls);
}
pfree(relname);
pfree(chattrs);
pfree(newvals);
+ pfree(newnulls);
return PointerGetDatum(rettuple);
}
diff --git a/contrib/spi/insert_username.c b/contrib/spi/insert_username.c
index 3812525c4c..a2e1747ff7 100644
--- a/contrib/spi/insert_username.c
+++ b/contrib/spi/insert_username.c
@@ -1,6 +1,4 @@
/*
- * insert_username.c
- * $Modified: Thu Oct 16 08:13:42 1997 by brook $
* contrib/spi/insert_username.c
*
* insert user name in response to a trigger
@@ -8,6 +6,7 @@
*/
#include "postgres.h"
+#include "access/htup_details.h"
#include "catalog/pg_type.h"
#include "commands/trigger.h"
#include "executor/spi.h"
@@ -26,6 +25,7 @@ insert_username(PG_FUNCTION_ARGS)
Trigger *trigger; /* to get trigger name */
int nargs; /* # of arguments */
Datum newval; /* new value of column */
+ bool newnull; /* null flag */
char **args; /* arguments */
char *relname; /* triggered relation name */
Relation rel; /* triggered relation */
@@ -67,7 +67,7 @@ insert_username(PG_FUNCTION_ARGS)
attnum = SPI_fnumber(tupdesc, args[0]);
- if (attnum < 0)
+ if (attnum <= 0)
ereport(ERROR,
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
errmsg("\"%s\" has no attribute \"%s\"", relname, args[0])));
@@ -80,13 +80,11 @@ insert_username(PG_FUNCTION_ARGS)
/* create fields containing name */
newval = CStringGetTextDatum(GetUserNameFromId(GetUserId(), false));
+ newnull = false;
/* construct new tuple */
- rettuple = SPI_modifytuple(rel, rettuple, 1, &attnum, &newval, NULL);
- if (rettuple == NULL)
- /* internal error */
- elog(ERROR, "insert_username (\"%s\"): %d returned by SPI_modifytuple",
- relname, SPI_result);
+ rettuple = heap_modify_tuple_by_cols(rettuple, tupdesc,
+ 1, &attnum, &newval, &newnull);
pfree(relname);
diff --git a/contrib/spi/moddatetime.c b/contrib/spi/moddatetime.c
index c6d33b7355..70476f77c2 100644
--- a/contrib/spi/moddatetime.c
+++ b/contrib/spi/moddatetime.c
@@ -15,11 +15,12 @@ OH, me, I'm Terry Mackintosh <terry@terrym.com>
*/
#include "postgres.h"
+#include "access/htup_details.h"
#include "catalog/pg_type.h"
#include "executor/spi.h"
#include "commands/trigger.h"
+#include "utils/builtins.h"
#include "utils/rel.h"
-#include "utils/timestamp.h"
PG_MODULE_MAGIC;
@@ -34,6 +35,7 @@ moddatetime(PG_FUNCTION_ARGS)
int attnum; /* positional number of field to change */
Oid atttypid; /* type OID of field to change */
Datum newdt; /* The current datetime. */
+ bool newdtnull; /* null flag for it */
char **args; /* arguments */
char *relname; /* triggered relation name */
Relation rel; /* triggered relation */
@@ -84,9 +86,9 @@ moddatetime(PG_FUNCTION_ARGS)
/*
* This is where we check to see if the field we are supposed to update
- * even exists. The above function must return -1 if name not found?
+ * even exists.
*/
- if (attnum < 0)
+ if (attnum <= 0)
ereport(ERROR,
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
errmsg("\"%s\" has no attribute \"%s\"",
@@ -115,22 +117,13 @@ moddatetime(PG_FUNCTION_ARGS)
args[0], relname)));
newdt = (Datum) 0; /* keep compiler quiet */
}
+ newdtnull = false;
-/* 1 is the number of items in the arrays attnum and newdt.
- attnum is the positional number of the field to be updated.
- newdt is the new datetime stamp.
- NOTE that attnum and newdt are not arrays, but then a 1 element array
- is not an array any more then they are. Thus, they can be considered a
- one element array.
-*/
- rettuple = SPI_modifytuple(rel, rettuple, 1, &attnum, &newdt, NULL);
-
- if (rettuple == NULL)
- /* internal error */
- elog(ERROR, "moddatetime (%s): %d returned by SPI_modifytuple",
- relname, SPI_result);
+ /* Replace the attnum'th column with newdt */
+ rettuple = heap_modify_tuple_by_cols(rettuple, tupdesc,
+ 1, &attnum, &newdt, &newdtnull);
-/* Clean up */
+ /* Clean up */
pfree(relname);
return PointerGetDatum(rettuple);
diff --git a/contrib/spi/refint.c b/contrib/spi/refint.c
index 01dd717522..208ff6103d 100644
--- a/contrib/spi/refint.c
+++ b/contrib/spi/refint.c
@@ -89,7 +89,7 @@ check_primary_key(PG_FUNCTION_ARGS)
/* internal error */
elog(ERROR, "check_primary_key: cannot process DELETE events");
- /* If UPDATion the must check new Tuple, not old one */
+ /* If UPDATE, then must check new Tuple, not old one */
else
tuple = trigdata->tg_newtuple;
@@ -135,7 +135,7 @@ check_primary_key(PG_FUNCTION_ARGS)
int fnumber = SPI_fnumber(tupdesc, args[i]);
/* Bad guys may give us un-existing column in CREATE TRIGGER */
- if (fnumber < 0)
+ if (fnumber <= 0)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("there is no attribute \"%s\" in relation \"%s\"",
@@ -362,7 +362,7 @@ check_foreign_key(PG_FUNCTION_ARGS)
int fnumber = SPI_fnumber(tupdesc, args[i]);
/* Bad guys may give us un-existing column in CREATE TRIGGER */
- if (fnumber < 0)
+ if (fnumber <= 0)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("there is no attribute \"%s\" in relation \"%s\"",
@@ -469,6 +469,7 @@ check_foreign_key(PG_FUNCTION_ARGS)
char *type;
fn = SPI_fnumber(tupdesc, args_temp[k - 1]);
+ Assert(fn > 0); /* already checked above */
nv = SPI_getvalue(newtuple, tupdesc, fn);
type = SPI_gettype(tupdesc, fn);
diff --git a/contrib/spi/timetravel.c b/contrib/spi/timetravel.c
index 5a345841c6..19bf8a892c 100644
--- a/contrib/spi/timetravel.c
+++ b/contrib/spi/timetravel.c
@@ -11,6 +11,7 @@
#include <ctype.h>
+#include "access/htup_details.h"
#include "catalog/pg_type.h"
#include "commands/trigger.h"
#include "executor/spi.h"
@@ -50,7 +51,7 @@ static EPlan *find_plan(char *ident, EPlan **eplan, int *nplans);
* and stop_date eq INFINITY [ and update_user eq current user ]
* and all other column values as in new tuple, and insert tuple
* with old data and stop_date eq current date
- * ELSE - skip updation of tuple.
+ * ELSE - skip updating of tuple.
* 2. IF a delete affects tuple with stop_date eq INFINITY
* then insert the same tuple with stop_date eq current date
* [ and delete_user eq current user ]
@@ -157,7 +158,7 @@ timetravel(PG_FUNCTION_ARGS)
for (i = 0; i < MinAttrNum; i++)
{
attnum[i] = SPI_fnumber(tupdesc, args[i]);
- if (attnum[i] < 0)
+ if (attnum[i] <= 0)
elog(ERROR, "timetravel (%s): there is no attribute %s", relname, args[i]);
if (SPI_gettypeid(tupdesc, attnum[i]) != ABSTIMEOID)
elog(ERROR, "timetravel (%s): attribute %s must be of abstime type",
@@ -166,7 +167,7 @@ timetravel(PG_FUNCTION_ARGS)
for (; i < argc; i++)
{
attnum[i] = SPI_fnumber(tupdesc, args[i]);
- if (attnum[i] < 0)
+ if (attnum[i] <= 0)
elog(ERROR, "timetravel (%s): there is no attribute %s", relname, args[i]);
if (SPI_gettypeid(tupdesc, attnum[i]) != TEXTOID)
elog(ERROR, "timetravel (%s): attribute %s must be of text type",
@@ -183,13 +184,13 @@ timetravel(PG_FUNCTION_ARGS)
int chnattrs = 0;
int chattrs[MaxAttrNum];
Datum newvals[MaxAttrNum];
- char newnulls[MaxAttrNum];
+ bool newnulls[MaxAttrNum];
oldtimeon = SPI_getbinval(trigtuple, tupdesc, attnum[a_time_on], &isnull);
if (isnull)
{
newvals[chnattrs] = GetCurrentAbsoluteTime();
- newnulls[chnattrs] = ' ';
+ newnulls[chnattrs] = false;
chattrs[chnattrs] = attnum[a_time_on];
chnattrs++;
}
@@ -201,7 +202,7 @@ timetravel(PG_FUNCTION_ARGS)
(chnattrs > 0 && DatumGetInt32(newvals[a_time_on]) >= NOEND_ABSTIME))
elog(ERROR, "timetravel (%s): %s is infinity", relname, args[a_time_on]);
newvals[chnattrs] = NOEND_ABSTIME;
- newnulls[chnattrs] = ' ';
+ newnulls[chnattrs] = false;
chattrs[chnattrs] = attnum[a_time_off];
chnattrs++;
}
@@ -220,21 +221,23 @@ timetravel(PG_FUNCTION_ARGS)
{
/* clear update_user value */
newvals[chnattrs] = nulltext;
- newnulls[chnattrs] = 'n';
+ newnulls[chnattrs] = true;
chattrs[chnattrs] = attnum[a_upd_user];
chnattrs++;
/* clear delete_user value */
newvals[chnattrs] = nulltext;
- newnulls[chnattrs] = 'n';
+ newnulls[chnattrs] = true;
chattrs[chnattrs] = attnum[a_del_user];
chnattrs++;
/* set insert_user value */
newvals[chnattrs] = newuser;
- newnulls[chnattrs] = ' ';
+ newnulls[chnattrs] = false;
chattrs[chnattrs] = attnum[a_ins_user];
chnattrs++;
}
- rettuple = SPI_modifytuple(rel, trigtuple, chnattrs, chattrs, newvals, newnulls);
+ rettuple = heap_modify_tuple_by_cols(trigtuple, tupdesc,
+ chnattrs, chattrs,
+ newvals, newnulls);
return PointerGetDatum(rettuple);
/* end of INSERT */
}
@@ -395,13 +398,11 @@ timetravel(PG_FUNCTION_ARGS)
chnattrs++;
}
- rettuple = SPI_modifytuple(rel, newtuple, chnattrs, chattrs, newvals, newnulls);
-
/*
- * SPI_copytuple allocates tmptuple in upper executor context - have
- * to free allocation using SPI_pfree
+ * Use SPI_modifytuple() here because we are inside SPI environment
+ * but rettuple must be allocated in caller's context.
*/
- /* SPI_pfree(tmptuple); */
+ rettuple = SPI_modifytuple(rel, newtuple, chnattrs, chattrs, newvals, newnulls);
}
else
/* DELETE case */