Re: Add operator for dividing interval by an interval

From: Andres Freund <andres(at)anarazel(dot)de>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: Add operator for dividing interval by an interval
Date: 2023-05-19 20:01:27
Message-ID: 20230519200127.l3mj7tyczin2i4ay@awork3.anarazel.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

On 2023-05-18 17:03:24 -0400, Tom Lane wrote:
> Andres Freund <andres(at)anarazel(dot)de> writes:
> > What about an interval / interval -> double operator that errors out whenever
> > month is non-zero? As far as I can tell that would always be deterministic.
>
> We have months, days, and microseconds, and microseconds-per-day isn't
> much more stable than days-per-month (because DST).

I was about to counter that, if you subtract a timestamp before/after DST
changes, you currently don't get a full day for the "shorter day":

SET timezone = 'America/Los_Angeles';
SELECT '2023-03-13 23:00:00-07'::timestamptz - '2023-03-11 23:00:00-08'::timestamptz;
┌────────────────┐
│ ?column? │
├────────────────┤
│ 1 day 23:00:00 │
└────────────────┘

which afaics would make it fine to just use 24h days when dividing intervals.

However, that seems to lead to quite broken results:

SET timezone = 'America/Los_Angeles';
WITH s AS (SELECT '2023-03-11 23:00-08'::timestamptz a, '2023-03-13 23:00-07'::timestamptz b) SELECT a, b, b - a AS b_min_a, a + (b - a) FROM s;
┌────────────────────────┬────────────────────────┬────────────────┬────────────────────────┐
│ a │ b │ b_min_a │ ?column? │
├────────────────────────┼────────────────────────┼────────────────┼────────────────────────┤
│ 2023-03-11 23:00:00-08 │ 2023-03-13 23:00:00-07 │ 1 day 23:00:00 │ 2023-03-13 22:00:00-07 │
└────────────────────────┴────────────────────────┴────────────────┴────────────────────────┘

I subsequently found a comment that seems to reference this in timestamp_mi().
/*----------
* This is wrong, but removing it breaks a lot of regression tests.
* For example:
*

How's this not a significant bug that we need to fix?

I'm not sure this ought to be fixed in timestamp_mi() - perhaps the order of
operations in timestamp_pl_interval() would be a better place?

We probably should document that interval math isn't associative:

postgres[2807421][1]=# SELECT ('2023-03-11 23:00:00-08'::timestamptz + '1 day'::interval) + '23h'::interval;
┌────────────────────────┐
│ ?column? │
├────────────────────────┤
│ 2023-03-13 22:00:00-07 │
└────────────────────────┘

postgres[2807421][1]=# SELECT ('2023-03-11 23:00:00-08'::timestamptz + '23h'::interval) + '1day'::interval;
┌────────────────────────┐
│ ?column? │
├────────────────────────┤
│ 2023-03-13 23:00:00-07 │
└────────────────────────┘

Greetings,

Andres Freund

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Corey Huinker 2023-05-19 20:57:44 Re: Adding SHOW CREATE TABLE
Previous Message Dimitry Markman 2023-05-19 19:32:05 Re: How to ensure that SSPI support (Windows) enabled?