2015-01-15 51 views
5

使用PostgreSQL 9.4:Postgres的int4range上限意外的值

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文件:

上(anyrange)|範圍的元素類型|範圍的上限| upper(numrange(1.1,2.2))| 2.2

雖然3技術上是一個上限的整數範圍[1,3) ∩ ℕ = {1, 2}的,因此是所有自然數≥2.我期望upper函數返回該範圍的(最小上界)。

我錯過了什麼嗎?

回答

1

發生這種情況是因爲int4rangediscrete range。這樣的範圍總是自動轉換爲它們的規範表示,以便能夠測試等價,f.ex:

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

內置的範圍類型int4rangeint8range,和daterange所有使用規範形式包括下限並排除上限;那就是,[)。然而,用戶定義的範圍類型可以使用其他約定。

+0

是的,它們被轉換爲規範形式。範圍[1,2]在N中與[1,3]完全相同,但在sup中爲3。既不。 – damians 2015-01-15 19:13:41

+0

@FireBiker是的,3不是上游,但它是'[1,3]'的上限(通過PostgreSQL的定義)。如果包含或不包含,您可以使用'upper_inc()'來檢測。我認爲這是因爲這樣函數是一致的(即'upper('[1,3]':: int4range)'和'upper('[1,3]':: numrange)''會給出'3') - 注意上游可以被稱爲*最小上限*,而PostgreSQL只使用術語*上限* – pozs 2015-01-15 21:15:52

0

範圍[1,2]的規範形式是[1,3)。函數upper()返回規範形式的上界。

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

這個範圍不包含價值3

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

有不同的功能,如果你需要知道上()返回的值是否是調用包括的。

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