Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update lower/upper bound of range type

Tags:

postgresql

I have column of tstzrange type (timestamp with time zone range) and I need to update only upper or lower bound of this value (and keep inclusive/exclusive boundaries)

I managed to change

(-infinity,infinity)

with

UPDATE table
SET
    my_column = tstzrange(
        lower(my_column),
        now(),
        '()'
    )

and I have

(-infinity, <current timestamp>)

but I don't know how to keep boundaries from default range.. this would change even [ ] to ( )

like image 722
boobiq Avatar asked Aug 09 '13 11:08

boobiq


People also ask

What is Tsrange?

Range types are data types representing a range of values of some element type (called the range's subtype). For instance, ranges of timestamp might be used to represent the ranges of time that a meeting room is reserved. In this case the data type is tsrange (short for “timestamp range”), and timestamp is the subtype.

What does @> mean in Postgres?

In general @> is the "contains" operator. It is defined for several data types.

Is upper bound inclusive?

In the text form of a range, an inclusive lower bound is represented by “ [ ” while an exclusive lower bound is represented by “ ( ”. Likewise, an inclusive upper bound is represented by “ ] ”, while an exclusive upper bound is represented by “ ) ”.

Does between include endpoints Postgres?

Now as far as I know between operator includes both the endpoints of the range being provided.


2 Answers

I found function I missed, it's possible to do that like this

UPDATE table
SET
    my_column = tstzrange(
        lower(my_column),
        now(),
        concat(
            CASE WHEN lower_inc(my_column) THEN '[' ELSE '(' END,
            CASE WHEN upper_inc(my_column) THEN ']' ELSE ')' END
        )
    )

It would be better to create function for this probably. Or is there any other (simpler/better) solution?

like image 70
boobiq Avatar answered Sep 30 '22 16:09

boobiq


Improvement to Mikes great answer.

When we use the pseudo-type anyrange, we only need a single function:

CREATE OR REPLACE FUNCTION range_bounds(IN range anyrange)
    RETURNS CHAR(2) AS
$$
SELECT CASE WHEN lower_inc(range) THEN '[' ELSE '(' END ||
       CASE WHEN upper_inc(range) THEN ']' ELSE ')' END;
$$
LANGUAGE SQL
RETURNS NULL ON NULL INPUT;
like image 37
TmTron Avatar answered Sep 30 '22 16:09

TmTron