1-- 2-- CREATE_TABLE 3-- 4-- 5-- CLASS DEFINITIONS 6-- 7CREATE TABLE hobbies_r ( 8 name text, 9 person text 10); 11 12CREATE TABLE equipment_r ( 13 name text, 14 hobby text 15); 16 17CREATE TABLE onek ( 18 unique1 int4, 19 unique2 int4, 20 two int4, 21 four int4, 22 ten int4, 23 twenty int4, 24 hundred int4, 25 thousand int4, 26 twothousand int4, 27 fivethous int4, 28 tenthous int4, 29 odd int4, 30 even int4, 31 stringu1 name, 32 stringu2 name, 33 string4 name 34); 35 36CREATE TABLE tenk1 ( 37 unique1 int4, 38 unique2 int4, 39 two int4, 40 four int4, 41 ten int4, 42 twenty int4, 43 hundred int4, 44 thousand int4, 45 twothousand int4, 46 fivethous int4, 47 tenthous int4, 48 odd int4, 49 even int4, 50 stringu1 name, 51 stringu2 name, 52 string4 name 53); 54 55CREATE TABLE tenk2 ( 56 unique1 int4, 57 unique2 int4, 58 two int4, 59 four int4, 60 ten int4, 61 twenty int4, 62 hundred int4, 63 thousand int4, 64 twothousand int4, 65 fivethous int4, 66 tenthous int4, 67 odd int4, 68 even int4, 69 stringu1 name, 70 stringu2 name, 71 string4 name 72); 73 74CREATE TABLE person ( 75 name text, 76 age int4, 77 location point 78); 79 80CREATE TABLE emp ( 81 salary int4, 82 manager name 83) 84INHERITS ( 85 person 86); 87 88CREATE TABLE student ( 89 gpa float8 90) 91INHERITS ( 92 person 93); 94 95CREATE TABLE stud_emp ( 96 percent int4 97) 98INHERITS ( 99 emp, 100 student 101); 102 103CREATE TABLE city ( 104 name name, 105 location box, 106 budget city_budget 107); 108 109CREATE TABLE dept ( 110 dname name, 111 mgrname text 112); 113 114CREATE TABLE slow_emp4000 ( 115 home_base box 116); 117 118CREATE TABLE fast_emp4000 ( 119 home_base box 120); 121 122CREATE TABLE road ( 123 name text, 124 thepath path 125); 126 127CREATE TABLE ihighway () 128INHERITS ( 129 road 130); 131 132CREATE TABLE shighway ( 133 surface text 134) 135INHERITS ( 136 road 137); 138 139CREATE TABLE real_city ( 140 pop int4, 141 cname text, 142 outline path 143); 144 145-- 146-- test the "star" operators a bit more thoroughly -- this time, 147-- throw in lots of NULL fields... 148-- 149-- a is the type root 150-- b and c inherit from a (one-level single inheritance) 151-- d inherits from b and c (two-level multiple inheritance) 152-- e inherits from c (two-level single inheritance) 153-- f inherits from e (three-level single inheritance) 154-- 155CREATE TABLE a_star ( 156 class char, 157 a int4 158); 159 160CREATE TABLE b_star ( 161 b text 162) 163INHERITS ( 164 a_star 165); 166 167CREATE TABLE c_star ( 168 c name 169) 170INHERITS ( 171 a_star 172); 173 174CREATE TABLE d_star ( 175 d float8 176) 177INHERITS ( 178 b_star, 179 c_star 180); 181 182CREATE TABLE e_star ( 183 e int2 184) 185INHERITS ( 186 c_star 187); 188 189CREATE TABLE f_star ( 190 f polygon 191) 192INHERITS ( 193 e_star 194); 195 196CREATE TABLE aggtest ( 197 a int2, 198 b float4 199); 200 201CREATE TABLE hash_i4_heap ( 202 seqno int4, 203 random int4 204); 205 206CREATE TABLE hash_name_heap ( 207 seqno int4, 208 random name 209); 210 211CREATE TABLE hash_txt_heap ( 212 seqno int4, 213 random text 214); 215 216CREATE TABLE hash_f8_heap ( 217 seqno int4, 218 random float8 219); 220 221-- don't include the hash_ovfl_heap stuff in the distribution 222-- the data set is too large for what it's worth 223-- 224-- CREATE TABLE hash_ovfl_heap ( 225-- x int4, 226-- y int4 227-- ); 228CREATE TABLE bt_i4_heap ( 229 seqno int4, 230 random int4 231); 232 233CREATE TABLE bt_name_heap ( 234 seqno name, 235 random int4 236); 237 238CREATE TABLE bt_txt_heap ( 239 seqno text, 240 random int4 241); 242 243CREATE TABLE bt_f8_heap ( 244 seqno float8, 245 random int4 246); 247 248CREATE TABLE array_op_test ( 249 seqno int4, 250 i int4[], 251 t text[] 252); 253 254CREATE TABLE array_index_op_test ( 255 seqno int4, 256 i int4[], 257 t text[] 258); 259 260CREATE TABLE testjsonb ( 261 j jsonb 262); 263 264CREATE TABLE unknowntab ( 265 u unknown -- fail 266); 267 268CREATE TYPE unknown_comptype AS ( 269 u unknown -- fail 270); 271 272CREATE TABLE IF NOT EXISTS test_tsvector ( 273 t text, 274 a tsvector 275); 276 277CREATE TABLE IF NOT EXISTS test_tsvector ( 278 t text 279); 280 281-- invalid: non-lowercase quoted reloptions identifiers 282CREATE TABLE tas_case WITH ( 283 "Fillfactor" = 10 284) AS 285SELECT 286 1 a; 287 288CREATE UNLOGGED TABLE unlogged1 ( 289 a int PRIMARY KEY 290); 291 292-- OK 293CREATE TEMPORARY TABLE unlogged2 ( 294 a int PRIMARY KEY 295); 296 297-- OK 298SELECT 299 relname, 300 relkind, 301 relpersistence 302FROM 303 pg_class 304WHERE 305 relname ~ '^unlogged\d' 306ORDER BY 307 relname; 308 309REINDEX INDEX unlogged1_pkey; 310 311REINDEX INDEX unlogged2_pkey; 312 313SELECT 314 relname, 315 relkind, 316 relpersistence 317FROM 318 pg_class 319WHERE 320 relname ~ '^unlogged\d' 321ORDER BY 322 relname; 323 324DROP TABLE unlogged2; 325 326INSERT INTO unlogged1 327 VALUES (42); 328 329CREATE UNLOGGED TABLE public.unlogged2 ( 330 a int PRIMARY KEY 331); 332 333-- also OK 334CREATE UNLOGGED TABLE pg_temp.unlogged3 ( 335 a int PRIMARY KEY 336); 337 338-- not OK 339CREATE TABLE pg_temp.implicitly_temp ( 340 a int PRIMARY KEY 341); 342 343-- OK 344CREATE TEMP TABLE explicitly_temp ( 345 a int PRIMARY KEY 346); 347 348-- also OK 349CREATE TEMP TABLE pg_temp.doubly_temp ( 350 a int PRIMARY KEY 351); 352 353-- also OK 354CREATE TEMP TABLE public.temp_to_perm ( 355 a int PRIMARY KEY 356); 357 358-- not OK 359DROP TABLE unlogged1, public.unlogged2; 360 361CREATE TABLE as_select1 AS 362SELECT 363 * 364FROM 365 pg_class 366WHERE 367 relkind = 'r'; 368 369CREATE TABLE as_select1 AS 370SELECT 371 * 372FROM 373 pg_class 374WHERE 375 relkind = 'r'; 376 377CREATE TABLE IF NOT EXISTS as_select1 AS 378SELECT 379 * 380FROM 381 pg_class 382WHERE 383 relkind = 'r'; 384 385DROP TABLE as_select1; 386 387PREPARE select1 AS 388SELECT 389 1 AS a; 390 391CREATE TABLE as_select1 AS 392EXECUTE select1; 393 394CREATE TABLE as_select1 AS 395EXECUTE select1; 396 397SELECT 398 * 399FROM 400 as_select1; 401 402CREATE TABLE IF NOT EXISTS as_select1 AS 403EXECUTE select1; 404 405DROP TABLE as_select1; 406 407DEALLOCATE select1; 408 409-- create an extra wide table to test for issues related to that 410-- (temporarily hide query, to avoid the long CREATE TABLE stmt) 411\set ECHO none 412SELECT 413 'CREATE TABLE extra_wide_table(firstc text, ' || array_to_string(array_agg('c' || i || ' bool'), ',') || ', lastc text);' 414FROM 415 generate_series(1, 1100) g (i) \gexec 416 417\set ECHO all 418INSERT INTO extra_wide_table (firstc, lastc) 419 VALUES ('first col', 'last col'); 420 421SELECT 422 firstc, 423 lastc 424FROM 425 extra_wide_table; 426 427-- check that tables with oids cannot be created anymore 428CREATE TABLE withoid ( 429) 430WITH OIDS; 431 432CREATE TABLE withoid ( 433) 434WITH ( 435 OIDS 436); 437 438CREATE TABLE withoid ( 439) 440WITH ( 441 OIDS = TRUE 442); 443 444-- but explicitly not adding oids is still supported 445CREATE TEMP TABLE withoutoid () WITHOUT OIDS; 446 447DROP TABLE withoutoid; 448 449CREATE TEMP TABLE withoutoid ( 450) 451WITH ( 452 OIDS = FALSE 453); 454 455DROP TABLE withoutoid; 456 457-- check restriction with default expressions 458-- invalid use of column reference in default expressions 459CREATE TABLE default_expr_column ( 460 id int DEFAULT (id) 461); 462 463CREATE TABLE default_expr_column ( 464 id int DEFAULT (bar.id) 465); 466 467CREATE TABLE default_expr_agg_column ( 468 id int DEFAULT (avg(id)) 469); 470 471-- invalid column definition 472CREATE TABLE default_expr_non_column ( 473 a int DEFAULT (avg(non_existent)) 474); 475 476-- invalid use of aggregate 477CREATE TABLE default_expr_agg ( 478 a int DEFAULT (avg(1)) 479); 480 481-- invalid use of subquery 482CREATE TABLE default_expr_agg ( 483 a int DEFAULT ( 484 SELECT 485 1) 486); 487 488-- invalid use of set-returning function 489CREATE TABLE default_expr_agg ( 490 a int DEFAULT (generate_series(1, 3)) 491); 492 493-- 494-- Partitioned tables 495-- 496-- cannot combine INHERITS and PARTITION BY (although grammar allows) 497CREATE TABLE partitioned ( 498 a int 499) 500INHERITS ( 501 some_table 502) 503PARTITION BY LIST (a); 504 505-- cannot use more than 1 column as partition key for list partitioned table 506CREATE TABLE partitioned ( 507 a1 int, 508 a2 int 509) 510PARTITION BY LIST (a1, a2); 511 512-- fail 513-- unsupported constraint type for partitioned tables 514CREATE TABLE partitioned ( 515 a int, 516 EXCLUDE USING gist (a WITH &&) 517) 518PARTITION BY RANGE (a); 519 520-- prevent using prohibited expressions in the key 521CREATE FUNCTION retset (a int) 522 RETURNS SETOF int 523 AS $$ 524 SELECT 525 1; 526 527$$ 528LANGUAGE SQL 529IMMUTABLE; 530 531CREATE TABLE partitioned ( 532 a int 533) 534PARTITION BY RANGE (retset (a)); 535 536DROP FUNCTION retset (int); 537 538CREATE TABLE partitioned ( 539 a int 540) 541PARTITION BY RANGE ((avg(a))); 542 543CREATE TABLE partitioned ( 544 a int, 545 b int 546) 547PARTITION BY RANGE ((avg(a) OVER (PARTITION BY b))); 548 549CREATE TABLE partitioned ( 550 a int 551) 552PARTITION BY LIST ((a LIKE ( 553SELECT 554 1))); 555 556CREATE TABLE partitioned ( 557 a int 558) 559PARTITION BY RANGE (('a')); 560 561CREATE FUNCTION const_func () 562 RETURNS int 563 AS $$ 564 SELECT 565 1; 566 567$$ 568LANGUAGE SQL 569IMMUTABLE; 570 571CREATE TABLE partitioned ( 572 a int 573) 574PARTITION BY RANGE (const_func ()); 575 576DROP FUNCTION const_func (); 577 578-- only accept valid partitioning strategy 579CREATE TABLE partitioned ( 580 a int 581) 582PARTITION BY MAGIC (a); 583 584-- specified column must be present in the table 585CREATE TABLE partitioned ( 586 a int 587) 588PARTITION BY RANGE (b); 589 590-- cannot use system columns in partition key 591CREATE TABLE partitioned ( 592 a int 593) 594PARTITION BY RANGE (xmin); 595 596-- functions in key must be immutable 597CREATE FUNCTION immut_func (a int) 598 RETURNS int 599 AS $$ 600 SELECT 601 a + random()::int; 602 603$$ 604LANGUAGE SQL; 605 606CREATE TABLE partitioned ( 607 a int 608) 609PARTITION BY RANGE (immut_func (a)); 610 611DROP FUNCTION immut_func (int); 612 613-- cannot contain whole-row references 614CREATE TABLE partitioned ( 615 a int 616) 617PARTITION BY RANGE ((partitioned)); 618 619-- prevent using columns of unsupported types in key (type must have a btree operator class) 620CREATE TABLE partitioned ( 621 a point 622) 623PARTITION BY LIST (a); 624 625CREATE TABLE partitioned ( 626 a point 627) 628PARTITION BY LIST (a point_ops); 629 630CREATE TABLE partitioned ( 631 a point 632) 633PARTITION BY RANGE (a); 634 635CREATE TABLE partitioned ( 636 a point 637) 638PARTITION BY RANGE (a point_ops); 639 640-- cannot add NO INHERIT constraints to partitioned tables 641CREATE TABLE partitioned ( 642 a int, 643 CONSTRAINT check_a CHECK (a > 0) NO INHERIT 644) 645PARTITION BY RANGE (a); 646 647-- some checks after successful creation of a partitioned table 648CREATE FUNCTION plusone (a int) 649 RETURNS int 650 AS $$ 651 SELECT 652 a + 1; 653 654$$ 655LANGUAGE SQL; 656 657CREATE TABLE partitioned ( 658 a int, 659 b int, 660 c text, 661 d text 662) 663PARTITION BY RANGE (a oid_ops, plusone (b), c COLLATE "default", d COLLATE "C"); 664 665-- check relkind 666SELECT 667 relkind 668FROM 669 pg_class 670WHERE 671 relname = 'partitioned'; 672 673-- prevent a function referenced in partition key from being dropped 674DROP FUNCTION plusone (int); 675 676-- partitioned table cannot participate in regular inheritance 677CREATE TABLE partitioned2 ( 678 a int, 679 b text 680) 681PARTITION BY RANGE ((a + 1), substr(b, 1, 5)); 682 683CREATE TABLE fail () 684INHERITS ( 685 partitioned2 686); 687 688-- Partition key in describe output 689\d partitioned 690\d+ partitioned2 691INSERT INTO partitioned2 692 VALUES (1, 'hello'); 693 694CREATE TABLE part2_1 PARTITION OF partitioned2 695FOR VALUES FROM (-1, 'aaaaa') TO (100, 'ccccc'); 696 697\d+ part2_1 698DROP TABLE partitioned, partitioned2; 699 700-- 701-- Partitions 702-- 703-- check partition bound syntax 704CREATE TABLE list_parted ( 705 a int 706) 707PARTITION BY LIST (a); 708 709CREATE TABLE part_p1 PARTITION OF list_parted 710FOR VALUES IN ('1'); 711 712CREATE TABLE part_p2 PARTITION OF list_parted 713FOR VALUES IN (2); 714 715CREATE TABLE part_p3 PARTITION OF list_parted 716FOR VALUES IN ((2 + 1)); 717 718CREATE TABLE part_null PARTITION OF list_parted 719FOR VALUES IN (NULL); 720 721\d+ list_parted 722-- forbidden expressions for partition bound with list partitioned table 723CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted 724FOR VALUES IN (somename); 725 726CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted 727FOR VALUES IN (somename.somename); 728 729CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted 730FOR VALUES IN (a); 731 732CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted 733FOR VALUES IN (sum(a)); 734 735CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted 736FOR VALUES IN (sum(somename)); 737 738CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted 739FOR VALUES IN (sum(1)); 740 741CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted 742FOR VALUES IN (( 743SELECT 744 1)); 745 746CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted 747FOR VALUES IN (generate_series(4, 6)); 748 749-- syntax does not allow empty list of values for list partitions 750CREATE TABLE fail_part PARTITION OF list_parted 751FOR VALUES IN (); 752 753-- trying to specify range for list partitioned table 754CREATE TABLE fail_part PARTITION OF list_parted 755FOR VALUES FROM (1) TO (2); 756 757-- trying to specify modulus and remainder for list partitioned table 758CREATE TABLE fail_part PARTITION OF list_parted 759FOR VALUES WITH (MODULUS 10, REMAINDER 1); 760 761-- check default partition cannot be created more than once 762CREATE TABLE part_default PARTITION OF list_parted DEFAULT; 763 764CREATE TABLE fail_default_part PARTITION OF list_parted DEFAULT; 765 766-- specified literal can't be cast to the partition column data type 767CREATE TABLE bools ( 768 a bool 769) 770PARTITION BY LIST (a); 771 772CREATE TABLE bools_true PARTITION OF bools 773FOR VALUES IN (1); 774 775DROP TABLE bools; 776 777-- specified literal can be cast, and the cast might not be immutable 778CREATE TABLE moneyp ( 779 a money 780) 781PARTITION BY LIST (a); 782 783CREATE TABLE moneyp_10 PARTITION OF moneyp 784FOR VALUES IN (10); 785 786CREATE TABLE moneyp_11 PARTITION OF moneyp 787FOR VALUES IN ('11'); 788 789CREATE TABLE moneyp_12 PARTITION OF moneyp 790FOR VALUES IN (to_char(12, '99')::int); 791 792DROP TABLE moneyp; 793 794-- cast is immutable 795CREATE TABLE bigintp ( 796 a bigint 797) 798PARTITION BY LIST (a); 799 800CREATE TABLE bigintp_10 PARTITION OF bigintp 801FOR VALUES IN (10); 802 803-- fails due to overlap: 804CREATE TABLE bigintp_10_2 PARTITION OF bigintp 805FOR VALUES IN ('10'); 806 807DROP TABLE bigintp; 808 809CREATE TABLE range_parted ( 810 a date 811) 812PARTITION BY RANGE (a); 813 814-- forbidden expressions for partition bounds with range partitioned table 815CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted 816FOR VALUES FROM (somename) TO ('2019-01-01'); 817 818CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted 819FOR VALUES FROM (somename.somename) TO ('2019-01-01'); 820 821CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted 822FOR VALUES FROM (a) TO ('2019-01-01'); 823 824CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted 825FOR VALUES FROM (max(a)) TO ('2019-01-01'); 826 827CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted 828FOR VALUES FROM (max(somename)) TO ('2019-01-01'); 829 830CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted 831FOR VALUES FROM (max('2019-02-01'::date)) TO ('2019-01-01'); 832 833CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted 834FOR VALUES FROM (( 835SELECT 836 1)) TO ('2019-01-01'); 837 838CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted 839FOR VALUES FROM (generate_series(1, 3)) TO ('2019-01-01'); 840 841-- trying to specify list for range partitioned table 842CREATE TABLE fail_part PARTITION OF range_parted 843FOR VALUES IN ('a'); 844 845-- trying to specify modulus and remainder for range partitioned table 846CREATE TABLE fail_part PARTITION OF range_parted 847FOR VALUES WITH (MODULUS 10, REMAINDER 1); 848 849-- each of start and end bounds must have same number of values as the 850-- length of the partition key 851CREATE TABLE fail_part PARTITION OF range_parted 852FOR VALUES FROM ('a', 1) TO ('z'); 853 854CREATE TABLE fail_part PARTITION OF range_parted 855FOR VALUES FROM ('a') TO ('z', 1); 856 857-- cannot specify null values in range bounds 858CREATE TABLE fail_part PARTITION OF range_parted 859FOR VALUES FROM (NULL) TO (MAXVALUE); 860 861-- trying to specify modulus and remainder for range partitioned table 862CREATE TABLE fail_part PARTITION OF range_parted 863FOR VALUES WITH (MODULUS 10, REMAINDER 1); 864 865-- check partition bound syntax for the hash partition 866CREATE TABLE hash_parted ( 867 a int 868) 869PARTITION BY HASH (a); 870 871CREATE TABLE hpart_1 PARTITION OF hash_parted 872FOR VALUES WITH (MODULUS 10, REMAINDER 0); 873 874CREATE TABLE hpart_2 PARTITION OF hash_parted 875FOR VALUES WITH (MODULUS 50, REMAINDER 1); 876 877CREATE TABLE hpart_3 PARTITION OF hash_parted 878FOR VALUES WITH (MODULUS 200, REMAINDER 2); 879 880-- modulus 25 is factor of modulus of 50 but 10 is not factor of 25. 881CREATE TABLE fail_part PARTITION OF hash_parted 882FOR VALUES WITH (MODULUS 25, REMAINDER 3); 883 884-- previous modulus 50 is factor of 150 but this modulus is not factor of next modulus 200. 885CREATE TABLE fail_part PARTITION OF hash_parted 886FOR VALUES WITH (MODULUS 150, REMAINDER 3); 887 888-- trying to specify range for the hash partitioned table 889CREATE TABLE fail_part PARTITION OF hash_parted 890FOR VALUES FROM ('a', 1) TO ('z'); 891 892-- trying to specify list value for the hash partitioned table 893CREATE TABLE fail_part PARTITION OF hash_parted 894FOR VALUES IN (1000); 895 896-- trying to create default partition for the hash partitioned table 897CREATE TABLE fail_default_part PARTITION OF hash_parted DEFAULT; 898 899-- check if compatible with the specified parent 900-- cannot create as partition of a non-partitioned table 901CREATE TABLE unparted ( 902 a int 903); 904 905CREATE TABLE fail_part PARTITION OF unparted 906FOR VALUES IN ('a'); 907 908CREATE TABLE fail_part PARTITION OF unparted 909FOR VALUES WITH (MODULUS 2, REMAINDER 1); 910 911DROP TABLE unparted; 912 913-- cannot create a permanent rel as partition of a temp rel 914CREATE TEMP TABLE temp_parted ( 915 a int 916) 917PARTITION BY LIST (a); 918 919CREATE TABLE fail_part PARTITION OF temp_parted 920FOR VALUES IN ('a'); 921 922DROP TABLE temp_parted; 923 924-- check for partition bound overlap and other invalid specifications 925CREATE TABLE list_parted2 ( 926 a varchar 927) 928PARTITION BY LIST (a); 929 930CREATE TABLE part_null_z PARTITION OF list_parted2 931FOR VALUES IN (NULL, 'z'); 932 933CREATE TABLE part_ab PARTITION OF list_parted2 934FOR VALUES IN ('a', 'b'); 935 936CREATE TABLE list_parted2_def PARTITION OF list_parted2 DEFAULT; 937 938CREATE TABLE fail_part PARTITION OF list_parted2 939FOR VALUES IN (NULL); 940 941CREATE TABLE fail_part PARTITION OF list_parted2 942FOR VALUES IN ('b', 'c'); 943 944-- check default partition overlap 945INSERT INTO list_parted2 946 VALUES ('X'); 947 948CREATE TABLE fail_part PARTITION OF list_parted2 949FOR VALUES IN ('W', 'X', 'Y'); 950 951CREATE TABLE range_parted2 ( 952 a int 953) 954PARTITION BY RANGE (a); 955 956-- trying to create range partition with empty range 957CREATE TABLE fail_part PARTITION OF range_parted2 958FOR VALUES FROM (1) TO (0); 959 960-- note that the range '[1, 1)' has no elements 961CREATE TABLE fail_part PARTITION OF range_parted2 962FOR VALUES FROM (1) TO (1); 963 964CREATE TABLE part0 PARTITION OF range_parted2 965FOR VALUES FROM (MINVALUE) TO (1); 966 967CREATE TABLE fail_part PARTITION OF range_parted2 968FOR VALUES FROM (MINVALUE) TO (2); 969 970CREATE TABLE part1 PARTITION OF range_parted2 971FOR VALUES FROM (1) TO (10); 972 973CREATE TABLE fail_part PARTITION OF range_parted2 974FOR VALUES FROM (9) TO (MAXVALUE); 975 976CREATE TABLE part2 PARTITION OF range_parted2 977FOR VALUES FROM (20) TO (30); 978 979CREATE TABLE part3 PARTITION OF range_parted2 980FOR VALUES FROM (30) TO (40); 981 982CREATE TABLE fail_part PARTITION OF range_parted2 983FOR VALUES FROM (10) TO (30); 984 985CREATE TABLE fail_part PARTITION OF range_parted2 986FOR VALUES FROM (10) TO (50); 987 988-- Create a default partition for range partitioned table 989CREATE TABLE range2_default PARTITION OF range_parted2 DEFAULT; 990 991-- More than one default partition is not allowed, so this should give error 992CREATE TABLE fail_default_part PARTITION OF range_parted2 DEFAULT; 993 994-- Check if the range for default partitions overlap 995INSERT INTO range_parted2 996 VALUES (85); 997 998CREATE TABLE fail_part PARTITION OF range_parted2 999FOR VALUES FROM (80) TO (90); 1000 1001CREATE TABLE part4 PARTITION OF range_parted2 1002FOR VALUES FROM (90) TO (100); 1003 1004-- now check for multi-column range partition key 1005CREATE TABLE range_parted3 ( 1006 a int, 1007 b int 1008) 1009PARTITION BY RANGE (a, (b + 1)); 1010 1011CREATE TABLE part00 PARTITION OF range_parted3 1012FOR VALUES FROM (0, 1013MINVALUE) TO (0, 1014MAXVALUE); 1015 1016CREATE TABLE fail_part PARTITION OF range_parted3 1017FOR VALUES FROM (0, 1018MINVALUE) TO (0, 1); 1019 1020CREATE TABLE part10 PARTITION OF range_parted3 1021FOR VALUES FROM (1, 1022MINVALUE) TO (1, 1); 1023 1024CREATE TABLE part11 PARTITION OF range_parted3 1025FOR VALUES FROM (1, 1) TO (1, 10); 1026 1027CREATE TABLE part12 PARTITION OF range_parted3 1028FOR VALUES FROM (1, 10) TO (1, 1029MAXVALUE); 1030 1031CREATE TABLE fail_part PARTITION OF range_parted3 1032FOR VALUES FROM (1, 10) TO (1, 20); 1033 1034CREATE TABLE range3_default PARTITION OF range_parted3 DEFAULT; 1035 1036-- cannot create a partition that says column b is allowed to range 1037-- from -infinity to +infinity, while there exist partitions that have 1038-- more specific ranges 1039CREATE TABLE fail_part PARTITION OF range_parted3 1040FOR VALUES FROM (1, 1041MINVALUE) TO (1, 1042MAXVALUE); 1043 1044-- check for partition bound overlap and other invalid specifications for the hash partition 1045CREATE TABLE hash_parted2 ( 1046 a varchar 1047) 1048PARTITION BY HASH (a); 1049 1050CREATE TABLE h2part_1 PARTITION OF hash_parted2 1051FOR VALUES WITH (MODULUS 4, REMAINDER 2); 1052 1053CREATE TABLE h2part_2 PARTITION OF hash_parted2 1054FOR VALUES WITH (MODULUS 8, REMAINDER 0); 1055 1056CREATE TABLE h2part_3 PARTITION OF hash_parted2 1057FOR VALUES WITH (MODULUS 8, REMAINDER 4); 1058 1059CREATE TABLE h2part_4 PARTITION OF hash_parted2 1060FOR VALUES WITH (MODULUS 8, REMAINDER 5); 1061 1062-- overlap with part_4 1063CREATE TABLE fail_part PARTITION OF hash_parted2 1064FOR VALUES WITH (MODULUS 2, REMAINDER 1); 1065 1066-- modulus must be greater than zero 1067CREATE TABLE fail_part PARTITION OF hash_parted2 1068FOR VALUES WITH (MODULUS 0, REMAINDER 1); 1069 1070-- remainder must be greater than or equal to zero and less than modulus 1071CREATE TABLE fail_part PARTITION OF hash_parted2 1072FOR VALUES WITH (MODULUS 8, REMAINDER 8); 1073 1074-- check schema propagation from parent 1075CREATE TABLE parted ( 1076 a text, 1077 b int NOT NULL DEFAULT 0, 1078 CONSTRAINT check_a CHECK (length(a) > 0) 1079) 1080PARTITION BY LIST (a); 1081 1082CREATE TABLE part_a PARTITION OF parted 1083FOR VALUES IN ('a'); 1084 1085-- only inherited attributes (never local ones) 1086SELECT 1087 attname, 1088 attislocal, 1089 attinhcount 1090FROM 1091 pg_attribute 1092WHERE 1093 attrelid = 'part_a'::regclass 1094 AND attnum > 0 1095ORDER BY 1096 attnum; 1097 1098-- able to specify column default, column constraint, and table constraint 1099-- first check the "column specified more than once" error 1100CREATE TABLE part_b PARTITION OF parted (b NOT NULL, b DEFAULT 1, b CHECK (b >= 0), CONSTRAINT check_a CHECK (length(a) > 0)) 1101FOR VALUES IN ('b'); 1102 1103CREATE TABLE part_b PARTITION OF parted (b NOT NULL DEFAULT 1, CONSTRAINT check_a CHECK (length(a) > 0), CONSTRAINT check_b CHECK (b >= 0)) 1104FOR VALUES IN ('b'); 1105 1106-- conislocal should be false for any merged constraints, true otherwise 1107SELECT 1108 conislocal, 1109 coninhcount 1110FROM 1111 pg_constraint 1112WHERE 1113 conrelid = 'part_b'::regclass 1114ORDER BY 1115 conislocal, 1116 coninhcount; 1117 1118-- Once check_b is added to the parent, it should be made non-local for part_b 1119ALTER TABLE parted 1120 ADD CONSTRAINT check_b CHECK (b >= 0); 1121 1122SELECT 1123 conislocal, 1124 coninhcount 1125FROM 1126 pg_constraint 1127WHERE 1128 conrelid = 'part_b'::regclass; 1129 1130-- Neither check_a nor check_b are droppable from part_b 1131ALTER TABLE part_b 1132 DROP CONSTRAINT check_a; 1133 1134ALTER TABLE part_b 1135 DROP CONSTRAINT check_b; 1136 1137-- And dropping it from parted should leave no trace of them on part_b, unlike 1138-- traditional inheritance where they will be left behind, because they would 1139-- be local constraints. 1140ALTER TABLE parted 1141 DROP CONSTRAINT check_a, 1142 DROP CONSTRAINT check_b; 1143 1144SELECT 1145 conislocal, 1146 coninhcount 1147FROM 1148 pg_constraint 1149WHERE 1150 conrelid = 'part_b'::regclass; 1151 1152-- specify PARTITION BY for a partition 1153CREATE TABLE fail_part_col_not_found PARTITION OF parted 1154FOR VALUES IN ('c') 1155PARTITION BY RANGE (c); 1156 1157CREATE TABLE part_c PARTITION OF parted (b WITH OPTIONS NOT NULL DEFAULT 0) 1158FOR VALUES IN ('c') 1159PARTITION BY RANGE ((b)); 1160 1161-- create a level-2 partition 1162CREATE TABLE part_c_1_10 PARTITION OF part_c 1163FOR VALUES FROM (1) TO (10); 1164 1165-- check that NOT NULL and default value are inherited correctly 1166CREATE TABLE parted_notnull_inh_test ( 1167 a int DEFAULT 1, 1168 b int NOT NULL DEFAULT 0 1169) 1170PARTITION BY LIST (a); 1171 1172CREATE TABLE parted_notnull_inh_test1 PARTITION OF parted_notnull_inh_test (a NOT NULL, b DEFAULT 1) 1173FOR VALUES IN (1); 1174 1175INSERT INTO parted_notnull_inh_test (b) 1176 VALUES (NULL); 1177 1178-- note that while b's default is overriden, a's default is preserved 1179\d parted_notnull_inh_test1 1180DROP TABLE parted_notnull_inh_test; 1181 1182-- check for a conflicting COLLATE clause 1183CREATE TABLE parted_collate_must_match ( 1184 a text COLLATE "C", 1185 b text COLLATE "C" 1186) 1187PARTITION BY RANGE (a); 1188 1189-- on the partition key 1190CREATE TABLE parted_collate_must_match1 PARTITION OF parted_collate_must_match (a COLLATE "POSIX") 1191FOR VALUES FROM ('a') TO ('m'); 1192 1193-- on another column 1194CREATE TABLE parted_collate_must_match2 PARTITION OF parted_collate_must_match (b COLLATE "POSIX") 1195FOR VALUES FROM ('m') TO ('z'); 1196 1197DROP TABLE parted_collate_must_match; 1198 1199-- check that specifying incompatible collations for partition bound 1200-- expressions fails promptly 1201CREATE TABLE test_part_coll_posix ( 1202 a text 1203) 1204PARTITION BY RANGE (a COLLATE "POSIX"); 1205 1206-- fail 1207CREATE TABLE test_part_coll PARTITION OF test_part_coll_posix 1208FOR VALUES FROM ('a' COLLATE "C") TO ('g'); 1209 1210-- ok 1211CREATE TABLE test_part_coll PARTITION OF test_part_coll_posix 1212FOR VALUES FROM ('a' COLLATE "POSIX") TO ('g'); 1213 1214-- ok 1215CREATE TABLE test_part_coll2 PARTITION OF test_part_coll_posix 1216FOR VALUES FROM ('g') TO ('m'); 1217 1218-- using a cast expression uses the target type's default collation 1219-- fail 1220CREATE TABLE test_part_coll_cast PARTITION OF test_part_coll_posix 1221FOR VALUES FROM (name 'm' COLLATE "C") TO ('s'); 1222 1223-- ok 1224CREATE TABLE test_part_coll_cast PARTITION OF test_part_coll_posix 1225FOR VALUES FROM (name 'm' COLLATE "POSIX") TO ('s'); 1226 1227-- ok; partition collation silently overrides the default collation of type 'name' 1228CREATE TABLE test_part_coll_cast2 PARTITION OF test_part_coll_posix 1229FOR VALUES FROM (name 's') TO ('z'); 1230 1231DROP TABLE test_part_coll_posix; 1232 1233-- Partition bound in describe output 1234\d+ part_b 1235-- Both partition bound and partition key in describe output 1236\d+ part_c 1237-- a level-2 partition's constraint will include the parent's expressions 1238\d+ part_c_1_10 1239-- Show partition count in the parent's describe output 1240-- Tempted to include \d+ output listing partitions with bound info but 1241-- output could vary depending on the order in which partition oids are 1242-- returned. 1243\d parted 1244\d hash_parted 1245-- check that we get the expected partition constraints 1246CREATE TABLE range_parted4 ( 1247 a int, 1248 b int, 1249 c int 1250) 1251PARTITION BY RANGE (abs(a), abs(b), c); 1252 1253CREATE TABLE unbounded_range_part PARTITION OF range_parted4 1254FOR VALUES FROM (MINVALUE, 1255MINVALUE, 1256MINVALUE) TO (MAXVALUE, 1257MAXVALUE, 1258MAXVALUE); 1259 1260\d+ unbounded_range_part 1261DROP TABLE unbounded_range_part; 1262 1263CREATE TABLE range_parted4_1 PARTITION OF range_parted4 1264FOR VALUES FROM (MINVALUE, 1265MINVALUE, 1266MINVALUE) TO (1, 1267MAXVALUE, 1268MAXVALUE); 1269 1270\d+ range_parted4_1 1271CREATE TABLE range_parted4_2 PARTITION OF range_parted4 1272FOR VALUES FROM (3, 4, 5) TO (6, 7, 1273MAXVALUE); 1274 1275\d+ range_parted4_2 1276CREATE TABLE range_parted4_3 PARTITION OF range_parted4 1277FOR VALUES FROM (6, 8, 1278MINVALUE) TO (9, 1279MAXVALUE, 1280MAXVALUE); 1281 1282\d+ range_parted4_3 1283DROP TABLE range_parted4; 1284 1285-- user-defined operator class in partition key 1286CREATE FUNCTION my_int4_sort (int4, int4) 1287 RETURNS int 1288 LANGUAGE sql 1289 AS $$ 1290 SELECT 1291 CASE WHEN $1 = $2 THEN 1292 0 1293 WHEN $1 > $2 THEN 1294 1 1295 ELSE 1296 -1 1297 END; 1298 1299$$; 1300 1301CREATE OPERATOR CLASS test_int4_ops FOR TYPE int4 1302 USING btree AS 1303 OPERATOR 1 < (int4, int4), 1304 OPERATOR 2 <= (int4, int4), 1305 OPERATOR 3 = (int4, int4), 1306 OPERATOR 4 >= (int4, int4), 1307 OPERATOR 5 > (int4, int4), 1308 FUNCTION 1 my_int4_sort (int4, int4 1309); 1310 1311CREATE TABLE partkey_t ( 1312 a int4 1313) 1314PARTITION BY RANGE (a test_int4_ops); 1315 1316CREATE TABLE partkey_t_1 PARTITION OF partkey_t 1317FOR VALUES FROM (0) TO (1000); 1318 1319INSERT INTO partkey_t 1320 VALUES (100); 1321 1322INSERT INTO partkey_t 1323 VALUES (200); 1324 1325-- cleanup 1326DROP TABLE parted, list_parted, range_parted, list_parted2, range_parted2, range_parted3; 1327 1328DROP TABLE partkey_t, hash_parted, hash_parted2; 1329 1330DROP OPERATOR CLASS test_int4_ops 1331 USING btree; 1332 1333DROP FUNCTION my_int4_sort (int4, int4); 1334 1335-- comments on partitioned tables columns 1336CREATE TABLE parted_col_comment ( 1337 a int, 1338 b text 1339) 1340PARTITION BY LIST (a); 1341 1342COMMENT ON TABLE parted_col_comment IS 'Am partitioned table'; 1343 1344COMMENT ON COLUMN parted_col_comment.a IS 'Partition key'; 1345 1346SELECT 1347 obj_description('parted_col_comment'::regclass); 1348 1349\d+ parted_col_comment 1350DROP TABLE parted_col_comment; 1351 1352-- list partitioning on array type column 1353CREATE TABLE arrlp ( 1354 a int[] 1355) 1356PARTITION BY LIST (a); 1357 1358CREATE TABLE arrlp12 PARTITION OF arrlp 1359FOR VALUES IN ('{1}', '{2}'); 1360 1361\d+ arrlp12 1362DROP TABLE arrlp; 1363 1364-- partition on boolean column 1365CREATE TABLE boolspart ( 1366 a bool 1367) 1368PARTITION BY LIST (a); 1369 1370CREATE TABLE boolspart_t PARTITION OF boolspart 1371FOR VALUES IN (TRUE); 1372 1373CREATE TABLE boolspart_f PARTITION OF boolspart 1374FOR VALUES IN (FALSE); 1375 1376\d+ boolspart 1377DROP TABLE boolspart; 1378 1379-- partitions mixing temporary and permanent relations 1380CREATE TABLE perm_parted ( 1381 a int 1382) 1383PARTITION BY LIST (a); 1384 1385CREATE TEMPORARY TABLE temp_parted ( 1386 a int 1387) 1388PARTITION BY LIST (a); 1389 1390CREATE TABLE perm_part PARTITION OF temp_parted DEFAULT; 1391 1392-- error 1393CREATE temp TABLE temp_part PARTITION OF perm_parted DEFAULT; 1394 1395-- error 1396CREATE temp TABLE temp_part PARTITION OF temp_parted DEFAULT; 1397 1398-- ok 1399DROP TABLE perm_parted CASCADE; 1400 1401DROP TABLE temp_parted CASCADE; 1402 1403-- check that adding partitions to a table while it is being used is prevented 1404CREATE TABLE tab_part_create ( 1405 a int 1406) 1407PARTITION BY LIST (a); 1408 1409CREATE OR REPLACE FUNCTION func_part_create () 1410 RETURNS TRIGGER 1411 LANGUAGE plpgsql 1412 AS $$ 1413BEGIN 1414 EXECUTE 'create table tab_part_create_1 partition of tab_part_create for values in (1)'; 1415 RETURN NULL; 1416END 1417$$; 1418 1419CREATE TRIGGER trig_part_create 1420 BEFORE INSERT ON tab_part_create FOR EACH statement 1421 EXECUTE PROCEDURE func_part_create (); 1422 1423INSERT INTO tab_part_create 1424 VALUES (1); 1425 1426DROP TABLE tab_part_create; 1427 1428DROP FUNCTION func_part_create (); 1429 1430-- test using a volatile expression as partition bound 1431CREATE TABLE volatile_partbound_test ( 1432 partkey timestamp 1433) 1434PARTITION BY RANGE (partkey); 1435 1436CREATE TABLE volatile_partbound_test1 PARTITION OF volatile_partbound_test 1437FOR VALUES FROM (MINVALUE) TO (CURRENT_TIMESTAMP); 1438 1439CREATE TABLE volatile_partbound_test2 PARTITION OF volatile_partbound_test 1440FOR VALUES FROM (CURRENT_TIMESTAMP) TO (MAXVALUE); 1441 1442-- this should go into the partition volatile_partbound_test2 1443INSERT INTO volatile_partbound_test 1444 VALUES (CURRENT_TIMESTAMP); 1445 1446SELECT 1447 tableoid::regclass 1448FROM 1449 volatile_partbound_test; 1450 1451DROP TABLE volatile_partbound_test; 1452 1453