Re: Have I found an interval arithmetic bug? - Mailing list pgsql-hackers
From | Bryn Llewellyn |
---|---|
Subject | Re: Have I found an interval arithmetic bug? |
Date | |
Msg-id | 4EE3B8DC-2F84-4C9B-9A99-4650562A4F84@yugabyte.com Whole thread Raw |
In response to | Re: Have I found an interval arithmetic bug? (Bruce Momjian <bruce@momjian.us>) |
List | pgsql-hackers |
> On 08-Apr-2021, at 10:24, Bruce Momjian <bruce@momjian.us> wrote: > > On Mon, Apr 5, 2021 at 02:01:58PM -0400, Bruce Momjian wrote: >> On Mon, Apr 5, 2021 at 11:33:10AM -0500, Justin Pryzby wrote: >> Well, bug or not, we are not going to change back branches for this, and >> if you want a larger discussion, it will have to wait for PG 15. >> >>>> https://www.google.com/url?q=https://www.postgresql.org/docs/current/datatype-datetime.html%23DATATYPE-INTERVAL-INPUT&source=gmail-imap&ust=1618507489000000&usg=AOvVaw2h2TNbK7O41zsDn8HfD88C >>>> « …field values can have fractional parts; for example '1.5 week' or '01:02:03.45'. Such input is converted to the appropriatenumber of months, days, and seconds for storage. When this would result in a fractional number of months or days,the fraction is added to the lower-order fields using the conversion factors 1 month = 30 days and 1 day = 24 hours.For example, '1.5 month' becomes 1 month and 15 days. Only seconds will ever be shown as fractional on output. » >> >> I see that. What is not clear here is how far we flow down. I was >> looking at adding documentation or regression tests for that, but was >> unsure. I adjusted the docs slightly in the attached patch. > > Here is an updated patch, which will be for PG 15. It updates the > documentation to state: > > The fractional parts are used to compute appropriate values for the next > lower-order internal fields (months, days, seconds). > > It removes the flow from fractional months/weeks to > hours-minutes-seconds, and adds missing rounding for fractional > computations. Thank you Bruce. I look forward to documenting this new algorithm for YugabyteDB. The algorithm implements the transformationfrom this: [ yy_in numeric, mo_in numeric, dd_in numeric, hh_in numeric, mi_in numeric, ss_in numeric ] to this: [ mo_internal_representation int, dd_internal_representation int, ss_internal_representation numeric(1000,6) ] I am convinced that a prose account of the algorithm, by itself, is not the best way to tell the reader the rules that thealgorithm implements. Rather, psuedocode is needed. I mentioned before that, better still, is actual executable PL/pgSQLcode. (I can expect readers to be fluent in PL/pgSQL.) Given this executable simulation, an informal prose sketchof what it does will definitely add value. May I ask you to fill in the body of this stub by translating the C that you have in hand? create type internal_representation_t as( mo_internal_representation int, dd_internal_representation int, ss_internal_representation numeric(1000,6)); create function internal_representation( yy_in numeric default 0, mo_in numeric default 0, dd_in numeric default 0, hh_in numeric default 0, mi_in numeric default 0, ss_in numeric default 0) returns internal_representation_t language plpgsql as $body$ declare mo_internal_representation int not null := 0; dd_internal_representation int not null := 0; ss_internal_representation numeric not null := 0.0; ok constant boolean := (yy_in is not null) and (mo_in is not null) and (dd_in is not null) and (hh_in is not null) and (mi_in is not null) and (ss_in is not null); begin assert ok, 'No actual argument, when provided, may be null'; -- The algorithm. return (mo_internal_representation, dd_internal_representation, ss_internal_representation)::internal_representation_t; end; $body$; By the way, I believe that a user might well decide always to supply all the fields in a "from text to interval" typecast,except for the seconds, as integral values. This, after all, is what the "make_interval()" function enforces. But,because the typecast approach allows non-integral values, the reference documentation must explain the rules unambiguouslyso that the reader can predict the outcome of any ad hoc test that they might try. It's a huge pity that the three values of the internal representation cannot be observed directly using SQL because eachbehaves with different semantics when an interval value is added to a timestamptz value. However, as a second best (andknowing the algorithm above), a user can create interval values where only one of the three fields is populated and testtheir understanding of the semantic rules that way.
pgsql-hackers by date: