Skip to content

Commit 7a8d821

Browse files
committed
Fix extract epoch from interval calculation
The new numeric code for extract epoch from interval accidentally truncated the DAYS_PER_YEAR value to an integer, leading to results that mismatched the floating-point interval_part calculations. The commit a2da77c that introduced this actually contains the regression test change that this reverts. I suppose this was missed at the time. Reported-by: Joseph Koshakow <koshy44@gmail.com> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://www.postgresql.org/message-id/flat/CAAvxfHd5n%3D13NYA2q_tUq%3D3%3DSuWU-CufmTf-Ozj%3DfrEgt7pXwQ%40mail.gmail.com
1 parent c9dea58 commit 7a8d821

File tree

2 files changed

+12
-6
lines changed

2 files changed

+12
-6
lines changed

src/backend/utils/adt/timestamp.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5287,10 +5287,16 @@ interval_part_common(PG_FUNCTION_ARGS, bool retnumeric)
52875287
int64 secs_from_day_month;
52885288
int64 val;
52895289

5290-
/* this always fits into int64 */
5291-
secs_from_day_month = ((int64) DAYS_PER_YEAR * (interval->month / MONTHS_PER_YEAR) +
5292-
(int64) DAYS_PER_MONTH * (interval->month % MONTHS_PER_YEAR) +
5293-
interval->day) * SECS_PER_DAY;
5290+
/*
5291+
* To do this calculation in integer arithmetic even though
5292+
* DAYS_PER_YEAR is fractional, multiply everything by 4 and then
5293+
* divide by 4 again at the end. This relies on DAYS_PER_YEAR
5294+
* being a multiple of 0.25 and on SECS_PER_DAY being a multiple
5295+
* of 4.
5296+
*/
5297+
secs_from_day_month = ((int64) (4 * DAYS_PER_YEAR) * (interval->month / MONTHS_PER_YEAR) +
5298+
(int64) (4 * DAYS_PER_MONTH) * (interval->month % MONTHS_PER_YEAR) +
5299+
(int64) 4 * interval->day) * (SECS_PER_DAY / 4);
52945300

52955301
/*---
52965302
* result = secs_from_day_month + interval->time / 1'000'000

src/test/regress/expected/interval.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -953,11 +953,11 @@ SELECT f1,
953953
@ 1 min | 0 | 0.000 | 0.000000 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 60.000000
954954
@ 5 hours | 0 | 0.000 | 0.000000 | 0 | 5 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 18000.000000
955955
@ 10 days | 0 | 0.000 | 0.000000 | 0 | 0 | 10 | 0 | 1 | 0 | 0 | 0 | 0 | 864000.000000
956-
@ 34 years | 0 | 0.000 | 0.000000 | 0 | 0 | 0 | 0 | 1 | 34 | 3 | 0 | 0 | 1072224000.000000
956+
@ 34 years | 0 | 0.000 | 0.000000 | 0 | 0 | 0 | 0 | 1 | 34 | 3 | 0 | 0 | 1072958400.000000
957957
@ 3 mons | 0 | 0.000 | 0.000000 | 0 | 0 | 0 | 3 | 2 | 0 | 0 | 0 | 0 | 7776000.000000
958958
@ 14 secs ago | -14000000 | -14000.000 | -14.000000 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | -14.000000
959959
@ 1 day 2 hours 3 mins 4 secs | 4000000 | 4000.000 | 4.000000 | 3 | 2 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 93784.000000
960-
@ 6 years | 0 | 0.000 | 0.000000 | 0 | 0 | 0 | 0 | 1 | 6 | 0 | 0 | 0 | 189216000.000000
960+
@ 6 years | 0 | 0.000 | 0.000000 | 0 | 0 | 0 | 0 | 1 | 6 | 0 | 0 | 0 | 189345600.000000
961961
@ 5 mons | 0 | 0.000 | 0.000000 | 0 | 0 | 0 | 5 | 2 | 0 | 0 | 0 | 0 | 12960000.000000
962962
@ 5 mons 12 hours | 0 | 0.000 | 0.000000 | 0 | 12 | 0 | 5 | 2 | 0 | 0 | 0 | 0 | 13003200.000000
963963
(10 rows)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy