aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-09-26 01:10:42 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-09-26 01:10:42 +0000
commit6f21c57a975acdc600c22f16521f2f6a3847e83d (patch)
tree8808cfcab28e5e917955d301409a41fb439a8683 /src
parent93407d3998cc8717993dbc102f854a478985bc19 (diff)
downloadpostgresql-6f21c57a975acdc600c22f16521f2f6a3847e83d.tar.gz
postgresql-6f21c57a975acdc600c22f16521f2f6a3847e83d.zip
In the integer-datetimes case, date2timestamp and date2timestamptz need
to check for overflow because the legal range of type date is actually wider than timestamp's. Problem found by Neil Conway.
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/date.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c
index c3cc78977ff..be37584190e 100644
--- a/src/backend/utils/adt/date.c
+++ b/src/backend/utils/adt/date.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.135 2007/08/04 01:26:53 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.136 2007/09/26 01:10:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -336,16 +336,27 @@ date_mii(PG_FUNCTION_ARGS)
* time zone
*/
+static Timestamp
+date2timestamp(DateADT dateVal)
+{
+ Timestamp result;
+
#ifdef HAVE_INT64_TIMESTAMP
-/* date is days since 2000, timestamp is microseconds since same... */
-#define date2timestamp(dateVal) \
- ((Timestamp) ((dateVal) * USECS_PER_DAY))
+ /* date is days since 2000, timestamp is microseconds since same... */
+ result = dateVal * USECS_PER_DAY;
+ /* Date's range is wider than timestamp's, so must check for overflow */
+ if (result / USECS_PER_DAY != dateVal)
+ ereport(ERROR,
+ (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+ errmsg("date out of range for timestamp")));
#else
-/* date is days since 2000, timestamp is seconds since same... */
-#define date2timestamp(dateVal) \
- ((Timestamp) ((dateVal) * (double)SECS_PER_DAY))
+ /* date is days since 2000, timestamp is seconds since same... */
+ result = dateVal * (double) SECS_PER_DAY;
#endif
+ return result;
+}
+
static TimestampTz
date2timestamptz(DateADT dateVal)
{
@@ -364,6 +375,11 @@ date2timestamptz(DateADT dateVal)
#ifdef HAVE_INT64_TIMESTAMP
result = dateVal * USECS_PER_DAY + tz * USECS_PER_SEC;
+ /* Date's range is wider than timestamp's, so must check for overflow */
+ if ((result - tz * USECS_PER_SEC) / USECS_PER_DAY != dateVal)
+ ereport(ERROR,
+ (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+ errmsg("date out of range for timestamp")));
#else
result = dateVal * (double) SECS_PER_DAY + tz;
#endif