Postgres int4range上限意外值

时间:2015-01-15 17:51:29

标签: postgresql range upperbound

使用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文档:

  

upper(anyrange)|范围的元素类型|范围的上限| upper(numrange(1.1,2.2))| 2.2

虽然3技术上是整数范围[1,3) ∩ ℕ = {1, 2}的上限,但所有自然数≥2。我希望upper函数返回 supremum (最小上限)范围。

我错过了什么吗?

2 个答案:

答案 0 :(得分:1)

这是因为int4rangediscrete range。这些范围总是自动转换为规范表示,以便能够测试等价,f.ex。:

SELECT '[4,8]'::int4range = '(3,9)'::int4range
  

内置范围类型int4rangeint8rangedaterange都使用包含下限并排除上限的规范形式;也就是[)。但是,用户定义的范围类型可以使用其他约定。

答案 1 :(得分:0)

范围[1,2]的规范形式为[1,3)。函数upper()返回规范形式的上限。

select upper(int4range(1, 2, '[]'));  -- Canonical form is '[1,3)'
3

该范围不包含值3。

select int4range(1, 2, '[]') @> 3;
f

如果您需要知道upper()返回的值是否包含在内,则可以调用不同的函数。

select upper_inc(int4range(1, 2, '[]'));
f