2011-11-03 12:16:28 +01:00
|
|
|
--
|
|
|
|
-- test parser
|
|
|
|
--
|
|
|
|
create type textrange as range (subtype=text, collation="C");
|
|
|
|
-- negative tests; should fail
|
|
|
|
select ''::textrange;
|
|
|
|
ERROR: malformed range literal: ""
|
|
|
|
LINE 1: select ''::textrange;
|
|
|
|
^
|
|
|
|
DETAIL: Missing left parenthesis or bracket.
|
|
|
|
select '-[a,z)'::textrange;
|
|
|
|
ERROR: malformed range literal: "-[a,z)"
|
|
|
|
LINE 1: select '-[a,z)'::textrange;
|
|
|
|
^
|
|
|
|
DETAIL: Missing left parenthesis or bracket.
|
|
|
|
select '[a,z) - '::textrange;
|
|
|
|
ERROR: malformed range literal: "[a,z) - "
|
|
|
|
LINE 1: select '[a,z) - '::textrange;
|
|
|
|
^
|
|
|
|
DETAIL: Junk after right parenthesis or bracket.
|
|
|
|
select '(",a)'::textrange;
|
|
|
|
ERROR: malformed range literal: "(",a)"
|
|
|
|
LINE 1: select '(",a)'::textrange;
|
|
|
|
^
|
|
|
|
DETAIL: Unexpected end of input.
|
|
|
|
select '(,,a)'::textrange;
|
|
|
|
ERROR: malformed range literal: "(,,a)"
|
|
|
|
LINE 1: select '(,,a)'::textrange;
|
|
|
|
^
|
|
|
|
DETAIL: Too many boundaries.
|
|
|
|
select '(),a)'::textrange;
|
|
|
|
ERROR: malformed range literal: "(),a)"
|
|
|
|
LINE 1: select '(),a)'::textrange;
|
|
|
|
^
|
|
|
|
DETAIL: Missing upper bound.
|
|
|
|
select '(a,))'::textrange;
|
|
|
|
ERROR: malformed range literal: "(a,))"
|
|
|
|
LINE 1: select '(a,))'::textrange;
|
|
|
|
^
|
|
|
|
DETAIL: Junk after right parenthesis or bracket.
|
|
|
|
select '(],a)'::textrange;
|
|
|
|
ERROR: malformed range literal: "(],a)"
|
|
|
|
LINE 1: select '(],a)'::textrange;
|
|
|
|
^
|
|
|
|
DETAIL: Missing upper bound.
|
|
|
|
select '(a,])'::textrange;
|
|
|
|
ERROR: malformed range literal: "(a,])"
|
|
|
|
LINE 1: select '(a,])'::textrange;
|
|
|
|
^
|
|
|
|
DETAIL: Junk after right parenthesis or bracket.
|
2011-11-17 22:50:32 +01:00
|
|
|
select '( , )'::textrange;
|
|
|
|
ERROR: range lower bound must be less than or equal to range upper bound
|
|
|
|
LINE 1: select '( , )'::textrange;
|
|
|
|
^
|
|
|
|
select '("","")'::textrange;
|
|
|
|
ERROR: range lower bound must be less than or equal to range upper bound
|
|
|
|
LINE 1: select '("","")'::textrange;
|
|
|
|
^
|
|
|
|
select '(",",",")'::textrange;
|
|
|
|
ERROR: range lower bound must be less than or equal to range upper bound
|
|
|
|
LINE 1: select '(",",",")'::textrange;
|
|
|
|
^
|
|
|
|
select '("\\","\\")'::textrange;
|
|
|
|
ERROR: range lower bound must be less than or equal to range upper bound
|
|
|
|
LINE 1: select '("\\","\\")'::textrange;
|
|
|
|
^
|
|
|
|
select '[a,a)'::textrange;
|
|
|
|
ERROR: range lower bound must be less than or equal to range upper bound
|
|
|
|
LINE 1: select '[a,a)'::textrange;
|
|
|
|
^
|
|
|
|
select '(a,a]'::textrange;
|
|
|
|
ERROR: range lower bound must be less than or equal to range upper bound
|
|
|
|
LINE 1: select '(a,a]'::textrange;
|
|
|
|
^
|
2011-11-03 12:16:28 +01:00
|
|
|
-- should succeed
|
|
|
|
select ' empty '::textrange;
|
|
|
|
textrange
|
|
|
|
-----------
|
|
|
|
empty
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select ' ( empty, empty ) '::textrange;
|
|
|
|
textrange
|
|
|
|
----------------------
|
|
|
|
(" empty"," empty ")
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select ' ( " a " " a ", " z " " z " ) '::textrange;
|
|
|
|
textrange
|
|
|
|
--------------------------
|
|
|
|
(" a a "," z z ")
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '(,z)'::textrange;
|
|
|
|
textrange
|
|
|
|
-----------
|
|
|
|
(,z)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '(a,)'::textrange;
|
|
|
|
textrange
|
|
|
|
-----------
|
|
|
|
(a,)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '[,z]'::textrange;
|
|
|
|
textrange
|
|
|
|
-----------
|
|
|
|
(,z]
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '[a,]'::textrange;
|
|
|
|
textrange
|
|
|
|
-----------
|
|
|
|
[a,)
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-17 22:50:32 +01:00
|
|
|
select '(,)'::textrange;
|
2011-11-03 12:16:28 +01:00
|
|
|
textrange
|
|
|
|
-----------
|
2011-11-17 22:50:32 +01:00
|
|
|
(,)
|
2011-11-03 12:16:28 +01:00
|
|
|
(1 row)
|
|
|
|
|
2011-11-17 22:50:32 +01:00
|
|
|
select '["",""]'::textrange;
|
2011-11-03 12:16:28 +01:00
|
|
|
textrange
|
|
|
|
-----------
|
2011-11-17 22:50:32 +01:00
|
|
|
["",""]
|
2011-11-03 12:16:28 +01:00
|
|
|
(1 row)
|
|
|
|
|
2011-11-17 22:50:32 +01:00
|
|
|
select '[",",","]'::textrange;
|
2011-11-03 12:16:28 +01:00
|
|
|
textrange
|
|
|
|
-----------
|
2011-11-17 22:50:32 +01:00
|
|
|
[",",","]
|
2011-11-03 12:16:28 +01:00
|
|
|
(1 row)
|
|
|
|
|
2011-11-17 22:50:32 +01:00
|
|
|
select '["\\","\\"]'::textrange;
|
|
|
|
textrange
|
|
|
|
-------------
|
|
|
|
["\\","\\"]
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '(\\,a)'::textrange;
|
2011-11-03 12:16:28 +01:00
|
|
|
textrange
|
|
|
|
-----------
|
2011-11-17 22:50:32 +01:00
|
|
|
("\\",a)
|
2011-11-03 12:16:28 +01:00
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '((,z)'::textrange;
|
|
|
|
textrange
|
|
|
|
-----------
|
|
|
|
("(",z)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '([,z)'::textrange;
|
|
|
|
textrange
|
|
|
|
-----------
|
|
|
|
("[",z)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '(!,()'::textrange;
|
|
|
|
textrange
|
|
|
|
-----------
|
|
|
|
(!,"(")
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '(!,[)'::textrange;
|
|
|
|
textrange
|
|
|
|
-----------
|
|
|
|
(!,"[")
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
--
|
|
|
|
-- create some test data and test the operators
|
|
|
|
--
|
|
|
|
CREATE TABLE numrange_test (nr NUMRANGE);
|
|
|
|
create index numrange_test_btree on numrange_test(nr);
|
|
|
|
SET enable_seqscan = f;
|
|
|
|
INSERT INTO numrange_test VALUES('[,)');
|
|
|
|
INSERT INTO numrange_test VALUES('[3,]');
|
|
|
|
INSERT INTO numrange_test VALUES('[, 5)');
|
|
|
|
INSERT INTO numrange_test VALUES(numrange(1.1, 2.2));
|
|
|
|
INSERT INTO numrange_test VALUES('empty');
|
|
|
|
INSERT INTO numrange_test VALUES(numrange(1.7));
|
|
|
|
SELECT isempty(nr) FROM numrange_test;
|
|
|
|
isempty
|
|
|
|
---------
|
|
|
|
f
|
|
|
|
f
|
|
|
|
f
|
|
|
|
f
|
|
|
|
t
|
|
|
|
f
|
|
|
|
(6 rows)
|
|
|
|
|
|
|
|
SELECT lower_inc(nr), lower(nr), upper(nr), upper_inc(nr) FROM numrange_test
|
|
|
|
WHERE NOT isempty(nr) AND NOT lower_inf(nr) AND NOT upper_inf(nr);
|
|
|
|
lower_inc | lower | upper | upper_inc
|
|
|
|
-----------+-------+-------+-----------
|
|
|
|
t | 1.1 | 2.2 | f
|
|
|
|
t | 1.7 | 1.7 | t
|
|
|
|
(2 rows)
|
|
|
|
|
2011-11-17 00:21:34 +01:00
|
|
|
SELECT * FROM numrange_test WHERE range_contains(nr, numrange(1.9,1.91));
|
2011-11-03 12:16:28 +01:00
|
|
|
nr
|
|
|
|
-----------
|
|
|
|
(,)
|
|
|
|
(,5)
|
|
|
|
[1.1,2.2)
|
|
|
|
(3 rows)
|
|
|
|
|
|
|
|
SELECT * FROM numrange_test WHERE nr @> numrange(1.0,10000.1);
|
|
|
|
nr
|
|
|
|
-----
|
|
|
|
(,)
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-17 00:21:34 +01:00
|
|
|
SELECT * FROM numrange_test WHERE range_contained_by(numrange(-1e7,-10000.1), nr);
|
2011-11-03 12:16:28 +01:00
|
|
|
nr
|
|
|
|
------
|
|
|
|
(,)
|
|
|
|
(,5)
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
SELECT * FROM numrange_test WHERE 1.9 <@ nr;
|
|
|
|
nr
|
|
|
|
-----------
|
|
|
|
(,)
|
|
|
|
(,5)
|
|
|
|
[1.1,2.2)
|
|
|
|
(3 rows)
|
|
|
|
|
|
|
|
SELECT * FROM numrange_test WHERE nr = 'empty';
|
|
|
|
nr
|
|
|
|
-------
|
|
|
|
empty
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT * FROM numrange_test WHERE range_eq(nr, '(1.1, 2.2)');
|
|
|
|
nr
|
|
|
|
----
|
|
|
|
(0 rows)
|
|
|
|
|
|
|
|
SELECT * FROM numrange_test WHERE nr = '[1.1, 2.2)';
|
|
|
|
nr
|
|
|
|
-----------
|
|
|
|
[1.1,2.2)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(2.0, 1.0);
|
|
|
|
ERROR: range lower bound must be less than or equal to range upper bound
|
|
|
|
select numrange(2.0, 3.0) -|- numrange(3.0, 4.0);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-17 00:21:34 +01:00
|
|
|
select range_adjacent(numrange(2.0, 3.0), numrange(3.1, 4.0));
|
|
|
|
range_adjacent
|
|
|
|
----------------
|
2011-11-03 12:16:28 +01:00
|
|
|
f
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(2.0, 3.0, '[]') -|- numrange(3.0, 4.0, '()');
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(1.0, 2.0) -|- numrange(2.0, 3.0,'[]');
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-17 00:21:34 +01:00
|
|
|
select range_adjacent(numrange(2.0, 3.0, '(]'), numrange(1.0, 2.0, '(]'));
|
|
|
|
range_adjacent
|
|
|
|
----------------
|
2011-11-03 12:16:28 +01:00
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(1.1, 3.3) <@ numrange(0.1,10.1);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(0.1, 10.1) <@ numrange(1.1,3.3);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
f
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(1.1, 2.2) - numrange(2.0, 3.0);
|
|
|
|
?column?
|
|
|
|
-----------
|
|
|
|
[1.1,2.0)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(1.1, 2.2) - numrange(2.2, 3.0);
|
|
|
|
?column?
|
|
|
|
-----------
|
|
|
|
[1.1,2.2)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(1.1, 2.2,'[]') - numrange(2.0, 3.0);
|
|
|
|
?column?
|
|
|
|
-----------
|
|
|
|
[1.1,2.0)
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-17 00:21:34 +01:00
|
|
|
select range_minus(numrange(10.1,12.2,'[]'), numrange(110.0,120.2,'(]'));
|
|
|
|
range_minus
|
2011-11-03 12:16:28 +01:00
|
|
|
-------------
|
|
|
|
[10.1,12.2]
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-17 00:21:34 +01:00
|
|
|
select range_minus(numrange(10.1,12.2,'[]'), numrange(0.0,120.2,'(]'));
|
|
|
|
range_minus
|
|
|
|
-------------
|
2011-11-03 12:16:28 +01:00
|
|
|
empty
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(4.5, 5.5, '[]') && numrange(5.5, 6.5);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(1.0, 2.0) << numrange(3.0, 4.0);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-17 22:50:32 +01:00
|
|
|
select numrange(1.0, 3.0,'[]') << numrange(3.0, 4.0,'[]');
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
f
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(1.0, 3.0,'()') << numrange(3.0, 4.0,'()');
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-03 12:16:28 +01:00
|
|
|
select numrange(1.0, 2.0) >> numrange(3.0, 4.0);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
f
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(3.0, 70.0) &< numrange(6.6, 100.0);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(1.1, 2.2) < numrange(1.0, 200.2);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
f
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(1.1, 2.2) < numrange(1.1, 1.2);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
f
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(1.0, 2.0) + numrange(2.0, 3.0);
|
|
|
|
?column?
|
|
|
|
-----------
|
|
|
|
[1.0,3.0)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(1.0, 2.0) + numrange(1.5, 3.0);
|
|
|
|
?column?
|
|
|
|
-----------
|
|
|
|
[1.0,3.0)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(1.0, 2.0) + numrange(2.5, 3.0);
|
2011-11-14 19:59:34 +01:00
|
|
|
ERROR: result of range union would not be contiguous
|
2011-11-03 12:16:28 +01:00
|
|
|
select numrange(1.0, 2.0) * numrange(2.0, 3.0);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
empty
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(1.0, 2.0) * numrange(1.5, 3.0);
|
|
|
|
?column?
|
|
|
|
-----------
|
|
|
|
[1.5,2.0)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select numrange(1.0, 2.0) * numrange(2.5, 3.0);
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
empty
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select * from numrange_test where nr < numrange(-1000.0, -1000.0,'[]');
|
|
|
|
nr
|
|
|
|
-------
|
|
|
|
(,)
|
|
|
|
(,5)
|
|
|
|
empty
|
|
|
|
(3 rows)
|
|
|
|
|
|
|
|
select * from numrange_test where nr < numrange(0.0, 1.0,'[]');
|
|
|
|
nr
|
|
|
|
-------
|
|
|
|
(,)
|
|
|
|
(,5)
|
|
|
|
empty
|
|
|
|
(3 rows)
|
|
|
|
|
|
|
|
select * from numrange_test where nr < numrange(1000.0, 1001.0,'[]');
|
|
|
|
nr
|
|
|
|
-----------
|
|
|
|
(,)
|
|
|
|
[3,)
|
|
|
|
(,5)
|
|
|
|
[1.1,2.2)
|
|
|
|
empty
|
|
|
|
[1.7,1.7]
|
|
|
|
(6 rows)
|
|
|
|
|
|
|
|
select * from numrange_test where nr > numrange(-1001.0, -1000.0,'[]');
|
|
|
|
nr
|
|
|
|
-----------
|
|
|
|
[3,)
|
|
|
|
[1.1,2.2)
|
|
|
|
[1.7,1.7]
|
|
|
|
(3 rows)
|
|
|
|
|
|
|
|
select * from numrange_test where nr > numrange(0.0, 1.0,'[]');
|
|
|
|
nr
|
|
|
|
-----------
|
|
|
|
[3,)
|
|
|
|
[1.1,2.2)
|
|
|
|
[1.7,1.7]
|
|
|
|
(3 rows)
|
|
|
|
|
|
|
|
select * from numrange_test where nr > numrange(1000.0, 1000.0,'[]');
|
|
|
|
nr
|
|
|
|
----
|
|
|
|
(0 rows)
|
|
|
|
|
|
|
|
create table numrange_test2(nr numrange);
|
|
|
|
create index numrange_test2_hash_idx on numrange_test2 (nr);
|
|
|
|
INSERT INTO numrange_test2 VALUES('[, 5)');
|
|
|
|
INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2));
|
|
|
|
INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2));
|
|
|
|
INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2,'()'));
|
|
|
|
INSERT INTO numrange_test2 VALUES('empty');
|
|
|
|
select * from numrange_test2 where nr = 'empty'::numrange;
|
|
|
|
nr
|
|
|
|
-------
|
|
|
|
empty
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select * from numrange_test2 where nr = numrange(1.1, 2.2);
|
|
|
|
nr
|
|
|
|
-----------
|
|
|
|
[1.1,2.2)
|
|
|
|
[1.1,2.2)
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
select * from numrange_test2 where nr = numrange(1.1, 2.3);
|
|
|
|
nr
|
|
|
|
----
|
|
|
|
(0 rows)
|
|
|
|
|
|
|
|
set enable_nestloop=t;
|
|
|
|
set enable_hashjoin=f;
|
|
|
|
set enable_mergejoin=f;
|
|
|
|
select * from numrange_test natural join numrange_test2 order by nr;
|
|
|
|
nr
|
|
|
|
-----------
|
|
|
|
empty
|
|
|
|
(,5)
|
|
|
|
[1.1,2.2)
|
|
|
|
[1.1,2.2)
|
|
|
|
(4 rows)
|
|
|
|
|
|
|
|
set enable_nestloop=f;
|
|
|
|
set enable_hashjoin=t;
|
|
|
|
set enable_mergejoin=f;
|
|
|
|
select * from numrange_test natural join numrange_test2 order by nr;
|
|
|
|
nr
|
|
|
|
-----------
|
|
|
|
empty
|
|
|
|
(,5)
|
|
|
|
[1.1,2.2)
|
|
|
|
[1.1,2.2)
|
|
|
|
(4 rows)
|
|
|
|
|
|
|
|
set enable_nestloop=f;
|
|
|
|
set enable_hashjoin=f;
|
|
|
|
set enable_mergejoin=t;
|
|
|
|
select * from numrange_test natural join numrange_test2 order by nr;
|
|
|
|
nr
|
|
|
|
-----------
|
|
|
|
empty
|
|
|
|
(,5)
|
|
|
|
[1.1,2.2)
|
|
|
|
[1.1,2.2)
|
|
|
|
(4 rows)
|
|
|
|
|
|
|
|
set enable_nestloop to default;
|
|
|
|
set enable_hashjoin to default;
|
|
|
|
set enable_mergejoin to default;
|
|
|
|
SET enable_seqscan TO DEFAULT;
|
|
|
|
DROP TABLE numrange_test;
|
|
|
|
DROP TABLE numrange_test2;
|
|
|
|
-- test canonical form for int4range
|
|
|
|
select int4range(1,10,'[]');
|
|
|
|
int4range
|
|
|
|
-----------
|
|
|
|
[1,11)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select int4range(1,10,'[)');
|
|
|
|
int4range
|
|
|
|
-----------
|
|
|
|
[1,10)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select int4range(1,10,'(]');
|
|
|
|
int4range
|
|
|
|
-----------
|
|
|
|
[2,11)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select int4range(1,10,'[]');
|
|
|
|
int4range
|
|
|
|
-----------
|
|
|
|
[1,11)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- test canonical form for daterange
|
|
|
|
select daterange('2000-01-10'::date, '2000-01-20'::date,'[]');
|
|
|
|
daterange
|
|
|
|
-------------------------
|
|
|
|
[01-10-2000,01-21-2000)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select daterange('2000-01-10'::date, '2000-01-20'::date,'[)');
|
|
|
|
daterange
|
|
|
|
-------------------------
|
|
|
|
[01-10-2000,01-20-2000)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select daterange('2000-01-10'::date, '2000-01-20'::date,'(]');
|
|
|
|
daterange
|
|
|
|
-------------------------
|
|
|
|
[01-11-2000,01-21-2000)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select daterange('2000-01-10'::date, '2000-01-20'::date,'[]');
|
|
|
|
daterange
|
|
|
|
-------------------------
|
|
|
|
[01-10-2000,01-21-2000)
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-14 21:15:53 +01:00
|
|
|
-- test GiST index that's been built incrementally
|
2011-11-03 12:16:28 +01:00
|
|
|
create table test_range_gist(ir int4range);
|
|
|
|
create index test_range_gist_idx on test_range_gist using gist (ir);
|
|
|
|
insert into test_range_gist select int4range(g, g+10) from generate_series(1,2000) g;
|
|
|
|
insert into test_range_gist select 'empty'::int4range from generate_series(1,500) g;
|
|
|
|
insert into test_range_gist select int4range(g, g+10000) from generate_series(1,1000) g;
|
|
|
|
insert into test_range_gist select 'empty'::int4range from generate_series(1,500) g;
|
|
|
|
insert into test_range_gist select int4range(NULL,g*10,'(]') from generate_series(1,100) g;
|
|
|
|
insert into test_range_gist select int4range(g*10,NULL,'(]') from generate_series(1,100) g;
|
|
|
|
insert into test_range_gist select int4range(g, g+10) from generate_series(1,2000) g;
|
2011-11-14 21:15:53 +01:00
|
|
|
-- first, verify non-indexed results
|
|
|
|
SET enable_seqscan = t;
|
|
|
|
SET enable_indexscan = f;
|
|
|
|
SET enable_bitmapscan = f;
|
2011-11-03 12:16:28 +01:00
|
|
|
select count(*) from test_range_gist where ir @> 'empty'::int4range;
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
6200
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir = int4range(10,20);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
2
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir @> 10;
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
130
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir @> int4range(10,20);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
111
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir && int4range(10,20);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
158
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir <@ int4range(10,50);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
1062
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-14 21:15:53 +01:00
|
|
|
select count(*) from test_range_gist where ir << int4range(100,500);
|
2011-11-03 12:16:28 +01:00
|
|
|
count
|
|
|
|
-------
|
|
|
|
189
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-14 21:15:53 +01:00
|
|
|
select count(*) from test_range_gist where ir >> int4range(100,500);
|
2011-11-03 12:16:28 +01:00
|
|
|
count
|
|
|
|
-------
|
|
|
|
3554
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-14 21:15:53 +01:00
|
|
|
select count(*) from test_range_gist where ir &< int4range(100,500);
|
2011-11-03 12:16:28 +01:00
|
|
|
count
|
|
|
|
-------
|
|
|
|
1029
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-14 21:15:53 +01:00
|
|
|
select count(*) from test_range_gist where ir &> int4range(100,500);
|
2011-11-03 12:16:28 +01:00
|
|
|
count
|
|
|
|
-------
|
|
|
|
4794
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-14 21:15:53 +01:00
|
|
|
select count(*) from test_range_gist where ir -|- int4range(100,500);
|
2011-11-03 12:16:28 +01:00
|
|
|
count
|
|
|
|
-------
|
|
|
|
5
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-14 21:15:53 +01:00
|
|
|
-- now check same queries using index
|
|
|
|
SET enable_seqscan = f;
|
|
|
|
SET enable_indexscan = t;
|
|
|
|
SET enable_bitmapscan = f;
|
2011-11-03 12:16:28 +01:00
|
|
|
select count(*) from test_range_gist where ir @> 'empty'::int4range;
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
6200
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir = int4range(10,20);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
2
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir @> 10;
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
130
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir @> int4range(10,20);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
111
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir && int4range(10,20);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
158
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir <@ int4range(10,50);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
1062
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir << int4range(100,500);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
189
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir >> int4range(100,500);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
3554
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir &< int4range(100,500);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
1029
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir &> int4range(100,500);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
4794
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir -|- int4range(100,500);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
5
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-14 21:15:53 +01:00
|
|
|
-- now check same queries using a bulk-loaded index
|
2011-11-03 12:16:28 +01:00
|
|
|
drop index test_range_gist_idx;
|
|
|
|
create index test_range_gist_idx on test_range_gist using gist (ir);
|
|
|
|
select count(*) from test_range_gist where ir @> 'empty'::int4range;
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
6200
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir = int4range(10,20);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
2
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir @> 10;
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
130
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir @> int4range(10,20);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
111
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir && int4range(10,20);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
158
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir <@ int4range(10,50);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
1062
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir << int4range(100,500);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
189
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir >> int4range(100,500);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
3554
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir &< int4range(100,500);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
1029
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir &> int4range(100,500);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
4794
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select count(*) from test_range_gist where ir -|- int4range(100,500);
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
5
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-14 21:15:53 +01:00
|
|
|
RESET enable_seqscan;
|
|
|
|
RESET enable_indexscan;
|
|
|
|
RESET enable_bitmapscan;
|
2011-11-03 12:16:28 +01:00
|
|
|
--
|
|
|
|
-- Btree_gist is not included by default, so to test exclusion
|
|
|
|
-- constraints with range types, use singleton int ranges for the "="
|
|
|
|
-- portion of the constraint.
|
|
|
|
--
|
|
|
|
create table test_range_excl(
|
|
|
|
room int4range,
|
|
|
|
speaker int4range,
|
|
|
|
during tsrange,
|
|
|
|
exclude using gist (room with =, during with &&),
|
|
|
|
exclude using gist (speaker with =, during with &&)
|
|
|
|
);
|
|
|
|
NOTICE: CREATE TABLE / EXCLUDE will create implicit index "test_range_excl_room_during_excl" for table "test_range_excl"
|
|
|
|
NOTICE: CREATE TABLE / EXCLUDE will create implicit index "test_range_excl_speaker_during_excl" for table "test_range_excl"
|
|
|
|
insert into test_range_excl
|
|
|
|
values(int4range(123), int4range(1), '[2010-01-02 10:00, 2010-01-02 11:00)');
|
|
|
|
insert into test_range_excl
|
|
|
|
values(int4range(123), int4range(2), '[2010-01-02 11:00, 2010-01-02 12:00)');
|
|
|
|
insert into test_range_excl
|
|
|
|
values(int4range(123), int4range(3), '[2010-01-02 10:10, 2010-01-02 11:10)');
|
|
|
|
ERROR: conflicting key value violates exclusion constraint "test_range_excl_room_during_excl"
|
|
|
|
DETAIL: Key (room, during)=([123,124), ["Sat Jan 02 10:10:00 2010","Sat Jan 02 11:10:00 2010")) conflicts with existing key (room, during)=([123,124), ["Sat Jan 02 10:00:00 2010","Sat Jan 02 11:00:00 2010")).
|
|
|
|
insert into test_range_excl
|
|
|
|
values(int4range(124), int4range(3), '[2010-01-02 10:10, 2010-01-02 11:10)');
|
|
|
|
insert into test_range_excl
|
|
|
|
values(int4range(125), int4range(1), '[2010-01-02 10:10, 2010-01-02 11:10)');
|
|
|
|
ERROR: conflicting key value violates exclusion constraint "test_range_excl_speaker_during_excl"
|
|
|
|
DETAIL: Key (speaker, during)=([1,2), ["Sat Jan 02 10:10:00 2010","Sat Jan 02 11:10:00 2010")) conflicts with existing key (speaker, during)=([1,2), ["Sat Jan 02 10:00:00 2010","Sat Jan 02 11:00:00 2010")).
|
|
|
|
-- test bigint ranges
|
|
|
|
select int8range(10000000000::int8, 20000000000::int8,'(]');
|
|
|
|
int8range
|
|
|
|
---------------------------
|
|
|
|
[10000000001,20000000001)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- test tstz ranges
|
|
|
|
set timezone to '-08';
|
|
|
|
select '[2010-01-01 01:00:00 -05, 2010-01-01 02:00:00 -08)'::tstzrange;
|
|
|
|
tstzrange
|
|
|
|
-----------------------------------------------------------------
|
|
|
|
["Thu Dec 31 22:00:00 2009 -08","Fri Jan 01 02:00:00 2010 -08")
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- should fail
|
|
|
|
select '[2010-01-01 01:00:00 -08, 2010-01-01 02:00:00 -05)'::tstzrange;
|
|
|
|
ERROR: range lower bound must be less than or equal to range upper bound
|
|
|
|
LINE 1: select '[2010-01-01 01:00:00 -08, 2010-01-01 02:00:00 -05)':...
|
|
|
|
^
|
|
|
|
set timezone to default;
|
|
|
|
--
|
|
|
|
-- Test user-defined range of floats
|
|
|
|
--
|
|
|
|
--should fail
|
|
|
|
create type float8range as range (subtype=float8, subtype_diff=float4mi);
|
|
|
|
ERROR: function float4mi(double precision, double precision) does not exist
|
|
|
|
--should succeed
|
|
|
|
create type float8range as range (subtype=float8, subtype_diff=float8mi);
|
|
|
|
select '[123.001, 5.e9)'::float8range @> 888.882::float8;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
create table float8range_test(f8r float8range, i int);
|
|
|
|
insert into float8range_test values(float8range(-100.00007, '1.111113e9'));
|
|
|
|
select * from float8range_test;
|
|
|
|
f8r | i
|
|
|
|
-------------------------+---
|
|
|
|
[-100.00007,1111113000) |
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
drop table float8range_test;
|
|
|
|
--
|
|
|
|
-- Test range types over domains
|
|
|
|
--
|
|
|
|
create domain mydomain as int4;
|
|
|
|
create type mydomainrange as range(subtype=mydomain);
|
|
|
|
select '[4,50)'::mydomainrange @> 7::mydomain;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
drop type mydomainrange;
|
|
|
|
drop domain mydomain;
|
|
|
|
--
|
|
|
|
-- Test domains over range types
|
|
|
|
--
|
|
|
|
create domain restrictedrange as int4range check (upper(value) < 10);
|
|
|
|
select '[4,5)'::restrictedrange @> 7;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
f
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
select '[4,50)'::restrictedrange @> 7; -- should fail
|
|
|
|
ERROR: value for domain restrictedrange violates check constraint "restrictedrange_check"
|
|
|
|
drop domain restrictedrange;
|
|
|
|
--
|
|
|
|
-- Test multiple range types over the same subtype
|
|
|
|
--
|
|
|
|
create type textrange1 as range(subtype=text, collation="C");
|
|
|
|
create type textrange2 as range(subtype=text, collation="C");
|
|
|
|
select textrange1('a','Z') @> 'b'::text;
|
|
|
|
ERROR: range lower bound must be less than or equal to range upper bound
|
|
|
|
select textrange2('a','z') @> 'b'::text;
|
|
|
|
?column?
|
|
|
|
----------
|
|
|
|
t
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
drop type textrange1;
|
|
|
|
drop type textrange2;
|
|
|
|
--
|
|
|
|
-- Test out polymorphic type system
|
|
|
|
--
|
|
|
|
create function anyarray_anyrange_func(a anyarray, r anyrange)
|
|
|
|
returns anyelement as 'select $1[1] + lower($2);' language sql;
|
|
|
|
select anyarray_anyrange_func(ARRAY[1,2], int4range(10,20));
|
|
|
|
anyarray_anyrange_func
|
|
|
|
------------------------
|
|
|
|
11
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
-- should fail
|
|
|
|
select anyarray_anyrange_func(ARRAY[1,2], numrange(10,20));
|
|
|
|
ERROR: function anyarray_anyrange_func(integer[], numrange) does not exist
|
|
|
|
LINE 1: select anyarray_anyrange_func(ARRAY[1,2], numrange(10,20));
|
|
|
|
^
|
|
|
|
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
|
|
|
|
drop function anyarray_anyrange_func(anyarray, anyrange);
|
|
|
|
-- should fail
|
|
|
|
create function bogus_func(anyelement)
|
|
|
|
returns anyrange as 'select int4range(1,10)' language sql;
|
|
|
|
ERROR: cannot determine result data type
|
|
|
|
DETAIL: A function returning ANYRANGE must have at least one ANYRANGE argument.
|
|
|
|
-- should fail
|
|
|
|
create function bogus_func(int)
|
|
|
|
returns anyrange as 'select int4range(1,10)' language sql;
|
|
|
|
ERROR: cannot determine result data type
|
|
|
|
DETAIL: A function returning a polymorphic type must have at least one polymorphic argument.
|
|
|
|
create function range_add_bounds(anyrange)
|
|
|
|
returns anyelement as 'select lower($1) + upper($1)' language sql;
|
|
|
|
select range_add_bounds(numrange(1.0001, 123.123));
|
|
|
|
range_add_bounds
|
|
|
|
------------------
|
|
|
|
124.1231
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
--
|
|
|
|
-- Arrays of ranges
|
|
|
|
--
|
|
|
|
select ARRAY[numrange(1.1), numrange(12.3,155.5)];
|
|
|
|
array
|
|
|
|
------------------------------
|
|
|
|
{"[1.1,1.1]","[12.3,155.5)"}
|
|
|
|
(1 row)
|
|
|
|
|
2011-11-15 03:42:04 +01:00
|
|
|
create table i8r_array (f1 int, f2 int8range[]);
|
|
|
|
insert into i8r_array values (42, array[int8range(1,10), int8range(2,20)]);
|
|
|
|
select * from i8r_array;
|
|
|
|
f1 | f2
|
|
|
|
----+---------------------
|
|
|
|
42 | {"[1,10)","[2,20)"}
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
drop table i8r_array;
|
2011-11-03 12:16:28 +01:00
|
|
|
--
|
|
|
|
-- Ranges of arrays
|
|
|
|
--
|
|
|
|
create type arrayrange as range (subtype=int4[]);
|
|
|
|
select arrayrange(ARRAY[1,2], ARRAY[2,1]);
|
|
|
|
arrayrange
|
|
|
|
-------------------
|
|
|
|
["{1,2}","{2,1}")
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
--
|
|
|
|
-- OUT/INOUT/TABLE functions
|
|
|
|
--
|
|
|
|
create function outparam_succeed(i anyrange, out r anyrange, out t text)
|
|
|
|
as $$ select $1, 'foo' $$ language sql;
|
|
|
|
create function inoutparam_succeed(out i anyelement, inout r anyrange)
|
|
|
|
as $$ select $1, $2 $$ language sql;
|
|
|
|
create function table_succeed(i anyelement, r anyrange) returns table(i anyelement, r anyrange)
|
|
|
|
as $$ select $1, $2 $$ language sql;
|
|
|
|
-- should fail
|
|
|
|
create function outparam_fail(i anyelement, out r anyrange, out t text)
|
|
|
|
as $$ select '[1,10]', 'foo' $$ language sql;
|
|
|
|
ERROR: cannot determine result data type
|
|
|
|
DETAIL: A function returning ANYRANGE must have at least one ANYRANGE argument.
|
|
|
|
--should fail
|
|
|
|
create function inoutparam_fail(inout i anyelement, out r anyrange)
|
|
|
|
as $$ select $1, '[1,10]' $$ language sql;
|
|
|
|
ERROR: cannot determine result data type
|
|
|
|
DETAIL: A function returning ANYRANGE must have at least one ANYRANGE argument.
|
|
|
|
--should fail
|
|
|
|
create function table_succeed(i anyelement) returns table(i anyelement, r anyrange)
|
|
|
|
as $$ select $1, '[1,10]' $$ language sql;
|
|
|
|
ERROR: cannot determine result data type
|
|
|
|
DETAIL: A function returning ANYRANGE must have at least one ANYRANGE argument.
|