BUG #15696: year field of interval type is not rounded to nearest integer

From: PG Bug reporting form <noreply(at)postgresql(dot)org>
To: pgsql-bugs(at)lists(dot)postgresql(dot)org
Cc: 110876189(at)qq(dot)com
Subject: BUG #15696: year field of interval type is not rounded to nearest integer
Date: 2019-03-16 03:55:11
Message-ID: 15696-50cd52decb98f630@postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

The following bug has been logged on the website:

Bug reference: 15696
Logged by: zhou xiaowei
Email address: 110876189(at)qq(dot)com
PostgreSQL version: 11.2
Operating system: Linux x86_64
Description:

all fields of interval type use rule of rounding to nearest integer(by
rint() function), except for year field.
details:
postgres=# select '0.9999999999999999 year'::interval month;
interval
----------
11 mons
(1 row)

postgres=# select '0.9999999999999999 dec'::interval year;
interval
----------
9 years
(1 row)

postgres=# select '0.9999999999999999 cent'::interval year;
interval
----------
99 years
(1 row)

postgres=# select '0.9999999999999999 mil'::interval year;
interval
-----------
999 years
(1 row)

the reason is that assign double value to int value in function
DecodeInterval() :
int DecodeInterval(char **field, int *ftype, int nf, int range,
int *dtype, struct pg_tm *tm, fsec_t *fsec)
{
double fval;
.......
switch (ftype[i])
case DTK_YEAR:
tm->tm_year += val;
if (fval != 0)
tm->tm_mon += fval * MONTHS_PER_YEAR;
tmask = DTK_M(YEAR);
break;
case DTK_DECADE:
tm->tm_year += val * 10;
if (fval != 0)
tm->tm_mon += fval * MONTHS_PER_YEAR * 10;
tmask = DTK_M(DECADE);
break;

case DTK_CENTURY:
tm->tm_year += val * 100;
if (fval != 0)
tm->tm_mon += fval * MONTHS_PER_YEAR * 100;
tmask = DTK_M(CENTURY);
break;

case DTK_MILLENNIUM:
tm->tm_year += val * 1000;
if (fval != 0)
tm->tm_mon += fval * MONTHS_PER_YEAR * 1000;
tmask = DTK_M(MILLENNIUM);
break;
......
}
The code 'tm->tm_mon' is int type.I think this is a bug,need use rint() to
adjust it’s result,like:
tm->tm_mon += rint(fval * MONTHS_PER_YEAR * 1000);

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message PG Bug reporting form 2019-03-16 07:59:13 BUG #15697: Restarting the server because of the error checkpointer
Previous Message Tom Lane 2019-03-15 21:27:59 Re: pg_restore: [archiver (db)] could not execute query: ERROR: operator does not exist: public.hstore = public.hstore