Update lower/upper bound of range type

前端 未结 3 1403
走了就别回头了
走了就别回头了 2021-02-08 19:13

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

3条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-02-08 20:12

    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;
    

提交回复
热议问题