INT4RANGE Upper bound always includes a higher number
The following documentation comment has been logged on the website:
Page: https://www.postgresql.org/docs/16/rangetypes.html
Description:
Hi,
First I just wanted to say, the documentation is overall excellent, it has
been such a pleasure learning postgres.
In the RANGE types where it says the square bracket indicates upper bound
inclusive ],
But the issue with this is when I do upper bound inclusive it always goes
one number above.
This is contrary to your documentation says and it is also counter
intuitive.
According to your example (copied from your docs):
-- includes 3, does not include 7, and does include all points in between
SELECT '[3,7)'::int4range;
But this is not true, it shows 3 and 7
And if i do:
SELECT '(3,7]'::INT4RANGE;
It shows:
[4,8)
(1 row)
Please can someone explain ?
Thank you
PG Doc comments form <noreply@postgresql.org> writes:
According to your example (copied from your docs):
-- includes 3, does not include 7, and does include all points in between
SELECT '[3,7)'::int4range;
But this is not true, it shows 3 and 7
What's not true about it?
postgres=# SELECT 3 <@ '[3,7)'::int4range;
?column?
----------
t
(1 row)
postgres=# SELECT 6 <@ '[3,7)'::int4range;
?column?
----------
t
(1 row)
postgres=# SELECT 7 <@ '[3,7)'::int4range;
?column?
----------
f
(1 row)
7 is not a member of that range, only an endpoint.
And if i do:
SELECT '(3,7]'::INT4RANGE;
It shows:
[4,8)
(1 row)
This is a consequence of canonicalization. There are four different
ways to write the same integer range:
[3,6]
[3,7)
(2,6]
(2,7)
All of these include 3,4,5,6 and no other integer.
INT4RANGE has a canonicalize function that converts ranges into the
"[m,n)" form so that ranges that are functionally identical look
identical. If you don't like that, you can make a user-defined
range type with a different canonicalize function, or none at all.
See
https://www.postgresql.org/docs/current/rangetypes.html#RANGETYPES-DISCRETE
regards, tom lane