Thread

  1. Should ranges validate their subtypes' domains after canonicalization?

    Paul A Jungwirth <pj@illuminatedcomputing.com> — 2025-12-03T18:43:35Z

    Hi Hackers,
    
    While reviewing
    https://www.postgresql.org/message-id/CACJufxGoAmN_0iJ%3DhjTG0vGpOSOyy-vYyfE%2B-q0AWxrq2_p5XQ%40mail.gmail.com,
    I noticed this inconsistency in how ranges enforce domains over their
    subtypes:
    
    ```
    [v19devel:5432][426675] postgres=# create type int4_d_range;
    CREATE TYPE
    [v19devel:5432][426675] postgres=# create or replace function
    int4_d_range_canonical(int4_d_range) returns int4_d_range language
    internal immutable parallel safe strict as
    $function$int4range_canonical$function$;
    NOTICE:  argument type int4_d_range is only a shell
    LINE 1: create or replace function int4_d_range_canonical(int4_d_ran...
                                                              ^
    NOTICE:  return type int4_d_range is only a shell
    CREATE FUNCTION
    [v19devel:5432][426675] postgres=# create type int4_d_range as range
    (subtype = int4_d, canonical = int4_d_range_canonical);
    CREATE TYPE
    [v19devel:5432][426675] postgres=# select '[9,10)'::int4_d_range;
    ERROR:  value for domain int4_d violates check constraint "int4_d_check"
    LINE 1: select '[9,10)'::int4_d_range;
                   ^
    [v19devel:5432][426675] postgres=# select '[9,9]'::int4_d_range;
     int4_d_range
    --------------
     [9,10)
    (1 row)
    ```
    
    The same inconsistency happens without a canonical function, but it
    seems okay there, based on this line from the docs:
    
    > If a canonicalization function is not specified, then ranges with different formatting will always be treated as unequal, even though they might represent the same set of values in reality.
    
    But should a range validate its domain after canonicalizing? It seems
    like it is happening before.
    
    Yours,
    
    -- 
    Paul              ~{:-)
    pj@illuminatedcomputing.com