agora inbox for pgsql-sql@postgresql.org
help / color / mirror / Atom feedFrom: Adam Jensen <hanzer@riseup.net>
To: pgsql-sql@lists.postgresql.org
Subject: Re: interval origami
Date: Fri, 30 Nov 2018 19:04:10 -0500
Message-ID: <80ea3708-11be-e7e3-9f49-011a682e3bf4@riseup.net> (raw)
In-Reply-To: <6d32b24f-2d3e-df79-81d2-3b1abb8cc4b4@riseup.net>
References: <20181130175719.l7izv65wjwgkls35@alvherre.pgsql>
<d05565aa-551d-fac3-ba88-8215c8cbe0d4@riseup.net>
<6d32b24f-2d3e-df79-81d2-3b1abb8cc4b4@riseup.net>
On 11/30/18 4:02 PM, Adam Jensen wrote:
> On 11/30/18 3:19 PM, Adam Jensen wrote:
>> The 'numrange' type with the 'overlaps' and 'intersection' operators
>> seem to cover the fundamental computations in a very natural way.
>
> Actually, those operators might not be entirely sufficient. Given two
> ranges like this:
>
> 10.0|39.0|interesting
> 15.0|21.0|fail
>
> Something like the negative or inverse of the intersection is needed:
>
> 10.0|15.0|interesting
> 21.0|39.0|interesting
I've mapped out nine time segment overlap scenarios:
1. good(10, 40) | bad(05, 15) -> good(15, 40)
2. good(10, 40) | bad(10, 15) -> good(15, 40)
3. good(10, 40) | bad(20, 30) -> good(10, 20), good(30, 40)
4. good(10, 40) | bad(20, 40) -> good(10, 20)
5. good(10, 40) | bad(20, 45) -> good(10, 20)
6. good(10, 40) | bad(05, 40) -> good()
7. good(10, 40) | bad(05, 45) -> good()
8. good(10, 40) | bad(10, 40) -> good()
9. good(10, 40) | bad(10, 45) -> good()
Letting gs/gf and bs/bf represent "good start-time"/"good finish-time"
and so on, pseudo-code to remove the bad segments looks like this:
find overlap: good(gs, gf) | bad(bs, bf)
CASE
WHEN ((bs <= gs) AND (bf < gf)) THEN # 1 & 2
-> (bf, gf)
WHEN ((bs > gs) AND (bf < gf)) THEN # 3
-> (gs, bs), (bf, gf)
WHEN ((bs > gs) AND (bf >= gf)) THEN # 4 &
-> (gs, bs)
WHEN ((bs <= gs) AND (bf >= gf)) THEN # 6 & 7 & 8 & 9
-> ()
END CASE;
And my first attempt at writing a PostgreSQL function looks like this:
CREATE FUNCTION find_overlap(gs REAL, gf REAL, bs REAL, bf REAL)
RETURNS TABLE (start REAL, stop REAL) AS $$
BEGIN
CASE
WHEN ((bs <= gs) AND (bf < gf)) THEN
RETURN NEXT (bf, gf);
RETURN;
WHEN ((bs > gs) AND (bf < gf)) THEN
RETURN NEXT (gs, bs);
RETURN NEXT (bf, gf);
RETURN;
WHEN ((bs > gs) AND (bf >= gf)) THEN
RETURN NEXT (gs, bs);
RETURN;
WHEN ((bs <= gs) AND (bf >= gf)) THEN
RETURN;
END CASE;
END; $$
LANGUAGE plpgsql;
It results in:
ERROR: RETURN NEXT cannot have a parameter in function with OUT parameters
LINE 6: RETURN NEXT (bf, gf);
Page 83 of the book "PostgreSQL Server Programming" mentions this
situation but doesn't actually describe or explain anything; nor does it
present a working example...
Any ideas?
view thread (10+ messages) latest in thread
Message-ID: <80ea3708-11be-e7e3-9f49-011a682e3bf4@riseup.net>
Permalink: ../80ea3708-11be-e7e3-9f49-011a682e3bf4@riseup.net/
Also on: postgresql.org/message-id/80ea3708-11be-e7e3-9f49-011a682e3bf4@riseup.net
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-sql@postgresql.org
Cc: hanzer@riseup.net, pgsql-sql@lists.postgresql.org
Subject: Re: interval origami
In-Reply-To: <80ea3708-11be-e7e3-9f49-011a682e3bf4@riseup.net>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox