diff --git a/contrib/spi/moddatetime.c b/contrib/spi/moddatetime.c
index 9a1addb78a..f5a0d93ef5 100644
--- a/contrib/spi/moddatetime.c
+++ b/contrib/spi/moddatetime.c
@@ -32,6 +32,7 @@ moddatetime(PG_FUNCTION_ARGS)
Trigger *trigger; /* to get trigger name */
int nargs; /* # of arguments */
int attnum; /* positional number of field to change */
+ Oid atttypid; /* type OID of field to change */
Datum newdt; /* The current datetime. */
char **args; /* arguments */
char *relname; /* triggered relation name */
@@ -75,12 +76,6 @@ moddatetime(PG_FUNCTION_ARGS)
/* must be the field layout? */
tupdesc = rel->rd_att;
- /* Get the current datetime. */
- newdt = DirectFunctionCall3(timestamp_in,
- CStringGetDatum("now"),
- ObjectIdGetDatum(InvalidOid),
- Int32GetDatum(-1));
-
/*
* This gets the position in the tuple of the field we want. args[0] being
* the name of the field to update, as passed in from the trigger.
@@ -88,8 +83,8 @@ moddatetime(PG_FUNCTION_ARGS)
attnum = SPI_fnumber(tupdesc, args[0]);
/*
- * This is were we check to see if the field we are supposed to update
- * even exits. The above function must return -1 if name not found?
+ * 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?
*/
if (attnum < 0)
ereport(ERROR,
@@ -98,20 +93,33 @@ moddatetime(PG_FUNCTION_ARGS)
relname, args[0])));
/*
- * OK, this is where we make sure the timestamp field that we are
- * modifying is really a timestamp field. Hay, error checking, what a
- * novel idea !-)
+ * Check the target field has an allowed type, and get the current
+ * datetime as a value of that type.
*/
- if (SPI_gettypeid(tupdesc, attnum) != TIMESTAMPOID)
+ atttypid = SPI_gettypeid(tupdesc, attnum);
+ if (atttypid == TIMESTAMPOID)
+ newdt = DirectFunctionCall3(timestamp_in,
+ CStringGetDatum("now"),
+ ObjectIdGetDatum(InvalidOid),
+ Int32GetDatum(-1));
+ else if (atttypid == TIMESTAMPTZOID)
+ newdt = DirectFunctionCall3(timestamptz_in,
+ CStringGetDatum("now"),
+ ObjectIdGetDatum(InvalidOid),
+ Int32GetDatum(-1));
+ else
+ {
ereport(ERROR,
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
- errmsg("attribute \"%s\" of \"%s\" must be type TIMESTAMP",
+ errmsg("attribute \"%s\" of \"%s\" must be type TIMESTAMP or TIMESTAMPTZ",
args[0], relname)));
+ newdt = (Datum) 0; /* keep compiler quiet */
+ }
/* 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 ellement array
+ 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.
*/
diff --git a/doc/src/sgml/contrib-spi.sgml b/doc/src/sgml/contrib-spi.sgml
index 0f5a1f6787..a8761f61b7 100644
--- a/doc/src/sgml/contrib-spi.sgml
+++ b/doc/src/sgml/contrib-spi.sgml
@@ -211,7 +211,9 @@ CREATE TABLE mytab (
To use, create a BEFORE UPDATE>
trigger using this function. Specify a single trigger
- argument: the name of the timestamp> column to be modified.
+ argument: the name of the column to be modified.
+ The column must be of type timestamp> or timestamp with
+ time zone>.