1 -- Tests for range data types.
2 create type textrange as range (subtype=text, collation="C");
6 -- negative tests; should fail
8 ERROR: malformed range literal: ""
9 LINE 1: select ''::textrange;
11 DETAIL: Missing left parenthesis or bracket.
12 select '-[a,z)'::textrange;
13 ERROR: malformed range literal: "-[a,z)"
14 LINE 1: select '-[a,z)'::textrange;
16 DETAIL: Missing left parenthesis or bracket.
17 select '[a,z) - '::textrange;
18 ERROR: malformed range literal: "[a,z) - "
19 LINE 1: select '[a,z) - '::textrange;
21 DETAIL: Junk after right parenthesis or bracket.
22 select '(",a)'::textrange;
23 ERROR: malformed range literal: "(",a)"
24 LINE 1: select '(",a)'::textrange;
26 DETAIL: Unexpected end of input.
27 select '(,,a)'::textrange;
28 ERROR: malformed range literal: "(,,a)"
29 LINE 1: select '(,,a)'::textrange;
31 DETAIL: Too many commas.
32 select '(),a)'::textrange;
33 ERROR: malformed range literal: "(),a)"
34 LINE 1: select '(),a)'::textrange;
36 DETAIL: Missing comma after lower bound.
37 select '(a,))'::textrange;
38 ERROR: malformed range literal: "(a,))"
39 LINE 1: select '(a,))'::textrange;
41 DETAIL: Junk after right parenthesis or bracket.
42 select '(],a)'::textrange;
43 ERROR: malformed range literal: "(],a)"
44 LINE 1: select '(],a)'::textrange;
46 DETAIL: Missing comma after lower bound.
47 select '(a,])'::textrange;
48 ERROR: malformed range literal: "(a,])"
49 LINE 1: select '(a,])'::textrange;
51 DETAIL: Junk after right parenthesis or bracket.
52 select '[z,a]'::textrange;
53 ERROR: range lower bound must be less than or equal to range upper bound
54 LINE 1: select '[z,a]'::textrange;
57 select ' empty '::textrange;
63 select ' ( empty, empty ) '::textrange;
65 ----------------------
69 select ' ( " a " " a ", " z " " z " ) '::textrange;
71 --------------------------
75 select '(,z)'::textrange;
81 select '(a,)'::textrange;
87 select '[,z]'::textrange;
93 select '[a,]'::textrange;
99 select '(,)'::textrange;
105 select '[ , ]'::textrange;
111 select '["",""]'::textrange;
117 select '[",",","]'::textrange;
123 select '["\\","\\"]'::textrange;
129 select '(\\,a)'::textrange;
135 select '((,z)'::textrange;
141 select '([,z)'::textrange;
147 select '(!,()'::textrange;
153 select '(!,[)'::textrange;
159 select '[a,a]'::textrange;
165 -- these are allowed but normalize to empty:
166 select '[a,a)'::textrange;
172 select '(a,a]'::textrange;
178 select '(a,a)'::textrange;
185 -- create some test data and test the operators
187 CREATE TABLE numrange_test (nr NUMRANGE);
188 create index numrange_test_btree on numrange_test(nr);
189 INSERT INTO numrange_test VALUES('[,)');
190 INSERT INTO numrange_test VALUES('[3,]');
191 INSERT INTO numrange_test VALUES('[, 5)');
192 INSERT INTO numrange_test VALUES(numrange(1.1, 2.2));
193 INSERT INTO numrange_test VALUES('empty');
194 INSERT INTO numrange_test VALUES(numrange(1.7, 1.7, '[]'));
195 SELECT nr, isempty(nr), lower(nr), upper(nr) FROM numrange_test;
196 nr | isempty | lower | upper
197 -----------+---------+-------+-------
201 [1.1,2.2) | f | 1.1 | 2.2
203 [1.7,1.7] | f | 1.7 | 1.7
206 SELECT nr, lower_inc(nr), lower_inf(nr), upper_inc(nr), upper_inf(nr) FROM numrange_test;
207 nr | lower_inc | lower_inf | upper_inc | upper_inf
208 -----------+-----------+-----------+-----------+-----------
212 [1.1,2.2) | t | f | f | f
213 empty | f | f | f | f
214 [1.7,1.7] | t | f | t | f
217 SELECT * FROM numrange_test WHERE range_contains(nr, numrange(1.9,1.91));
225 SELECT * FROM numrange_test WHERE nr @> numrange(1.0,10000.1);
231 SELECT * FROM numrange_test WHERE range_contained_by(numrange(-1e7,-10000.1), nr);
238 SELECT * FROM numrange_test WHERE 1.9 <@ nr;
246 select * from numrange_test where nr = 'empty';
252 select * from numrange_test where nr = '(1.1, 2.2)';
257 select * from numrange_test where nr = '[1.1, 2.2)';
263 select * from numrange_test where nr < 'empty';
268 select * from numrange_test where nr < numrange(-1000.0, -1000.0,'[]');
276 select * from numrange_test where nr < numrange(0.0, 1.0,'[]');
284 select * from numrange_test where nr < numrange(1000.0, 1001.0,'[]');
295 select * from numrange_test where nr <= 'empty';
301 select * from numrange_test where nr >= 'empty';
312 select * from numrange_test where nr > 'empty';
322 select * from numrange_test where nr > numrange(-1001.0, -1000.0,'[]');
330 select * from numrange_test where nr > numrange(0.0, 1.0,'[]');
338 select * from numrange_test where nr > numrange(1000.0, 1000.0,'[]');
343 select numrange(2.0, 1.0);
344 ERROR: range lower bound must be less than or equal to range upper bound
345 select numrange(2.0, 3.0) -|- numrange(3.0, 4.0);
351 select range_adjacent(numrange(2.0, 3.0), numrange(3.1, 4.0));
357 select range_adjacent(numrange(2.0, 3.0), numrange(3.1, null));
363 select numrange(2.0, 3.0, '[]') -|- numrange(3.0, 4.0, '()');
369 select numrange(1.0, 2.0) -|- numrange(2.0, 3.0,'[]');
375 select range_adjacent(numrange(2.0, 3.0, '(]'), numrange(1.0, 2.0, '(]'));
381 select numrange(1.1, 3.3) <@ numrange(0.1,10.1);
387 select numrange(0.1, 10.1) <@ numrange(1.1,3.3);
393 select numrange(1.1, 2.2) - numrange(2.0, 3.0);
399 select numrange(1.1, 2.2) - numrange(2.2, 3.0);
405 select numrange(1.1, 2.2,'[]') - numrange(2.0, 3.0);
411 select range_minus(numrange(10.1,12.2,'[]'), numrange(110.0,120.2,'(]'));
417 select range_minus(numrange(10.1,12.2,'[]'), numrange(0.0,120.2,'(]'));
423 select numrange(4.5, 5.5, '[]') && numrange(5.5, 6.5);
429 select numrange(1.0, 2.0) << numrange(3.0, 4.0);
435 select numrange(1.0, 3.0,'[]') << numrange(3.0, 4.0,'[]');
441 select numrange(1.0, 3.0,'()') << numrange(3.0, 4.0,'()');
447 select numrange(1.0, 2.0) >> numrange(3.0, 4.0);
453 select numrange(3.0, 70.0) &< numrange(6.6, 100.0);
459 select numrange(1.1, 2.2) < numrange(1.0, 200.2);
465 select numrange(1.1, 2.2) < numrange(1.1, 1.2);
471 select numrange(1.0, 2.0) + numrange(2.0, 3.0);
477 select numrange(1.0, 2.0) + numrange(1.5, 3.0);
483 select numrange(1.0, 2.0) + numrange(2.5, 3.0); -- should fail
484 ERROR: result of range union would not be contiguous
485 select range_merge(numrange(1.0, 2.0), numrange(2.0, 3.0));
491 select range_merge(numrange(1.0, 2.0), numrange(1.5, 3.0));
497 select range_merge(numrange(1.0, 2.0), numrange(2.5, 3.0)); -- shouldn't fail
503 select numrange(1.0, 2.0) * numrange(2.0, 3.0);
509 select numrange(1.0, 2.0) * numrange(1.5, 3.0);
515 select numrange(1.0, 2.0) * numrange(2.5, 3.0);
521 select range_intersect_agg(nr) from numrange_test;
523 ---------------------
527 select range_intersect_agg(nr) from numrange_test where false;
529 ---------------------
533 select range_intersect_agg(nr) from numrange_test where nr @> 4.0;
535 ---------------------
539 analyze numrange_test;
540 create table numrange_test2(nr numrange);
541 create index numrange_test2_hash_idx on numrange_test2 using hash (nr);
542 INSERT INTO numrange_test2 VALUES('[, 5)');
543 INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2));
544 INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2));
545 INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2,'()'));
546 INSERT INTO numrange_test2 VALUES('empty');
547 select * from numrange_test2 where nr = 'empty'::numrange;
553 select * from numrange_test2 where nr = numrange(1.1, 2.2);
560 select * from numrange_test2 where nr = numrange(1.1, 2.3);
565 set enable_nestloop=t;
566 set enable_hashjoin=f;
567 set enable_mergejoin=f;
568 select * from numrange_test natural join numrange_test2 order by nr;
577 set enable_nestloop=f;
578 set enable_hashjoin=t;
579 set enable_mergejoin=f;
580 select * from numrange_test natural join numrange_test2 order by nr;
589 set enable_nestloop=f;
590 set enable_hashjoin=f;
591 set enable_mergejoin=t;
592 select * from numrange_test natural join numrange_test2 order by nr;
601 set enable_nestloop to default;
602 set enable_hashjoin to default;
603 set enable_mergejoin to default;
604 -- keep numrange_test around to help exercise dump/reload
605 DROP TABLE numrange_test2;
607 -- Apply a subset of the above tests on a collatable type, too
609 CREATE TABLE textrange_test (tr textrange);
610 create index textrange_test_btree on textrange_test(tr);
611 INSERT INTO textrange_test VALUES('[,)');
612 INSERT INTO textrange_test VALUES('["a",]');
613 INSERT INTO textrange_test VALUES('[,"q")');
614 INSERT INTO textrange_test VALUES(textrange('b', 'g'));
615 INSERT INTO textrange_test VALUES('empty');
616 INSERT INTO textrange_test VALUES(textrange('d', 'd', '[]'));
617 SELECT tr, isempty(tr), lower(tr), upper(tr) FROM textrange_test;
618 tr | isempty | lower | upper
619 -------+---------+-------+-------
628 SELECT tr, lower_inc(tr), lower_inf(tr), upper_inc(tr), upper_inf(tr) FROM textrange_test;
629 tr | lower_inc | lower_inf | upper_inc | upper_inf
630 -------+-----------+-----------+-----------+-----------
634 [b,g) | t | f | f | f
635 empty | f | f | f | f
636 [d,d] | t | f | t | f
639 SELECT * FROM textrange_test WHERE range_contains(tr, textrange('f', 'fx'));
648 SELECT * FROM textrange_test WHERE tr @> textrange('a', 'z');
655 SELECT * FROM textrange_test WHERE range_contained_by(textrange('0','9'), tr);
662 SELECT * FROM textrange_test WHERE 'e'::text <@ tr;
671 select * from textrange_test where tr = 'empty';
677 select * from textrange_test where tr = '("b","g")';
682 select * from textrange_test where tr = '["b","g")';
688 select * from textrange_test where tr < 'empty';
693 -- test canonical form for int4range
694 select int4range(1, 10, '[]');
700 select int4range(1, 10, '[)');
706 select int4range(1, 10, '(]');
712 select int4range(1, 10, '()');
718 select int4range(1, 2, '()');
724 -- test canonical form for daterange
725 select daterange('2000-01-10'::date, '2000-01-20'::date, '[]');
727 -------------------------
728 [01-10-2000,01-21-2000)
731 select daterange('2000-01-10'::date, '2000-01-20'::date, '[)');
733 -------------------------
734 [01-10-2000,01-20-2000)
737 select daterange('2000-01-10'::date, '2000-01-20'::date, '(]');
739 -------------------------
740 [01-11-2000,01-21-2000)
743 select daterange('2000-01-10'::date, '2000-01-20'::date, '()');
745 -------------------------
746 [01-11-2000,01-20-2000)
749 select daterange('2000-01-10'::date, '2000-01-11'::date, '()');
755 select daterange('2000-01-10'::date, '2000-01-11'::date, '(]');
757 -------------------------
758 [01-11-2000,01-12-2000)
761 select daterange('-infinity'::date, '2000-01-01'::date, '()');
763 ------------------------
764 (-infinity,01-01-2000)
767 select daterange('-infinity'::date, '2000-01-01'::date, '[)');
769 ------------------------
770 [-infinity,01-01-2000)
773 select daterange('2000-01-01'::date, 'infinity'::date, '[)');
775 -----------------------
776 [01-01-2000,infinity)
779 select daterange('2000-01-01'::date, 'infinity'::date, '[]');
781 -----------------------
782 [01-01-2000,infinity]
785 -- test GiST index that's been built incrementally
786 create table test_range_gist(ir int4range);
787 create index test_range_gist_idx on test_range_gist using gist (ir);
788 insert into test_range_gist select int4range(g, g+10) from generate_series(1,2000) g;
789 insert into test_range_gist select 'empty'::int4range from generate_series(1,500) g;
790 insert into test_range_gist select int4range(g, g+10000) from generate_series(1,1000) g;
791 insert into test_range_gist select 'empty'::int4range from generate_series(1,500) g;
792 insert into test_range_gist select int4range(NULL,g*10,'(]') from generate_series(1,100) g;
793 insert into test_range_gist select int4range(g*10,NULL,'(]') from generate_series(1,100) g;
794 insert into test_range_gist select int4range(g, g+10) from generate_series(1,2000) g;
795 -- test statistics and selectivity estimation as well
797 -- We don't check the accuracy of selectivity estimation, but at least check
799 analyze test_range_gist;
800 -- first, verify non-indexed results
801 SET enable_seqscan = t;
802 SET enable_indexscan = f;
803 SET enable_bitmapscan = f;
804 select count(*) from test_range_gist where ir @> 'empty'::int4range;
810 select count(*) from test_range_gist where ir = int4range(10,20);
816 select count(*) from test_range_gist where ir @> 10;
822 select count(*) from test_range_gist where ir @> int4range(10,20);
828 select count(*) from test_range_gist where ir && int4range(10,20);
834 select count(*) from test_range_gist where ir <@ int4range(10,50);
840 select count(*) from test_range_gist where ir << int4range(100,500);
846 select count(*) from test_range_gist where ir >> int4range(100,500);
852 select count(*) from test_range_gist where ir &< int4range(100,500);
858 select count(*) from test_range_gist where ir &> int4range(100,500);
864 select count(*) from test_range_gist where ir -|- int4range(100,500);
870 select count(*) from test_range_gist where ir @> '{}'::int4multirange;
876 select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40));
882 select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange;
888 select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange;
894 select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500));
900 select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500));
906 select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500));
912 select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500));
918 select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500));
924 -- now check same queries using index
925 SET enable_seqscan = f;
926 SET enable_indexscan = t;
927 SET enable_bitmapscan = f;
928 select count(*) from test_range_gist where ir @> 'empty'::int4range;
934 select count(*) from test_range_gist where ir = int4range(10,20);
940 select count(*) from test_range_gist where ir @> 10;
946 select count(*) from test_range_gist where ir @> int4range(10,20);
952 select count(*) from test_range_gist where ir && int4range(10,20);
958 select count(*) from test_range_gist where ir <@ int4range(10,50);
964 select count(*) from test_range_gist where ir << int4range(100,500);
970 select count(*) from test_range_gist where ir >> int4range(100,500);
976 select count(*) from test_range_gist where ir &< int4range(100,500);
982 select count(*) from test_range_gist where ir &> int4range(100,500);
988 select count(*) from test_range_gist where ir -|- int4range(100,500);
994 select count(*) from test_range_gist where ir @> '{}'::int4multirange;
1000 select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40));
1006 select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange;
1012 select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange;
1018 select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500));
1024 select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500));
1030 select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500));
1036 select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500));
1042 select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500));
1048 -- now check same queries using a bulk-loaded index
1049 drop index test_range_gist_idx;
1050 create index test_range_gist_idx on test_range_gist using gist (ir);
1051 select count(*) from test_range_gist where ir @> 'empty'::int4range;
1057 select count(*) from test_range_gist where ir = int4range(10,20);
1063 select count(*) from test_range_gist where ir @> 10;
1069 select count(*) from test_range_gist where ir @> int4range(10,20);
1075 select count(*) from test_range_gist where ir && int4range(10,20);
1081 select count(*) from test_range_gist where ir <@ int4range(10,50);
1087 select count(*) from test_range_gist where ir << int4range(100,500);
1093 select count(*) from test_range_gist where ir >> int4range(100,500);
1099 select count(*) from test_range_gist where ir &< int4range(100,500);
1105 select count(*) from test_range_gist where ir &> int4range(100,500);
1111 select count(*) from test_range_gist where ir -|- int4range(100,500);
1117 select count(*) from test_range_gist where ir @> '{}'::int4multirange;
1123 select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40));
1129 select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange;
1135 select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange;
1141 select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500));
1147 select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500));
1153 select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500));
1159 select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500));
1165 select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500));
1171 -- test SP-GiST index that's been built incrementally
1172 create table test_range_spgist(ir int4range);
1173 create index test_range_spgist_idx on test_range_spgist using spgist (ir);
1174 insert into test_range_spgist select int4range(g, g+10) from generate_series(1,2000) g;
1175 insert into test_range_spgist select 'empty'::int4range from generate_series(1,500) g;
1176 insert into test_range_spgist select int4range(g, g+10000) from generate_series(1,1000) g;
1177 insert into test_range_spgist select 'empty'::int4range from generate_series(1,500) g;
1178 insert into test_range_spgist select int4range(NULL,g*10,'(]') from generate_series(1,100) g;
1179 insert into test_range_spgist select int4range(g*10,NULL,'(]') from generate_series(1,100) g;
1180 insert into test_range_spgist select int4range(g, g+10) from generate_series(1,2000) g;
1181 -- first, verify non-indexed results
1182 SET enable_seqscan = t;
1183 SET enable_indexscan = f;
1184 SET enable_bitmapscan = f;
1185 select count(*) from test_range_spgist where ir @> 'empty'::int4range;
1191 select count(*) from test_range_spgist where ir = int4range(10,20);
1197 select count(*) from test_range_spgist where ir @> 10;
1203 select count(*) from test_range_spgist where ir @> int4range(10,20);
1209 select count(*) from test_range_spgist where ir && int4range(10,20);
1215 select count(*) from test_range_spgist where ir <@ int4range(10,50);
1221 select count(*) from test_range_spgist where ir << int4range(100,500);
1227 select count(*) from test_range_spgist where ir >> int4range(100,500);
1233 select count(*) from test_range_spgist where ir &< int4range(100,500);
1239 select count(*) from test_range_spgist where ir &> int4range(100,500);
1245 select count(*) from test_range_spgist where ir -|- int4range(100,500);
1251 -- now check same queries using index
1252 SET enable_seqscan = f;
1253 SET enable_indexscan = t;
1254 SET enable_bitmapscan = f;
1255 select count(*) from test_range_spgist where ir @> 'empty'::int4range;
1261 select count(*) from test_range_spgist where ir = int4range(10,20);
1267 select count(*) from test_range_spgist where ir @> 10;
1273 select count(*) from test_range_spgist where ir @> int4range(10,20);
1279 select count(*) from test_range_spgist where ir && int4range(10,20);
1285 select count(*) from test_range_spgist where ir <@ int4range(10,50);
1291 select count(*) from test_range_spgist where ir << int4range(100,500);
1297 select count(*) from test_range_spgist where ir >> int4range(100,500);
1303 select count(*) from test_range_spgist where ir &< int4range(100,500);
1309 select count(*) from test_range_spgist where ir &> int4range(100,500);
1315 select count(*) from test_range_spgist where ir -|- int4range(100,500);
1321 -- now check same queries using a bulk-loaded index
1322 drop index test_range_spgist_idx;
1323 create index test_range_spgist_idx on test_range_spgist using spgist (ir);
1324 select count(*) from test_range_spgist where ir @> 'empty'::int4range;
1330 select count(*) from test_range_spgist where ir = int4range(10,20);
1336 select count(*) from test_range_spgist where ir @> 10;
1342 select count(*) from test_range_spgist where ir @> int4range(10,20);
1348 select count(*) from test_range_spgist where ir && int4range(10,20);
1354 select count(*) from test_range_spgist where ir <@ int4range(10,50);
1360 select count(*) from test_range_spgist where ir << int4range(100,500);
1366 select count(*) from test_range_spgist where ir >> int4range(100,500);
1372 select count(*) from test_range_spgist where ir &< int4range(100,500);
1378 select count(*) from test_range_spgist where ir &> int4range(100,500);
1384 select count(*) from test_range_spgist where ir -|- int4range(100,500);
1390 -- test index-only scans
1392 select ir from test_range_spgist where ir -|- int4range(10,20) order by ir;
1394 ------------------------------------------------------------------------
1397 -> Index Only Scan using test_range_spgist_idx on test_range_spgist
1398 Index Cond: (ir -|- '[10,20)'::int4range)
1401 select ir from test_range_spgist where ir -|- int4range(10,20) order by ir;
1409 RESET enable_seqscan;
1410 RESET enable_indexscan;
1411 RESET enable_bitmapscan;
1412 -- test elem <@ range operator
1413 create table test_range_elem(i int4);
1414 create index test_range_elem_idx on test_range_elem (i);
1415 insert into test_range_elem select i from generate_series(1,100) i;
1416 SET enable_seqscan = f;
1417 select count(*) from test_range_elem where i <@ int4range(10,50);
1423 -- also test spgist index on anyrange expression
1424 create index on test_range_elem using spgist(int4range(i,i+10));
1426 select count(*) from test_range_elem where int4range(i,i+10) <@ int4range(10,30);
1428 -------------------------------------------------------------------------
1430 -> Index Scan using test_range_elem_int4range_idx on test_range_elem
1431 Index Cond: (int4range(i, (i + 10)) <@ '[10,30)'::int4range)
1434 select count(*) from test_range_elem where int4range(i,i+10) <@ int4range(10,30);
1440 RESET enable_seqscan;
1441 drop table test_range_elem;
1443 -- Btree_gist is not included by default, so to test exclusion
1444 -- constraints with range types, use singleton int ranges for the "="
1445 -- portion of the constraint.
1447 create table test_range_excl(
1451 exclude using gist (room with =, during with &&),
1452 exclude using gist (speaker with =, during with &&)
1454 insert into test_range_excl
1455 values(int4range(123, 123, '[]'), int4range(1, 1, '[]'), '[2010-01-02 10:00, 2010-01-02 11:00)');
1456 insert into test_range_excl
1457 values(int4range(123, 123, '[]'), int4range(2, 2, '[]'), '[2010-01-02 11:00, 2010-01-02 12:00)');
1458 insert into test_range_excl
1459 values(int4range(123, 123, '[]'), int4range(3, 3, '[]'), '[2010-01-02 10:10, 2010-01-02 11:00)');
1460 ERROR: conflicting key value violates exclusion constraint "test_range_excl_room_during_excl"
1461 DETAIL: Key (room, during)=([123,124), ["Sat Jan 02 10:10:00 2010","Sat Jan 02 11:00:00 2010")) conflicts with existing key (room, during)=([123,124), ["Sat Jan 02 10:00:00 2010","Sat Jan 02 11:00:00 2010")).
1462 insert into test_range_excl
1463 values(int4range(124, 124, '[]'), int4range(3, 3, '[]'), '[2010-01-02 10:10, 2010-01-02 11:10)');
1464 insert into test_range_excl
1465 values(int4range(125, 125, '[]'), int4range(1, 1, '[]'), '[2010-01-02 10:10, 2010-01-02 11:00)');
1466 ERROR: conflicting key value violates exclusion constraint "test_range_excl_speaker_during_excl"
1467 DETAIL: Key (speaker, during)=([1,2), ["Sat Jan 02 10:10:00 2010","Sat Jan 02 11:00:00 2010")) conflicts with existing key (speaker, during)=([1,2), ["Sat Jan 02 10:00:00 2010","Sat Jan 02 11:00:00 2010")).
1468 -- test bigint ranges
1469 select int8range(10000000000::int8, 20000000000::int8,'(]');
1471 ---------------------------
1472 [10000000001,20000000001)
1476 set timezone to '-08';
1477 select '[2010-01-01 01:00:00 -05, 2010-01-01 02:00:00 -08)'::tstzrange;
1479 -----------------------------------------------------------------
1480 ["Thu Dec 31 22:00:00 2009 -08","Fri Jan 01 02:00:00 2010 -08")
1484 select '[2010-01-01 01:00:00 -08, 2010-01-01 02:00:00 -05)'::tstzrange;
1485 ERROR: range lower bound must be less than or equal to range upper bound
1486 LINE 1: select '[2010-01-01 01:00:00 -08, 2010-01-01 02:00:00 -05)':...
1488 set timezone to default;
1490 -- Test user-defined range of floats
1493 create type float8range as range (subtype=float8, subtype_diff=float4mi);
1494 ERROR: function float4mi(double precision, double precision) does not exist
1496 create type float8range as range (subtype=float8, subtype_diff=float8mi);
1497 select '[123.001, 5.e9)'::float8range @> 888.882::float8;
1503 create table float8range_test(f8r float8range, i int);
1504 insert into float8range_test values(float8range(-100.00007, '1.111113e9'), 42);
1505 select * from float8range_test;
1507 -------------------------+----
1508 [-100.00007,1111113000) | 42
1511 drop table float8range_test;
1513 -- Test range types over domains
1515 create domain mydomain as int4;
1516 create type mydomainrange as range(subtype=mydomain);
1517 select '[4,50)'::mydomainrange @> 7::mydomain;
1523 drop domain mydomain; -- fail
1524 ERROR: cannot drop type mydomain because other objects depend on it
1525 DETAIL: type mydomainrange depends on type mydomain
1526 HINT: Use DROP ... CASCADE to drop the dependent objects too.
1527 drop domain mydomain cascade;
1528 NOTICE: drop cascades to type mydomainrange
1530 -- Test domains over range types
1532 create domain restrictedrange as int4range check (upper(value) < 10);
1533 select '[4,5)'::restrictedrange @> 7;
1539 select '[4,50)'::restrictedrange @> 7; -- should fail
1540 ERROR: value for domain restrictedrange violates check constraint "restrictedrange_check"
1541 drop domain restrictedrange;
1543 -- Test multiple range types over the same subtype
1545 create type textrange1 as range(subtype=text, collation="C");
1546 create type textrange2 as range(subtype=text, collation="C");
1547 select textrange1('a','Z') @> 'b'::text;
1548 ERROR: range lower bound must be less than or equal to range upper bound
1549 select textrange2('a','z') @> 'b'::text;
1555 drop type textrange1;
1556 drop type textrange2;
1558 -- Test polymorphic type system
1560 create function anyarray_anyrange_func(a anyarray, r anyrange)
1561 returns anyelement as 'select $1[1] + lower($2);' language sql;
1562 select anyarray_anyrange_func(ARRAY[1,2], int4range(10,20));
1563 anyarray_anyrange_func
1564 ------------------------
1569 select anyarray_anyrange_func(ARRAY[1,2], numrange(10,20));
1570 ERROR: function anyarray_anyrange_func(integer[], numrange) does not exist
1571 LINE 1: select anyarray_anyrange_func(ARRAY[1,2], numrange(10,20));
1573 HINT: No function matches the given name and argument types. You might need to add explicit type casts.
1574 drop function anyarray_anyrange_func(anyarray, anyrange);
1576 create function bogus_func(anyelement)
1577 returns anyrange as 'select int4range(1,10)' language sql;
1578 ERROR: cannot determine result data type
1579 DETAIL: A result of type anyrange requires at least one input of type anyrange or anymultirange.
1581 create function bogus_func(int)
1582 returns anyrange as 'select int4range(1,10)' language sql;
1583 ERROR: cannot determine result data type
1584 DETAIL: A result of type anyrange requires at least one input of type anyrange or anymultirange.
1585 create function range_add_bounds(anyrange)
1586 returns anyelement as 'select lower($1) + upper($1)' language sql;
1587 select range_add_bounds(int4range(1, 17));
1593 select range_add_bounds(numrange(1.0001, 123.123));
1599 create function rangetypes_sql(q anyrange, b anyarray, out c anyelement)
1600 as $$ select upper($1) + $2[1] $$
1602 select rangetypes_sql(int4range(1,10), ARRAY[2,20]);
1608 select rangetypes_sql(numrange(1,10), ARRAY[2,20]); -- match failure
1609 ERROR: function rangetypes_sql(numrange, integer[]) does not exist
1610 LINE 1: select rangetypes_sql(numrange(1,10), ARRAY[2,20]);
1612 HINT: No function matches the given name and argument types. You might need to add explicit type casts.
1613 create function anycompatiblearray_anycompatiblerange_func(a anycompatiblearray, r anycompatiblerange)
1614 returns anycompatible as 'select $1[1] + lower($2);' language sql;
1615 select anycompatiblearray_anycompatiblerange_func(ARRAY[1,2], int4range(10,20));
1616 anycompatiblearray_anycompatiblerange_func
1617 --------------------------------------------
1621 select anycompatiblearray_anycompatiblerange_func(ARRAY[1,2], numrange(10,20));
1622 anycompatiblearray_anycompatiblerange_func
1623 --------------------------------------------
1628 select anycompatiblearray_anycompatiblerange_func(ARRAY[1.1,2], int4range(10,20));
1629 ERROR: function anycompatiblearray_anycompatiblerange_func(numeric[], int4range) does not exist
1630 LINE 1: select anycompatiblearray_anycompatiblerange_func(ARRAY[1.1,...
1632 HINT: No function matches the given name and argument types. You might need to add explicit type casts.
1633 drop function anycompatiblearray_anycompatiblerange_func(anycompatiblearray, anycompatiblerange);
1635 create function bogus_func(anycompatible)
1636 returns anycompatiblerange as 'select int4range(1,10)' language sql;
1637 ERROR: cannot determine result data type
1638 DETAIL: A result of type anycompatiblerange requires at least one input of type anycompatiblerange or anycompatiblemultirange.
1642 select ARRAY[numrange(1.1, 1.2), numrange(12.3, 155.5)];
1644 ------------------------------
1645 {"[1.1,1.2)","[12.3,155.5)"}
1648 create table i8r_array (f1 int, f2 int8range[]);
1649 insert into i8r_array values (42, array[int8range(1,10), int8range(2,20)]);
1650 select * from i8r_array;
1652 ----+---------------------
1653 42 | {"[1,10)","[2,20)"}
1656 drop table i8r_array;
1660 create type arrayrange as range (subtype=int4[]);
1661 select arrayrange(ARRAY[1,2], ARRAY[2,1]);
1667 select arrayrange(ARRAY[2,1], ARRAY[1,2]); -- fail
1668 ERROR: range lower bound must be less than or equal to range upper bound
1669 select array[1,1] <@ arrayrange(array[1,2], array[2,1]);
1675 select array[1,3] <@ arrayrange(array[1,2], array[2,1]);
1682 -- Ranges of composites
1684 create type two_ints as (a int, b int);
1685 create type two_ints_range as range (subtype = two_ints);
1686 -- with force_parallel_mode on, this exercises tqueue.c's range remapping
1687 select *, row_to_json(upper(t)) as u from
1688 (values (two_ints_range(row(1,2), row(3,4))),
1689 (two_ints_range(row(5,6), row(7,8)))) v(t);
1691 -------------------+---------------
1692 ["(1,2)","(3,4)") | {"a":3,"b":4}
1693 ["(5,6)","(7,8)") | {"a":7,"b":8}
1696 -- this must be rejected to avoid self-inclusion issues:
1697 alter type two_ints add attribute c two_ints_range;
1698 ERROR: composite type two_ints cannot be made a member of itself
1699 drop type two_ints cascade;
1700 NOTICE: drop cascades to type two_ints_range
1702 -- Check behavior when subtype lacks a hash function
1704 create type cashrange as range (subtype = money);
1705 set enable_sort = off; -- try to make it pick a hash setop implementation
1706 select '(2,5)'::cashrange except select '(5,6)'::cashrange;
1714 -- OUT/INOUT/TABLE functions
1716 -- infer anyrange from anyrange
1717 create function outparam_succeed(i anyrange, out r anyrange, out t text)
1718 as $$ select $1, 'foo'::text $$ language sql;
1719 select * from outparam_succeed(int4range(1,2));
1725 create function outparam2_succeed(r anyrange, out lu anyarray, out ul anyarray)
1726 as $$ select array[lower($1), upper($1)], array[upper($1), lower($1)] $$
1728 select * from outparam2_succeed(int4range(1,11));
1734 -- infer anyarray from anyrange
1735 create function outparam_succeed2(i anyrange, out r anyarray, out t text)
1736 as $$ select ARRAY[upper($1)], 'foo'::text $$ language sql;
1737 select * from outparam_succeed2(int4range(int4range(1,2)));
1743 -- infer anyelement from anyrange
1744 create function inoutparam_succeed(out i anyelement, inout r anyrange)
1745 as $$ select upper($1), $1 $$ language sql;
1746 select * from inoutparam_succeed(int4range(1,2));
1752 create function table_succeed(r anyrange)
1753 returns table(l anyelement, u anyelement)
1754 as $$ select lower($1), upper($1) $$
1756 select * from table_succeed(int4range(1,11));
1763 create function outparam_fail(i anyelement, out r anyrange, out t text)
1764 as $$ select '[1,10]', 'foo' $$ language sql;
1765 ERROR: cannot determine result data type
1766 DETAIL: A result of type anyrange requires at least one input of type anyrange or anymultirange.
1768 create function inoutparam_fail(inout i anyelement, out r anyrange)
1769 as $$ select $1, '[1,10]' $$ language sql;
1770 ERROR: cannot determine result data type
1771 DETAIL: A result of type anyrange requires at least one input of type anyrange or anymultirange.
1773 create function table_fail(i anyelement) returns table(i anyelement, r anyrange)
1774 as $$ select $1, '[1,10]' $$ language sql;
1775 ERROR: cannot determine result data type
1776 DETAIL: A result of type anyrange requires at least one input of type anyrange or anymultirange.