0007-Fix-distance-calculation-for-extreme-interval-values.patch
text/x-patch
Filename: 0007-Fix-distance-calculation-for-extreme-interval-values.patch
Type: text/x-patch
Part: 6
Patch
Format: format-patch
Series: patch 0007
Subject: Fix distance calculation for extreme interval values
| File | + | − |
|---|---|---|
| src/backend/access/brin/brin_minmax_multi.c | 4 | 29 |
From 40566b81ff8d34f9a400d9b426b0301e8fbd577f Mon Sep 17 00:00:00 2001
From: Tomas Vondra <tomas.vondra@postgresql.org>
Date: Tue, 17 Oct 2023 20:38:01 +0200
Subject: [PATCH 7/8] Fix distance calculation for extreme interval values
Make sure we can calculate distance even for extreme interval values,
which for extreme values was triggering 'interval out of range' errors.
Instead of building a new interval, calculate the distance directly.
---
src/backend/access/brin/brin_minmax_multi.c | 33 +++------------------
1 file changed, 4 insertions(+), 29 deletions(-)
diff --git a/src/backend/access/brin/brin_minmax_multi.c b/src/backend/access/brin/brin_minmax_multi.c
index 37706e5bf28..9811451b542 100644
--- a/src/backend/access/brin/brin_minmax_multi.c
+++ b/src/backend/access/brin/brin_minmax_multi.c
@@ -2160,45 +2160,20 @@ brin_minmax_multi_distance_interval(PG_FUNCTION_ARGS)
Interval *ia = PG_GETARG_INTERVAL_P(0);
Interval *ib = PG_GETARG_INTERVAL_P(1);
- Interval *result;
int64 dayfraction;
int64 days;
- result = (Interval *) palloc(sizeof(Interval));
-
- result->month = ib->month - ia->month;
- /* overflow check copied from int4mi */
- if (!SAMESIGN(ib->month, ia->month) &&
- !SAMESIGN(result->month, ib->month))
- ereport(ERROR,
- (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
- errmsg("interval out of range")));
-
- result->day = ib->day - ia->day;
- if (!SAMESIGN(ib->day, ia->day) &&
- !SAMESIGN(result->day, ib->day))
- ereport(ERROR,
- (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
- errmsg("interval out of range")));
-
- result->time = ib->time - ia->time;
- if (!SAMESIGN(ib->time, ia->time) &&
- !SAMESIGN(result->time, ib->time))
- ereport(ERROR,
- (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
- errmsg("interval out of range")));
-
/*
* Delta is (fractional) number of days between the intervals. Assume
* months have 30 days for consistency with interval_cmp_internal. We
* don't need to be exact, in the worst case we'll build a bit less
* efficient ranges. But we should not contradict interval_cmp.
*/
- dayfraction = result->time % USECS_PER_DAY;
- days = result->time / USECS_PER_DAY;
- days += result->month * INT64CONST(30);
- days += result->day;
+ dayfraction = (ib->time % USECS_PER_DAY) - (ia->time % USECS_PER_DAY);
+ days = (ib->time / USECS_PER_DAY) - (ia->time / USECS_PER_DAY);
+ days += (int64) ib->day - (int64) ia->day;
+ days += ((int64) ib->month - (int64) ia->month) * INT64CONST(30);
/* convert to double precision */
delta = (double) days + dayfraction / (double) USECS_PER_DAY;
--
2.41.0