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.
 */

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to