1-- Tests for multirange data types. 2 3-- 4-- test input parser 5-- 6 7-- negative tests; should fail 8select ''::textmultirange; 9select '{,}'::textmultirange; 10select '{(,)}.'::textmultirange; 11select '{[a,c),}'::textmultirange; 12select '{,[a,c)}'::textmultirange; 13select '{-[a,z)}'::textmultirange; 14select '{[a,z) - }'::textmultirange; 15select '{(",a)}'::textmultirange; 16select '{(,,a)}'::textmultirange; 17select '{(),a)}'::textmultirange; 18select '{(a,))}'::textmultirange; 19select '{(],a)}'::textmultirange; 20select '{(a,])}'::textmultirange; 21select '{[z,a]}'::textmultirange; 22 23-- should succeed 24select '{}'::textmultirange; 25select ' {} '::textmultirange; 26select ' { empty, empty } '::textmultirange; 27select ' {( " a " " a ", " z " " z " ) }'::textmultirange; 28select '{(,z)}'::textmultirange; 29select '{(a,)}'::textmultirange; 30select '{[,z]}'::textmultirange; 31select '{[a,]}'::textmultirange; 32select '{(,)}'::textmultirange; 33select '{[ , ]}'::textmultirange; 34select '{["",""]}'::textmultirange; 35select '{[",",","]}'::textmultirange; 36select '{["\\","\\"]}'::textmultirange; 37select '{["""","\""]}'::textmultirange; 38select '{(\\,a)}'::textmultirange; 39select '{((,z)}'::textmultirange; 40select '{([,z)}'::textmultirange; 41select '{(!,()}'::textmultirange; 42select '{(!,[)}'::textmultirange; 43select '{[a,a]}'::textmultirange; 44select '{[a,a],[a,b]}'::textmultirange; 45select '{[a,b), [b,e]}'::textmultirange; 46select '{[a,d), [b,f]}'::textmultirange; 47select '{[a,a],[b,b]}'::textmultirange; 48-- without canonicalization, we can't join these: 49select '{[a,a], [b,b]}'::textmultirange; 50-- with canonicalization, we can join these: 51select '{[1,2], [3,4]}'::int4multirange; 52select '{[a,a], [b,b], [c,c]}'::textmultirange; 53select '{[a,d], [b,e]}'::textmultirange; 54select '{[a,d), [d,e)}'::textmultirange; 55-- these are allowed but normalize to empty: 56select '{[a,a)}'::textmultirange; 57select '{(a,a]}'::textmultirange; 58select '{(a,a)}'::textmultirange; 59 60-- 61-- test the constructor 62--- 63select textmultirange(); 64select textmultirange(textrange('a', 'c')); 65select textmultirange(textrange('a', 'c'), textrange('f', 'g')); 66select textmultirange(textrange('a', 'c'), textrange('b', 'd')); 67 68-- 69-- test casts, both a built-in range type and a user-defined one: 70-- 71select 'empty'::int4range::int4multirange; 72select int4range(1, 3)::int4multirange; 73select int4range(1, null)::int4multirange; 74select int4range(null, null)::int4multirange; 75select 'empty'::textrange::textmultirange; 76select textrange('a', 'c')::textmultirange; 77select textrange('a', null)::textmultirange; 78select textrange(null, null)::textmultirange; 79 80-- 81-- test unnest(multirange) function 82-- 83select unnest(int4multirange(int4range('5', '6'), int4range('1', '2'))); 84select unnest(textmultirange(textrange('a', 'b'), textrange('d', 'e'))); 85 86-- 87-- create some test data and test the operators 88-- 89 90CREATE TABLE nummultirange_test (nmr NUMMULTIRANGE); 91CREATE INDEX nummultirange_test_btree ON nummultirange_test(nmr); 92 93INSERT INTO nummultirange_test VALUES('{}'); 94INSERT INTO nummultirange_test VALUES('{[,)}'); 95INSERT INTO nummultirange_test VALUES('{[3,]}'); 96INSERT INTO nummultirange_test VALUES('{[,), [3,]}'); 97INSERT INTO nummultirange_test VALUES('{[, 5)}'); 98INSERT INTO nummultirange_test VALUES(nummultirange()); 99INSERT INTO nummultirange_test VALUES(nummultirange(variadic '{}'::numrange[])); 100INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.1, 2.2))); 101INSERT INTO nummultirange_test VALUES('{empty}'); 102INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.7, 1.7, '[]'), numrange(1.7, 1.9))); 103INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.7, 1.7, '[]'), numrange(1.9, 2.1))); 104 105SELECT nmr, isempty(nmr), lower(nmr), upper(nmr) FROM nummultirange_test ORDER BY nmr; 106SELECT nmr, lower_inc(nmr), lower_inf(nmr), upper_inc(nmr), upper_inf(nmr) FROM nummultirange_test ORDER BY nmr; 107 108SELECT * FROM nummultirange_test WHERE nmr = '{}'; 109SELECT * FROM nummultirange_test WHERE nmr = '{(,5)}'; 110SELECT * FROM nummultirange_test WHERE nmr = '{[3,)}'; 111SELECT * FROM nummultirange_test WHERE nmr = '{[1.7,1.7]}'; 112SELECT * FROM nummultirange_test WHERE nmr = '{[1.7,1.7],[1.9,2.1)}'; 113SELECT * FROM nummultirange_test WHERE nmr < '{}'; 114SELECT * FROM nummultirange_test WHERE nmr < '{[-1000.0, -1000.0]}'; 115SELECT * FROM nummultirange_test WHERE nmr < '{[0.0, 1.0]}'; 116SELECT * FROM nummultirange_test WHERE nmr < '{[1000.0, 1001.0]}'; 117SELECT * FROM nummultirange_test WHERE nmr <= '{}'; 118SELECT * FROM nummultirange_test WHERE nmr <= '{[3,)}'; 119SELECT * FROM nummultirange_test WHERE nmr >= '{}'; 120SELECT * FROM nummultirange_test WHERE nmr >= '{[3,)}'; 121SELECT * FROM nummultirange_test WHERE nmr > '{}'; 122SELECT * FROM nummultirange_test WHERE nmr > '{[-1000.0, -1000.0]}'; 123SELECT * FROM nummultirange_test WHERE nmr > '{[0.0, 1.0]}'; 124SELECT * FROM nummultirange_test WHERE nmr > '{[1000.0, 1001.0]}'; 125SELECT * FROM nummultirange_test WHERE nmr <> '{}'; 126SELECT * FROM nummultirange_test WHERE nmr <> '{(,5)}'; 127 128select nummultirange(numrange(2.0, 1.0)); 129select nummultirange(numrange(5.0, 6.0), numrange(1.0, 2.0)); 130 131analyze nummultirange_test; 132 133-- overlaps 134SELECT * FROM nummultirange_test WHERE range_overlaps_multirange(numrange(4.0, 4.2), nmr); 135SELECT * FROM nummultirange_test WHERE numrange(4.0, 4.2) && nmr; 136SELECT * FROM nummultirange_test WHERE multirange_overlaps_range(nmr, numrange(4.0, 4.2)); 137SELECT * FROM nummultirange_test WHERE nmr && numrange(4.0, 4.2); 138SELECT * FROM nummultirange_test WHERE multirange_overlaps_multirange(nmr, nummultirange(numrange(4.0, 4.2), numrange(6.0, 7.0))); 139SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(4.0, 4.2), numrange(6.0, 7.0)); 140SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(6.0, 7.0)); 141SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(6.0, 7.0), numrange(8.0, 9.0)); 142 143-- mr contains x 144SELECT * FROM nummultirange_test WHERE multirange_contains_elem(nmr, 4.0); 145SELECT * FROM nummultirange_test WHERE nmr @> 4.0; 146SELECT * FROM nummultirange_test WHERE multirange_contains_range(nmr, numrange(4.0, 4.2)); 147SELECT * FROM nummultirange_test WHERE nmr @> numrange(4.0, 4.2); 148SELECT * FROM nummultirange_test WHERE multirange_contains_multirange(nmr, '{[4.0,4.2), [6.0, 8.0)}'); 149SELECT * FROM nummultirange_test WHERE nmr @> '{[4.0,4.2), [6.0, 8.0)}'::nummultirange; 150 151-- x is contained by mr 152SELECT * FROM nummultirange_test WHERE elem_contained_by_multirange(4.0, nmr); 153SELECT * FROM nummultirange_test WHERE 4.0 <@ nmr; 154SELECT * FROM nummultirange_test WHERE range_contained_by_multirange(numrange(4.0, 4.2), nmr); 155SELECT * FROM nummultirange_test WHERE numrange(4.0, 4.2) <@ nmr; 156SELECT * FROM nummultirange_test WHERE multirange_contained_by_multirange('{[4.0,4.2), [6.0, 8.0)}', nmr); 157SELECT * FROM nummultirange_test WHERE '{[4.0,4.2), [6.0, 8.0)}'::nummultirange <@ nmr; 158 159-- overlaps 160SELECT 'empty'::numrange && nummultirange(); 161SELECT 'empty'::numrange && nummultirange(numrange(1,2)); 162SELECT nummultirange() && 'empty'::numrange; 163SELECT nummultirange(numrange(1,2)) && 'empty'::numrange; 164SELECT nummultirange() && nummultirange(); 165SELECT nummultirange() && nummultirange(numrange(1,2)); 166SELECT nummultirange(numrange(1,2)) && nummultirange(); 167SELECT nummultirange(numrange(3,4)) && nummultirange(numrange(1,2), numrange(7,8)); 168SELECT nummultirange(numrange(1,2), numrange(7,8)) && nummultirange(numrange(3,4)); 169SELECT nummultirange(numrange(3,4)) && nummultirange(numrange(1,2), numrange(3.5,8)); 170SELECT nummultirange(numrange(1,2), numrange(3.5,8)) && numrange(3,4); 171SELECT nummultirange(numrange(1,2), numrange(3.5,8)) && nummultirange(numrange(3,4)); 172select '{(10,20),(30,40),(50,60)}'::nummultirange && '(42,92)'::numrange; 173 174-- contains 175SELECT nummultirange() @> nummultirange(); 176SELECT nummultirange() @> 'empty'::numrange; 177SELECT nummultirange(numrange(null,null)) @> numrange(1,2); 178SELECT nummultirange(numrange(null,null)) @> numrange(null,2); 179SELECT nummultirange(numrange(null,null)) @> numrange(2,null); 180SELECT nummultirange(numrange(null,5)) @> numrange(null,3); 181SELECT nummultirange(numrange(null,5)) @> numrange(null,8); 182SELECT nummultirange(numrange(5,null)) @> numrange(8,null); 183SELECT nummultirange(numrange(5,null)) @> numrange(3,null); 184SELECT nummultirange(numrange(1,5)) @> numrange(8,9); 185SELECT nummultirange(numrange(1,5)) @> numrange(3,9); 186SELECT nummultirange(numrange(1,5)) @> numrange(1,4); 187SELECT nummultirange(numrange(1,5)) @> numrange(1,5); 188SELECT nummultirange(numrange(-4,-2), numrange(1,5)) @> numrange(1,5); 189SELECT nummultirange(numrange(1,5), numrange(8,9)) @> numrange(1,5); 190SELECT nummultirange(numrange(1,5), numrange(8,9)) @> numrange(6,7); 191SELECT nummultirange(numrange(1,5), numrange(6,9)) @> numrange(6,7); 192SELECT '{[1,5)}'::nummultirange @> '{[1,5)}'; 193SELECT '{[-4,-2), [1,5)}'::nummultirange @> '{[1,5)}'; 194SELECT '{[1,5), [8,9)}'::nummultirange @> '{[1,5)}'; 195SELECT '{[1,5), [8,9)}'::nummultirange @> '{[6,7)}'; 196SELECT '{[1,5), [6,9)}'::nummultirange @> '{[6,7)}'; 197select '{(10,20),(30,40),(50,60)}'::nummultirange @> '(52,56)'::numrange; 198SELECT numrange(null,null) @> nummultirange(numrange(1,2)); 199SELECT numrange(null,null) @> nummultirange(numrange(null,2)); 200SELECT numrange(null,null) @> nummultirange(numrange(2,null)); 201SELECT numrange(null,5) @> nummultirange(numrange(null,3)); 202SELECT numrange(null,5) @> nummultirange(numrange(null,8)); 203SELECT numrange(5,null) @> nummultirange(numrange(8,null)); 204SELECT numrange(5,null) @> nummultirange(numrange(3,null)); 205SELECT numrange(1,5) @> nummultirange(numrange(8,9)); 206SELECT numrange(1,5) @> nummultirange(numrange(3,9)); 207SELECT numrange(1,5) @> nummultirange(numrange(1,4)); 208SELECT numrange(1,5) @> nummultirange(numrange(1,5)); 209SELECT numrange(1,9) @> nummultirange(numrange(-4,-2), numrange(1,5)); 210SELECT numrange(1,9) @> nummultirange(numrange(1,5), numrange(8,9)); 211SELECT numrange(1,9) @> nummultirange(numrange(1,5), numrange(6,9)); 212SELECT numrange(1,9) @> nummultirange(numrange(1,5), numrange(6,10)); 213SELECT '{[1,9)}' @> '{[1,5)}'::nummultirange; 214SELECT '{[1,9)}' @> '{[-4,-2), [1,5)}'::nummultirange; 215SELECT '{[1,9)}' @> '{[1,5), [8,9)}'::nummultirange; 216SELECT '{[1,9)}' @> '{[1,5), [6,9)}'::nummultirange; 217SELECT '{[1,9)}' @> '{[1,5), [6,10)}'::nummultirange; 218 219-- is contained by 220SELECT nummultirange() <@ nummultirange(); 221SELECT 'empty'::numrange <@ nummultirange(); 222SELECT numrange(1,2) <@ nummultirange(numrange(null,null)); 223SELECT numrange(null,2) <@ nummultirange(numrange(null,null)); 224SELECT numrange(2,null) <@ nummultirange(numrange(null,null)); 225SELECT numrange(null,3) <@ nummultirange(numrange(null,5)); 226SELECT numrange(null,8) <@ nummultirange(numrange(null,5)); 227SELECT numrange(8,null) <@ nummultirange(numrange(5,null)); 228SELECT numrange(3,null) <@ nummultirange(numrange(5,null)); 229SELECT numrange(8,9) <@ nummultirange(numrange(1,5)); 230SELECT numrange(3,9) <@ nummultirange(numrange(1,5)); 231SELECT numrange(1,4) <@ nummultirange(numrange(1,5)); 232SELECT numrange(1,5) <@ nummultirange(numrange(1,5)); 233SELECT numrange(1,5) <@ nummultirange(numrange(-4,-2), numrange(1,5)); 234SELECT numrange(1,5) <@ nummultirange(numrange(1,5), numrange(8,9)); 235SELECT numrange(6,7) <@ nummultirange(numrange(1,5), numrange(8,9)); 236SELECT numrange(6,7) <@ nummultirange(numrange(1,5), numrange(6,9)); 237SELECT '{[1,5)}' <@ '{[1,5)}'::nummultirange; 238SELECT '{[1,5)}' <@ '{[-4,-2), [1,5)}'::nummultirange; 239SELECT '{[1,5)}' <@ '{[1,5), [8,9)}'::nummultirange; 240SELECT '{[6,7)}' <@ '{[1,5), [8,9)}'::nummultirange; 241SELECT '{[6,7)}' <@ '{[1,5), [6,9)}'::nummultirange; 242SELECT nummultirange(numrange(1,2)) <@ numrange(null,null); 243SELECT nummultirange(numrange(null,2)) <@ numrange(null,null); 244SELECT nummultirange(numrange(2,null)) <@ numrange(null,null); 245SELECT nummultirange(numrange(null,3)) <@ numrange(null,5); 246SELECT nummultirange(numrange(null,8)) <@ numrange(null,5); 247SELECT nummultirange(numrange(8,null)) <@ numrange(5,null); 248SELECT nummultirange(numrange(3,null)) <@ numrange(5,null); 249SELECT nummultirange(numrange(8,9)) <@ numrange(1,5); 250SELECT nummultirange(numrange(3,9)) <@ numrange(1,5); 251SELECT nummultirange(numrange(1,4)) <@ numrange(1,5); 252SELECT nummultirange(numrange(1,5)) <@ numrange(1,5); 253SELECT nummultirange(numrange(-4,-2), numrange(1,5)) <@ numrange(1,9); 254SELECT nummultirange(numrange(1,5), numrange(8,9)) <@ numrange(1,9); 255SELECT nummultirange(numrange(1,5), numrange(6,9)) <@ numrange(1,9); 256SELECT nummultirange(numrange(1,5), numrange(6,10)) <@ numrange(1,9); 257SELECT '{[1,5)}'::nummultirange <@ '{[1,9)}'; 258SELECT '{[-4,-2), [1,5)}'::nummultirange <@ '{[1,9)}'; 259SELECT '{[1,5), [8,9)}'::nummultirange <@ '{[1,9)}'; 260SELECT '{[1,5), [6,9)}'::nummultirange <@ '{[1,9)}'; 261SELECT '{[1,5), [6,10)}'::nummultirange <@ '{[1,9)}'; 262 263-- overleft 264SELECT 'empty'::numrange &< nummultirange(); 265SELECT 'empty'::numrange &< nummultirange(numrange(1,2)); 266SELECT nummultirange() &< 'empty'::numrange; 267SELECT nummultirange(numrange(1,2)) &< 'empty'::numrange; 268SELECT nummultirange() &< nummultirange(); 269SELECT nummultirange(numrange(1,2)) &< nummultirange(); 270SELECT nummultirange() &< nummultirange(numrange(1,2)); 271SELECT numrange(6,7) &< nummultirange(numrange(3,4)); 272SELECT numrange(1,2) &< nummultirange(numrange(3,4)); 273SELECT numrange(1,4) &< nummultirange(numrange(3,4)); 274SELECT numrange(1,6) &< nummultirange(numrange(3,4)); 275SELECT numrange(3.5,6) &< nummultirange(numrange(3,4)); 276SELECT nummultirange(numrange(6,7)) &< numrange(3,4); 277SELECT nummultirange(numrange(1,2)) &< numrange(3,4); 278SELECT nummultirange(numrange(1,4)) &< numrange(3,4); 279SELECT nummultirange(numrange(1,6)) &< numrange(3,4); 280SELECT nummultirange(numrange(3.5,6)) &< numrange(3,4); 281SELECT nummultirange(numrange(6,7)) &< nummultirange(numrange(3,4)); 282SELECT nummultirange(numrange(1,2)) &< nummultirange(numrange(3,4)); 283SELECT nummultirange(numrange(1,4)) &< nummultirange(numrange(3,4)); 284SELECT nummultirange(numrange(1,6)) &< nummultirange(numrange(3,4)); 285SELECT nummultirange(numrange(3.5,6)) &< nummultirange(numrange(3,4)); 286 287-- overright 288SELECT nummultirange() &> 'empty'::numrange; 289SELECT nummultirange(numrange(1,2)) &> 'empty'::numrange; 290SELECT 'empty'::numrange &> nummultirange(); 291SELECT 'empty'::numrange &> nummultirange(numrange(1,2)); 292SELECT nummultirange() &> nummultirange(); 293SELECT nummultirange() &> nummultirange(numrange(1,2)); 294SELECT nummultirange(numrange(1,2)) &> nummultirange(); 295SELECT nummultirange(numrange(3,4)) &> numrange(6,7); 296SELECT nummultirange(numrange(3,4)) &> numrange(1,2); 297SELECT nummultirange(numrange(3,4)) &> numrange(1,4); 298SELECT nummultirange(numrange(3,4)) &> numrange(1,6); 299SELECT nummultirange(numrange(3,4)) &> numrange(3.5,6); 300SELECT numrange(3,4) &> nummultirange(numrange(6,7)); 301SELECT numrange(3,4) &> nummultirange(numrange(1,2)); 302SELECT numrange(3,4) &> nummultirange(numrange(1,4)); 303SELECT numrange(3,4) &> nummultirange(numrange(1,6)); 304SELECT numrange(3,4) &> nummultirange(numrange(3.5,6)); 305SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(6,7)); 306SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(1,2)); 307SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(1,4)); 308SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(1,6)); 309SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(3.5,6)); 310 311-- meets 312SELECT 'empty'::numrange -|- nummultirange(); 313SELECT 'empty'::numrange -|- nummultirange(numrange(1,2)); 314SELECT nummultirange() -|- 'empty'::numrange; 315SELECT nummultirange(numrange(1,2)) -|- 'empty'::numrange; 316SELECT nummultirange() -|- nummultirange(); 317SELECT nummultirange(numrange(1,2)) -|- nummultirange(); 318SELECT nummultirange() -|- nummultirange(numrange(1,2)); 319SELECT numrange(1,2) -|- nummultirange(numrange(2,4)); 320SELECT numrange(1,2) -|- nummultirange(numrange(3,4)); 321SELECT nummultirange(numrange(1,2)) -|- numrange(2,4); 322SELECT nummultirange(numrange(1,2)) -|- numrange(3,4); 323SELECT nummultirange(numrange(1,2)) -|- nummultirange(numrange(2,4)); 324SELECT nummultirange(numrange(1,2)) -|- nummultirange(numrange(3,4)); 325SELECT nummultirange(numrange(1,2), numrange(5,6)) -|- nummultirange(numrange(3,4)); 326SELECT nummultirange(numrange(1,2), numrange(5,6)) -|- nummultirange(numrange(6,7)); 327SELECT nummultirange(numrange(1,2), numrange(5,6)) -|- nummultirange(numrange(8,9)); 328SELECT nummultirange(numrange(1,2)) -|- nummultirange(numrange(2,4), numrange(6,7)); 329 330-- strictly left 331select 'empty'::numrange << nummultirange(); 332select numrange(1,2) << nummultirange(); 333select numrange(1,2) << nummultirange(numrange(3,4)); 334select numrange(1,2) << nummultirange(numrange(0,4)); 335select numrange(1,2) << nummultirange(numrange(0,4), numrange(7,8)); 336select nummultirange() << 'empty'::numrange; 337select nummultirange() << numrange(1,2); 338select nummultirange(numrange(3,4)) << numrange(3,6); 339select nummultirange(numrange(0,2)) << numrange(3,6); 340select nummultirange(numrange(0,2), numrange(7,8)) << numrange(3,6); 341select nummultirange(numrange(-4,-2), numrange(0,2)) << numrange(3,6); 342select nummultirange() << nummultirange(); 343select nummultirange() << nummultirange(numrange(1,2)); 344select nummultirange(numrange(1,2)) << nummultirange(); 345select nummultirange(numrange(1,2)) << nummultirange(numrange(1,2)); 346select nummultirange(numrange(1,2)) << nummultirange(numrange(3,4)); 347select nummultirange(numrange(1,2)) << nummultirange(numrange(3,4), numrange(7,8)); 348select nummultirange(numrange(1,2), numrange(4,5)) << nummultirange(numrange(3,4), numrange(7,8)); 349 350-- strictly right 351select nummultirange() >> 'empty'::numrange; 352select nummultirange() >> numrange(1,2); 353select nummultirange(numrange(3,4)) >> numrange(1,2); 354select nummultirange(numrange(0,4)) >> numrange(1,2); 355select nummultirange(numrange(0,4), numrange(7,8)) >> numrange(1,2); 356select 'empty'::numrange >> nummultirange(); 357select numrange(1,2) >> nummultirange(); 358select numrange(3,6) >> nummultirange(numrange(3,4)); 359select numrange(3,6) >> nummultirange(numrange(0,2)); 360select numrange(3,6) >> nummultirange(numrange(0,2), numrange(7,8)); 361select numrange(3,6) >> nummultirange(numrange(-4,-2), numrange(0,2)); 362select nummultirange() >> nummultirange(); 363select nummultirange(numrange(1,2)) >> nummultirange(); 364select nummultirange() >> nummultirange(numrange(1,2)); 365select nummultirange(numrange(1,2)) >> nummultirange(numrange(1,2)); 366select nummultirange(numrange(3,4)) >> nummultirange(numrange(1,2)); 367select nummultirange(numrange(3,4), numrange(7,8)) >> nummultirange(numrange(1,2)); 368select nummultirange(numrange(3,4), numrange(7,8)) >> nummultirange(numrange(1,2), numrange(4,5)); 369 370-- union 371SELECT nummultirange() + nummultirange(); 372SELECT nummultirange() + nummultirange(numrange(1,2)); 373SELECT nummultirange(numrange(1,2)) + nummultirange(); 374SELECT nummultirange(numrange(1,2)) + nummultirange(numrange(1,2)); 375SELECT nummultirange(numrange(1,2)) + nummultirange(numrange(2,4)); 376SELECT nummultirange(numrange(1,2)) + nummultirange(numrange(3,4)); 377SELECT nummultirange(numrange(1,2), numrange(4,5)) + nummultirange(numrange(2,4)); 378SELECT nummultirange(numrange(1,2), numrange(4,5)) + nummultirange(numrange(3,4)); 379SELECT nummultirange(numrange(1,2), numrange(4,5)) + nummultirange(numrange(0,9)); 380 381-- merge 382SELECT range_merge(nummultirange()); 383SELECT range_merge(nummultirange(numrange(1,2))); 384SELECT range_merge(nummultirange(numrange(1,2), numrange(7,8))); 385 386-- minus 387SELECT nummultirange() - nummultirange(); 388SELECT nummultirange() - nummultirange(numrange(1,2)); 389SELECT nummultirange(numrange(1,2)) - nummultirange(); 390SELECT nummultirange(numrange(1,2), numrange(3,4)) - nummultirange(); 391SELECT nummultirange(numrange(1,2)) - nummultirange(numrange(1,2)); 392SELECT nummultirange(numrange(1,2)) - nummultirange(numrange(2,4)); 393SELECT nummultirange(numrange(1,2)) - nummultirange(numrange(3,4)); 394SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(1,2)); 395SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(2,3)); 396SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(0,8)); 397SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(0,2)); 398SELECT nummultirange(numrange(1,8)) - nummultirange(numrange(0,2), numrange(3,4)); 399SELECT nummultirange(numrange(1,8)) - nummultirange(numrange(2,3), numrange(5,null)); 400SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(-2,0)); 401SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(2,4)); 402SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(3,5)); 403SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(0,9)); 404SELECT nummultirange(numrange(1,3), numrange(4,5)) - nummultirange(numrange(2,9)); 405SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(8,9)); 406SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(-2,0), numrange(8,9)); 407 408-- intersection 409SELECT nummultirange() * nummultirange(); 410SELECT nummultirange() * nummultirange(numrange(1,2)); 411SELECT nummultirange(numrange(1,2)) * nummultirange(); 412SELECT '{[1,3)}'::nummultirange * '{[1,5)}'::nummultirange; 413SELECT '{[1,3)}'::nummultirange * '{[0,5)}'::nummultirange; 414SELECT '{[1,3)}'::nummultirange * '{[0,2)}'::nummultirange; 415SELECT '{[1,3)}'::nummultirange * '{[2,5)}'::nummultirange; 416SELECT '{[1,4)}'::nummultirange * '{[2,3)}'::nummultirange; 417SELECT '{[1,4)}'::nummultirange * '{[0,2), [3,5)}'::nummultirange; 418SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,8), [9,12)}'::nummultirange; 419SELECT '{[1,4), [7,10)}'::nummultirange * '{[9,12)}'::nummultirange; 420SELECT '{[1,4), [7,10)}'::nummultirange * '{[-5,-4), [5,6), [9,12)}'::nummultirange; 421SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,2), [3,8), [9,12)}'::nummultirange; 422SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,2), [3,8), [9,12)}'::nummultirange; 423 424-- test GiST index 425create table test_multirange_gist(mr int4multirange); 426insert into test_multirange_gist select int4multirange(int4range(g, g+10),int4range(g+20, g+30),int4range(g+40, g+50)) from generate_series(1,2000) g; 427insert into test_multirange_gist select '{}'::int4multirange from generate_series(1,500) g; 428insert into test_multirange_gist select int4multirange(int4range(g, g+10000)) from generate_series(1,1000) g; 429insert into test_multirange_gist select int4multirange(int4range(NULL, g*10, '(]'), int4range(g*10, g*20, '(]')) from generate_series(1,100) g; 430insert into test_multirange_gist select int4multirange(int4range(g*10, g*20, '(]'), int4range(g*20, NULL, '(]')) from generate_series(1,100) g; 431create index test_mulrirange_gist_idx on test_multirange_gist using gist (mr); 432 433-- test statistics and selectivity estimation as well 434-- 435-- We don't check the accuracy of selectivity estimation, but at least check 436-- it doesn't fall. 437analyze test_multirange_gist; 438 439-- first, verify non-indexed results 440SET enable_seqscan = t; 441SET enable_indexscan = f; 442SET enable_bitmapscan = f; 443 444select count(*) from test_multirange_gist where mr = '{}'::int4multirange; 445select count(*) from test_multirange_gist where mr @> 'empty'::int4range; 446select count(*) from test_multirange_gist where mr && 'empty'::int4range; 447select count(*) from test_multirange_gist where mr <@ 'empty'::int4range; 448select count(*) from test_multirange_gist where mr << 'empty'::int4range; 449select count(*) from test_multirange_gist where mr >> 'empty'::int4range; 450select count(*) from test_multirange_gist where mr &< 'empty'::int4range; 451select count(*) from test_multirange_gist where mr &> 'empty'::int4range; 452select count(*) from test_multirange_gist where mr -|- 'empty'::int4range; 453select count(*) from test_multirange_gist where mr @> '{}'::int4multirange; 454select count(*) from test_multirange_gist where mr @> '{}'::int4multirange; 455select count(*) from test_multirange_gist where mr && '{}'::int4multirange; 456select count(*) from test_multirange_gist where mr <@ '{}'::int4multirange; 457select count(*) from test_multirange_gist where mr << '{}'::int4multirange; 458select count(*) from test_multirange_gist where mr >> '{}'::int4multirange; 459select count(*) from test_multirange_gist where mr &< '{}'::int4multirange; 460select count(*) from test_multirange_gist where mr &> '{}'::int4multirange; 461select count(*) from test_multirange_gist where mr -|- '{}'::int4multirange; 462 463select count(*) from test_multirange_gist where mr = int4multirange(int4range(10,20), int4range(30,40), int4range(50,60)); 464select count(*) from test_multirange_gist where mr @> 10; 465select count(*) from test_multirange_gist where mr @> int4range(10,20); 466select count(*) from test_multirange_gist where mr && int4range(10,20); 467select count(*) from test_multirange_gist where mr <@ int4range(10,50); 468select count(*) from test_multirange_gist where mr << int4range(100,500); 469select count(*) from test_multirange_gist where mr >> int4range(100,500); 470select count(*) from test_multirange_gist where mr &< int4range(100,500); 471select count(*) from test_multirange_gist where mr &> int4range(100,500); 472select count(*) from test_multirange_gist where mr -|- int4range(100,500); 473select count(*) from test_multirange_gist where mr @> '{}'::int4multirange; 474select count(*) from test_multirange_gist where mr @> int4multirange(int4range(10,20), int4range(30,40)); 475select count(*) from test_multirange_gist where mr && '{(10,20),(30,40),(50,60)}'::int4multirange; 476select count(*) from test_multirange_gist where mr <@ '{(10,30),(40,60),(70,90)}'::int4multirange; 477select count(*) from test_multirange_gist where mr << int4multirange(int4range(100,200), int4range(400,500)); 478select count(*) from test_multirange_gist where mr >> int4multirange(int4range(100,200), int4range(400,500)); 479select count(*) from test_multirange_gist where mr &< int4multirange(int4range(100,200), int4range(400,500)); 480select count(*) from test_multirange_gist where mr &> int4multirange(int4range(100,200), int4range(400,500)); 481select count(*) from test_multirange_gist where mr -|- int4multirange(int4range(100,200), int4range(400,500)); 482 483-- now check same queries using index 484SET enable_seqscan = f; 485SET enable_indexscan = t; 486SET enable_bitmapscan = f; 487 488select count(*) from test_multirange_gist where mr = '{}'::int4multirange; 489select count(*) from test_multirange_gist where mr @> 'empty'::int4range; 490select count(*) from test_multirange_gist where mr && 'empty'::int4range; 491select count(*) from test_multirange_gist where mr <@ 'empty'::int4range; 492select count(*) from test_multirange_gist where mr << 'empty'::int4range; 493select count(*) from test_multirange_gist where mr >> 'empty'::int4range; 494select count(*) from test_multirange_gist where mr &< 'empty'::int4range; 495select count(*) from test_multirange_gist where mr &> 'empty'::int4range; 496select count(*) from test_multirange_gist where mr -|- 'empty'::int4range; 497select count(*) from test_multirange_gist where mr @> '{}'::int4multirange; 498select count(*) from test_multirange_gist where mr @> '{}'::int4multirange; 499select count(*) from test_multirange_gist where mr && '{}'::int4multirange; 500select count(*) from test_multirange_gist where mr <@ '{}'::int4multirange; 501select count(*) from test_multirange_gist where mr << '{}'::int4multirange; 502select count(*) from test_multirange_gist where mr >> '{}'::int4multirange; 503select count(*) from test_multirange_gist where mr &< '{}'::int4multirange; 504select count(*) from test_multirange_gist where mr &> '{}'::int4multirange; 505select count(*) from test_multirange_gist where mr -|- '{}'::int4multirange; 506 507select count(*) from test_multirange_gist where mr @> 'empty'::int4range; 508select count(*) from test_multirange_gist where mr = int4multirange(int4range(10,20), int4range(30,40), int4range(50,60)); 509select count(*) from test_multirange_gist where mr @> 10; 510select count(*) from test_multirange_gist where mr @> int4range(10,20); 511select count(*) from test_multirange_gist where mr && int4range(10,20); 512select count(*) from test_multirange_gist where mr <@ int4range(10,50); 513select count(*) from test_multirange_gist where mr << int4range(100,500); 514select count(*) from test_multirange_gist where mr >> int4range(100,500); 515select count(*) from test_multirange_gist where mr &< int4range(100,500); 516select count(*) from test_multirange_gist where mr &> int4range(100,500); 517select count(*) from test_multirange_gist where mr -|- int4range(100,500); 518select count(*) from test_multirange_gist where mr @> '{}'::int4multirange; 519select count(*) from test_multirange_gist where mr @> int4multirange(int4range(10,20), int4range(30,40)); 520select count(*) from test_multirange_gist where mr && '{(10,20),(30,40),(50,60)}'::int4multirange; 521select count(*) from test_multirange_gist where mr <@ '{(10,30),(40,60),(70,90)}'::int4multirange; 522select count(*) from test_multirange_gist where mr << int4multirange(int4range(100,200), int4range(400,500)); 523select count(*) from test_multirange_gist where mr >> int4multirange(int4range(100,200), int4range(400,500)); 524select count(*) from test_multirange_gist where mr &< int4multirange(int4range(100,200), int4range(400,500)); 525select count(*) from test_multirange_gist where mr &> int4multirange(int4range(100,200), int4range(400,500)); 526select count(*) from test_multirange_gist where mr -|- int4multirange(int4range(100,200), int4range(400,500)); 527 528drop table test_multirange_gist; 529 530-- 531-- range_agg function 532-- 533create table reservations ( room_id integer not null, booked_during daterange ); 534insert into reservations values 535-- 1: has a meets and a gap 536(1, daterange('2018-07-01', '2018-07-07')), 537(1, daterange('2018-07-07', '2018-07-14')), 538(1, daterange('2018-07-20', '2018-07-22')), 539-- 2: just a single row 540(2, daterange('2018-07-01', '2018-07-03')), 541-- 3: one null range 542(3, NULL), 543-- 4: two null ranges 544(4, NULL), 545(4, NULL), 546-- 5: a null range and a non-null range 547(5, NULL), 548(5, daterange('2018-07-01', '2018-07-03')), 549-- 6: has overlap 550(6, daterange('2018-07-01', '2018-07-07')), 551(6, daterange('2018-07-05', '2018-07-10')), 552-- 7: two ranges that meet: no gap or overlap 553(7, daterange('2018-07-01', '2018-07-07')), 554(7, daterange('2018-07-07', '2018-07-14')), 555-- 8: an empty range 556(8, 'empty'::daterange) 557; 558SELECT room_id, range_agg(booked_during) 559FROM reservations 560GROUP BY room_id 561ORDER BY room_id; 562 563-- range_agg on a custom range type too 564SELECT range_agg(r) 565FROM (VALUES 566 ('[a,c]'::textrange), 567 ('[b,b]'::textrange), 568 ('[c,f]'::textrange), 569 ('[g,h)'::textrange), 570 ('[h,j)'::textrange) 571 ) t(r); 572 573select range_intersect_agg(nmr) from nummultirange_test; 574select range_intersect_agg(nmr) from nummultirange_test where false; 575-- test with just one input: 576select range_intersect_agg(nmr) from (values ('{[1,2]}'::nummultirange)) t(nmr); 577select range_intersect_agg(nmr) from nummultirange_test where nmr @> 4.0; 578 579create table nummultirange_test2(nmr nummultirange); 580create index nummultirange_test2_hash_idx on nummultirange_test2 using hash (nmr); 581 582INSERT INTO nummultirange_test2 VALUES('{[, 5)}'); 583INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2))); 584INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2))); 585INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2,'()'))); 586INSERT INTO nummultirange_test2 VALUES('{}'); 587 588select * from nummultirange_test2 where nmr = '{}'; 589select * from nummultirange_test2 where nmr = nummultirange(numrange(1.1, 2.2)); 590select * from nummultirange_test2 where nmr = nummultirange(numrange(1.1, 2.3)); 591 592set enable_nestloop=t; 593set enable_hashjoin=f; 594set enable_mergejoin=f; 595select * from nummultirange_test natural join nummultirange_test2 order by nmr; 596set enable_nestloop=f; 597set enable_hashjoin=t; 598set enable_mergejoin=f; 599select * from nummultirange_test natural join nummultirange_test2 order by nmr; 600set enable_nestloop=f; 601set enable_hashjoin=f; 602set enable_mergejoin=t; 603select * from nummultirange_test natural join nummultirange_test2 order by nmr; 604 605set enable_nestloop to default; 606set enable_hashjoin to default; 607set enable_mergejoin to default; 608 609DROP TABLE nummultirange_test2; 610 611-- 612-- Test user-defined multirange of floats 613-- 614 615select '{[123.001, 5.e9)}'::float8multirange @> 888.882::float8; 616create table float8multirange_test(f8mr float8multirange, i int); 617insert into float8multirange_test values(float8multirange(float8range(-100.00007, '1.111113e9')), 42); 618select * from float8multirange_test; 619drop table float8multirange_test; 620 621-- 622-- Test multirange types over domains 623-- 624 625create domain mydomain as int4; 626create type mydomainrange as range(subtype=mydomain); 627select '{[4,50)}'::mydomainmultirange @> 7::mydomain; 628drop domain mydomain cascade; 629 630-- 631-- Test domains over multirange types 632-- 633 634create domain restrictedmultirange as int4multirange check (upper(value) < 10); 635select '{[4,5)}'::restrictedmultirange @> 7; 636select '{[4,50)}'::restrictedmultirange @> 7; -- should fail 637drop domain restrictedmultirange; 638 639--- 640-- Check automatic naming of multiranges 641--- 642 643create type intr as range(subtype=int); 644select intr_multirange(intr(1,10)); 645drop type intr; 646create type intmultirange as (x int, y int); 647create type intrange as range(subtype=int); -- should fail 648drop type intmultirange; 649create type intr_multirange as (x int, y int); 650create type intr as range(subtype=int); -- should fail 651drop type intr_multirange; 652 653-- 654-- Test multiple multirange types over the same subtype and manual naming of 655-- the multirange type. 656-- 657 658-- should fail 659create type textrange1 as range(subtype=text, multirange_type_name=int, collation="C"); 660-- should pass 661create type textrange1 as range(subtype=text, multirange_type_name=multirange_of_text, collation="C"); 662-- should pass, because existing _textrange1 is automatically renamed 663create type textrange2 as range(subtype=text, multirange_type_name=_textrange1, collation="C"); 664 665select multirange_of_text(textrange2('a','Z')); -- should fail 666select multirange_of_text(textrange1('a','Z')) @> 'b'::text; 667select unnest(multirange_of_text(textrange1('a','b'), textrange1('d','e'))); 668select _textrange1(textrange2('a','z')) @> 'b'::text; 669 670drop type textrange1; 671drop type textrange2; 672 673-- 674-- Test polymorphic type system 675-- 676 677create function anyarray_anymultirange_func(a anyarray, r anymultirange) 678 returns anyelement as 'select $1[1] + lower($2);' language sql; 679 680select anyarray_anymultirange_func(ARRAY[1,2], int4multirange(int4range(10,20))); 681 682-- should fail 683select anyarray_anymultirange_func(ARRAY[1,2], nummultirange(numrange(10,20))); 684 685drop function anyarray_anymultirange_func(anyarray, anymultirange); 686 687-- should fail 688create function bogus_func(anyelement) 689 returns anymultirange as 'select int4multirange(int4range(1,10))' language sql; 690 691-- should fail 692create function bogus_func(int) 693 returns anymultirange as 'select int4multirange(int4range(1,10))' language sql; 694 695create function range_add_bounds(anymultirange) 696 returns anyelement as 'select lower($1) + upper($1)' language sql; 697 698select range_add_bounds(int4multirange(int4range(1, 17))); 699select range_add_bounds(nummultirange(numrange(1.0001, 123.123))); 700 701create function multirangetypes_sql(q anymultirange, b anyarray, out c anyelement) 702 as $$ select upper($1) + $2[1] $$ 703 language sql; 704 705select multirangetypes_sql(int4multirange(int4range(1,10)), ARRAY[2,20]); 706select multirangetypes_sql(nummultirange(numrange(1,10)), ARRAY[2,20]); -- match failure 707 708create function anycompatiblearray_anycompatiblemultirange_func(a anycompatiblearray, mr anycompatiblemultirange) 709 returns anycompatible as 'select $1[1] + lower($2);' language sql; 710 711select anycompatiblearray_anycompatiblemultirange_func(ARRAY[1,2], multirange(int4range(10,20))); 712 713select anycompatiblearray_anycompatiblemultirange_func(ARRAY[1,2], multirange(numrange(10,20))); 714 715-- should fail 716select anycompatiblearray_anycompatiblemultirange_func(ARRAY[1.1,2], multirange(int4range(10,20))); 717 718drop function anycompatiblearray_anycompatiblemultirange_func(anycompatiblearray, anycompatiblemultirange); 719 720create function anycompatiblerange_anycompatiblemultirange_func(r anycompatiblerange, mr anycompatiblemultirange) 721 returns anycompatible as 'select lower($1) + lower($2);' language sql; 722 723select anycompatiblerange_anycompatiblemultirange_func(int4range(1,2), multirange(int4range(10,20))); 724 725-- should fail 726select anycompatiblerange_anycompatiblemultirange_func(numrange(1,2), multirange(int4range(10,20))); 727 728drop function anycompatiblerange_anycompatiblemultirange_func(anycompatiblerange, anycompatiblemultirange); 729 730-- should fail 731create function bogus_func(anycompatible) 732 returns anycompatiblerange as 'select int4range(1,10)' language sql; 733 734-- 735-- Arrays of multiranges 736-- 737 738select ARRAY[nummultirange(numrange(1.1, 1.2)), nummultirange(numrange(12.3, 155.5))]; 739 740create table i8mr_array (f1 int, f2 int8multirange[]); 741insert into i8mr_array values (42, array[int8multirange(int8range(1,10)), int8multirange(int8range(2,20))]); 742select * from i8mr_array; 743drop table i8mr_array; 744 745-- 746-- Multiranges of arrays 747-- 748 749select arraymultirange(arrayrange(ARRAY[1,2], ARRAY[2,1])); 750select arraymultirange(arrayrange(ARRAY[2,1], ARRAY[1,2])); -- fail 751 752select array[1,1] <@ arraymultirange(arrayrange(array[1,2], array[2,1])); 753select array[1,3] <@ arraymultirange(arrayrange(array[1,2], array[2,1])); 754 755-- 756-- Ranges of composites 757-- 758 759create type two_ints as (a int, b int); 760create type two_ints_range as range (subtype = two_ints); 761 762-- with force_parallel_mode on, this exercises tqueue.c's range remapping 763select *, row_to_json(upper(t)) as u from 764 (values (two_ints_multirange(two_ints_range(row(1,2), row(3,4)))), 765 (two_ints_multirange(two_ints_range(row(5,6), row(7,8))))) v(t); 766 767drop type two_ints cascade; 768 769-- 770-- Check behavior when subtype lacks a hash function 771-- 772 773set enable_sort = off; -- try to make it pick a hash setop implementation 774 775select '{(2,5)}'::cashmultirange except select '{(5,6)}'::cashmultirange; 776 777reset enable_sort; 778 779-- 780-- OUT/INOUT/TABLE functions 781-- 782 783-- infer anymultirange from anymultirange 784create function mr_outparam_succeed(i anymultirange, out r anymultirange, out t text) 785 as $$ select $1, 'foo'::text $$ language sql; 786 787select * from mr_outparam_succeed(int4multirange(int4range(1,2))); 788 789-- infer anyarray from anymultirange 790create function mr_outparam_succeed2(i anymultirange, out r anyarray, out t text) 791 as $$ select ARRAY[upper($1)], 'foo'::text $$ language sql; 792 793select * from mr_outparam_succeed2(int4multirange(int4range(1,2))); 794 795-- infer anyrange from anymultirange 796create function mr_outparam_succeed3(i anymultirange, out r anyrange, out t text) 797 as $$ select range_merge($1), 'foo'::text $$ language sql; 798select * from mr_outparam_succeed3(int4multirange(int4range(1,2))); 799 800-- infer anymultirange from anyrange 801create function mr_outparam_succeed4(i anyrange, out r anymultirange, out t text) 802 as $$ select multirange($1), 'foo'::text $$ language sql; 803 804select * from mr_outparam_succeed4(int4range(1,2)); 805 806-- infer anyelement from anymultirange 807create function mr_inoutparam_succeed(out i anyelement, inout r anymultirange) 808 as $$ select upper($1), $1 $$ language sql; 809 810select * from mr_inoutparam_succeed(int4multirange(int4range(1,2))); 811 812-- infer anyelement+anymultirange from anyelement+anymultirange 813create function mr_table_succeed(i anyelement, r anymultirange) returns table(i anyelement, r anymultirange) 814 as $$ select $1, $2 $$ language sql; 815 816select * from mr_table_succeed(123, int4multirange(int4range(1,11))); 817 818-- use anymultirange in plpgsql 819create function mr_polymorphic(i anyrange) returns anymultirange 820 as $$ begin return multirange($1); end; $$ language plpgsql; 821select mr_polymorphic(int4range(1, 4)); 822 823-- should fail 824create function mr_outparam_fail(i anyelement, out r anymultirange, out t text) 825 as $$ select '[1,10]', 'foo' $$ language sql; 826 827--should fail 828create function mr_inoutparam_fail(inout i anyelement, out r anymultirange) 829 as $$ select $1, '[1,10]' $$ language sql; 830 831--should fail 832create function mr_table_fail(i anyelement) returns table(i anyelement, r anymultirange) 833 as $$ select $1, '[1,10]' $$ language sql; 834