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 boundari
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;
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?
As far as I know, using CASE WHEN... is the best way to get the bounds. Here are some simple user-defined functions that return the range bounds for all the native range types.
Warning: These functions behave in surprising ways, because the range types behave in sometimes surprising ways.
The built-in range types int4range, int8range, and daterange all use a canonical form that includes the lower bound and excludes the upper bound; that is, [).
And
Although '(]' is specified here, on display the value will be converted to canonical form, since int8range is a discrete range type . . .
(emphasis added)
PostgreSQL canonicalizes the closed range from 1 to 10 as a half open range from 1 to 11.
select int4range('[1,10]');
[1,11)
It does the same thing for ranges that are half open on the left.
select int4range('(1,10]');
[2,11)
range_bounds() returns the bounds for result, not for the input.
select range_bounds(int4range('(1,10]'));
[)
The functions
create or replace function range_bounds(in range int4range)
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;
create or replace function range_bounds(in range int8range)
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;
create or replace function range_bounds(in range numrange)
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;
create or replace function range_bounds(in range tsrange)
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;
create or replace function range_bounds(in range tstzrange)
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;
create or replace function range_bounds(in range daterange)
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;