1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-26 12:21:12 +03:00

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 a2da77cdb4 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
This commit is contained in:
Peter Eisentraut
2022-04-19 20:38:53 +02:00
parent a62bff74b1
commit f2a2bf66c8
2 changed files with 12 additions and 6 deletions

View File

@ -5308,10 +5308,16 @@ interval_part_common(PG_FUNCTION_ARGS, bool retnumeric)
int64 secs_from_day_month;
int64 val;
/* this always fits into int64 */
secs_from_day_month = ((int64) DAYS_PER_YEAR * (interval->month / MONTHS_PER_YEAR) +
(int64) DAYS_PER_MONTH * (interval->month % MONTHS_PER_YEAR) +
interval->day) * SECS_PER_DAY;
/*
* To do this calculation in integer arithmetic even though
* DAYS_PER_YEAR is fractional, multiply everything by 4 and then
* divide by 4 again at the end. This relies on DAYS_PER_YEAR
* being a multiple of 0.25 and on SECS_PER_DAY being a multiple
* of 4.
*/
secs_from_day_month = ((int64) (4 * DAYS_PER_YEAR) * (interval->month / MONTHS_PER_YEAR) +
(int64) (4 * DAYS_PER_MONTH) * (interval->month % MONTHS_PER_YEAR) +
(int64) 4 * interval->day) * (SECS_PER_DAY / 4);
/*---
* result = secs_from_day_month + interval->time / 1'000'000