diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2003-07-04 18:21:14 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2003-07-04 18:21:14 +0000 |
commit | 841b4a2d5552fcee2333dff53e66052fbee7bd22 (patch) | |
tree | 3daf58ab3f61b70db10f8403c3572bbb25734159 /src | |
parent | 3abbce39d5b6988f06c432dc1a18da1d7dd2f9c3 (diff) | |
download | postgresql-841b4a2d5552fcee2333dff53e66052fbee7bd22.tar.gz postgresql-841b4a2d5552fcee2333dff53e66052fbee7bd22.zip |
tm2timestamp should return -1, not elog, on overflow. (In the backend
this is merely an API inconsistency, but in ecpg it's fatal.) Also,
fix misconceived overflow test in HAVE_INT64_TIMESTAMP case.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/utils/adt/timestamp.c | 15 | ||||
-rw-r--r-- | src/interfaces/ecpg/pgtypeslib/timestamp.c | 13 |
2 files changed, 19 insertions, 9 deletions
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index 6cfd2bf1ec6..6cf4f3667cf 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.84 2003/05/12 23:08:50 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.85 2003/07/04 18:21:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1052,6 +1052,8 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, fsec_t *fsec, char **tzn) * Convert a tm structure to a timestamp data type. * Note that year is _not_ 1900-based, but is an explicit full value. * Also, month is one-based, _not_ zero-based. + * + * Returns -1 on failure (overflow). */ int tm2timestamp(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) date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE; time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec); #ifdef HAVE_INT64_TIMESTAMP - *result = ((date * INT64CONST(86400000000)) + time); - if ((*result < 0 && date >= 0) || (*result >= 0 && date < 0)) - elog(ERROR, "TIMESTAMP out of range '%04d-%02d-%02d'", - tm->tm_year, tm->tm_mon, tm->tm_mday); + *result = (date * INT64CONST(86400000000)) + time; + /* check for major overflow */ + if ((*result - time) / INT64CONST(86400000000) != date) + return -1; + /* check for just-barely overflow (okay except time-of-day wraps) */ + if ((*result < 0) ? (date >= 0) : (date < 0)) + return -1; #else *result = ((date * 86400) + time); #endif diff --git a/src/interfaces/ecpg/pgtypeslib/timestamp.c b/src/interfaces/ecpg/pgtypeslib/timestamp.c index 6bc2d5e5ad2..564e1f83c6b 100644 --- a/src/interfaces/ecpg/pgtypeslib/timestamp.c +++ b/src/interfaces/ecpg/pgtypeslib/timestamp.c @@ -44,6 +44,8 @@ dt2local(Timestamp dt, int tz) * Convert a tm structure to a timestamp data type. * Note that year is _not_ 1900-based, but is an explicit full value. * Also, month is one-based, _not_ zero-based. + * + * Returns -1 on failure (overflow). */ static int tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, Timestamp *result) @@ -64,10 +66,13 @@ tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, Timestamp *result) date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1); time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec); #ifdef HAVE_INT64_TIMESTAMP - *result = ((date * INT64CONST(86400000000)) + time); - if ((*result < 0 && date >= 0) || (*result >= 0 && date < 0)) - elog(ERROR, "TIMESTAMP out of range '%04d-%02d-%02d'", - tm->tm_year, tm->tm_mon, tm->tm_mday); + *result = (date * INT64CONST(86400000000)) + time; + /* check for major overflow */ + if ((*result - time) / INT64CONST(86400000000) != date) + return -1; + /* check for just-barely overflow (okay except time-of-day wraps) */ + if ((*result < 0) ? (date >= 0) : (date < 0)) + return -1; #else *result = ((date * 86400) + time); #endif |