When checking for datetime field overflow, we should allow a fractional-second

part that rounds up to exactly 1.0 second.  The previous coding rejected input
like "00:12:57.9999999999999999999999999999", with the exact number of nines
needed to cause failure varying depending on float-timestamp option and
possibly on platform.  Obviously this should round up to the next integral
second, if we don't have enough precision to distinguish the value from that.
Per bug #4789 from Robert Kruus.

In passing, fix a missed check for fractional seconds in one copy of the
"is it greater than 24:00:00" code.

Broken all the way back, so patch all the way back.
This commit is contained in:
Tom Lane 2009-05-01 19:29:34 +00:00
parent 6e7b2d846c
commit 7c26416ffd

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.137.4.8 2009/03/05 14:29:12 heikki Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.137.4.9 2009/05/01 19:29:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -2207,13 +2207,13 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
if ((tm->tm_hour < 0) || (tm->tm_hour > 23)
|| (tm->tm_min < 0) || (tm->tm_min > 59)
|| (tm->tm_sec < 0) || (tm->tm_sec > 60)
|| (*fsec < INT64CONST(0)) || (*fsec >= INT64CONST(1000000)))
|| (*fsec < INT64CONST(0)) || (*fsec > INT64CONST(1000000)))
return DTERR_FIELD_OVERFLOW;
#else
if ((tm->tm_hour < 0) || (tm->tm_hour > 23)
|| (tm->tm_min < 0) || (tm->tm_min > 59)
|| (tm->tm_sec < 0) || (tm->tm_sec > 60)
|| (*fsec < 0) || (*fsec >= 1))
|| (*fsec < 0) || (*fsec > 1))
return DTERR_FIELD_OVERFLOW;
#endif
@ -2493,13 +2493,13 @@ DecodeTime(char *str, int fmask, int *tmask, struct pg_tm * tm, fsec_t *fsec)
if ((tm->tm_hour < 0)
|| (tm->tm_min < 0) || (tm->tm_min > 59)
|| (tm->tm_sec < 0) || (tm->tm_sec > 60)
|| (*fsec < INT64CONST(0)) || (*fsec >= INT64CONST(1000000)))
|| (*fsec < INT64CONST(0)) || (*fsec > INT64CONST(1000000)))
return DTERR_FIELD_OVERFLOW;
#else
if ((tm->tm_hour < 0)
|| (tm->tm_min < 0) || (tm->tm_min > 59)
|| (tm->tm_sec < 0) || (tm->tm_sec > 60)
|| (*fsec < 0) || (*fsec >= 1))
|| (*fsec < 0) || (*fsec > 1))
return DTERR_FIELD_OVERFLOW;
#endif