The following bug has been logged on the website:
Bug reference: 15696
Logged by: zhou xiaowei
Email address: 110876189@qq.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);