88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.108 2004/06/0302:08:04 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.109 2004/06/0317:57:09 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -166,12 +166,26 @@ Datum
166166timestamp_recv (PG_FUNCTION_ARGS )
167167{
168168StringInfo buf = (StringInfo )PG_GETARG_POINTER (0 );
169+ Timestamp timestamp ;
170+ struct pg_tm tt ,
171+ * tm = & tt ;
172+ fsec_t fsec ;
169173
170174#ifdef HAVE_INT64_TIMESTAMP
171- PG_RETURN_TIMESTAMP (( Timestamp )pq_getmsgint64 (buf ) );
175+ timestamp = ( Timestamp )pq_getmsgint64 (buf );
172176#else
173- PG_RETURN_TIMESTAMP (( Timestamp )pq_getmsgfloat8 (buf ) );
177+ timestamp = ( Timestamp )pq_getmsgfloat8 (buf );
174178#endif
179+
180+ /* rangecheck: see if timestamp_out would like it */
181+ if (TIMESTAMP_NOT_FINITE (timestamp ))
182+ /* ok */ ;
183+ else if (timestamp2tm (timestamp ,NULL ,tm ,& fsec ,NULL )!= 0 )
184+ ereport (ERROR ,
185+ (errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
186+ errmsg ("timestamp out of range" )));
187+
188+ PG_RETURN_TIMESTAMP (timestamp );
175189}
176190
177191/*
@@ -393,12 +407,28 @@ Datum
393407timestamptz_recv (PG_FUNCTION_ARGS )
394408{
395409StringInfo buf = (StringInfo )PG_GETARG_POINTER (0 );
410+ TimestampTz timestamp ;
411+ int tz ;
412+ struct pg_tm tt ,
413+ * tm = & tt ;
414+ fsec_t fsec ;
415+ char * tzn ;
396416
397417#ifdef HAVE_INT64_TIMESTAMP
398- PG_RETURN_TIMESTAMPTZ (( TimestampTz )pq_getmsgint64 (buf ) );
418+ timestamp = ( TimestampTz )pq_getmsgint64 (buf );
399419#else
400- PG_RETURN_TIMESTAMPTZ (( TimestampTz )pq_getmsgfloat8 (buf ) );
420+ timestamp = ( TimestampTz )pq_getmsgfloat8 (buf );
401421#endif
422+
423+ /* rangecheck: see if timestamptz_out would like it */
424+ if (TIMESTAMP_NOT_FINITE (timestamp ))
425+ /* ok */ ;
426+ else if (timestamp2tm (timestamp ,& tz ,tm ,& fsec ,& tzn )!= 0 )
427+ ereport (ERROR ,
428+ (errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
429+ errmsg ("timestamp out of range" )));
430+
431+ PG_RETURN_TIMESTAMPTZ (timestamp );
402432}
403433
404434/*
@@ -933,13 +963,8 @@ dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
933963int
934964timestamp2tm (Timestamp dt ,int * tzp ,struct pg_tm * tm ,fsec_t * fsec ,char * * tzn )
935965{
936- #ifdef HAVE_INT64_TIMESTAMP
937- int date ;
938- int64 time ;
939- #else
940- double date ;
941- double time ;
942- #endif
966+ Timestamp date ;
967+ Timestamp time ;
943968pg_time_t utime ;
944969
945970/*
@@ -950,7 +975,7 @@ timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, char **tzn)
950975if (HasCTZSet && (tzp != NULL ))
951976{
952977#ifdef HAVE_INT64_TIMESTAMP
953- dt -= ( CTimeZone * INT64CONST (1000000 ) );
978+ dt -= CTimeZone * INT64CONST (1000000 );
954979#else
955980dt -= CTimeZone ;
956981#endif
@@ -975,13 +1000,13 @@ timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, char **tzn)
9751000}
9761001#endif
9771002
978- /* Julian day routine does not work for negative Julian days */
979- if (date < - POSTGRES_EPOCH_JDATE )
980- return -1 ;
981-
9821003/* add offset to go from J2000 back to standard Julian date */
9831004date += POSTGRES_EPOCH_JDATE ;
9841005
1006+ /* Julian day routine does not work for negative Julian days */
1007+ if (date < 0 || date > (Timestamp )INT_MAX )
1008+ return -1 ;
1009+
9851010j2date ((int )date ,& tm -> tm_year ,& tm -> tm_mon ,& tm -> tm_mday );
9861011dt2time (time ,& tm -> tm_hour ,& tm -> tm_min ,& tm -> tm_sec ,fsec );
9871012