diff options
Diffstat (limited to 'src/backend/utils/adt/timestamp.c')
-rw-r--r-- | src/backend/utils/adt/timestamp.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index c38f88dba78..ed03c50a6de 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -1509,17 +1509,23 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod, if (interval->time >= INT64CONST(0)) { - interval->time = ((interval->time + - IntervalOffsets[precision]) / - IntervalScales[precision]) * - IntervalScales[precision]; + if (pg_add_s64_overflow(interval->time, + IntervalOffsets[precision], + &interval->time)) + ereturn(escontext, false, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("interval out of range"))); + interval->time -= interval->time % IntervalScales[precision]; } else { - interval->time = -(((-interval->time + - IntervalOffsets[precision]) / - IntervalScales[precision]) * - IntervalScales[precision]); + if (pg_sub_s64_overflow(interval->time, + IntervalOffsets[precision], + &interval->time)) + ereturn(escontext, false, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("interval out of range"))); + interval->time -= interval->time % IntervalScales[precision]; } } } |