Am 04.11.2010 04:55, schrieb Tom Lane: > I don't actually see any point in having two functions at all. Since > the trigger is examining the column type internally, it could perfectly > well do the right thing at runtime depending on column type.
Got the point. Here's another patch, hope my limited C skills are sufficient... Works here, at least. BTW: Is there a way to achieve the same in pure PL/pgSQL or PL/perl? Bye... Dirk
diff -u spi.old/moddatetime.c spi/moddatetime.c --- spi.old/moddatetime.c 2010-10-01 15:35:31.000000000 +0200 +++ spi/moddatetime.c 2010-11-04 19:32:11.877235825 +0100 @@ -38,6 +38,7 @@ Relation rel; /* triggered relation */ HeapTuple rettuple = NULL; TupleDesc tupdesc; /* tuple description */ + Oid stampOid; if (!CALLED_AS_TRIGGER(fcinfo)) /* internal error */ @@ -75,12 +76,6 @@ /* 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. @@ -102,16 +97,29 @@ * modifying is really a timestamp field. Hay, error checking, what a * novel idea !-) */ - if (SPI_gettypeid(tupdesc, attnum) != TIMESTAMPOID) - ereport(ERROR, - (errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION), - errmsg("attribute \"%s\" of \"%s\" must be type TIMESTAMP", - args[0], relname))); + stampOid = SPI_gettypeid(tupdesc, attnum); + if (stampOid == TIMESTAMPOID) + /* Get the current datetime. */ + newdt = DirectFunctionCall3(timestamp_in, + CStringGetDatum("now"), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); + else if (stampOid == TIMESTAMPTZOID) + /* Get the current datetime. */ + 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", + args[0], relname))); /* 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. */
signature.asc
Description: OpenPGP digital signature