aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/timestamp.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2019-11-07 11:22:52 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2019-11-07 11:23:06 -0500
commit8d380864a523362777d325872997ae706d1d34e1 (patch)
treedd08113ba32e223e410f4997becd7daa8c7590d4 /src/backend/utils/adt/timestamp.c
parent1accf997482122d69493f942a6aa89cf34b3fd75 (diff)
downloadpostgresql-8d380864a523362777d325872997ae706d1d34e1.tar.gz
postgresql-8d380864a523362777d325872997ae706d1d34e1.zip
Fix integer-overflow edge case detection in interval_mul and pgbench.
This patch adopts the overflow check logic introduced by commit cbdb8b4c0 into two more places. interval_mul() failed to notice if it computed a new microseconds value that was one more than INT64_MAX, and pgbench's double-to-int64 logic had the same sorts of edge-case problems that cbdb8b4c0 fixed in the core code. To make this easier to get right in future, put the guts of the checks into new macros in c.h, and add commentary about how to use the macros correctly. Back-patch to all supported branches, as we did with the previous fix. Yuya Watari Discussion: https://postgr.es/m/CAJ2pMkbkkFw2hb9Qb1Zj8d06EhWAQXFLy73St4qWv6aX=vqnjw@mail.gmail.com
Diffstat (limited to 'src/backend/utils/adt/timestamp.c')
-rw-r--r--src/backend/utils/adt/timestamp.c10
1 files changed, 1 insertions, 9 deletions
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index d24ab8560c8..13b24af80ce 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -44,14 +44,6 @@
#define SAMESIGN(a,b) (((a) < 0) == ((b) < 0))
-#ifndef INT64_MAX
-#define INT64_MAX INT64CONST(0x7FFFFFFFFFFFFFFF)
-#endif
-
-#ifndef INT64_MIN
-#define INT64_MIN (-INT64CONST(0x7FFFFFFFFFFFFFFF) - 1)
-#endif
-
/* Set at postmaster start */
TimestampTz PgStartTime;
@@ -3417,7 +3409,7 @@ interval_mul(PG_FUNCTION_ARGS)
result->day += (int32) month_remainder_days;
#ifdef HAVE_INT64_TIMESTAMP
result_double = rint(span->time * factor + sec_remainder * USECS_PER_SEC);
- if (result_double > INT64_MAX || result_double < INT64_MIN)
+ if (isnan(result_double) || !FLOAT8_FITS_IN_INT64(result_double))
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("interval out of range")));