Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f2a2bf6

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 a62bff7 commit f2a2bf6

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
@@ -5308,10 +5308,16 @@ interval_part_common(PG_FUNCTION_ARGS, bool retnumeric)
53085308
int64 secs_from_day_month;
53095309
int64 val;
53105310

5311-
/* this always fits into int64 */
5312-
secs_from_day_month = ((int64) DAYS_PER_YEAR * (interval->month / MONTHS_PER_YEAR) +
5313-
(int64) DAYS_PER_MONTH * (interval->month % MONTHS_PER_YEAR) +
5314-
interval->day) * SECS_PER_DAY;
5311+
/*
5312+
* To do this calculation in integer arithmetic even though
5313+
* DAYS_PER_YEAR is fractional, multiply everything by 4 and then
5314+
* divide by 4 again at the end. This relies on DAYS_PER_YEAR
5315+
* being a multiple of 0.25 and on SECS_PER_DAY being a multiple
5316+
* of 4.
5317+
*/
5318+
secs_from_day_month = ((int64) (4 * DAYS_PER_YEAR) * (interval->month / MONTHS_PER_YEAR) +
5319+
(int64) (4 * DAYS_PER_MONTH) * (interval->month % MONTHS_PER_YEAR) +
5320+
(int64) 4 * interval->day) * (SECS_PER_DAY / 4);
53155321

53165322
/*---
53175323
* 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
@@ -1655,11 +1655,11 @@ SELECT f1,
16551655
@ 1 min | 0 | 0.000 | 0.000000 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 60.000000
16561656
@ 5 hours | 0 | 0.000 | 0.000000 | 0 | 5 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 18000.000000
16571657
@ 10 days | 0 | 0.000 | 0.000000 | 0 | 0 | 10 | 0 | 1 | 0 | 0 | 0 | 0 | 864000.000000
1658-
@ 34 years | 0 | 0.000 | 0.000000 | 0 | 0 | 0 | 0 | 1 | 34 | 3 | 0 | 0 | 1072224000.000000
1658+
@ 34 years | 0 | 0.000 | 0.000000 | 0 | 0 | 0 | 0 | 1 | 34 | 3 | 0 | 0 | 1072958400.000000
16591659
@ 3 mons | 0 | 0.000 | 0.000000 | 0 | 0 | 0 | 3 | 2 | 0 | 0 | 0 | 0 | 7776000.000000
16601660
@ 14 secs ago | -14000000 | -14000.000 | -14.000000 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | -14.000000
16611661
@ 1 day 2 hours 3 mins 4 secs | 4000000 | 4000.000 | 4.000000 | 3 | 2 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 93784.000000
1662-
@ 6 years | 0 | 0.000 | 0.000000 | 0 | 0 | 0 | 0 | 1 | 6 | 0 | 0 | 0 | 189216000.000000
1662+
@ 6 years | 0 | 0.000 | 0.000000 | 0 | 0 | 0 | 0 | 1 | 6 | 0 | 0 | 0 | 189345600.000000
16631663
@ 5 mons | 0 | 0.000 | 0.000000 | 0 | 0 | 0 | 5 | 2 | 0 | 0 | 0 | 0 | 12960000.000000
16641664
@ 5 mons 12 hours | 0 | 0.000 | 0.000000 | 0 | 12 | 0 | 5 | 2 | 0 | 0 | 0 | 0 | 13003200.000000
16651665
(10 rows)

0 commit comments

Comments
 (0)