]> granicus.if.org Git - postgresql/commitdiff
Allow moddatetime's target column to be of type timestamptz.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 4 Nov 2010 20:34:47 +0000 (16:34 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 4 Nov 2010 20:34:47 +0000 (16:34 -0400)
Dirk Heinrichs

contrib/spi/moddatetime.c
doc/src/sgml/contrib-spi.sgml

index 9a1addb78ad838514573039af44cb2e36bf7a5cd..f5a0d93ef5fb7a37bc0384d04ff7a5e9929da173 100644 (file)
@@ -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.
 */
index 0f5a1f6787ad78a23129060f239b283f6780f5f6..a8761f61b7aeef831652bd12951d4d048ab028ae 100644 (file)
@@ -211,7 +211,9 @@ CREATE TABLE mytab (
   <para>
    To use, create a <literal>BEFORE UPDATE</>
    trigger using this function.  Specify a single trigger
-   argument: the name of the <type>timestamp</> column to be modified.
+   argument: the name of the column to be modified.
+   The column must be of type <type>timestamp</> or <type>timestamp with
+   time zone</>.
   </para>
 
   <para>