Skip to content

Commit 5e8b7b0

Browse files
committed
Allow moddatetime's target column to be of type timestamptz.
Dirk Heinrichs
1 parent 0921165 commit 5e8b7b0

File tree

2 files changed

+25
-15
lines changed

2 files changed

+25
-15
lines changed

contrib/spi/moddatetime.c

+22-14
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ moddatetime(PG_FUNCTION_ARGS)
3232
Trigger *trigger; /* to get trigger name */
3333
int nargs; /* # of arguments */
3434
int attnum; /* positional number of field to change */
35+
Oid atttypid; /* type OID of field to change */
3536
Datum newdt; /* The current datetime. */
3637
char **args; /* arguments */
3738
char *relname; /* triggered relation name */
@@ -75,21 +76,15 @@ moddatetime(PG_FUNCTION_ARGS)
7576
/* must be the field layout? */
7677
tupdesc = rel->rd_att;
7778

78-
/* Get the current datetime. */
79-
newdt = DirectFunctionCall3(timestamp_in,
80-
CStringGetDatum("now"),
81-
ObjectIdGetDatum(InvalidOid),
82-
Int32GetDatum(-1));
83-
8479
/*
8580
* This gets the position in the tuple of the field we want. args[0] being
8681
* the name of the field to update, as passed in from the trigger.
8782
*/
8883
attnum = SPI_fnumber(tupdesc, args[0]);
8984

9085
/*
91-
* This is were we check to see if the field we are supposed to update
92-
* even exits. The above function must return -1 if name not found?
86+
* This is where we check to see if the field we are supposed to update
87+
* even exists. The above function must return -1 if name not found?
9388
*/
9489
if (attnum < 0)
9590
ereport(ERROR,
@@ -98,20 +93,33 @@ moddatetime(PG_FUNCTION_ARGS)
9893
relname, args[0])));
9994

10095
/*
101-
* OK, this is where we make sure the timestamp field that we are
102-
* modifying is really a timestamp field. Hay, error checking, what a
103-
* novel idea !-)
96+
* Check the target field has an allowed type, and get the current
97+
* datetime as a value of that type.
10498
*/
105-
if (SPI_gettypeid(tupdesc, attnum) != TIMESTAMPOID)
99+
atttypid = SPI_gettypeid(tupdesc, attnum);
100+
if (atttypid == TIMESTAMPOID)
101+
newdt = DirectFunctionCall3(timestamp_in,
102+
CStringGetDatum("now"),
103+
ObjectIdGetDatum(InvalidOid),
104+
Int32GetDatum(-1));
105+
else if (atttypid == TIMESTAMPTZOID)
106+
newdt = DirectFunctionCall3(timestamptz_in,
107+
CStringGetDatum("now"),
108+
ObjectIdGetDatum(InvalidOid),
109+
Int32GetDatum(-1));
110+
else
111+
{
106112
ereport(ERROR,
107113
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
108-
errmsg("attribute \"%s\" of \"%s\" must be type TIMESTAMP",
114+
errmsg("attribute \"%s\" of \"%s\" must be type TIMESTAMP or TIMESTAMPTZ",
109115
args[0], relname)));
116+
newdt = (Datum) 0; /* keep compiler quiet */
117+
}
110118

111119
/* 1 is the number of items in the arrays attnum and newdt.
112120
attnum is the positional number of the field to be updated.
113121
newdt is the new datetime stamp.
114-
NOTE that attnum and newdt are not arrays, but then a 1 ellement array
122+
NOTE that attnum and newdt are not arrays, but then a 1 element array
115123
is not an array any more then they are. Thus, they can be considered a
116124
one element array.
117125
*/

doc/src/sgml/contrib-spi.sgml

+3-1
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,9 @@ CREATE TABLE mytab (
211211
<para>
212212
To use, create a <literal>BEFORE UPDATE</>
213213
trigger using this function. Specify a single trigger
214-
argument: the name of the <type>timestamp</> column to be modified.
214+
argument: the name of the column to be modified.
215+
The column must be of type <type>timestamp</> or <type>timestamp with
216+
time zone</>.
215217
</para>
216218

217219
<para>

0 commit comments

Comments
 (0)