2015-01-15 14 views
5

Korzystanie z PostgreSQL 9.4:Postgres int4range górna granica wartości nieoczekiwany

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 

Sprawdźmy dalej:

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 

Z dokumentacji pg:

górna (anyrange) | typ elementu zakresu | górna granica zakresu | górny (numrange (1.1,2.2)) | 2,2

Podczas 3 technicznie górna granica zakresu całkowitej [1,3) ∩ ℕ = {1, 2}, więc są liczbami naturalnymi ≥ 2. byłoby oczekiwać, funkcja upper zwraca Supremum (przynajmniej górna granica) zakresu.

Czy brakuje mi czegoś?

Odpowiedz

1

Dzieje się tak, ponieważ int4range jest discrete range. Takie zakresy zawsze automatycznie przekształca się w ich reprezentacji kanonicznej, aby móc sprawdzić równoważności f.ex .:

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

Wbudowany rodzaju zakres int4range, int8range i daterange używają postać kanoniczną, która obejmuje dolną granicę i wyklucza górną granicę; to jest [). Zdefiniowane przez użytkownika typy zakresów mogą jednak korzystać z innych konwencji.

+0

Tak, są przekształcane do postaci kanonicznej. A zakres [1,2] jest dokładnie taki sam jak [1,3] w N. Ale 3 w sup. żadnego z nich. – damians

+0

@FireBiker tak, 3 nie jest supremum, ale jest górną granicą (według definicji PostgreSQL) '[1,3)'. Możesz użyć 'upper_inc()', aby wykryć, czy jest to element włączający czy nie. Myślę, że to dlatego, że w ten sposób funkcje są spójne (tj. Zarówno 'upper ('[1,3)' :: int4range)' i 'upper ('[1,3)' :: numrange)' daje '3') - pamiętaj, że supremum może być określane jako * najmniejsza górna granica *, podczas gdy PostgreSQL używa tylko terminu * górna granica * – pozs

0

Forma kanoniczna zakresu [1,2] to [1,3). Funkcja upper() zwraca górną granicę formy kanonicznej.

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

Ten zakres nie zawiera wartości 3.

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

Jest inna funkcja zadzwonić, jeśli chcesz wiedzieć, czy wartość zwracana przez górny() jest włącznie.

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