diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2006-10-18 16:43:14 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2006-10-18 16:43:14 +0000 |
commit | 877f08da14719a1bead6154785ab45714d347998 (patch) | |
tree | fe730f9ddff1b81fb8d28d97924d1f81565d8370 /src/backend/utils/adt/datetime.c | |
parent | 723f716be04c3e59bb7fdaa6ff044bda6ea4f94b (diff) | |
download | postgresql-877f08da14719a1bead6154785ab45714d347998.tar.gz postgresql-877f08da14719a1bead6154785ab45714d347998.zip |
Fix up timetz input so that a date is required only when the specified
timezone actually has a daylight-savings rule. This avoids breaking
cases that used to work because they went through the DecodePosixTimezone
code path. Per contrib regression failures (mea culpa for not running
those yesterday...). Also document the already-applied change to allow
GMT offsets up to 14 hours.
Diffstat (limited to 'src/backend/utils/adt/datetime.c')
-rw-r--r-- | src/backend/utils/adt/datetime.c | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c index cfb29dce568..f72d1c6b403 100644 --- a/src/backend/utils/adt/datetime.c +++ b/src/backend/utils/adt/datetime.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.173 2006/10/17 21:03:21 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.174 2006/10/18 16:43:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1199,6 +1199,18 @@ DecodeDateTime(char **field, int *ftype, int nf, ptype = val; break; + case UNKNOWN_FIELD: + /* + * Before giving up and declaring error, check to see + * if it is an all-alpha timezone name. + */ + namedTz = pg_tzset(field[i]); + if (!namedTz) + return DTERR_BAD_FORMAT; + /* we'll apply the zone setting below */ + tmask = DTK_M(TZ); + break; + default: return DTERR_BAD_FORMAT; } @@ -1911,6 +1923,18 @@ DecodeTimeOnly(char **field, int *ftype, int nf, ptype = val; break; + case UNKNOWN_FIELD: + /* + * Before giving up and declaring error, check to see + * if it is an all-alpha timezone name. + */ + namedTz = pg_tzset(field[i]); + if (!namedTz) + return DTERR_BAD_FORMAT; + /* we'll apply the zone setting below */ + tmask = DTK_M(TZ); + break; + default: return DTERR_BAD_FORMAT; } @@ -1952,18 +1976,28 @@ DecodeTimeOnly(char **field, int *ftype, int nf, /* * If we had a full timezone spec, compute the offset (we could not - * do it before, because we need the date to resolve DST status). + * do it before, because we may need the date to resolve DST status). */ if (namedTz != NULL) { - /* a date has to be specified */ - if ((fmask & DTK_DATE_M) != DTK_DATE_M) - return DTERR_BAD_FORMAT; + long int gmtoff; + /* daylight savings time modifier disallowed with full TZ */ if (fmask & DTK_M(DTZMOD)) return DTERR_BAD_FORMAT; - *tzp = DetermineTimeZoneOffset(tm, namedTz); + /* if non-DST zone, we do not need to know the date */ + if (pg_get_timezone_offset(namedTz, &gmtoff)) + { + *tzp = -(int) gmtoff; + } + else + { + /* a date has to be specified */ + if ((fmask & DTK_DATE_M) != DTK_DATE_M) + return DTERR_BAD_FORMAT; + *tzp = DetermineTimeZoneOffset(tm, namedTz); + } } /* timezone not specified? then find local timezone if possible */ |