88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.84 2003/05/12 23:08:50 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.85 2003/07/04 18:21:13 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -1052,6 +1052,8 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, fsec_t *fsec, char **tzn)
10521052 * Convert a tm structure to a timestamp data type.
10531053 * Note that year is _not_ 1900-based, but is an explicit full value.
10541054 * Also, month is one-based, _not_ zero-based.
1055+ *
1056+ * Returns -1 on failure (overflow).
10551057 */
10561058int
10571059tm2timestamp (struct tm * tm ,fsec_t fsec ,int * tzp ,Timestamp * result )
@@ -1072,10 +1074,13 @@ tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, Timestamp *result)
10721074date = date2j (tm -> tm_year ,tm -> tm_mon ,tm -> tm_mday )- POSTGRES_EPOCH_JDATE ;
10731075time = time2t (tm -> tm_hour ,tm -> tm_min ,tm -> tm_sec ,fsec );
10741076#ifdef HAVE_INT64_TIMESTAMP
1075- * result = ((date * INT64CONST (86400000000 ))+ time );
1076- if ((* result < 0 && date >=0 )|| (* result >=0 && date < 0 ))
1077- elog (ERROR ,"TIMESTAMP out of range '%04d-%02d-%02d'" ,
1078- tm -> tm_year ,tm -> tm_mon ,tm -> tm_mday );
1077+ * result = (date * INT64CONST (86400000000 ))+ time ;
1078+ /* check for major overflow */
1079+ if ((* result - time ) /INT64CONST (86400000000 )!= date )
1080+ return -1 ;
1081+ /* check for just-barely overflow (okay except time-of-day wraps) */
1082+ if ((* result < 0 ) ? (date >=0 ) : (date < 0 ))
1083+ return -1 ;
10791084#else
10801085* result = ((date * 86400 )+ time );
10811086#endif