1 -- Tests for range data types.
4 -- (type textrange was already made in test_setup.sql)
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 '(a,)'::textrange;
81 select '[,z]'::textrange;
87 select '[a,]'::textrange;
93 select '(,)'::textrange;
99 select '[ , ]'::textrange;
105 select '["",""]'::textrange;
111 select '[",",","]'::textrange;
117 select '["\\","\\"]'::textrange;
123 select '(\\,a)'::textrange;
129 select '((,z)'::textrange;
135 select '([,z)'::textrange;
141 select '(!,()'::textrange;
147 select '(!,[)'::textrange;
153 select '[a,a]'::textrange;
159 -- these are allowed but normalize to empty:
160 select '[a,a)'::textrange;
166 select '(a,a]'::textrange;
172 select '(a,a)'::textrange;
178 -- Also try it with non-error-throwing API
179 select pg_input_is_valid('(1,4)', 'int4range');
185 select pg_input_is_valid('(1,4', 'int4range');
191 select * from pg_input_error_info('(1,4', 'int4range');
192 message | detail | hint | sql_error_code
193 ---------------------------------+--------------------------+------+----------------
194 malformed range literal: "(1,4" | Unexpected end of input. | | 22P02
197 select pg_input_is_valid('(4,1)', 'int4range');
203 select * from pg_input_error_info('(4,1)', 'int4range');
204 message | detail | hint | sql_error_code
205 -------------------------------------------------------------------+--------+------+----------------
206 range lower bound must be less than or equal to range upper bound | | | 22000
209 select pg_input_is_valid('(4,zed)', 'int4range');
215 select * from pg_input_error_info('(4,zed)', 'int4range');
216 message | detail | hint | sql_error_code
217 ----------------------------------------------+--------+------+----------------
218 invalid input syntax for type integer: "zed" | | | 22P02
221 select pg_input_is_valid('[1,2147483647]', 'int4range');
227 select * from pg_input_error_info('[1,2147483647]', 'int4range');
228 message | detail | hint | sql_error_code
229 ----------------------+--------+------+----------------
230 integer out of range | | | 22003
233 select pg_input_is_valid('[2000-01-01,5874897-12-31]', 'daterange');
239 select * from pg_input_error_info('[2000-01-01,5874897-12-31]', 'daterange');
240 message | detail | hint | sql_error_code
241 -------------------+--------+------+----------------
242 date out of range | | | 22008
246 -- create some test data and test the operators
248 CREATE TABLE numrange_test (nr NUMRANGE);
249 create index numrange_test_btree on numrange_test(nr);
250 INSERT INTO numrange_test VALUES('[,)');
251 INSERT INTO numrange_test VALUES('[3,]');
252 INSERT INTO numrange_test VALUES('[, 5)');
253 INSERT INTO numrange_test VALUES(numrange(1.1, 2.2));
254 INSERT INTO numrange_test VALUES('empty');
255 INSERT INTO numrange_test VALUES(numrange(1.7, 1.7, '[]'));
256 SELECT nr, isempty(nr), lower(nr), upper(nr) FROM numrange_test;
257 nr | isempty | lower | upper
258 -----------+---------+-------+-------
262 [1.1,2.2) | f | 1.1 | 2.2
264 [1.7,1.7] | f | 1.7 | 1.7
267 SELECT nr, lower_inc(nr), lower_inf(nr), upper_inc(nr), upper_inf(nr) FROM numrange_test;
268 nr | lower_inc | lower_inf | upper_inc | upper_inf
269 -----------+-----------+-----------+-----------+-----------
273 [1.1,2.2) | t | f | f | f
274 empty | f | f | f | f
275 [1.7,1.7] | t | f | t | f
278 SELECT * FROM numrange_test WHERE range_contains(nr, numrange(1.9,1.91));
286 SELECT * FROM numrange_test WHERE nr @> numrange(1.0,10000.1);
292 SELECT * FROM numrange_test WHERE range_contained_by(numrange(-1e7,-10000.1), nr);
299 SELECT * FROM numrange_test WHERE 1.9 <@ nr;
307 select * from numrange_test where nr = 'empty';
313 select * from numrange_test where nr = '(1.1, 2.2)';
318 select * from numrange_test where nr = '[1.1, 2.2)';
324 select * from numrange_test where nr < 'empty';
329 select * from numrange_test where nr < numrange(-1000.0, -1000.0,'[]');
337 select * from numrange_test where nr < numrange(0.0, 1.0,'[]');
345 select * from numrange_test where nr < numrange(1000.0, 1001.0,'[]');
356 select * from numrange_test where nr <= 'empty';
362 select * from numrange_test where nr >= 'empty';
373 select * from numrange_test where nr > 'empty';
383 select * from numrange_test where nr > numrange(-1001.0, -1000.0,'[]');
391 select * from numrange_test where nr > numrange(0.0, 1.0,'[]');
399 select * from numrange_test where nr > numrange(1000.0, 1000.0,'[]');
404 select numrange(2.0, 1.0);
405 ERROR: range lower bound must be less than or equal to range upper bound
406 select numrange(2.0, 3.0) -|- numrange(3.0, 4.0);
412 select range_adjacent(numrange(2.0, 3.0), numrange(3.1, 4.0));
418 select range_adjacent(numrange(2.0, 3.0), numrange(3.1, null));
424 select numrange(2.0, 3.0, '[]') -|- numrange(3.0, 4.0, '()');
430 select numrange(1.0, 2.0) -|- numrange(2.0, 3.0,'[]');
436 select range_adjacent(numrange(2.0, 3.0, '(]'), numrange(1.0, 2.0, '(]'));
442 select numrange(1.1, 3.3) <@ numrange(0.1,10.1);
448 select numrange(0.1, 10.1) <@ numrange(1.1,3.3);
454 select numrange(1.1, 2.2) - numrange(2.0, 3.0);
460 select numrange(1.1, 2.2) - numrange(2.2, 3.0);
466 select numrange(1.1, 2.2,'[]') - numrange(2.0, 3.0);
472 select range_minus(numrange(10.1,12.2,'[]'), numrange(110.0,120.2,'(]'));
478 select range_minus(numrange(10.1,12.2,'[]'), numrange(0.0,120.2,'(]'));
484 select numrange(4.5, 5.5, '[]') && numrange(5.5, 6.5);
490 select numrange(1.0, 2.0) << numrange(3.0, 4.0);
496 select numrange(1.0, 3.0,'[]') << numrange(3.0, 4.0,'[]');
502 select numrange(1.0, 3.0,'()') << numrange(3.0, 4.0,'()');
508 select numrange(1.0, 2.0) >> numrange(3.0, 4.0);
514 select numrange(3.0, 70.0) &< numrange(6.6, 100.0);
520 select numrange(1.1, 2.2) < numrange(1.0, 200.2);
526 select numrange(1.1, 2.2) < numrange(1.1, 1.2);
532 select numrange(1.0, 2.0) + numrange(2.0, 3.0);
538 select numrange(1.0, 2.0) + numrange(1.5, 3.0);
544 select numrange(1.0, 2.0) + numrange(2.5, 3.0); -- should fail
545 ERROR: result of range union would not be contiguous
546 select range_merge(numrange(1.0, 2.0), numrange(2.0, 3.0));
552 select range_merge(numrange(1.0, 2.0), numrange(1.5, 3.0));
558 select range_merge(numrange(1.0, 2.0), numrange(2.5, 3.0)); -- shouldn't fail
564 select numrange(1.0, 2.0) * numrange(2.0, 3.0);
570 select numrange(1.0, 2.0) * numrange(1.5, 3.0);
576 select numrange(1.0, 2.0) * numrange(2.5, 3.0);
582 select range_intersect_agg(nr) from numrange_test;
584 ---------------------
588 select range_intersect_agg(nr) from numrange_test where false;
590 ---------------------
594 select range_intersect_agg(nr) from numrange_test where nr @> 4.0;
596 ---------------------
600 analyze numrange_test;
601 create table numrange_test2(nr numrange);
602 create index numrange_test2_hash_idx on numrange_test2 using hash (nr);
603 INSERT INTO numrange_test2 VALUES('[, 5)');
604 INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2));
605 INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2));
606 INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2,'()'));
607 INSERT INTO numrange_test2 VALUES('empty');
608 select * from numrange_test2 where nr = 'empty'::numrange;
614 select * from numrange_test2 where nr = numrange(1.1, 2.2);
621 select * from numrange_test2 where nr = numrange(1.1, 2.3);
626 set enable_nestloop=t;
627 set enable_hashjoin=f;
628 set enable_mergejoin=f;
629 select * from numrange_test natural join numrange_test2 order by nr;
638 set enable_nestloop=f;
639 set enable_hashjoin=t;
640 set enable_mergejoin=f;
641 select * from numrange_test natural join numrange_test2 order by nr;
650 set enable_nestloop=f;
651 set enable_hashjoin=f;
652 set enable_mergejoin=t;
653 select * from numrange_test natural join numrange_test2 order by nr;
662 set enable_nestloop to default;
663 set enable_hashjoin to default;
664 set enable_mergejoin to default;
665 -- keep numrange_test around to help exercise dump/reload
666 DROP TABLE numrange_test2;
668 -- Apply a subset of the above tests on a collatable type, too
670 CREATE TABLE textrange_test (tr textrange);
671 create index textrange_test_btree on textrange_test(tr);
672 INSERT INTO textrange_test VALUES('[,)');
673 INSERT INTO textrange_test VALUES('["a",]');
674 INSERT INTO textrange_test VALUES('[,"q")');
675 INSERT INTO textrange_test VALUES(textrange('b', 'g'));
676 INSERT INTO textrange_test VALUES('empty');
677 INSERT INTO textrange_test VALUES(textrange('d', 'd', '[]'));
678 SELECT tr, isempty(tr), lower(tr), upper(tr) FROM textrange_test;
679 tr | isempty | lower | upper
680 -------+---------+-------+-------
689 SELECT tr, lower_inc(tr), lower_inf(tr), upper_inc(tr), upper_inf(tr) FROM textrange_test;
690 tr | lower_inc | lower_inf | upper_inc | upper_inf
691 -------+-----------+-----------+-----------+-----------
695 [b,g) | t | f | f | f
696 empty | f | f | f | f
697 [d,d] | t | f | t | f
700 SELECT * FROM textrange_test WHERE range_contains(tr, textrange('f', 'fx'));
709 SELECT * FROM textrange_test WHERE tr @> textrange('a', 'z');
716 SELECT * FROM textrange_test WHERE range_contained_by(textrange('0','9'), tr);
723 SELECT * FROM textrange_test WHERE 'e'::text <@ tr;
732 select * from textrange_test where tr = 'empty';
738 select * from textrange_test where tr = '("b","g")';
743 select * from textrange_test where tr = '["b","g")';
749 select * from textrange_test where tr < 'empty';
754 -- test canonical form for int4range
755 select int4range(1, 10, '[]');
761 select int4range(1, 10, '[)');
767 select int4range(1, 10, '(]');
773 select int4range(1, 10, '()');
779 select int4range(1, 2, '()');
785 -- test canonical form for daterange
786 select daterange('2000-01-10'::date, '2000-01-20'::date, '[]');
788 -------------------------
789 [01-10-2000,01-21-2000)
792 select daterange('2000-01-10'::date, '2000-01-20'::date, '[)');
794 -------------------------
795 [01-10-2000,01-20-2000)
798 select daterange('2000-01-10'::date, '2000-01-20'::date, '(]');
800 -------------------------
801 [01-11-2000,01-21-2000)
804 select daterange('2000-01-10'::date, '2000-01-20'::date, '()');
806 -------------------------
807 [01-11-2000,01-20-2000)
810 select daterange('2000-01-10'::date, '2000-01-11'::date, '()');
816 select daterange('2000-01-10'::date, '2000-01-11'::date, '(]');
818 -------------------------
819 [01-11-2000,01-12-2000)
822 select daterange('-infinity'::date, '2000-01-01'::date, '()');
824 ------------------------
825 (-infinity,01-01-2000)
828 select daterange('-infinity'::date, '2000-01-01'::date, '[)');
830 ------------------------
831 [-infinity,01-01-2000)
834 select daterange('2000-01-01'::date, 'infinity'::date, '[)');
836 -----------------------
837 [01-01-2000,infinity)
840 select daterange('2000-01-01'::date, 'infinity'::date, '[]');
842 -----------------------
843 [01-01-2000,infinity]
846 -- test GiST index that's been built incrementally
847 create table test_range_gist(ir int4range);
848 create index test_range_gist_idx on test_range_gist using gist (ir);
849 insert into test_range_gist select int4range(g, g+10) from generate_series(1,2000) g;
850 insert into test_range_gist select 'empty'::int4range from generate_series(1,500) g;
851 insert into test_range_gist select int4range(g, g+10000) from generate_series(1,1000) g;
852 insert into test_range_gist select 'empty'::int4range from generate_series(1,500) g;
853 insert into test_range_gist select int4range(NULL,g*10,'(]') from generate_series(1,100) g;
854 insert into test_range_gist select int4range(g*10,NULL,'(]') from generate_series(1,100) g;
855 insert into test_range_gist select int4range(g, g+10) from generate_series(1,2000) g;
856 -- test statistics and selectivity estimation as well
858 -- We don't check the accuracy of selectivity estimation, but at least check
860 analyze test_range_gist;
861 -- first, verify non-indexed results
862 SET enable_seqscan = t;
863 SET enable_indexscan = f;
864 SET enable_bitmapscan = f;
865 select count(*) from test_range_gist where ir @> 'empty'::int4range;
871 select count(*) from test_range_gist where ir = int4range(10,20);
877 select count(*) from test_range_gist where ir @> 10;
883 select count(*) from test_range_gist where ir @> int4range(10,20);
889 select count(*) from test_range_gist where ir && int4range(10,20);
895 select count(*) from test_range_gist where ir <@ int4range(10,50);
901 select count(*) from test_range_gist where ir << int4range(100,500);
907 select count(*) from test_range_gist where ir >> int4range(100,500);
913 select count(*) from test_range_gist where ir &< int4range(100,500);
919 select count(*) from test_range_gist where ir &> int4range(100,500);
925 select count(*) from test_range_gist where ir -|- int4range(100,500);
931 select count(*) from test_range_gist where ir @> '{}'::int4multirange;
937 select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40));
943 select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange;
949 select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange;
955 select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500));
961 select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500));
967 select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500));
973 select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500));
979 select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500));
985 -- now check same queries using index
986 SET enable_seqscan = f;
987 SET enable_indexscan = t;
988 SET enable_bitmapscan = f;
989 select count(*) from test_range_gist where ir @> 'empty'::int4range;
995 select count(*) from test_range_gist where ir = int4range(10,20);
1001 select count(*) from test_range_gist where ir @> 10;
1007 select count(*) from test_range_gist where ir @> int4range(10,20);
1013 select count(*) from test_range_gist where ir && int4range(10,20);
1019 select count(*) from test_range_gist where ir <@ int4range(10,50);
1025 select count(*) from test_range_gist where ir << int4range(100,500);
1031 select count(*) from test_range_gist where ir >> int4range(100,500);
1037 select count(*) from test_range_gist where ir &< int4range(100,500);
1043 select count(*) from test_range_gist where ir &> int4range(100,500);
1049 select count(*) from test_range_gist where ir -|- int4range(100,500);
1055 select count(*) from test_range_gist where ir @> '{}'::int4multirange;
1061 select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40));
1067 select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange;
1073 select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange;
1079 select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500));
1085 select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500));
1091 select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500));
1097 select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500));
1103 select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500));
1109 -- now check same queries using a bulk-loaded index
1110 drop index test_range_gist_idx;
1111 create index test_range_gist_idx on test_range_gist using gist (ir);
1112 select count(*) from test_range_gist where ir @> 'empty'::int4range;
1118 select count(*) from test_range_gist where ir = int4range(10,20);
1124 select count(*) from test_range_gist where ir @> 10;
1130 select count(*) from test_range_gist where ir @> int4range(10,20);
1136 select count(*) from test_range_gist where ir && int4range(10,20);
1142 select count(*) from test_range_gist where ir <@ int4range(10,50);
1148 select count(*) from test_range_gist where ir << int4range(100,500);
1154 select count(*) from test_range_gist where ir >> int4range(100,500);
1160 select count(*) from test_range_gist where ir &< int4range(100,500);
1166 select count(*) from test_range_gist where ir &> int4range(100,500);
1172 select count(*) from test_range_gist where ir -|- int4range(100,500);
1178 select count(*) from test_range_gist where ir @> '{}'::int4multirange;
1184 select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40));
1190 select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange;
1196 select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange;
1202 select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500));
1208 select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500));
1214 select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500));
1220 select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500));
1226 select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500));
1232 -- test SP-GiST index that's been built incrementally
1233 create table test_range_spgist(ir int4range);
1234 create index test_range_spgist_idx on test_range_spgist using spgist (ir);
1235 insert into test_range_spgist select int4range(g, g+10) from generate_series(1,2000) g;
1236 insert into test_range_spgist select 'empty'::int4range from generate_series(1,500) g;
1237 insert into test_range_spgist select int4range(g, g+10000) from generate_series(1,1000) g;
1238 insert into test_range_spgist select 'empty'::int4range from generate_series(1,500) g;
1239 insert into test_range_spgist select int4range(NULL,g*10,'(]') from generate_series(1,100) g;
1240 insert into test_range_spgist select int4range(g*10,NULL,'(]') from generate_series(1,100) g;
1241 insert into test_range_spgist select int4range(g, g+10) from generate_series(1,2000) g;
1242 -- first, verify non-indexed results
1243 SET enable_seqscan = t;
1244 SET enable_indexscan = f;
1245 SET enable_bitmapscan = f;
1246 select count(*) from test_range_spgist where ir @> 'empty'::int4range;
1252 select count(*) from test_range_spgist where ir = int4range(10,20);
1258 select count(*) from test_range_spgist where ir @> 10;
1264 select count(*) from test_range_spgist where ir @> int4range(10,20);
1270 select count(*) from test_range_spgist where ir && int4range(10,20);
1276 select count(*) from test_range_spgist where ir <@ int4range(10,50);
1282 select count(*) from test_range_spgist where ir << int4range(100,500);
1288 select count(*) from test_range_spgist where ir >> int4range(100,500);
1294 select count(*) from test_range_spgist where ir &< int4range(100,500);
1300 select count(*) from test_range_spgist where ir &> int4range(100,500);
1306 select count(*) from test_range_spgist where ir -|- int4range(100,500);
1312 -- now check same queries using index
1313 SET enable_seqscan = f;
1314 SET enable_indexscan = t;
1315 SET enable_bitmapscan = f;
1316 select count(*) from test_range_spgist where ir @> 'empty'::int4range;
1322 select count(*) from test_range_spgist where ir = int4range(10,20);
1328 select count(*) from test_range_spgist where ir @> 10;
1334 select count(*) from test_range_spgist where ir @> int4range(10,20);
1340 select count(*) from test_range_spgist where ir && int4range(10,20);
1346 select count(*) from test_range_spgist where ir <@ int4range(10,50);
1352 select count(*) from test_range_spgist where ir << int4range(100,500);
1358 select count(*) from test_range_spgist where ir >> int4range(100,500);
1364 select count(*) from test_range_spgist where ir &< int4range(100,500);
1370 select count(*) from test_range_spgist where ir &> int4range(100,500);
1376 select count(*) from test_range_spgist where ir -|- int4range(100,500);
1382 -- now check same queries using a bulk-loaded index
1383 drop index test_range_spgist_idx;
1384 create index test_range_spgist_idx on test_range_spgist using spgist (ir);
1385 select count(*) from test_range_spgist where ir @> 'empty'::int4range;
1391 select count(*) from test_range_spgist where ir = int4range(10,20);
1397 select count(*) from test_range_spgist where ir @> 10;
1403 select count(*) from test_range_spgist where ir @> int4range(10,20);
1409 select count(*) from test_range_spgist where ir && int4range(10,20);
1415 select count(*) from test_range_spgist where ir <@ int4range(10,50);
1421 select count(*) from test_range_spgist where ir << int4range(100,500);
1427 select count(*) from test_range_spgist where ir >> int4range(100,500);
1433 select count(*) from test_range_spgist where ir &< int4range(100,500);
1439 select count(*) from test_range_spgist where ir &> int4range(100,500);
1445 select count(*) from test_range_spgist where ir -|- int4range(100,500);
1451 -- test index-only scans
1453 select ir from test_range_spgist where ir -|- int4range(10,20) order by ir;
1455 ------------------------------------------------------------------------
1458 -> Index Only Scan using test_range_spgist_idx on test_range_spgist
1459 Index Cond: (ir -|- '[10,20)'::int4range)
1462 select ir from test_range_spgist where ir -|- int4range(10,20) order by ir;
1470 RESET enable_seqscan;
1471 RESET enable_indexscan;
1472 RESET enable_bitmapscan;
1473 -- test elem <@ range operator
1474 create table test_range_elem(i int4);
1475 create index test_range_elem_idx on test_range_elem (i);
1476 insert into test_range_elem select i from generate_series(1,100) i;
1477 SET enable_seqscan = f;
1478 select count(*) from test_range_elem where i <@ int4range(10,50);
1484 -- also test spgist index on anyrange expression
1485 create index on test_range_elem using spgist(int4range(i,i+10));
1487 select count(*) from test_range_elem where int4range(i,i+10) <@ int4range(10,30);
1489 -------------------------------------------------------------------------
1491 -> Index Scan using test_range_elem_int4range_idx on test_range_elem
1492 Index Cond: (int4range(i, (i + 10)) <@ '[10,30)'::int4range)
1495 select count(*) from test_range_elem where int4range(i,i+10) <@ int4range(10,30);
1501 RESET enable_seqscan;
1502 drop table test_range_elem;
1504 -- Btree_gist is not included by default, so to test exclusion
1505 -- constraints with range types, use singleton int ranges for the "="
1506 -- portion of the constraint.
1508 create table test_range_excl(
1512 exclude using gist (room with =, during with &&),
1513 exclude using gist (speaker with =, during with &&)
1515 insert into test_range_excl
1516 values(int4range(123, 123, '[]'), int4range(1, 1, '[]'), '[2010-01-02 10:00, 2010-01-02 11:00)');
1517 insert into test_range_excl
1518 values(int4range(123, 123, '[]'), int4range(2, 2, '[]'), '[2010-01-02 11:00, 2010-01-02 12:00)');
1519 insert into test_range_excl
1520 values(int4range(123, 123, '[]'), int4range(3, 3, '[]'), '[2010-01-02 10:10, 2010-01-02 11:00)');
1521 ERROR: conflicting key value violates exclusion constraint "test_range_excl_room_during_excl"
1522 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")).
1523 insert into test_range_excl
1524 values(int4range(124, 124, '[]'), int4range(3, 3, '[]'), '[2010-01-02 10:10, 2010-01-02 11:10)');
1525 insert into test_range_excl
1526 values(int4range(125, 125, '[]'), int4range(1, 1, '[]'), '[2010-01-02 10:10, 2010-01-02 11:00)');
1527 ERROR: conflicting key value violates exclusion constraint "test_range_excl_speaker_during_excl"
1528 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")).
1529 -- test bigint ranges
1530 select int8range(10000000000::int8, 20000000000::int8,'(]');
1532 ---------------------------
1533 [10000000001,20000000001)
1537 set timezone to '-08';
1538 select '[2010-01-01 01:00:00 -05, 2010-01-01 02:00:00 -08)'::tstzrange;
1540 -----------------------------------------------------------------
1541 ["Thu Dec 31 22:00:00 2009 -08","Fri Jan 01 02:00:00 2010 -08")
1545 select '[2010-01-01 01:00:00 -08, 2010-01-01 02:00:00 -05)'::tstzrange;
1546 ERROR: range lower bound must be less than or equal to range upper bound
1547 LINE 1: select '[2010-01-01 01:00:00 -08, 2010-01-01 02:00:00 -05)':...
1549 set timezone to default;
1551 -- Test user-defined range of floats
1552 -- (type float8range was already made in test_setup.sql)
1555 create type bogus_float8range as range (subtype=float8, subtype_diff=float4mi);
1556 ERROR: function float4mi(double precision, double precision) does not exist
1557 select '[123.001, 5.e9)'::float8range @> 888.882::float8;
1563 create table float8range_test(f8r float8range, i int);
1564 insert into float8range_test values(float8range(-100.00007, '1.111113e9'), 42);
1565 select * from float8range_test;
1567 -------------------------+----
1568 [-100.00007,1111113000) | 42
1571 drop table float8range_test;
1573 -- Test range types over domains
1575 create domain mydomain as int4;
1576 create type mydomainrange as range(subtype=mydomain);
1577 select '[4,50)'::mydomainrange @> 7::mydomain;
1583 drop domain mydomain; -- fail
1584 ERROR: cannot drop type mydomain because other objects depend on it
1585 DETAIL: type mydomainrange depends on type mydomain
1586 HINT: Use DROP ... CASCADE to drop the dependent objects too.
1587 drop domain mydomain cascade;
1588 NOTICE: drop cascades to type mydomainrange
1590 -- Test domains over range types
1592 create domain restrictedrange as int4range check (upper(value) < 10);
1593 select '[4,5)'::restrictedrange @> 7;
1599 select '[4,50)'::restrictedrange @> 7; -- should fail
1600 ERROR: value for domain restrictedrange violates check constraint "restrictedrange_check"
1601 drop domain restrictedrange;
1603 -- Test multiple range types over the same subtype
1605 create type textrange1 as range(subtype=text, collation="C");
1606 create type textrange2 as range(subtype=text, collation="C");
1607 select textrange1('a','Z') @> 'b'::text;
1608 ERROR: range lower bound must be less than or equal to range upper bound
1609 select textrange2('a','z') @> 'b'::text;
1615 drop type textrange1;
1616 drop type textrange2;
1618 -- Test polymorphic type system
1620 create function anyarray_anyrange_func(a anyarray, r anyrange)
1621 returns anyelement as 'select $1[1] + lower($2);' language sql;
1622 select anyarray_anyrange_func(ARRAY[1,2], int4range(10,20));
1623 anyarray_anyrange_func
1624 ------------------------
1629 select anyarray_anyrange_func(ARRAY[1,2], numrange(10,20));
1630 ERROR: function anyarray_anyrange_func(integer[], numrange) does not exist
1631 LINE 1: select anyarray_anyrange_func(ARRAY[1,2], numrange(10,20));
1633 HINT: No function matches the given name and argument types. You might need to add explicit type casts.
1634 drop function anyarray_anyrange_func(anyarray, anyrange);
1636 create function bogus_func(anyelement)
1637 returns anyrange as 'select int4range(1,10)' language sql;
1638 ERROR: cannot determine result data type
1639 DETAIL: A result of type anyrange requires at least one input of type anyrange or anymultirange.
1641 create function bogus_func(int)
1642 returns anyrange as 'select int4range(1,10)' language sql;
1643 ERROR: cannot determine result data type
1644 DETAIL: A result of type anyrange requires at least one input of type anyrange or anymultirange.
1645 create function range_add_bounds(anyrange)
1646 returns anyelement as 'select lower($1) + upper($1)' language sql;
1647 select range_add_bounds(int4range(1, 17));
1653 select range_add_bounds(numrange(1.0001, 123.123));
1659 create function rangetypes_sql(q anyrange, b anyarray, out c anyelement)
1660 as $$ select upper($1) + $2[1] $$
1662 select rangetypes_sql(int4range(1,10), ARRAY[2,20]);
1668 select rangetypes_sql(numrange(1,10), ARRAY[2,20]); -- match failure
1669 ERROR: function rangetypes_sql(numrange, integer[]) does not exist
1670 LINE 1: select rangetypes_sql(numrange(1,10), ARRAY[2,20]);
1672 HINT: No function matches the given name and argument types. You might need to add explicit type casts.
1673 create function anycompatiblearray_anycompatiblerange_func(a anycompatiblearray, r anycompatiblerange)
1674 returns anycompatible as 'select $1[1] + lower($2);' language sql;
1675 select anycompatiblearray_anycompatiblerange_func(ARRAY[1,2], int4range(10,20));
1676 anycompatiblearray_anycompatiblerange_func
1677 --------------------------------------------
1681 select anycompatiblearray_anycompatiblerange_func(ARRAY[1,2], numrange(10,20));
1682 anycompatiblearray_anycompatiblerange_func
1683 --------------------------------------------
1688 select anycompatiblearray_anycompatiblerange_func(ARRAY[1.1,2], int4range(10,20));
1689 ERROR: function anycompatiblearray_anycompatiblerange_func(numeric[], int4range) does not exist
1690 LINE 1: select anycompatiblearray_anycompatiblerange_func(ARRAY[1.1,...
1692 HINT: No function matches the given name and argument types. You might need to add explicit type casts.
1693 drop function anycompatiblearray_anycompatiblerange_func(anycompatiblearray, anycompatiblerange);
1695 create function bogus_func(anycompatible)
1696 returns anycompatiblerange as 'select int4range(1,10)' language sql;
1697 ERROR: cannot determine result data type
1698 DETAIL: A result of type anycompatiblerange requires at least one input of type anycompatiblerange or anycompatiblemultirange.
1702 select ARRAY[numrange(1.1, 1.2), numrange(12.3, 155.5)];
1704 ------------------------------
1705 {"[1.1,1.2)","[12.3,155.5)"}
1708 create table i8r_array (f1 int, f2 int8range[]);
1709 insert into i8r_array values (42, array[int8range(1,10), int8range(2,20)]);
1710 select * from i8r_array;
1712 ----+---------------------
1713 42 | {"[1,10)","[2,20)"}
1716 drop table i8r_array;
1720 create type arrayrange as range (subtype=int4[]);
1721 select arrayrange(ARRAY[1,2], ARRAY[2,1]);
1727 select arrayrange(ARRAY[2,1], ARRAY[1,2]); -- fail
1728 ERROR: range lower bound must be less than or equal to range upper bound
1729 select array[1,1] <@ arrayrange(array[1,2], array[2,1]);
1735 select array[1,3] <@ arrayrange(array[1,2], array[2,1]);
1742 -- Ranges of composites
1744 create type two_ints as (a int, b int);
1745 create type two_ints_range as range (subtype = two_ints);
1746 -- with debug_parallel_query on, this exercises tqueue.c's range remapping
1747 select *, row_to_json(upper(t)) as u from
1748 (values (two_ints_range(row(1,2), row(3,4))),
1749 (two_ints_range(row(5,6), row(7,8)))) v(t);
1751 -------------------+---------------
1752 ["(1,2)","(3,4)") | {"a":3,"b":4}
1753 ["(5,6)","(7,8)") | {"a":7,"b":8}
1756 -- this must be rejected to avoid self-inclusion issues:
1757 alter type two_ints add attribute c two_ints_range;
1758 ERROR: composite type two_ints cannot be made a member of itself
1759 drop type two_ints cascade;
1760 NOTICE: drop cascades to type two_ints_range
1762 -- Check behavior when subtype lacks a hash function
1764 create type varbitrange as range (subtype = varbit);
1765 set enable_sort = off; -- try to make it pick a hash setop implementation
1766 select '(01,10)'::varbitrange except select '(10,11)'::varbitrange;
1774 -- OUT/INOUT/TABLE functions
1776 -- infer anyrange from anyrange
1777 create function outparam_succeed(i anyrange, out r anyrange, out t text)
1778 as $$ select $1, 'foo'::text $$ language sql;
1779 select * from outparam_succeed(int4range(1,2));
1785 create function outparam2_succeed(r anyrange, out lu anyarray, out ul anyarray)
1786 as $$ select array[lower($1), upper($1)], array[upper($1), lower($1)] $$
1788 select * from outparam2_succeed(int4range(1,11));
1794 -- infer anyarray from anyrange
1795 create function outparam_succeed2(i anyrange, out r anyarray, out t text)
1796 as $$ select ARRAY[upper($1)], 'foo'::text $$ language sql;
1797 select * from outparam_succeed2(int4range(int4range(1,2)));
1803 -- infer anyelement from anyrange
1804 create function inoutparam_succeed(out i anyelement, inout r anyrange)
1805 as $$ select upper($1), $1 $$ language sql;
1806 select * from inoutparam_succeed(int4range(1,2));
1812 create function table_succeed(r anyrange)
1813 returns table(l anyelement, u anyelement)
1814 as $$ select lower($1), upper($1) $$
1816 select * from table_succeed(int4range(1,11));
1823 create function outparam_fail(i anyelement, out r anyrange, out t text)
1824 as $$ select '[1,10]', 'foo' $$ language sql;
1825 ERROR: cannot determine result data type
1826 DETAIL: A result of type anyrange requires at least one input of type anyrange or anymultirange.
1828 create function inoutparam_fail(inout i anyelement, out r anyrange)
1829 as $$ select $1, '[1,10]' $$ language sql;
1830 ERROR: cannot determine result data type
1831 DETAIL: A result of type anyrange requires at least one input of type anyrange or anymultirange.
1833 create function table_fail(i anyelement) returns table(i anyelement, r anyrange)
1834 as $$ select $1, '[1,10]' $$ language sql;
1835 ERROR: cannot determine result data type
1836 DETAIL: A result of type anyrange requires at least one input of type anyrange or anymultirange.
1838 -- Test support functions
1841 explain (verbose, costs off)
1842 select current_date <@ daterange 'empty';
1850 explain (verbose, costs off)
1851 select current_date <@ daterange(NULL, NULL);
1858 -- only lower bound present
1859 explain (verbose, costs off)
1860 select current_date <@ daterange('2000-01-01', NULL, '[)');
1862 ------------------------------------------------
1864 Output: (CURRENT_DATE >= '01-01-2000'::date)
1867 -- only upper bound present
1868 explain (verbose, costs off)
1869 select current_date <@ daterange(NULL, '2000-01-01', '(]');
1871 -----------------------------------------------
1873 Output: (CURRENT_DATE < '01-02-2000'::date)
1876 -- lower range "-Infinity" excluded
1877 explain (verbose, costs off)
1878 select current_date <@ daterange('-Infinity', '1997-04-10'::date, '()');
1880 ----------------------------------------------------------------------------------------
1882 Output: ((CURRENT_DATE > '-infinity'::date) AND (CURRENT_DATE < '04-10-1997'::date))
1885 -- lower range "-Infinity" included
1886 explain (verbose, costs off)
1887 select current_date <@ daterange('-Infinity', '1997-04-10'::date, '[)');
1889 -----------------------------------------------------------------------------------------
1891 Output: ((CURRENT_DATE >= '-infinity'::date) AND (CURRENT_DATE < '04-10-1997'::date))
1894 -- upper range "Infinity" excluded
1895 explain (verbose, costs off)
1896 select current_date <@ daterange('2002-09-25'::date, 'Infinity', '[)');
1898 ----------------------------------------------------------------------------------------
1900 Output: ((CURRENT_DATE >= '09-25-2002'::date) AND (CURRENT_DATE < 'infinity'::date))
1903 -- upper range "Infinity" included
1904 explain (verbose, costs off)
1905 select current_date <@ daterange('2002-09-25'::date, 'Infinity', '[]');
1907 -----------------------------------------------------------------------------------------
1909 Output: ((CURRENT_DATE >= '09-25-2002'::date) AND (CURRENT_DATE <= 'infinity'::date))
1912 -- should also work if we use "@>"
1913 explain (verbose, costs off)
1914 select daterange('-Infinity', '1997-04-10'::date, '()') @> current_date;
1916 ----------------------------------------------------------------------------------------
1918 Output: ((CURRENT_DATE > '-infinity'::date) AND (CURRENT_DATE < '04-10-1997'::date))
1921 explain (verbose, costs off)
1922 select daterange('2002-09-25'::date, 'Infinity', '[]') @> current_date;
1924 -----------------------------------------------------------------------------------------
1926 Output: ((CURRENT_DATE >= '09-25-2002'::date) AND (CURRENT_DATE <= 'infinity'::date))
1929 -- Check that volatile cases are not optimized
1930 explain (verbose, costs off)
1931 select now() <@ tstzrange('2024-01-20 00:00', '2024-01-21 00:00');
1933 --------------------------------------------------------------------------------------------------------------------------------------------------------
1935 Output: ((now() >= 'Sat Jan 20 00:00:00 2024 PST'::timestamp with time zone) AND (now() < 'Sun Jan 21 00:00:00 2024 PST'::timestamp with time zone))
1938 explain (verbose, costs off) -- unsafe!
1939 select clock_timestamp() <@ tstzrange('2024-01-20 00:00', '2024-01-21 00:00');
1941 ---------------------------------------------------------------------------------------------------------------
1943 Output: (clock_timestamp() <@ '["Sat Jan 20 00:00:00 2024 PST","Sun Jan 21 00:00:00 2024 PST")'::tstzrange)
1946 explain (verbose, costs off)
1947 select clock_timestamp() <@ tstzrange('2024-01-20 00:00', NULL);
1949 -------------------------------------------------------------------------------------------
1951 Output: (clock_timestamp() >= 'Sat Jan 20 00:00:00 2024 PST'::timestamp with time zone)
1954 -- test a custom range type with a non-default operator class
1955 create type textrange_supp as range (
1957 subtype_opclass = text_pattern_ops
1959 create temp table text_support_test (t text collate "C");
1960 insert into text_support_test values ('a'), ('c'), ('d'), ('ch');
1962 select * from text_support_test where t <@ textrange_supp('a', 'd');
1964 ------------------------------------------------------
1965 Seq Scan on text_support_test
1966 Filter: ((t ~>=~ 'a'::text) AND (t ~<~ 'd'::text))
1969 select * from text_support_test where t <@ textrange_supp('a', 'd');
1977 drop table text_support_test;
1978 drop type textrange_supp;