1-- Tests for range data types. 2CREATE TYPE textrange AS RANGE ( 3 subtype = text, 4 COLLATION = "C" 5); 6 7-- 8-- test input parser 9-- 10-- negative tests; should fail 11SELECT 12 ''::textrange; 13 14SELECT 15 '-[a,z)'::textrange; 16 17SELECT 18 '[a,z) - '::textrange; 19 20SELECT 21 '(",a)'::textrange; 22 23SELECT 24 '(,,a)'::textrange; 25 26SELECT 27 '(),a)'::textrange; 28 29SELECT 30 '(a,))'::textrange; 31 32SELECT 33 '(],a)'::textrange; 34 35SELECT 36 '(a,])'::textrange; 37 38SELECT 39 '[z,a]'::textrange; 40 41-- should succeed 42SELECT 43 ' empty '::textrange; 44 45SELECT 46 ' ( empty, empty ) '::textrange; 47 48SELECT 49 ' ( " a " " a ", " z " " z " ) '::textrange; 50 51SELECT 52 '(,z)'::textrange; 53 54SELECT 55 '(a,)'::textrange; 56 57SELECT 58 '[,z]'::textrange; 59 60SELECT 61 '[a,]'::textrange; 62 63SELECT 64 '(,)'::textrange; 65 66SELECT 67 '[ , ]'::textrange; 68 69SELECT 70 '["",""]'::textrange; 71 72SELECT 73 '[",",","]'::textrange; 74 75SELECT 76 '["\\","\\"]'::textrange; 77 78SELECT 79 '(\\,a)'::textrange; 80 81SELECT 82 '((,z)'::textrange; 83 84SELECT 85 '([,z)'::textrange; 86 87SELECT 88 '(!,()'::textrange; 89 90SELECT 91 '(!,[)'::textrange; 92 93SELECT 94 '[a,a]'::textrange; 95 96-- these are allowed but normalize to empty: 97SELECT 98 '[a,a)'::textrange; 99 100SELECT 101 '(a,a]'::textrange; 102 103SELECT 104 '(a,a)'::textrange; 105 106-- 107-- create some test data and test the operators 108-- 109CREATE TABLE numrange_test ( 110 nr numrange 111); 112 113CREATE INDEX numrange_test_btree ON numrange_test (nr); 114 115INSERT INTO numrange_test 116 VALUES ('[,)'); 117 118INSERT INTO numrange_test 119 VALUES ('[3,]'); 120 121INSERT INTO numrange_test 122 VALUES ('[, 5)'); 123 124INSERT INTO numrange_test 125 VALUES (numrange(1.1, 2.2)); 126 127INSERT INTO numrange_test 128 VALUES ('empty'); 129 130INSERT INTO numrange_test 131 VALUES (numrange(1.7, 1.7, '[]')); 132 133SELECT 134 nr, 135 isempty(nr), 136 lower(nr), 137 upper(nr) 138FROM 139 numrange_test; 140 141SELECT 142 nr, 143 lower_inc(nr), 144 lower_inf(nr), 145 upper_inc(nr), 146 upper_inf(nr) 147FROM 148 numrange_test; 149 150SELECT 151 * 152FROM 153 numrange_test 154WHERE 155 range_contains(nr, numrange(1.9, 1.91)); 156 157SELECT 158 * 159FROM 160 numrange_test 161WHERE 162 nr @> numrange(1.0, 10000.1); 163 164SELECT 165 * 166FROM 167 numrange_test 168WHERE 169 range_contained_by(numrange(- 1e7, -10000.1), nr); 170 171SELECT 172 * 173FROM 174 numrange_test 175WHERE 176 1.9 <@ nr; 177 178SELECT 179 * 180FROM 181 numrange_test 182WHERE 183 nr = 'empty'; 184 185SELECT 186 * 187FROM 188 numrange_test 189WHERE 190 nr = '(1.1, 2.2)'; 191 192SELECT 193 * 194FROM 195 numrange_test 196WHERE 197 nr = '[1.1, 2.2)'; 198 199SELECT 200 * 201FROM 202 numrange_test 203WHERE 204 nr < 'empty'; 205 206SELECT 207 * 208FROM 209 numrange_test 210WHERE 211 nr < numrange(-1000.0, -1000.0, '[]'); 212 213SELECT 214 * 215FROM 216 numrange_test 217WHERE 218 nr < numrange(0.0, 1.0, '[]'); 219 220SELECT 221 * 222FROM 223 numrange_test 224WHERE 225 nr < numrange(1000.0, 1001.0, '[]'); 226 227SELECT 228 * 229FROM 230 numrange_test 231WHERE 232 nr <= 'empty'; 233 234SELECT 235 * 236FROM 237 numrange_test 238WHERE 239 nr >= 'empty'; 240 241SELECT 242 * 243FROM 244 numrange_test 245WHERE 246 nr > 'empty'; 247 248SELECT 249 * 250FROM 251 numrange_test 252WHERE 253 nr > numrange(-1001.0, -1000.0, '[]'); 254 255SELECT 256 * 257FROM 258 numrange_test 259WHERE 260 nr > numrange(0.0, 1.0, '[]'); 261 262SELECT 263 * 264FROM 265 numrange_test 266WHERE 267 nr > numrange(1000.0, 1000.0, '[]'); 268 269SELECT 270 numrange(2.0, 1.0); 271 272SELECT 273 numrange(2.0, 3.0) -|- numrange(3.0, 4.0); 274 275SELECT 276 range_adjacent(numrange(2.0, 3.0), numrange(3.1, 4.0)); 277 278SELECT 279 range_adjacent(numrange(2.0, 3.0), numrange(3.1, NULL)); 280 281SELECT 282 numrange(2.0, 3.0, '[]') -|- numrange(3.0, 4.0, '()'); 283 284SELECT 285 numrange(1.0, 2.0) -|- numrange(2.0, 3.0, '[]'); 286 287SELECT 288 range_adjacent(numrange(2.0, 3.0, '(]'), numrange(1.0, 2.0, '(]')); 289 290SELECT 291 numrange(1.1, 3.3) <@ numrange(0.1, 10.1); 292 293SELECT 294 numrange(0.1, 10.1) <@ numrange(1.1, 3.3); 295 296SELECT 297 numrange(1.1, 2.2) - numrange(2.0, 3.0); 298 299SELECT 300 numrange(1.1, 2.2) - numrange(2.2, 3.0); 301 302SELECT 303 numrange(1.1, 2.2, '[]') - numrange(2.0, 3.0); 304 305SELECT 306 range_minus(numrange(10.1, 12.2, '[]'), numrange(110.0, 120.2, '(]')); 307 308SELECT 309 range_minus(numrange(10.1, 12.2, '[]'), numrange(0.0, 120.2, '(]')); 310 311SELECT 312 numrange(4.5, 5.5, '[]') && numrange(5.5, 6.5); 313 314SELECT 315 numrange(1.0, 2.0) << numrange(3.0, 4.0); 316 317SELECT 318 numrange(1.0, 3.0, '[]') << numrange(3.0, 4.0, '[]'); 319 320SELECT 321 numrange(1.0, 3.0, '()') << numrange(3.0, 4.0, '()'); 322 323SELECT 324 numrange(1.0, 2.0) >> numrange(3.0, 4.0); 325 326SELECT 327 numrange(3.0, 70.0) &< numrange(6.6, 100.0); 328 329SELECT 330 numrange(1.1, 2.2) < numrange(1.0, 200.2); 331 332SELECT 333 numrange(1.1, 2.2) < numrange(1.1, 1.2); 334 335SELECT 336 numrange(1.0, 2.0) + numrange(2.0, 3.0); 337 338SELECT 339 numrange(1.0, 2.0) + numrange(1.5, 3.0); 340 341SELECT 342 numrange(1.0, 2.0) + numrange(2.5, 3.0); 343 344-- should fail 345SELECT 346 range_merge(numrange(1.0, 2.0), numrange(2.0, 3.0)); 347 348SELECT 349 range_merge(numrange(1.0, 2.0), numrange(1.5, 3.0)); 350 351SELECT 352 range_merge(numrange(1.0, 2.0), numrange(2.5, 3.0)); 353 354-- shouldn't fail 355SELECT 356 numrange(1.0, 2.0) * numrange(2.0, 3.0); 357 358SELECT 359 numrange(1.0, 2.0) * numrange(1.5, 3.0); 360 361SELECT 362 numrange(1.0, 2.0) * numrange(2.5, 3.0); 363 364CREATE TABLE numrange_test2 ( 365 nr numrange 366); 367 368CREATE INDEX numrange_test2_hash_idx ON numrange_test2 (nr); 369 370INSERT INTO numrange_test2 371 VALUES ('[, 5)'); 372 373INSERT INTO numrange_test2 374 VALUES (numrange(1.1, 2.2)); 375 376INSERT INTO numrange_test2 377 VALUES (numrange(1.1, 2.2)); 378 379INSERT INTO numrange_test2 380 VALUES (numrange(1.1, 2.2, '()')); 381 382INSERT INTO numrange_test2 383 VALUES ('empty'); 384 385SELECT 386 * 387FROM 388 numrange_test2 389WHERE 390 nr = 'empty'::numrange; 391 392SELECT 393 * 394FROM 395 numrange_test2 396WHERE 397 nr = numrange(1.1, 2.2); 398 399SELECT 400 * 401FROM 402 numrange_test2 403WHERE 404 nr = numrange(1.1, 2.3); 405 406SET enable_nestloop = t; 407 408SET enable_hashjoin = f; 409 410SET enable_mergejoin = f; 411 412SELECT 413 * 414FROM 415 numrange_test 416 NATURAL JOIN numrange_test2 417ORDER BY 418 nr; 419 420SET enable_nestloop = f; 421 422SET enable_hashjoin = t; 423 424SET enable_mergejoin = f; 425 426SELECT 427 * 428FROM 429 numrange_test 430 NATURAL JOIN numrange_test2 431ORDER BY 432 nr; 433 434SET enable_nestloop = f; 435 436SET enable_hashjoin = f; 437 438SET enable_mergejoin = t; 439 440SELECT 441 * 442FROM 443 numrange_test 444 NATURAL JOIN numrange_test2 445ORDER BY 446 nr; 447 448SET enable_nestloop TO DEFAULT; 449 450SET enable_hashjoin TO DEFAULT; 451 452SET enable_mergejoin TO DEFAULT; 453 454DROP TABLE numrange_test; 455 456DROP TABLE numrange_test2; 457 458-- test canonical form for int4range 459SELECT 460 int4range(1, 10, '[]'); 461 462SELECT 463 int4range(1, 10, '[)'); 464 465SELECT 466 int4range(1, 10, '(]'); 467 468SELECT 469 int4range(1, 10, '()'); 470 471SELECT 472 int4range(1, 2, '()'); 473 474-- test canonical form for daterange 475SELECT 476 daterange('2000-01-10'::date, '2000-01-20'::date, '[]'); 477 478SELECT 479 daterange('2000-01-10'::date, '2000-01-20'::date, '[)'); 480 481SELECT 482 daterange('2000-01-10'::date, '2000-01-20'::date, '(]'); 483 484SELECT 485 daterange('2000-01-10'::date, '2000-01-20'::date, '()'); 486 487SELECT 488 daterange('2000-01-10'::date, '2000-01-11'::date, '()'); 489 490SELECT 491 daterange('2000-01-10'::date, '2000-01-11'::date, '(]'); 492 493-- test GiST index that's been built incrementally 494CREATE TABLE test_range_gist ( 495 ir int4range 496); 497 498CREATE INDEX test_range_gist_idx ON test_range_gist USING gist (ir); 499 500INSERT INTO test_range_gist 501SELECT 502 int4range(g, g + 10) 503FROM 504 generate_series(1, 2000) g; 505 506INSERT INTO test_range_gist 507SELECT 508 'empty'::int4range 509FROM 510 generate_series(1, 500) g; 511 512INSERT INTO test_range_gist 513SELECT 514 int4range(g, g + 10000) 515FROM 516 generate_series(1, 1000) g; 517 518INSERT INTO test_range_gist 519SELECT 520 'empty'::int4range 521FROM 522 generate_series(1, 500) g; 523 524INSERT INTO test_range_gist 525SELECT 526 int4range(NULL, g * 10, '(]') 527FROM 528 generate_series(1, 100) g; 529 530INSERT INTO test_range_gist 531SELECT 532 int4range(g * 10, NULL, '(]') 533FROM 534 generate_series(1, 100) g; 535 536INSERT INTO test_range_gist 537SELECT 538 int4range(g, g + 10) 539FROM 540 generate_series(1, 2000) g; 541 542-- first, verify non-indexed results 543SET enable_seqscan = t; 544 545SET enable_indexscan = f; 546 547SET enable_bitmapscan = f; 548 549SELECT 550 count(*) 551FROM 552 test_range_gist 553WHERE 554 ir @> 'empty'::int4range; 555 556SELECT 557 count(*) 558FROM 559 test_range_gist 560WHERE 561 ir = int4range(10, 20); 562 563SELECT 564 count(*) 565FROM 566 test_range_gist 567WHERE 568 ir @> 10; 569 570SELECT 571 count(*) 572FROM 573 test_range_gist 574WHERE 575 ir @> int4range(10, 20); 576 577SELECT 578 count(*) 579FROM 580 test_range_gist 581WHERE 582 ir && int4range(10, 20); 583 584SELECT 585 count(*) 586FROM 587 test_range_gist 588WHERE 589 ir <@ int4range(10, 50); 590 591SELECT 592 count(*) 593FROM 594 test_range_gist 595WHERE 596 ir << int4range(100, 500); 597 598SELECT 599 count(*) 600FROM 601 test_range_gist 602WHERE 603 ir >> int4range(100, 500); 604 605SELECT 606 count(*) 607FROM 608 test_range_gist 609WHERE 610 ir &< int4range(100, 500); 611 612SELECT 613 count(*) 614FROM 615 test_range_gist 616WHERE 617 ir &> int4range(100, 500); 618 619SELECT 620 count(*) 621FROM 622 test_range_gist 623WHERE 624 ir -|- int4range(100, 500); 625 626-- now check same queries using index 627SET enable_seqscan = f; 628 629SET enable_indexscan = t; 630 631SET enable_bitmapscan = f; 632 633SELECT 634 count(*) 635FROM 636 test_range_gist 637WHERE 638 ir @> 'empty'::int4range; 639 640SELECT 641 count(*) 642FROM 643 test_range_gist 644WHERE 645 ir = int4range(10, 20); 646 647SELECT 648 count(*) 649FROM 650 test_range_gist 651WHERE 652 ir @> 10; 653 654SELECT 655 count(*) 656FROM 657 test_range_gist 658WHERE 659 ir @> int4range(10, 20); 660 661SELECT 662 count(*) 663FROM 664 test_range_gist 665WHERE 666 ir && int4range(10, 20); 667 668SELECT 669 count(*) 670FROM 671 test_range_gist 672WHERE 673 ir <@ int4range(10, 50); 674 675SELECT 676 count(*) 677FROM 678 test_range_gist 679WHERE 680 ir << int4range(100, 500); 681 682SELECT 683 count(*) 684FROM 685 test_range_gist 686WHERE 687 ir >> int4range(100, 500); 688 689SELECT 690 count(*) 691FROM 692 test_range_gist 693WHERE 694 ir &< int4range(100, 500); 695 696SELECT 697 count(*) 698FROM 699 test_range_gist 700WHERE 701 ir &> int4range(100, 500); 702 703SELECT 704 count(*) 705FROM 706 test_range_gist 707WHERE 708 ir -|- int4range(100, 500); 709 710-- now check same queries using a bulk-loaded index 711DROP INDEX test_range_gist_idx; 712 713CREATE INDEX test_range_gist_idx ON test_range_gist USING gist (ir); 714 715SELECT 716 count(*) 717FROM 718 test_range_gist 719WHERE 720 ir @> 'empty'::int4range; 721 722SELECT 723 count(*) 724FROM 725 test_range_gist 726WHERE 727 ir = int4range(10, 20); 728 729SELECT 730 count(*) 731FROM 732 test_range_gist 733WHERE 734 ir @> 10; 735 736SELECT 737 count(*) 738FROM 739 test_range_gist 740WHERE 741 ir @> int4range(10, 20); 742 743SELECT 744 count(*) 745FROM 746 test_range_gist 747WHERE 748 ir && int4range(10, 20); 749 750SELECT 751 count(*) 752FROM 753 test_range_gist 754WHERE 755 ir <@ int4range(10, 50); 756 757SELECT 758 count(*) 759FROM 760 test_range_gist 761WHERE 762 ir << int4range(100, 500); 763 764SELECT 765 count(*) 766FROM 767 test_range_gist 768WHERE 769 ir >> int4range(100, 500); 770 771SELECT 772 count(*) 773FROM 774 test_range_gist 775WHERE 776 ir &< int4range(100, 500); 777 778SELECT 779 count(*) 780FROM 781 test_range_gist 782WHERE 783 ir &> int4range(100, 500); 784 785SELECT 786 count(*) 787FROM 788 test_range_gist 789WHERE 790 ir -|- int4range(100, 500); 791 792-- test SP-GiST index that's been built incrementally 793CREATE TABLE test_range_spgist ( 794 ir int4range 795); 796 797CREATE INDEX test_range_spgist_idx ON test_range_spgist USING spgist (ir); 798 799INSERT INTO test_range_spgist 800SELECT 801 int4range(g, g + 10) 802FROM 803 generate_series(1, 2000) g; 804 805INSERT INTO test_range_spgist 806SELECT 807 'empty'::int4range 808FROM 809 generate_series(1, 500) g; 810 811INSERT INTO test_range_spgist 812SELECT 813 int4range(g, g + 10000) 814FROM 815 generate_series(1, 1000) g; 816 817INSERT INTO test_range_spgist 818SELECT 819 'empty'::int4range 820FROM 821 generate_series(1, 500) g; 822 823INSERT INTO test_range_spgist 824SELECT 825 int4range(NULL, g * 10, '(]') 826FROM 827 generate_series(1, 100) g; 828 829INSERT INTO test_range_spgist 830SELECT 831 int4range(g * 10, NULL, '(]') 832FROM 833 generate_series(1, 100) g; 834 835INSERT INTO test_range_spgist 836SELECT 837 int4range(g, g + 10) 838FROM 839 generate_series(1, 2000) g; 840 841-- first, verify non-indexed results 842SET enable_seqscan = t; 843 844SET enable_indexscan = f; 845 846SET enable_bitmapscan = f; 847 848SELECT 849 count(*) 850FROM 851 test_range_spgist 852WHERE 853 ir @> 'empty'::int4range; 854 855SELECT 856 count(*) 857FROM 858 test_range_spgist 859WHERE 860 ir = int4range(10, 20); 861 862SELECT 863 count(*) 864FROM 865 test_range_spgist 866WHERE 867 ir @> 10; 868 869SELECT 870 count(*) 871FROM 872 test_range_spgist 873WHERE 874 ir @> int4range(10, 20); 875 876SELECT 877 count(*) 878FROM 879 test_range_spgist 880WHERE 881 ir && int4range(10, 20); 882 883SELECT 884 count(*) 885FROM 886 test_range_spgist 887WHERE 888 ir <@ int4range(10, 50); 889 890SELECT 891 count(*) 892FROM 893 test_range_spgist 894WHERE 895 ir << int4range(100, 500); 896 897SELECT 898 count(*) 899FROM 900 test_range_spgist 901WHERE 902 ir >> int4range(100, 500); 903 904SELECT 905 count(*) 906FROM 907 test_range_spgist 908WHERE 909 ir &< int4range(100, 500); 910 911SELECT 912 count(*) 913FROM 914 test_range_spgist 915WHERE 916 ir &> int4range(100, 500); 917 918SELECT 919 count(*) 920FROM 921 test_range_spgist 922WHERE 923 ir -|- int4range(100, 500); 924 925-- now check same queries using index 926SET enable_seqscan = f; 927 928SET enable_indexscan = t; 929 930SET enable_bitmapscan = f; 931 932SELECT 933 count(*) 934FROM 935 test_range_spgist 936WHERE 937 ir @> 'empty'::int4range; 938 939SELECT 940 count(*) 941FROM 942 test_range_spgist 943WHERE 944 ir = int4range(10, 20); 945 946SELECT 947 count(*) 948FROM 949 test_range_spgist 950WHERE 951 ir @> 10; 952 953SELECT 954 count(*) 955FROM 956 test_range_spgist 957WHERE 958 ir @> int4range(10, 20); 959 960SELECT 961 count(*) 962FROM 963 test_range_spgist 964WHERE 965 ir && int4range(10, 20); 966 967SELECT 968 count(*) 969FROM 970 test_range_spgist 971WHERE 972 ir <@ int4range(10, 50); 973 974SELECT 975 count(*) 976FROM 977 test_range_spgist 978WHERE 979 ir << int4range(100, 500); 980 981SELECT 982 count(*) 983FROM 984 test_range_spgist 985WHERE 986 ir >> int4range(100, 500); 987 988SELECT 989 count(*) 990FROM 991 test_range_spgist 992WHERE 993 ir &< int4range(100, 500); 994 995SELECT 996 count(*) 997FROM 998 test_range_spgist 999WHERE 1000 ir &> int4range(100, 500); 1001 1002SELECT 1003 count(*) 1004FROM 1005 test_range_spgist 1006WHERE 1007 ir -|- int4range(100, 500); 1008 1009-- now check same queries using a bulk-loaded index 1010DROP INDEX test_range_spgist_idx; 1011 1012CREATE INDEX test_range_spgist_idx ON test_range_spgist USING spgist (ir); 1013 1014SELECT 1015 count(*) 1016FROM 1017 test_range_spgist 1018WHERE 1019 ir @> 'empty'::int4range; 1020 1021SELECT 1022 count(*) 1023FROM 1024 test_range_spgist 1025WHERE 1026 ir = int4range(10, 20); 1027 1028SELECT 1029 count(*) 1030FROM 1031 test_range_spgist 1032WHERE 1033 ir @> 10; 1034 1035SELECT 1036 count(*) 1037FROM 1038 test_range_spgist 1039WHERE 1040 ir @> int4range(10, 20); 1041 1042SELECT 1043 count(*) 1044FROM 1045 test_range_spgist 1046WHERE 1047 ir && int4range(10, 20); 1048 1049SELECT 1050 count(*) 1051FROM 1052 test_range_spgist 1053WHERE 1054 ir <@ int4range(10, 50); 1055 1056SELECT 1057 count(*) 1058FROM 1059 test_range_spgist 1060WHERE 1061 ir << int4range(100, 500); 1062 1063SELECT 1064 count(*) 1065FROM 1066 test_range_spgist 1067WHERE 1068 ir >> int4range(100, 500); 1069 1070SELECT 1071 count(*) 1072FROM 1073 test_range_spgist 1074WHERE 1075 ir &< int4range(100, 500); 1076 1077SELECT 1078 count(*) 1079FROM 1080 test_range_spgist 1081WHERE 1082 ir &> int4range(100, 500); 1083 1084SELECT 1085 count(*) 1086FROM 1087 test_range_spgist 1088WHERE 1089 ir -|- int4range(100, 500); 1090 1091-- test index-only scans 1092EXPLAIN ( 1093 COSTS OFF 1094) 1095SELECT 1096 ir 1097FROM 1098 test_range_spgist 1099WHERE 1100 ir -|- int4range(10, 20) 1101ORDER BY 1102 ir; 1103 1104SELECT 1105 ir 1106FROM 1107 test_range_spgist 1108WHERE 1109 ir -|- int4range(10, 20) 1110ORDER BY 1111 ir; 1112 1113RESET enable_seqscan; 1114 1115RESET enable_indexscan; 1116 1117RESET enable_bitmapscan; 1118 1119-- test elem <@ range operator 1120CREATE TABLE test_range_elem ( 1121 i int4 1122); 1123 1124CREATE INDEX test_range_elem_idx ON test_range_elem (i); 1125 1126INSERT INTO test_range_elem 1127SELECT 1128 i 1129FROM 1130 generate_series(1, 100) i; 1131 1132SELECT 1133 count(*) 1134FROM 1135 test_range_elem 1136WHERE 1137 i <@ int4range(10, 50); 1138 1139DROP TABLE test_range_elem; 1140 1141-- 1142-- Btree_gist is not included by default, so to test exclusion 1143-- constraints with range types, use singleton int ranges for the "=" 1144-- portion of the constraint. 1145-- 1146CREATE TABLE test_range_excl ( 1147 room int4range, 1148 speaker int4range, 1149 during tsrange, 1150 EXCLUDE USING gist (room WITH =, during WITH &&), 1151 EXCLUDE USING gist (speaker WITH =, during WITH &&) 1152); 1153 1154INSERT INTO test_range_excl 1155 VALUES (int4range(123, 123, '[]'), int4range(1, 1, '[]'), '[2010-01-02 10:00, 2010-01-02 11:00)'); 1156 1157INSERT INTO test_range_excl 1158 VALUES (int4range(123, 123, '[]'), int4range(2, 2, '[]'), '[2010-01-02 11:00, 2010-01-02 12:00)'); 1159 1160INSERT INTO test_range_excl 1161 VALUES (int4range(123, 123, '[]'), int4range(3, 3, '[]'), '[2010-01-02 10:10, 2010-01-02 11:00)'); 1162 1163INSERT INTO test_range_excl 1164 VALUES (int4range(124, 124, '[]'), int4range(3, 3, '[]'), '[2010-01-02 10:10, 2010-01-02 11:10)'); 1165 1166INSERT INTO test_range_excl 1167 VALUES (int4range(125, 125, '[]'), int4range(1, 1, '[]'), '[2010-01-02 10:10, 2010-01-02 11:00)'); 1168 1169-- test bigint ranges 1170SELECT 1171 int8range(10000000000::int8, 20000000000::int8, '(]'); 1172 1173-- test tstz ranges 1174SET timezone TO '-08'; 1175 1176SELECT 1177 '[2010-01-01 01:00:00 -05, 2010-01-01 02:00:00 -08)'::tstzrange; 1178 1179-- should fail 1180SELECT 1181 '[2010-01-01 01:00:00 -08, 2010-01-01 02:00:00 -05)'::tstzrange; 1182 1183SET timezone TO DEFAULT; 1184 1185-- 1186-- Test user-defined range of floats 1187-- 1188--should fail 1189CREATE TYPE float8range AS RANGE ( 1190 subtype = float8, 1191 subtype_diff = float4mi 1192); 1193 1194--should succeed 1195CREATE TYPE float8range AS RANGE ( 1196 subtype = float8, 1197 subtype_diff = float8mi 1198); 1199 1200SELECT 1201 '[123.001, 5.e9)'::float8range @> 888.882::float8; 1202 1203CREATE TABLE float8range_test ( 1204 f8r float8range, 1205 i int 1206); 1207 1208INSERT INTO float8range_test 1209 VALUES (float8range (-100.00007, '1.111113e9'), 42); 1210 1211SELECT 1212 * 1213FROM 1214 float8range_test; 1215 1216DROP TABLE float8range_test; 1217 1218-- 1219-- Test range types over domains 1220-- 1221CREATE DOMAIN mydomain AS int4; 1222 1223CREATE TYPE mydomainrange AS RANGE ( 1224 subtype = mydomain 1225); 1226 1227SELECT 1228 '[4,50)'::mydomainrange @> 7::mydomain; 1229 1230DROP DOMAIN mydomain; 1231 1232-- fail 1233DROP DOMAIN mydomain CASCADE; 1234 1235-- 1236-- Test domains over range types 1237-- 1238CREATE DOMAIN restrictedrange AS int4range CHECK (upper(value) < 10); 1239 1240SELECT 1241 '[4,5)'::restrictedrange @> 7; 1242 1243SELECT 1244 '[4,50)'::restrictedrange @> 7; 1245 1246-- should fail 1247DROP DOMAIN restrictedrange; 1248 1249-- 1250-- Test multiple range types over the same subtype 1251-- 1252CREATE TYPE textrange1 AS RANGE ( 1253 subtype = text, 1254 COLLATION = "C" 1255); 1256 1257CREATE TYPE textrange2 AS RANGE ( 1258 subtype = text, 1259 COLLATION = "C" 1260); 1261 1262SELECT 1263 textrange1 ('a', 'Z') @> 'b'::text; 1264 1265SELECT 1266 textrange2 ('a', 'z') @> 'b'::text; 1267 1268DROP TYPE textrange1; 1269 1270DROP TYPE textrange2; 1271 1272-- 1273-- Test polymorphic type system 1274-- 1275CREATE FUNCTION anyarray_anyrange_func (a anyarray, r anyrange) 1276 RETURNS anyelement 1277 AS 'select $1[1] + lower($2);' 1278 LANGUAGE sql; 1279 1280SELECT 1281 anyarray_anyrange_func (ARRAY[1, 2], int4range(10, 20)); 1282 1283-- should fail 1284SELECT 1285 anyarray_anyrange_func (ARRAY[1, 2], numrange(10, 20)); 1286 1287DROP FUNCTION anyarray_anyrange_func (anyarray, anyrange); 1288 1289-- should fail 1290CREATE FUNCTION bogus_func (anyelement) 1291 RETURNS anyrange 1292 AS 'select int4range(1,10)' 1293 LANGUAGE sql; 1294 1295-- should fail 1296CREATE FUNCTION bogus_func (int) 1297 RETURNS anyrange 1298 AS 'select int4range(1,10)' 1299 LANGUAGE sql; 1300 1301CREATE FUNCTION range_add_bounds (anyrange) 1302 RETURNS anyelement 1303 AS 'select lower($1) + upper($1)' 1304 LANGUAGE sql; 1305 1306SELECT 1307 range_add_bounds (int4range(1, 17)); 1308 1309SELECT 1310 range_add_bounds (numrange(1.0001, 123.123)); 1311 1312CREATE FUNCTION rangetypes_sql (q anyrange, b anyarray, out c anyelement) 1313AS $$ 1314 SELECT 1315 upper($1) + $2[1] 1316$$ 1317LANGUAGE sql; 1318 1319SELECT 1320 rangetypes_sql (int4range(1, 10), ARRAY[2, 20]); 1321 1322SELECT 1323 rangetypes_sql (numrange(1, 10), ARRAY[2, 20]); 1324 1325-- match failure 1326-- 1327-- Arrays of ranges 1328-- 1329SELECT 1330 ARRAY[numrange(1.1, 1.2), numrange(12.3, 155.5)]; 1331 1332CREATE TABLE i8r_array ( 1333 f1 int, 1334 f2 int8range[] 1335); 1336 1337INSERT INTO i8r_array 1338 VALUES (42, ARRAY[int8range(1, 10), int8range(2, 20)]); 1339 1340SELECT 1341 * 1342FROM 1343 i8r_array; 1344 1345DROP TABLE i8r_array; 1346 1347-- 1348-- Ranges of arrays 1349-- 1350CREATE TYPE arrayrange AS RANGE ( 1351 subtype = int4[] 1352); 1353 1354SELECT 1355 arrayrange (ARRAY[1, 2], ARRAY[2, 1]); 1356 1357SELECT 1358 arrayrange (ARRAY[2, 1], ARRAY[1, 2]); 1359 1360-- fail 1361SELECT 1362 ARRAY[1, 1] <@ arrayrange (ARRAY[1, 2], ARRAY[2, 1]); 1363 1364SELECT 1365 ARRAY[1, 3] <@ arrayrange (ARRAY[1, 2], ARRAY[2, 1]); 1366 1367-- 1368-- Ranges of composites 1369-- 1370CREATE TYPE two_ints AS ( 1371 a int, 1372 b int 1373); 1374 1375CREATE TYPE two_ints_range AS RANGE ( 1376 subtype = two_ints 1377); 1378 1379-- with force_parallel_mode on, this exercises tqueue.c's range remapping 1380SELECT 1381 *, 1382 row_to_json(upper(t)) AS u 1383FROM ( 1384 VALUES (two_ints_range (ROW (1, 2), ROW (3, 4))), 1385 (two_ints_range (ROW (5, 6), ROW (7, 8)))) v (t); 1386 1387DROP TYPE two_ints CASCADE; 1388 1389-- 1390-- Check behavior when subtype lacks a hash function 1391-- 1392CREATE TYPE cashrange AS RANGE ( 1393 subtype = money 1394); 1395 1396SET enable_sort = OFF; 1397 1398-- try to make it pick a hash setop implementation 1399SELECT 1400 '(2,5)'::cashrange 1401EXCEPT 1402SELECT 1403 '(5,6)'::cashrange; 1404 1405RESET enable_sort; 1406 1407-- 1408-- OUT/INOUT/TABLE functions 1409-- 1410CREATE FUNCTION outparam_succeed (i anyrange, out r anyrange, out t text) 1411AS $$ 1412 SELECT 1413 $1, 1414 'foo'::text 1415$$ 1416LANGUAGE sql; 1417 1418SELECT 1419 * 1420FROM 1421 outparam_succeed (int4range(1, 2)); 1422 1423CREATE FUNCTION inoutparam_succeed (out i anyelement, INOUT r anyrange) 1424AS $$ 1425 SELECT 1426 upper($1), 1427 $1 1428$$ 1429LANGUAGE sql; 1430 1431SELECT 1432 * 1433FROM 1434 inoutparam_succeed (int4range(1, 2)); 1435 1436CREATE FUNCTION table_succeed (i anyelement, r anyrange) 1437 RETURNS TABLE ( 1438 i anyelement, 1439 r anyrange 1440 ) 1441 AS $$ 1442 SELECT 1443 $1, 1444 $2 1445$$ 1446LANGUAGE sql; 1447 1448SELECT 1449 * 1450FROM 1451 table_succeed (123, int4range(1, 11)); 1452 1453-- should fail 1454CREATE FUNCTION outparam_fail (i anyelement, out r anyrange, out t text) 1455AS $$ 1456 SELECT 1457 '[1,10]', 1458 'foo' 1459$$ 1460LANGUAGE sql; 1461 1462--should fail 1463CREATE FUNCTION inoutparam_fail (INOUT i anyelement, out r anyrange) 1464AS $$ 1465 SELECT 1466 $1, 1467 '[1,10]' 1468$$ 1469LANGUAGE sql; 1470 1471--should fail 1472CREATE FUNCTION table_fail (i anyelement) 1473 RETURNS TABLE ( 1474 i anyelement, 1475 r anyrange 1476 ) 1477 AS $$ 1478 SELECT 1479 $1, 1480 '[1,10]' 1481$$ 1482LANGUAGE sql; 1483 1484