Re: Have I found an interval arithmetic bug?

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Bruce Momjian <bruce(at)momjian(dot)us>
Cc: Dean Rasheed <dean(dot)a(dot)rasheed(at)gmail(dot)com>, John W Higgins <wishdev(at)gmail(dot)com>, pgsql-hackers list <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: Have I found an interval arithmetic bug?
Date: 2021-07-30 16:49:34
Message-ID: 1008623.1627663774@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general pgsql-hackers

Bruce Momjian <bruce(at)momjian(dot)us> writes:
> On Fri, Jul 30, 2021 at 12:04:39PM -0400, Bruce Momjian wrote:
>> Unless I hear more feedback, I plan to apply this doc patch to all
>> branches with the word "rounded" changed to "truncated" in the back
>> branches, and apply the rounded code changes to master.

> Now that I think of it, I will just remove the word "rounded" from the
> back branch docs so we are technically breaking the documented API less
> in PG 15.

I think your first idea was better. Not documenting the behavior
doesn't make this not an API change; it just makes it harder for
people to understand what changed.

The doc patch itself is not exactly fine:

+ Field values can have fractional parts; for example, <literal>'1.5
+ weeks'</literal> or <literal>'01:02:03.45'</literal>. However,

I think "some field values", as it was worded previously, was better.
If you try to write 01.5:02:03, that is not going to be interpreted
as 1.5 hours. (Hmm, I get something that seems quite insane:

regression=# select '01.5:02:03'::interval;
interval
----------------
1 day 14:03:00
(1 row)

I wonder what it thinks it's doing there.)

This is wrong:

+ because interval internally stores only three integer units (months,
+ days, seconds), fractional units must be spilled to smaller units.

s/seconds/microseconds/ is probably enough to fix that.

+ For example, because months are approximated to equal 30 days,
+ fractional values of units greater than months is rounded to be the
+ nearest integer number of months. Fractional units of months or less
+ are computed to be an integer number of days and seconds, assuming
+ 24 hours per day. For example, <literal>'1.5 months'</literal>
+ becomes <literal>1 month 15 days</literal>.

This entire passage is vague, and grammatically shaky too. Perhaps
more like

Fractional parts of units larger than months are rounded to the
nearest integer number of months; for example '1.5 years'
becomes '1 year 6 mons'. Fractional parts of months are rounded
to the nearest integer number of days, using the assumption that
one month equals 30 days; for example '1.5 months'
becomes '1 mon 15 days'. Fractional parts of days and weeks
are converted to microseconds, using the assumption that one day
equals 24 hours.

On output, the months field is shown as an appropriate number of
years and months; the days field is shown as-is; the microseconds
field is converted to hours, minutes, and possibly-fractional
seconds.

regards, tom lane

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Bruce Momjian 2021-07-30 19:03:13 Re: Have I found an interval arithmetic bug?
Previous Message Bruce Momjian 2021-07-30 16:08:54 Re: Have I found an interval arithmetic bug?

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2021-07-30 17:05:12 Re: pg_upgrade does not upgrade pg_stat_statements properly
Previous Message Jan Wieck 2021-07-30 16:44:17 Re: pg_upgrade does not upgrade pg_stat_statements properly