Using PostgreSQL 9.4:
SELECT x, lower(x), upper(x) FROM (SELECT '[1,2]'::numrange x) q;
> [1,2] | 1 | 2 -- looks OK
SELECT x, lower(x), upper(x) FROM (SELECT '[1,2]'::int4range x) q;
> [1,3) | 1 | >>3<< -- this is unexpected
让我们进一步检查:
SELECT x, lower(x), upper(x) FROM (SELECT '[1,3)'::numrange x) q1;
> [1,3) | 1 | 3 -- looks OK
SELECT x, lower(x), upper(x) FROM (SELECT '[1,3]'::numrange x) q1;
> [1,3] | 1 | 3 -- looks OK
来自 pg 文档:
上限(任意范围) | 范围的元素类型 | 范围上限 | 上限(数字范围(1.1,2.2)) | 2.2
虽然3
技术上是整数范围[1,3) ∩ ℕ = {1, 2}
的上限,但所有自然数≥2也是如此。我希望 upper
函数返回范围的上确界(最小上限)。
我错过了什么吗?
是因为int4range
是一个离散范围。这些范围总是自动转换为它们的规范表示形式,以便能够测试等价性,例如:
SELECT '[4,8]'::int4range = '(3,9)'::int4range
内置范围类型
int4range
、int8range
和daterange
都使用包含下限和排除上限的规范形式,即[)
。但是,用户定义的范围类型可以使用其他约定。
闭合范围[1,2]
的规范形式是半开(或半闭合)范围[1,3)
。函数 upper() 返回规范形式的上限。
select upper(int4range(1, 2, '[]')); -- Canonical form is '[1,3)'
--
3
该范围不包含值 3。
select int4range(1, 2, '[]') @> 3;
--
f
内置范围类型 int4range、int8range 和日期范围都使用包含下限和排除上限的规范形式绑定;也就是说,[ 。用户定义的范围类型可以使用其他但是,约定。
来源:PostgreSQL 离散范围类型
如果您需要知道 upper() 返回的值是否包含,则可以调用不同的函数。
select upper_inc(int4range(1, 2, '[]'));
--
f