From 9f6643ebba9ef1a48b4a9e7c90142cfeb3723ddc Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Mon, 29 Oct 2012 14:47:17 +0100 Subject: [PATCH] RRTimeslice: Use TimestampTz rather than timestamp without time zone. This will, hopefully, avoid a whole lota problems when it comes to using PostRR with daylight savings time, different time zones, etc. --- src/postrr.sql.in | 14 +++++++------- src/rrtimeslice.c | 26 ++++++++++++++------------ 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/postrr.sql.in b/src/postrr.sql.in index 7197726..10aeb77 100644 --- a/src/postrr.sql.in +++ b/src/postrr.sql.in @@ -108,13 +108,13 @@ CREATE CAST (rrtimeslice AS rrtimeslice) WITH FUNCTION RRTimeslice(rrtimeslice, integer, boolean) AS IMPLICIT; -CREATE OR REPLACE FUNCTION Tstamp(rrtimeslice) - RETURNS timestamp - AS 'postrr-@POSTRR_MAJOR_VERSION@.@POSTRR_MINOR_VERSION@', 'rrtimeslice_to_timestamp' +CREATE OR REPLACE FUNCTION Tstamptz(rrtimeslice) + RETURNS timestamptz + AS 'postrr-@POSTRR_MAJOR_VERSION@.@POSTRR_MINOR_VERSION@', 'rrtimeslice_to_timestamptz' LANGUAGE 'C' IMMUTABLE STRICT; -CREATE CAST (rrtimeslice AS timestamp) - WITH FUNCTION Tstamp(rrtimeslice); +CREATE CAST (rrtimeslice AS timestamptz) + WITH FUNCTION Tstamptz(rrtimeslice); -- EXPLICIT CREATE OR REPLACE FUNCTION rrtimeslice_seq_eq(rrtimeslice, rrtimeslice) @@ -302,7 +302,7 @@ CREATE OR REPLACE FUNCTION CData_update(cdata, cdata) AS 'postrr-@POSTRR_MAJOR_VERSION@.@POSTRR_MINOR_VERSION@', 'cdata_update' LANGUAGE 'C' IMMUTABLE; -CREATE OR REPLACE FUNCTION PostRR_update(name, name, name, timestamp, double precision) +CREATE OR REPLACE FUNCTION PostRR_update(name, name, name, timestamptz, double precision) RETURNS cdata LANGUAGE plpgsql AS $$ @@ -348,7 +348,7 @@ BEGIN END; $$; -CREATE OR REPLACE FUNCTION PostRR_update(text, timestamp, double precision) +CREATE OR REPLACE FUNCTION PostRR_update(text, timestamptz, double precision) RETURNS SETOF cdata LANGUAGE plpgsql AS $$ diff --git a/src/rrtimeslice.c b/src/rrtimeslice.c index 7207dea..325d736 100644 --- a/src/rrtimeslice.c +++ b/src/rrtimeslice.c @@ -59,7 +59,7 @@ */ struct rrtimeslice { - Timestamp tstamp; + TimestampTz tstamp; int32 tsid; uint32 seq; }; @@ -207,7 +207,7 @@ PG_FUNCTION_INFO_V1(rrtimeslice_typmodin); PG_FUNCTION_INFO_V1(rrtimeslice_typmodout); PG_FUNCTION_INFO_V1(rrtimeslice_to_rrtimeslice); -PG_FUNCTION_INFO_V1(rrtimeslice_to_timestamp); +PG_FUNCTION_INFO_V1(rrtimeslice_to_timestamptz); PG_FUNCTION_INFO_V1(rrtimeslice_seq_eq); PG_FUNCTION_INFO_V1(rrtimeslice_seq_ne); @@ -259,7 +259,7 @@ rrtimeslice_in(PG_FUNCTION_ARGS) { rrtimeslice_t *tslice; - Timestamp tstamp = 0; + TimestampTz tstamp = 0; int32 typmod; struct pg_tm tm; @@ -295,7 +295,7 @@ rrtimeslice_in(PG_FUNCTION_ARGS) switch (dtype) { case DTK_DATE: - if (tm2timestamp(&tm, fsec, NULL, &tstamp)) + if (tm2timestamp(&tm, fsec, &tz, &tstamp)) ereport(ERROR, ( errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range: %s", time_str) @@ -334,7 +334,9 @@ rrtimeslice_out(PG_FUNCTION_ARGS) struct pg_tm tm; fsec_t fsec = 0; - char *tz = NULL; + int tz = 0; + + char *tz_str = NULL; char ts_str[MAXDATELEN + 1]; char buf_ts[MAXDATELEN + 1]; @@ -353,13 +355,13 @@ rrtimeslice_out(PG_FUNCTION_ARGS) tslice = PG_GETARG_RRTIMESLICE_P(0); if (TIMESTAMP_NOT_FINITE(tslice->tstamp) - || (timestamp2tm(tslice->tstamp, NULL, &tm, &fsec, NULL, NULL) != 0)) + || (timestamp2tm(tslice->tstamp, &tz, &tm, &fsec, &tz_str, NULL) != 0)) ereport(ERROR, ( errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("invalid (non-finite) timestamp") )); else - EncodeDateTime(&tm, fsec, NULL, &tz, DateStyle, buf_ts); + EncodeDateTime(&tm, fsec, &tz, &tz_str, DateStyle, buf_ts); if (! rrtimeslice_get_spec(tslice->tsid, &len, &num)) { memset(&interval, 0, sizeof(interval)); @@ -474,21 +476,21 @@ rrtimeslice_to_rrtimeslice(PG_FUNCTION_ARGS) } /* rrtimeslice_to_rrtimeslice */ Datum -rrtimeslice_to_timestamp(PG_FUNCTION_ARGS) +rrtimeslice_to_timestamptz(PG_FUNCTION_ARGS) { rrtimeslice_t *tslice; if (PG_NARGS() != 1) ereport(ERROR, ( - errmsg("rrtimeslice_to_timestamp() " + errmsg("rrtimeslice_to_timestamptz() " "expects one argument"), - errhint("Usage: rrtimeslice_to_timestamp" + errhint("Usage: rrtimeslice_to_timestamptz" "(rrtimeslice)") )); tslice = PG_GETARG_RRTIMESLICE_P(0); - PG_RETURN_TIMESTAMP(tslice->tstamp); -} /* rrtimeslice_to_timestamp */ + PG_RETURN_TIMESTAMPTZ(tslice->tstamp); +} /* rrtimeslice_to_timestamptz */ int rrtimeslice_seq_cmp_internal(rrtimeslice_t *ts1, rrtimeslice_t *ts2) -- 2.30.2