summaryrefslogtreecommitdiff
path: root/contrib/spi/moddatetime.c
diff options
context:
space:
mode:
authorMichael P2011-07-05 03:16:11 +0000
committerMichael P2011-07-06 03:40:35 +0000
commit0bbfc1e6338b5d98d6cb83fa75f2c38f527d4d4b (patch)
tree46fa412a31d08ea6e53d488ae7bc231df0b273da /contrib/spi/moddatetime.c
parent091b0e828cf0fd5bbd1f9ae58ab96fc983e55d77 (diff)
parenta4bebdd92624e018108c2610fc3f2c1584b6c687 (diff)
Merge commit 'a4bebdd92624e018108c2610fc3f2c1584b6c687' into master
This is the commit merge of Postgres-XC with the intersection of PostgreSQL REL9_1_STABLE and master branches. Conflicts: COPYRIGHT contrib/pgbench/pgbench.c src/Makefile src/backend/access/transam/recovery.conf.sample src/backend/access/transam/varsup.c src/backend/access/transam/xlog.c src/backend/catalog/Makefile src/backend/catalog/dependency.c src/backend/catalog/system_views.sql src/backend/commands/copy.c src/backend/commands/explain.c src/backend/commands/sequence.c src/backend/commands/tablecmds.c src/backend/commands/vacuum.c src/backend/executor/nodeAgg.c src/backend/nodes/copyfuncs.c src/backend/nodes/equalfuncs.c src/backend/nodes/outfuncs.c src/backend/nodes/readfuncs.c src/backend/optimizer/path/allpaths.c src/backend/optimizer/plan/createplan.c src/backend/optimizer/plan/setrefs.c src/backend/parser/gram.y src/backend/parser/parse_utilcmd.c src/backend/postmaster/postmaster.c src/backend/rewrite/rewriteHandler.c src/backend/storage/lmgr/proc.c src/backend/tcop/postgres.c src/backend/utils/adt/ruleutils.c src/backend/utils/init/postinit.c src/backend/utils/misc/guc.c src/backend/utils/misc/postgresql.conf.sample src/backend/utils/sort/tuplesort.c src/bin/initdb/initdb.c src/bin/pg_ctl/pg_ctl.c src/bin/pg_dump/pg_dump.c src/include/access/xlog.h src/include/catalog/catversion.h src/include/catalog/indexing.h src/include/catalog/pg_aggregate.h src/include/catalog/pg_proc.h src/include/commands/copy.h src/include/nodes/parsenodes.h src/include/nodes/primnodes.h src/include/optimizer/pathnode.h src/include/parser/kwlist.h src/include/storage/procarray.h src/test/regress/expected/.gitignore src/test/regress/expected/aggregates.out src/test/regress/expected/alter_table.out src/test/regress/expected/bit.out src/test/regress/expected/box.out src/test/regress/expected/delete.out src/test/regress/expected/float4.out src/test/regress/expected/float8.out src/test/regress/expected/int2.out src/test/regress/expected/int8.out src/test/regress/expected/interval.out src/test/regress/expected/numeric.out src/test/regress/expected/point.out src/test/regress/expected/polygon.out src/test/regress/expected/sequence.out src/test/regress/expected/timestamp.out src/test/regress/expected/timestamptz.out src/test/regress/expected/transactions.out src/test/regress/expected/window.out src/test/regress/input/misc.source src/test/regress/output/create_misc_1.source src/test/regress/output/misc.source src/test/regress/sql/aggregates.sql src/test/regress/sql/alter_table.sql src/test/regress/sql/bit.sql src/test/regress/sql/box.sql src/test/regress/sql/delete.sql src/test/regress/sql/domain.sql src/test/regress/sql/float4.sql src/test/regress/sql/float8.sql src/test/regress/sql/int2.sql src/test/regress/sql/int8.sql src/test/regress/sql/interval.sql src/test/regress/sql/lseg.sql src/test/regress/sql/numeric.sql src/test/regress/sql/path.sql src/test/regress/sql/point.sql src/test/regress/sql/polygon.sql src/test/regress/sql/portals.sql src/test/regress/sql/sequence.sql src/test/regress/sql/timestamp.sql src/test/regress/sql/timestamptz.sql src/test/regress/sql/transactions.sql src/test/regress/sql/window.sql src/test/regress/sql/with.sql
Diffstat (limited to 'contrib/spi/moddatetime.c')
-rw-r--r--contrib/spi/moddatetime.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/contrib/spi/moddatetime.c b/contrib/spi/moddatetime.c
index 0b4d3ba351..d02560c298 100644
--- a/contrib/spi/moddatetime.c
+++ b/contrib/spi/moddatetime.c
@@ -1,7 +1,7 @@
/*
moddatetime.c
-$PostgreSQL: pgsql/contrib/spi/moddatetime.c,v 1.15 2009/01/07 13:44:36 tgl Exp $
+contrib/spi/moddatetime.c
What is this?
It is a function to be called from a trigger for the purpose of updating
@@ -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 */
@@ -43,17 +44,17 @@ moddatetime(PG_FUNCTION_ARGS)
/* internal error */
elog(ERROR, "moddatetime: not fired by trigger manager");
- if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
+ if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
/* internal error */
- elog(ERROR, "moddatetime: cannot process STATEMENT events");
+ elog(ERROR, "moddatetime: must be fired for row");
- if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
+ if (!TRIGGER_FIRED_BEFORE(trigdata->tg_event))
/* internal error */
elog(ERROR, "moddatetime: must be fired before event");
if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
/* internal error */
- elog(ERROR, "moddatetime: must be fired before event");
+ elog(ERROR, "moddatetime: cannot process INSERT events");
else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
rettuple = trigdata->tg_newtuple;
else
@@ -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.
*/