88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.135 2007/08/04 01:26:53 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.136 2007/09/26 01:10:42 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -336,16 +336,27 @@ date_mii(PG_FUNCTION_ARGS)
336336 * time zone
337337 */
338338
339+ static Timestamp
340+ date2timestamp (DateADT dateVal )
341+ {
342+ Timestamp result ;
343+
339344#ifdef HAVE_INT64_TIMESTAMP
340- /* date is days since 2000, timestamp is microseconds since same... */
341- #define date2timestamp (dateVal ) \
342- ((Timestamp) ((dateVal) * USECS_PER_DAY))
345+ /* date is days since 2000, timestamp is microseconds since same... */
346+ result = dateVal * USECS_PER_DAY ;
347+ /* Date's range is wider than timestamp's, so must check for overflow */
348+ if (result /USECS_PER_DAY != dateVal )
349+ ereport (ERROR ,
350+ (errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
351+ errmsg ("date out of range for timestamp" )));
343352#else
344- /* date is days since 2000, timestamp is seconds since same... */
345- #define date2timestamp (dateVal ) \
346- ((Timestamp) ((dateVal) * (double)SECS_PER_DAY))
353+ /* date is days since 2000, timestamp is seconds since same... */
354+ result = dateVal * (double )SECS_PER_DAY ;
347355#endif
348356
357+ return result ;
358+ }
359+
349360static TimestampTz
350361date2timestamptz (DateADT dateVal )
351362{
@@ -364,6 +375,11 @@ date2timestamptz(DateADT dateVal)
364375
365376#ifdef HAVE_INT64_TIMESTAMP
366377result = dateVal * USECS_PER_DAY + tz * USECS_PER_SEC ;
378+ /* Date's range is wider than timestamp's, so must check for overflow */
379+ if ((result - tz * USECS_PER_SEC ) /USECS_PER_DAY != dateVal )
380+ ereport (ERROR ,
381+ (errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
382+ errmsg ("date out of range for timestamp" )));
367383#else
368384result = dateVal * (double )SECS_PER_DAY + tz ;
369385#endif