1-- 2-- Test inheritance features 3-- 4CREATE TABLE a ( 5 aa text 6); 7 8CREATE TABLE b ( 9 bb text 10) 11INHERITS ( 12 a 13); 14 15CREATE TABLE c ( 16 cc text 17) 18INHERITS ( 19 a 20); 21 22CREATE TABLE d ( 23 dd text 24) 25INHERITS ( 26 b, 27 c, 28 a 29); 30 31INSERT INTO a (aa) 32 VALUES ('aaa'); 33 34INSERT INTO a (aa) 35 VALUES ('aaaa'); 36 37INSERT INTO a (aa) 38 VALUES ('aaaaa'); 39 40INSERT INTO a (aa) 41 VALUES ('aaaaaa'); 42 43INSERT INTO a (aa) 44 VALUES ('aaaaaaa'); 45 46INSERT INTO a (aa) 47 VALUES ('aaaaaaaa'); 48 49INSERT INTO b (aa) 50 VALUES ('bbb'); 51 52INSERT INTO b (aa) 53 VALUES ('bbbb'); 54 55INSERT INTO b (aa) 56 VALUES ('bbbbb'); 57 58INSERT INTO b (aa) 59 VALUES ('bbbbbb'); 60 61INSERT INTO b (aa) 62 VALUES ('bbbbbbb'); 63 64INSERT INTO b (aa) 65 VALUES ('bbbbbbbb'); 66 67INSERT INTO c (aa) 68 VALUES ('ccc'); 69 70INSERT INTO c (aa) 71 VALUES ('cccc'); 72 73INSERT INTO c (aa) 74 VALUES ('ccccc'); 75 76INSERT INTO c (aa) 77 VALUES ('cccccc'); 78 79INSERT INTO c (aa) 80 VALUES ('ccccccc'); 81 82INSERT INTO c (aa) 83 VALUES ('cccccccc'); 84 85INSERT INTO d (aa) 86 VALUES ('ddd'); 87 88INSERT INTO d (aa) 89 VALUES ('dddd'); 90 91INSERT INTO d (aa) 92 VALUES ('ddddd'); 93 94INSERT INTO d (aa) 95 VALUES ('dddddd'); 96 97INSERT INTO d (aa) 98 VALUES ('ddddddd'); 99 100INSERT INTO d (aa) 101 VALUES ('dddddddd'); 102 103SELECT 104 relname, 105 a.* 106FROM 107 a, 108 pg_class 109WHERE 110 a.tableoid = pg_class.oid; 111 112SELECT 113 relname, 114 b.* 115FROM 116 b, 117 pg_class 118WHERE 119 b.tableoid = pg_class.oid; 120 121SELECT 122 relname, 123 c.* 124FROM 125 c, 126 pg_class 127WHERE 128 c.tableoid = pg_class.oid; 129 130SELECT 131 relname, 132 d.* 133FROM 134 d, 135 pg_class 136WHERE 137 d.tableoid = pg_class.oid; 138 139SELECT 140 relname, 141 a.* 142FROM 143 ONLY a, 144 pg_class 145WHERE 146 a.tableoid = pg_class.oid; 147 148SELECT 149 relname, 150 b.* 151FROM 152 ONLY b, 153 pg_class 154WHERE 155 b.tableoid = pg_class.oid; 156 157SELECT 158 relname, 159 c.* 160FROM 161 ONLY c, 162 pg_class 163WHERE 164 c.tableoid = pg_class.oid; 165 166SELECT 167 relname, 168 d.* 169FROM 170 ONLY d, 171 pg_class 172WHERE 173 d.tableoid = pg_class.oid; 174 175UPDATE 176 a 177SET 178 aa = 'zzzz' 179WHERE 180 aa = 'aaaa'; 181 182UPDATE 183 ONLY a 184SET 185 aa = 'zzzzz' 186WHERE 187 aa = 'aaaaa'; 188 189UPDATE 190 b 191SET 192 aa = 'zzz' 193WHERE 194 aa = 'aaa'; 195 196UPDATE 197 ONLY b 198SET 199 aa = 'zzz' 200WHERE 201 aa = 'aaa'; 202 203UPDATE 204 a 205SET 206 aa = 'zzzzzz' 207WHERE 208 aa LIKE 'aaa%'; 209 210SELECT 211 relname, 212 a.* 213FROM 214 a, 215 pg_class 216WHERE 217 a.tableoid = pg_class.oid; 218 219SELECT 220 relname, 221 b.* 222FROM 223 b, 224 pg_class 225WHERE 226 b.tableoid = pg_class.oid; 227 228SELECT 229 relname, 230 c.* 231FROM 232 c, 233 pg_class 234WHERE 235 c.tableoid = pg_class.oid; 236 237SELECT 238 relname, 239 d.* 240FROM 241 d, 242 pg_class 243WHERE 244 d.tableoid = pg_class.oid; 245 246SELECT 247 relname, 248 a.* 249FROM 250 ONLY a, 251 pg_class 252WHERE 253 a.tableoid = pg_class.oid; 254 255SELECT 256 relname, 257 b.* 258FROM 259 ONLY b, 260 pg_class 261WHERE 262 b.tableoid = pg_class.oid; 263 264SELECT 265 relname, 266 c.* 267FROM 268 ONLY c, 269 pg_class 270WHERE 271 c.tableoid = pg_class.oid; 272 273SELECT 274 relname, 275 d.* 276FROM 277 ONLY d, 278 pg_class 279WHERE 280 d.tableoid = pg_class.oid; 281 282UPDATE 283 b 284SET 285 aa = 'new'; 286 287SELECT 288 relname, 289 a.* 290FROM 291 a, 292 pg_class 293WHERE 294 a.tableoid = pg_class.oid; 295 296SELECT 297 relname, 298 b.* 299FROM 300 b, 301 pg_class 302WHERE 303 b.tableoid = pg_class.oid; 304 305SELECT 306 relname, 307 c.* 308FROM 309 c, 310 pg_class 311WHERE 312 c.tableoid = pg_class.oid; 313 314SELECT 315 relname, 316 d.* 317FROM 318 d, 319 pg_class 320WHERE 321 d.tableoid = pg_class.oid; 322 323SELECT 324 relname, 325 a.* 326FROM 327 ONLY a, 328 pg_class 329WHERE 330 a.tableoid = pg_class.oid; 331 332SELECT 333 relname, 334 b.* 335FROM 336 ONLY b, 337 pg_class 338WHERE 339 b.tableoid = pg_class.oid; 340 341SELECT 342 relname, 343 c.* 344FROM 345 ONLY c, 346 pg_class 347WHERE 348 c.tableoid = pg_class.oid; 349 350SELECT 351 relname, 352 d.* 353FROM 354 ONLY d, 355 pg_class 356WHERE 357 d.tableoid = pg_class.oid; 358 359UPDATE 360 a 361SET 362 aa = 'new'; 363 364DELETE FROM ONLY c 365WHERE aa = 'new'; 366 367SELECT 368 relname, 369 a.* 370FROM 371 a, 372 pg_class 373WHERE 374 a.tableoid = pg_class.oid; 375 376SELECT 377 relname, 378 b.* 379FROM 380 b, 381 pg_class 382WHERE 383 b.tableoid = pg_class.oid; 384 385SELECT 386 relname, 387 c.* 388FROM 389 c, 390 pg_class 391WHERE 392 c.tableoid = pg_class.oid; 393 394SELECT 395 relname, 396 d.* 397FROM 398 d, 399 pg_class 400WHERE 401 d.tableoid = pg_class.oid; 402 403SELECT 404 relname, 405 a.* 406FROM 407 ONLY a, 408 pg_class 409WHERE 410 a.tableoid = pg_class.oid; 411 412SELECT 413 relname, 414 b.* 415FROM 416 ONLY b, 417 pg_class 418WHERE 419 b.tableoid = pg_class.oid; 420 421SELECT 422 relname, 423 c.* 424FROM 425 ONLY c, 426 pg_class 427WHERE 428 c.tableoid = pg_class.oid; 429 430SELECT 431 relname, 432 d.* 433FROM 434 ONLY d, 435 pg_class 436WHERE 437 d.tableoid = pg_class.oid; 438 439DELETE FROM a; 440 441SELECT 442 relname, 443 a.* 444FROM 445 a, 446 pg_class 447WHERE 448 a.tableoid = pg_class.oid; 449 450SELECT 451 relname, 452 b.* 453FROM 454 b, 455 pg_class 456WHERE 457 b.tableoid = pg_class.oid; 458 459SELECT 460 relname, 461 c.* 462FROM 463 c, 464 pg_class 465WHERE 466 c.tableoid = pg_class.oid; 467 468SELECT 469 relname, 470 d.* 471FROM 472 d, 473 pg_class 474WHERE 475 d.tableoid = pg_class.oid; 476 477SELECT 478 relname, 479 a.* 480FROM 481 ONLY a, 482 pg_class 483WHERE 484 a.tableoid = pg_class.oid; 485 486SELECT 487 relname, 488 b.* 489FROM 490 ONLY b, 491 pg_class 492WHERE 493 b.tableoid = pg_class.oid; 494 495SELECT 496 relname, 497 c.* 498FROM 499 ONLY c, 500 pg_class 501WHERE 502 c.tableoid = pg_class.oid; 503 504SELECT 505 relname, 506 d.* 507FROM 508 ONLY d, 509 pg_class 510WHERE 511 d.tableoid = pg_class.oid; 512 513-- Confirm PRIMARY KEY adds NOT NULL constraint to child table 514CREATE TEMP TABLE z ( 515 b text, 516 PRIMARY KEY (aa, b) 517) 518INHERITS ( 519 a 520); 521 522INSERT INTO z 523 VALUES (NULL, 'text'); 524 525-- should fail 526-- Check inherited UPDATE with all children excluded 527CREATE TABLE some_tab ( 528 a int, 529 b int 530); 531 532CREATE TABLE some_tab_child () 533INHERITS ( 534 some_tab 535); 536 537INSERT INTO some_tab_child 538 VALUES (1, 2); 539 540EXPLAIN ( 541 VERBOSE, 542 COSTS OFF 543) UPDATE 544 some_tab 545SET 546 a = a + 1 547WHERE 548 FALSE; 549 550UPDATE 551 some_tab 552SET 553 a = a + 1 554WHERE 555 FALSE; 556 557EXPLAIN ( 558 VERBOSE, 559 COSTS OFF 560) UPDATE 561 some_tab 562SET 563 a = a + 1 564WHERE 565 FALSE 566RETURNING 567 b, 568 a; 569 570UPDATE 571 some_tab 572SET 573 a = a + 1 574WHERE 575 FALSE 576RETURNING 577 b, 578 a; 579 580TABLE some_tab; 581 582DROP TABLE some_tab CASCADE; 583 584-- Check UPDATE with inherited target and an inherited source table 585CREATE temp TABLE foo ( 586 f1 int, 587 f2 int 588); 589 590CREATE temp TABLE foo2 ( 591 f3 int 592) 593INHERITS ( 594 foo 595); 596 597CREATE temp TABLE bar ( 598 f1 int, 599 f2 int 600); 601 602CREATE temp TABLE bar2 ( 603 f3 int 604) 605INHERITS ( 606 bar 607); 608 609INSERT INTO foo 610 VALUES (1, 1); 611 612INSERT INTO foo 613 VALUES (3, 3); 614 615INSERT INTO foo2 616 VALUES (2, 2, 2); 617 618INSERT INTO foo2 619 VALUES (3, 3, 3); 620 621INSERT INTO bar 622 VALUES (1, 1); 623 624INSERT INTO bar 625 VALUES (2, 2); 626 627INSERT INTO bar 628 VALUES (3, 3); 629 630INSERT INTO bar 631 VALUES (4, 4); 632 633INSERT INTO bar2 634 VALUES (1, 1, 1); 635 636INSERT INTO bar2 637 VALUES (2, 2, 2); 638 639INSERT INTO bar2 640 VALUES (3, 3, 3); 641 642INSERT INTO bar2 643 VALUES (4, 4, 4); 644 645UPDATE 646 bar 647SET 648 f2 = f2 + 100 649WHERE 650 f1 IN ( 651 SELECT 652 f1 653 FROM 654 foo); 655 656SELECT 657 tableoid::regclass::text AS relname, 658 bar.* 659FROM 660 bar 661ORDER BY 662 1, 663 2; 664 665-- Check UPDATE with inherited target and an appendrel subquery 666UPDATE 667 bar 668SET 669 f2 = f2 + 100 670FROM ( 671 SELECT 672 f1 673 FROM 674 foo 675 UNION ALL 676 SELECT 677 f1 + 3 678 FROM 679 foo) ss 680WHERE 681 bar.f1 = ss.f1; 682 683SELECT 684 tableoid::regclass::text AS relname, 685 bar.* 686FROM 687 bar 688ORDER BY 689 1, 690 2; 691 692-- Check UPDATE with *partitioned* inherited target and an appendrel subquery 693CREATE TABLE some_tab ( 694 a int 695); 696 697INSERT INTO some_tab 698 VALUES (0); 699 700CREATE TABLE some_tab_child () 701INHERITS ( 702 some_tab 703); 704 705INSERT INTO some_tab_child 706 VALUES (1); 707 708CREATE TABLE parted_tab ( 709 a int, 710 b char 711) 712PARTITION BY LIST (a); 713 714CREATE TABLE parted_tab_part1 PARTITION OF parted_tab 715FOR VALUES IN (1); 716 717CREATE TABLE parted_tab_part2 PARTITION OF parted_tab 718FOR VALUES IN (2); 719 720CREATE TABLE parted_tab_part3 PARTITION OF parted_tab 721FOR VALUES IN (3); 722 723INSERT INTO parted_tab 724 VALUES (1, 'a'), (2, 'a'), (3, 'a'); 725 726UPDATE 727 parted_tab 728SET 729 b = 'b' 730FROM ( 731 SELECT 732 a 733 FROM 734 some_tab 735 UNION ALL 736 SELECT 737 a + 1 738 FROM 739 some_tab) ss (a) 740WHERE 741 parted_tab.a = ss.a; 742 743SELECT 744 tableoid::regclass::text AS relname, 745 parted_tab.* 746FROM 747 parted_tab 748ORDER BY 749 1, 750 2; 751 752TRUNCATE parted_tab; 753 754INSERT INTO parted_tab 755 VALUES (1, 'a'), (2, 'a'), (3, 'a'); 756 757UPDATE 758 parted_tab 759SET 760 b = 'b' 761FROM ( 762 SELECT 763 0 764 FROM 765 parted_tab 766 UNION ALL 767 SELECT 768 1 769 FROM 770 parted_tab) ss (a) 771WHERE 772 parted_tab.a = ss.a; 773 774SELECT 775 tableoid::regclass::text AS relname, 776 parted_tab.* 777FROM 778 parted_tab 779ORDER BY 780 1, 781 2; 782 783-- modifies partition key, but no rows will actually be updated 784EXPLAIN UPDATE 785 parted_tab 786SET 787 a = 2 788WHERE 789 FALSE; 790 791DROP TABLE parted_tab; 792 793-- Check UPDATE with multi-level partitioned inherited target 794CREATE TABLE mlparted_tab ( 795 a int, 796 b char, 797 c text 798) 799PARTITION BY LIST (a); 800 801CREATE TABLE mlparted_tab_part1 PARTITION OF mlparted_tab 802FOR VALUES IN (1); 803 804CREATE TABLE mlparted_tab_part2 PARTITION OF mlparted_tab 805FOR VALUES IN (2) 806PARTITION BY LIST (b); 807 808CREATE TABLE mlparted_tab_part3 PARTITION OF mlparted_tab 809FOR VALUES IN (3); 810 811CREATE TABLE mlparted_tab_part2a PARTITION OF mlparted_tab_part2 812FOR VALUES IN ('a'); 813 814CREATE TABLE mlparted_tab_part2b PARTITION OF mlparted_tab_part2 815FOR VALUES IN ('b'); 816 817INSERT INTO mlparted_tab 818 VALUES (1, 'a'), (2, 'a'), (2, 'b'), (3, 'a'); 819 820UPDATE 821 mlparted_tab mlp 822SET 823 c = 'xxx' 824FROM ( 825 SELECT 826 a 827 FROM 828 some_tab 829 UNION ALL 830 SELECT 831 a + 1 832 FROM 833 some_tab) ss (a) 834WHERE (mlp.a = ss.a 835 AND mlp.b = 'b') 836 OR mlp.a = 3; 837 838SELECT 839 tableoid::regclass::text AS relname, 840 mlparted_tab.* 841FROM 842 mlparted_tab 843ORDER BY 844 1, 845 2; 846 847DROP TABLE mlparted_tab; 848 849DROP TABLE some_tab CASCADE; 850 851 852/* Test multiple inheritance of column defaults */ 853CREATE TABLE firstparent ( 854 tomorrow date DEFAULT now() ::date + 1 855); 856 857CREATE TABLE secondparent ( 858 tomorrow date DEFAULT now() ::date + 1 859); 860 861CREATE TABLE jointchild () 862INHERITS ( 863 firstparent, 864 secondparent 865); 866 867-- ok 868CREATE TABLE thirdparent ( 869 tomorrow date DEFAULT now() ::date - 1 870); 871 872CREATE TABLE otherchild () 873INHERITS ( 874 firstparent, 875 thirdparent 876); 877 878-- not ok 879CREATE TABLE otherchild ( 880 tomorrow date DEFAULT now() 881) 882INHERITS ( 883 firstparent, 884 thirdparent 885); 886 887-- ok, child resolves ambiguous default 888DROP TABLE firstparent, secondparent, jointchild, thirdparent, otherchild; 889 890-- Test changing the type of inherited columns 891INSERT INTO d 892 VALUES ('test', 'one', 'two', 'three'); 893 894ALTER TABLE a 895 ALTER COLUMN aa TYPE integer 896 USING bit_length(aa); 897 898SELECT 899 * 900FROM 901 d; 902 903-- Test non-inheritable parent constraints 904CREATE TABLE p1 ( 905 ff1 int 906); 907 908ALTER TABLE p1 909 ADD CONSTRAINT p1chk CHECK (ff1 > 0) NO inherit; 910 911ALTER TABLE p1 912 ADD CONSTRAINT p2chk CHECK (ff1 > 10); 913 914-- connoinherit should be true for NO INHERIT constraint 915SELECT 916 pc.relname, 917 pgc.conname, 918 pgc.contype, 919 pgc.conislocal, 920 pgc.coninhcount, 921 pgc.connoinherit 922FROM 923 pg_class AS pc 924 INNER JOIN pg_constraint AS pgc ON (pgc.conrelid = pc.oid) 925WHERE 926 pc.relname = 'p1' 927ORDER BY 928 1, 929 2; 930 931-- Test that child does not inherit NO INHERIT constraints 932CREATE TABLE c1 () 933INHERITS ( 934 p1 935); 936 937\d p1 938\d c1 939-- Test that child does not override inheritable constraints of the parent 940CREATE TABLE c2 ( 941 CONSTRAINT p2chk CHECK (ff1 > 10) NO inherit 942) 943INHERITS ( 944 p1 945); 946 947--fails 948DROP TABLE p1 CASCADE; 949 950-- Tests for casting between the rowtypes of parent and child 951-- tables. See the pgsql-hackers thread beginning Dec. 4/04 952CREATE TABLE base ( 953 i integer 954); 955 956CREATE TABLE derived () 957INHERITS ( 958 base 959); 960 961CREATE TABLE more_derived ( 962 LIKE derived, 963 b int 964) 965INHERITS ( 966 derived 967); 968 969INSERT INTO derived (i) 970 VALUES (0); 971 972SELECT 973 derived::base 974FROM 975 derived; 976 977SELECT 978 NULL::derived::base; 979 980-- remove redundant conversions. 981EXPLAIN ( 982 VERBOSE ON, 983 COSTS OFF 984) 985SELECT 986 ROW (i, 987 b)::more_derived::derived::base 988FROM 989 more_derived; 990 991EXPLAIN ( 992 VERBOSE ON, 993 COSTS OFF 994) 995SELECT 996 (1, 997 2)::more_derived::derived::base; 998 999DROP TABLE more_derived; 1000 1001DROP TABLE derived; 1002 1003DROP TABLE base; 1004 1005CREATE TABLE p1 ( 1006 ff1 int 1007); 1008 1009CREATE TABLE p2 ( 1010 f1 text 1011); 1012 1013CREATE FUNCTION p2text (p2) 1014 RETURNS text 1015 AS 'select $1.f1' 1016 LANGUAGE sql; 1017 1018CREATE TABLE c1 ( 1019 f3 int 1020) 1021INHERITS ( 1022 p1, 1023 p2 1024); 1025 1026INSERT INTO c1 1027 VALUES (123456789, 'hi', 42); 1028 1029SELECT 1030 p2text (c1.*) 1031FROM 1032 c1; 1033 1034DROP FUNCTION p2text (p2); 1035 1036DROP TABLE c1; 1037 1038DROP TABLE p2; 1039 1040DROP TABLE p1; 1041 1042CREATE TABLE ac ( 1043 aa text 1044); 1045 1046ALTER TABLE ac 1047 ADD CONSTRAINT ac_check CHECK (aa IS NOT NULL); 1048 1049CREATE TABLE bc ( 1050 bb text 1051) 1052INHERITS ( 1053 ac 1054); 1055 1056SELECT 1057 pc.relname, 1058 pgc.conname, 1059 pgc.contype, 1060 pgc.conislocal, 1061 pgc.coninhcount, 1062 pg_get_expr(pgc.conbin, pc.oid) AS consrc 1063FROM 1064 pg_class AS pc 1065 INNER JOIN pg_constraint AS pgc ON (pgc.conrelid = pc.oid) 1066WHERE 1067 pc.relname IN ('ac', 'bc') 1068ORDER BY 1069 1, 1070 2; 1071 1072INSERT INTO ac (aa) 1073 VALUES (NULL); 1074 1075INSERT INTO bc (aa) 1076 VALUES (NULL); 1077 1078ALTER TABLE bc 1079 DROP CONSTRAINT ac_check; 1080 1081-- fail, disallowed 1082ALTER TABLE ac 1083 DROP CONSTRAINT ac_check; 1084 1085SELECT 1086 pc.relname, 1087 pgc.conname, 1088 pgc.contype, 1089 pgc.conislocal, 1090 pgc.coninhcount, 1091 pg_get_expr(pgc.conbin, pc.oid) AS consrc 1092FROM 1093 pg_class AS pc 1094 INNER JOIN pg_constraint AS pgc ON (pgc.conrelid = pc.oid) 1095WHERE 1096 pc.relname IN ('ac', 'bc') 1097ORDER BY 1098 1, 1099 2; 1100 1101-- try the unnamed-constraint case 1102ALTER TABLE ac 1103 ADD CHECK (aa IS NOT NULL); 1104 1105SELECT 1106 pc.relname, 1107 pgc.conname, 1108 pgc.contype, 1109 pgc.conislocal, 1110 pgc.coninhcount, 1111 pg_get_expr(pgc.conbin, pc.oid) AS consrc 1112FROM 1113 pg_class AS pc 1114 INNER JOIN pg_constraint AS pgc ON (pgc.conrelid = pc.oid) 1115WHERE 1116 pc.relname IN ('ac', 'bc') 1117ORDER BY 1118 1, 1119 2; 1120 1121INSERT INTO ac (aa) 1122 VALUES (NULL); 1123 1124INSERT INTO bc (aa) 1125 VALUES (NULL); 1126 1127ALTER TABLE bc 1128 DROP CONSTRAINT ac_aa_check; 1129 1130-- fail, disallowed 1131ALTER TABLE ac 1132 DROP CONSTRAINT ac_aa_check; 1133 1134SELECT 1135 pc.relname, 1136 pgc.conname, 1137 pgc.contype, 1138 pgc.conislocal, 1139 pgc.coninhcount, 1140 pg_get_expr(pgc.conbin, pc.oid) AS consrc 1141FROM 1142 pg_class AS pc 1143 INNER JOIN pg_constraint AS pgc ON (pgc.conrelid = pc.oid) 1144WHERE 1145 pc.relname IN ('ac', 'bc') 1146ORDER BY 1147 1, 1148 2; 1149 1150ALTER TABLE ac 1151 ADD CONSTRAINT ac_check CHECK (aa IS NOT NULL); 1152 1153ALTER TABLE bc NO inherit ac; 1154 1155SELECT 1156 pc.relname, 1157 pgc.conname, 1158 pgc.contype, 1159 pgc.conislocal, 1160 pgc.coninhcount, 1161 pg_get_expr(pgc.conbin, pc.oid) AS consrc 1162FROM 1163 pg_class AS pc 1164 INNER JOIN pg_constraint AS pgc ON (pgc.conrelid = pc.oid) 1165WHERE 1166 pc.relname IN ('ac', 'bc') 1167ORDER BY 1168 1, 1169 2; 1170 1171ALTER TABLE bc 1172 DROP CONSTRAINT ac_check; 1173 1174SELECT 1175 pc.relname, 1176 pgc.conname, 1177 pgc.contype, 1178 pgc.conislocal, 1179 pgc.coninhcount, 1180 pg_get_expr(pgc.conbin, pc.oid) AS consrc 1181FROM 1182 pg_class AS pc 1183 INNER JOIN pg_constraint AS pgc ON (pgc.conrelid = pc.oid) 1184WHERE 1185 pc.relname IN ('ac', 'bc') 1186ORDER BY 1187 1, 1188 2; 1189 1190ALTER TABLE ac 1191 DROP CONSTRAINT ac_check; 1192 1193SELECT 1194 pc.relname, 1195 pgc.conname, 1196 pgc.contype, 1197 pgc.conislocal, 1198 pgc.coninhcount, 1199 pg_get_expr(pgc.conbin, pc.oid) AS consrc 1200FROM 1201 pg_class AS pc 1202 INNER JOIN pg_constraint AS pgc ON (pgc.conrelid = pc.oid) 1203WHERE 1204 pc.relname IN ('ac', 'bc') 1205ORDER BY 1206 1, 1207 2; 1208 1209DROP TABLE bc; 1210 1211DROP TABLE ac; 1212 1213CREATE TABLE ac ( 1214 a int CONSTRAINT check_a CHECK (a <> 0) 1215); 1216 1217CREATE TABLE bc ( 1218 a int CONSTRAINT check_a CHECK (a <> 0), 1219 b int CONSTRAINT check_b CHECK (b <> 0) 1220) 1221INHERITS ( 1222 ac 1223); 1224 1225SELECT 1226 pc.relname, 1227 pgc.conname, 1228 pgc.contype, 1229 pgc.conislocal, 1230 pgc.coninhcount, 1231 pg_get_expr(pgc.conbin, pc.oid) AS consrc 1232FROM 1233 pg_class AS pc 1234 INNER JOIN pg_constraint AS pgc ON (pgc.conrelid = pc.oid) 1235WHERE 1236 pc.relname IN ('ac', 'bc') 1237ORDER BY 1238 1, 1239 2; 1240 1241DROP TABLE bc; 1242 1243DROP TABLE ac; 1244 1245CREATE TABLE ac ( 1246 a int CONSTRAINT check_a CHECK (a <> 0) 1247); 1248 1249CREATE TABLE bc ( 1250 b int CONSTRAINT check_b CHECK (b <> 0) 1251); 1252 1253CREATE TABLE cc ( 1254 c int CONSTRAINT check_c CHECK (c <> 0) 1255) 1256INHERITS ( 1257 ac, 1258 bc 1259); 1260 1261SELECT 1262 pc.relname, 1263 pgc.conname, 1264 pgc.contype, 1265 pgc.conislocal, 1266 pgc.coninhcount, 1267 pg_get_expr(pgc.conbin, pc.oid) AS consrc 1268FROM 1269 pg_class AS pc 1270 INNER JOIN pg_constraint AS pgc ON (pgc.conrelid = pc.oid) 1271WHERE 1272 pc.relname IN ('ac', 'bc', 'cc') 1273ORDER BY 1274 1, 1275 2; 1276 1277ALTER TABLE cc NO inherit bc; 1278 1279SELECT 1280 pc.relname, 1281 pgc.conname, 1282 pgc.contype, 1283 pgc.conislocal, 1284 pgc.coninhcount, 1285 pg_get_expr(pgc.conbin, pc.oid) AS consrc 1286FROM 1287 pg_class AS pc 1288 INNER JOIN pg_constraint AS pgc ON (pgc.conrelid = pc.oid) 1289WHERE 1290 pc.relname IN ('ac', 'bc', 'cc') 1291ORDER BY 1292 1, 1293 2; 1294 1295DROP TABLE cc; 1296 1297DROP TABLE bc; 1298 1299DROP TABLE ac; 1300 1301CREATE TABLE p1 ( 1302 f1 int 1303); 1304 1305CREATE TABLE p2 ( 1306 f2 int 1307); 1308 1309CREATE TABLE c1 ( 1310 f3 int 1311) 1312INHERITS ( 1313 p1, 1314 p2 1315); 1316 1317INSERT INTO c1 1318 VALUES (1, -1, 2); 1319 1320ALTER TABLE p2 1321 ADD CONSTRAINT cc CHECK (f2 > 0); 1322 1323-- fail 1324ALTER TABLE p2 1325 ADD CHECK (f2 > 0); 1326 1327-- check it without a name, too 1328DELETE FROM c1; 1329 1330INSERT INTO c1 1331 VALUES (1, 1, 2); 1332 1333ALTER TABLE p2 1334 ADD CHECK (f2 > 0); 1335 1336INSERT INTO c1 1337 VALUES (1, -1, 2); 1338 1339-- fail 1340CREATE TABLE c2 ( 1341 f3 int 1342) 1343INHERITS ( 1344 p1, 1345 p2 1346); 1347 1348\d c2 1349CREATE TABLE c3 ( 1350 f4 int 1351) 1352INHERITS ( 1353 c1, 1354 c2 1355); 1356 1357\d c3 1358DROP TABLE p1 CASCADE; 1359 1360DROP TABLE p2 CASCADE; 1361 1362CREATE TABLE pp1 ( 1363 f1 int 1364); 1365 1366CREATE TABLE cc1 ( 1367 f2 text, 1368 f3 int 1369) 1370INHERITS ( 1371 pp1 1372); 1373 1374ALTER TABLE pp1 1375 ADD COLUMN a1 int CHECK (a1 > 0); 1376 1377\d cc1 1378CREATE TABLE cc2 ( 1379 f4 float 1380) 1381INHERITS ( 1382 pp1, 1383 cc1 1384); 1385 1386\d cc2 1387ALTER TABLE pp1 1388 ADD COLUMN a2 int CHECK (a2 > 0); 1389 1390\d cc2 1391DROP TABLE pp1 CASCADE; 1392 1393-- Test for renaming in simple multiple inheritance 1394CREATE TABLE inht1 ( 1395 a int, 1396 b int 1397); 1398 1399CREATE TABLE inhs1 ( 1400 b int, 1401 c int 1402); 1403 1404CREATE TABLE inhts ( 1405 d int 1406) 1407INHERITS ( 1408 inht1, 1409 inhs1 1410); 1411 1412ALTER TABLE inht1 RENAME a TO aa; 1413 1414ALTER TABLE inht1 RENAME b TO bb; 1415 1416-- to be failed 1417ALTER TABLE inhts RENAME aa TO aaa; 1418 1419-- to be failed 1420ALTER TABLE inhts RENAME d TO dd; 1421 1422\d+ inhts 1423DROP TABLE inhts; 1424 1425-- Test for renaming in diamond inheritance 1426CREATE TABLE inht2 ( 1427 x int 1428) 1429INHERITS ( 1430 inht1 1431); 1432 1433CREATE TABLE inht3 ( 1434 y int 1435) 1436INHERITS ( 1437 inht1 1438); 1439 1440CREATE TABLE inht4 ( 1441 z int 1442) 1443INHERITS ( 1444 inht2, 1445 inht3 1446); 1447 1448ALTER TABLE inht1 RENAME aa TO aaa; 1449 1450\d+ inht4 1451CREATE TABLE inhts ( 1452 d int 1453) 1454INHERITS ( 1455 inht2, 1456 inhs1 1457); 1458 1459ALTER TABLE inht1 RENAME aaa TO aaaa; 1460 1461ALTER TABLE inht1 RENAME b TO bb; 1462 1463-- to be failed 1464\d+ inhts 1465WITH RECURSIVE r AS ( 1466 SELECT 1467 'inht1'::regclass AS inhrelid 1468 UNION ALL 1469 SELECT 1470 c.inhrelid 1471 FROM 1472 pg_inherits c, 1473 r 1474 WHERE 1475 r.inhrelid = c.inhparent 1476) 1477SELECT 1478 a.attrelid::regclass, 1479 a.attname, 1480 a.attinhcount, 1481 e.expected 1482FROM ( 1483 SELECT 1484 inhrelid, 1485 count(*) AS expected 1486 FROM 1487 pg_inherits 1488 WHERE 1489 inhparent IN ( 1490 SELECT 1491 inhrelid 1492 FROM 1493 r) 1494 GROUP BY 1495 inhrelid) e 1496 JOIN pg_attribute a ON e.inhrelid = a.attrelid 1497WHERE 1498 NOT attislocal 1499ORDER BY 1500 a.attrelid::regclass::name, 1501 a.attnum; 1502 1503DROP TABLE inht1, inhs1 CASCADE; 1504 1505-- Test non-inheritable indices [UNIQUE, EXCLUDE] constraints 1506CREATE TABLE test_constraints ( 1507 id int, 1508 val1 varchar, 1509 val2 int, 1510 UNIQUE (val1, val2) 1511); 1512 1513CREATE TABLE test_constraints_inh () 1514INHERITS ( 1515 test_constraints 1516); 1517 1518\d+ test_constraints 1519ALTER TABLE ONLY test_constraints 1520 DROP CONSTRAINT test_constraints_val1_val2_key; 1521 1522\d+ test_constraints 1523\d+ test_constraints_inh 1524DROP TABLE test_constraints_inh; 1525 1526DROP TABLE test_constraints; 1527 1528CREATE TABLE test_ex_constraints ( 1529 c circle, 1530 EXCLUDE USING gist (c WITH &&) 1531); 1532 1533CREATE TABLE test_ex_constraints_inh () 1534INHERITS ( 1535 test_ex_constraints 1536); 1537 1538\d+ test_ex_constraints 1539ALTER TABLE test_ex_constraints 1540 DROP CONSTRAINT test_ex_constraints_c_excl; 1541 1542\d+ test_ex_constraints 1543\d+ test_ex_constraints_inh 1544DROP TABLE test_ex_constraints_inh; 1545 1546DROP TABLE test_ex_constraints; 1547 1548-- Test non-inheritable foreign key constraints 1549CREATE TABLE test_primary_constraints ( 1550 id int PRIMARY KEY 1551); 1552 1553CREATE TABLE test_foreign_constraints ( 1554 id1 int REFERENCES test_primary_constraints (id) 1555); 1556 1557CREATE TABLE test_foreign_constraints_inh () 1558INHERITS ( 1559 test_foreign_constraints 1560); 1561 1562\d+ test_primary_constraints 1563\d+ test_foreign_constraints 1564ALTER TABLE test_foreign_constraints 1565 DROP CONSTRAINT test_foreign_constraints_id1_fkey; 1566 1567\d+ test_foreign_constraints 1568\d+ test_foreign_constraints_inh 1569DROP TABLE test_foreign_constraints_inh; 1570 1571DROP TABLE test_foreign_constraints; 1572 1573DROP TABLE test_primary_constraints; 1574 1575-- Test foreign key behavior 1576CREATE TABLE inh_fk_1 ( 1577 a int PRIMARY KEY 1578); 1579 1580INSERT INTO inh_fk_1 1581 VALUES (1), (2), (3); 1582 1583CREATE TABLE inh_fk_2 ( 1584 x int PRIMARY KEY, 1585 y int REFERENCES inh_fk_1 ON DELETE CASCADE 1586); 1587 1588INSERT INTO inh_fk_2 1589 VALUES (11, 1), (22, 2), (33, 3); 1590 1591CREATE TABLE inh_fk_2_child () 1592INHERITS ( 1593 inh_fk_2 1594); 1595 1596INSERT INTO inh_fk_2_child 1597 VALUES (111, 1), (222, 2); 1598 1599DELETE FROM inh_fk_1 1600WHERE a = 1; 1601 1602SELECT 1603 * 1604FROM 1605 inh_fk_1 1606ORDER BY 1607 1; 1608 1609SELECT 1610 * 1611FROM 1612 inh_fk_2 1613ORDER BY 1614 1, 1615 2; 1616 1617DROP TABLE inh_fk_1, inh_fk_2, inh_fk_2_child; 1618 1619-- Test that parent and child CHECK constraints can be created in either order 1620CREATE TABLE p1 ( 1621 f1 int 1622); 1623 1624CREATE TABLE p1_c1 () 1625INHERITS ( 1626 p1 1627); 1628 1629ALTER TABLE p1 1630 ADD CONSTRAINT inh_check_constraint1 CHECK (f1 > 0); 1631 1632ALTER TABLE p1_c1 1633 ADD CONSTRAINT inh_check_constraint1 CHECK (f1 > 0); 1634 1635ALTER TABLE p1_c1 1636 ADD CONSTRAINT inh_check_constraint2 CHECK (f1 < 10); 1637 1638ALTER TABLE p1 1639 ADD CONSTRAINT inh_check_constraint2 CHECK (f1 < 10); 1640 1641SELECT 1642 conrelid::regclass::text AS relname, 1643 conname, 1644 conislocal, 1645 coninhcount 1646FROM 1647 pg_constraint 1648WHERE 1649 conname LIKE 'inh\_check\_constraint%' 1650ORDER BY 1651 1, 1652 2; 1653 1654DROP TABLE p1 CASCADE; 1655 1656-- Test that a valid child can have not-valid parent, but not vice versa 1657CREATE TABLE invalid_check_con ( 1658 f1 int 1659); 1660 1661CREATE TABLE invalid_check_con_child () 1662INHERITS ( 1663 invalid_check_con 1664); 1665 1666ALTER TABLE invalid_check_con_child 1667 ADD CONSTRAINT inh_check_constraint CHECK (f1 > 0) NOT valid; 1668 1669ALTER TABLE invalid_check_con 1670 ADD CONSTRAINT inh_check_constraint CHECK (f1 > 0); 1671 1672-- fail 1673ALTER TABLE invalid_check_con_child 1674 DROP CONSTRAINT inh_check_constraint; 1675 1676INSERT INTO invalid_check_con 1677 VALUES (0); 1678 1679ALTER TABLE invalid_check_con_child 1680 ADD CONSTRAINT inh_check_constraint CHECK (f1 > 0); 1681 1682ALTER TABLE invalid_check_con 1683 ADD CONSTRAINT inh_check_constraint CHECK (f1 > 0) NOT valid; 1684 1685INSERT INTO invalid_check_con 1686 VALUES (0); 1687 1688-- fail 1689INSERT INTO invalid_check_con_child 1690 VALUES (0); 1691 1692-- fail 1693SELECT 1694 conrelid::regclass::text AS relname, 1695 conname, 1696 convalidated, 1697 conislocal, 1698 coninhcount, 1699 connoinherit 1700FROM 1701 pg_constraint 1702WHERE 1703 conname LIKE 'inh\_check\_constraint%' 1704ORDER BY 1705 1, 1706 2; 1707 1708-- We don't drop the invalid_check_con* tables, to test dump/reload with 1709-- 1710-- Test parameterized append plans for inheritance trees 1711-- 1712CREATE temp TABLE patest0 ( 1713 id, 1714 x 1715) AS 1716SELECT 1717 x, 1718 x 1719FROM 1720 generate_series(0, 1000) x; 1721 1722CREATE temp TABLE patest1 () 1723INHERITS ( 1724 patest0 1725); 1726 1727INSERT INTO patest1 1728SELECT 1729 x, 1730 x 1731FROM 1732 generate_series(0, 1000) x; 1733 1734CREATE temp TABLE patest2 () 1735INHERITS ( 1736 patest0 1737); 1738 1739INSERT INTO patest2 1740SELECT 1741 x, 1742 x 1743FROM 1744 generate_series(0, 1000) x; 1745 1746CREATE INDEX patest0i ON patest0 (id); 1747 1748CREATE INDEX patest1i ON patest1 (id); 1749 1750CREATE INDEX patest2i ON patest2 (id); 1751 1752ANALYZE patest0; 1753 1754ANALYZE patest1; 1755 1756ANALYZE patest2; 1757 1758EXPLAIN ( 1759 COSTS OFF 1760) 1761SELECT 1762 * 1763FROM 1764 patest0 1765 JOIN ( 1766 SELECT 1767 f1 1768 FROM 1769 int4_tbl 1770 LIMIT 1) ss ON id = f1; 1771 1772SELECT 1773 * 1774FROM 1775 patest0 1776 JOIN ( 1777 SELECT 1778 f1 1779 FROM 1780 int4_tbl 1781 LIMIT 1) ss ON id = f1; 1782 1783DROP INDEX patest2i; 1784 1785EXPLAIN ( 1786 COSTS OFF 1787) 1788SELECT 1789 * 1790FROM 1791 patest0 1792 JOIN ( 1793 SELECT 1794 f1 1795 FROM 1796 int4_tbl 1797 LIMIT 1) ss ON id = f1; 1798 1799SELECT 1800 * 1801FROM 1802 patest0 1803 JOIN ( 1804 SELECT 1805 f1 1806 FROM 1807 int4_tbl 1808 LIMIT 1) ss ON id = f1; 1809 1810DROP TABLE patest0 CASCADE; 1811 1812-- 1813-- Test merge-append plans for inheritance trees 1814-- 1815CREATE TABLE matest0 ( 1816 id serial PRIMARY KEY, 1817 name text 1818); 1819 1820CREATE TABLE matest1 ( 1821 id integer PRIMARY KEY 1822) 1823INHERITS ( 1824 matest0 1825); 1826 1827CREATE TABLE matest2 ( 1828 id integer PRIMARY KEY 1829) 1830INHERITS ( 1831 matest0 1832); 1833 1834CREATE TABLE matest3 ( 1835 id integer PRIMARY KEY 1836) 1837INHERITS ( 1838 matest0 1839); 1840 1841CREATE INDEX matest0i ON matest0 ((1 - id)); 1842 1843CREATE INDEX matest1i ON matest1 ((1 - id)); 1844 1845-- create index matest2i on matest2 ((1-id)); -- intentionally missing 1846CREATE INDEX matest3i ON matest3 ((1 - id)); 1847 1848INSERT INTO matest1 (name) 1849 VALUES ('Test 1'); 1850 1851INSERT INTO matest1 (name) 1852 VALUES ('Test 2'); 1853 1854INSERT INTO matest2 (name) 1855 VALUES ('Test 3'); 1856 1857INSERT INTO matest2 (name) 1858 VALUES ('Test 4'); 1859 1860INSERT INTO matest3 (name) 1861 VALUES ('Test 5'); 1862 1863INSERT INTO matest3 (name) 1864 VALUES ('Test 6'); 1865 1866SET enable_indexscan = OFF; 1867 1868-- force use of seqscan/sort, so no merge 1869EXPLAIN ( 1870 VERBOSE, 1871 COSTS OFF 1872) 1873SELECT 1874 * 1875FROM 1876 matest0 1877ORDER BY 1878 1 - id; 1879 1880SELECT 1881 * 1882FROM 1883 matest0 1884ORDER BY 1885 1 - id; 1886 1887EXPLAIN ( 1888 VERBOSE, 1889 COSTS OFF 1890) 1891SELECT 1892 min(1 - id) 1893FROM 1894 matest0; 1895 1896SELECT 1897 min(1 - id) 1898FROM 1899 matest0; 1900 1901RESET enable_indexscan; 1902 1903SET enable_seqscan = OFF; 1904 1905-- plan with fewest seqscans should be merge 1906SET enable_parallel_append = OFF; 1907 1908-- Don't let parallel-append interfere 1909EXPLAIN ( 1910 VERBOSE, 1911 COSTS OFF 1912) 1913SELECT 1914 * 1915FROM 1916 matest0 1917ORDER BY 1918 1 - id; 1919 1920SELECT 1921 * 1922FROM 1923 matest0 1924ORDER BY 1925 1 - id; 1926 1927EXPLAIN ( 1928 VERBOSE, 1929 COSTS OFF 1930) 1931SELECT 1932 min(1 - id) 1933FROM 1934 matest0; 1935 1936SELECT 1937 min(1 - id) 1938FROM 1939 matest0; 1940 1941RESET enable_seqscan; 1942 1943RESET enable_parallel_append; 1944 1945DROP TABLE matest0 CASCADE; 1946 1947-- 1948-- Check that use of an index with an extraneous column doesn't produce 1949-- a plan with extraneous sorting 1950-- 1951CREATE TABLE matest0 ( 1952 a int, 1953 b int, 1954 c int, 1955 d int 1956); 1957 1958CREATE TABLE matest1 () 1959INHERITS ( 1960 matest0 1961); 1962 1963CREATE INDEX matest0i ON matest0 (b, c); 1964 1965CREATE INDEX matest1i ON matest1 (b, c); 1966 1967SET enable_nestloop = OFF; 1968 1969-- we want a plan with two MergeAppends 1970EXPLAIN ( 1971 COSTS OFF 1972) 1973SELECT 1974 t1.* 1975FROM 1976 matest0 t1, 1977 matest0 t2 1978WHERE 1979 t1.b = t2.b 1980 AND t2.c = t2.d 1981ORDER BY 1982 t1.b 1983LIMIT 10; 1984 1985RESET enable_nestloop; 1986 1987DROP TABLE matest0 CASCADE; 1988 1989-- 1990-- Test merge-append for UNION ALL append relations 1991-- 1992SET enable_seqscan = OFF; 1993 1994SET enable_indexscan = ON; 1995 1996SET enable_bitmapscan = OFF; 1997 1998-- Check handling of duplicated, constant, or volatile targetlist items 1999EXPLAIN ( 2000 COSTS OFF 2001) 2002SELECT 2003 thousand, 2004 tenthous 2005FROM 2006 tenk1 2007UNION ALL 2008SELECT 2009 thousand, 2010 thousand 2011FROM 2012 tenk1 2013ORDER BY 2014 thousand, 2015 tenthous; 2016 2017EXPLAIN ( 2018 COSTS OFF 2019) 2020SELECT 2021 thousand, 2022 tenthous, 2023 thousand + tenthous AS x 2024FROM 2025 tenk1 2026UNION ALL 2027SELECT 2028 42, 2029 42, 2030 hundred 2031FROM 2032 tenk1 2033ORDER BY 2034 thousand, 2035 tenthous; 2036 2037EXPLAIN ( 2038 COSTS OFF 2039) 2040SELECT 2041 thousand, 2042 tenthous 2043FROM 2044 tenk1 2045UNION ALL 2046SELECT 2047 thousand, 2048 random()::integer 2049FROM 2050 tenk1 2051ORDER BY 2052 thousand, 2053 tenthous; 2054 2055-- Check min/max aggregate optimization 2056EXPLAIN ( 2057 COSTS OFF 2058) 2059SELECT 2060 min(x) 2061FROM ( 2062 SELECT 2063 unique1 AS x 2064 FROM 2065 tenk1 a 2066 UNION ALL 2067 SELECT 2068 unique2 AS x 2069 FROM 2070 tenk1 b) s; 2071 2072EXPLAIN ( 2073 COSTS OFF 2074) 2075SELECT 2076 min(y) 2077FROM ( 2078 SELECT 2079 unique1 AS x, 2080 unique1 AS y 2081 FROM 2082 tenk1 a 2083 UNION ALL 2084 SELECT 2085 unique2 AS x, 2086 unique2 AS y 2087 FROM 2088 tenk1 b) s; 2089 2090-- XXX planner doesn't recognize that index on unique2 is sufficiently sorted 2091EXPLAIN ( 2092 COSTS OFF 2093) 2094SELECT 2095 x, 2096 y 2097FROM ( 2098 SELECT 2099 thousand AS x, 2100 tenthous AS y 2101 FROM 2102 tenk1 a 2103 UNION ALL 2104 SELECT 2105 unique2 AS x, 2106 unique2 AS y 2107 FROM 2108 tenk1 b) s 2109ORDER BY 2110 x, 2111 y; 2112 2113-- exercise rescan code path via a repeatedly-evaluated subquery 2114EXPLAIN ( 2115 COSTS OFF 2116) 2117SELECT 2118 ARRAY ( 2119 SELECT 2120 f.i 2121 FROM (( 2122 SELECT 2123 d + g.i 2124 FROM 2125 generate_series(4, 30, 3) d 2126 ORDER BY 2127 1) 2128 UNION ALL ( 2129 SELECT 2130 d + g.i 2131 FROM 2132 generate_series(0, 30, 5) d 2133 ORDER BY 2134 1)) f (i) 2135 ORDER BY 2136 f.i 2137 LIMIT 10) 2138FROM 2139 generate_series(1, 3) g (i); 2140 2141SELECT 2142 ARRAY ( 2143 SELECT 2144 f.i 2145 FROM (( 2146 SELECT 2147 d + g.i 2148 FROM 2149 generate_series(4, 30, 3) d 2150 ORDER BY 2151 1) 2152 UNION ALL ( 2153 SELECT 2154 d + g.i 2155 FROM 2156 generate_series(0, 30, 5) d 2157 ORDER BY 2158 1)) f (i) 2159 ORDER BY 2160 f.i 2161 LIMIT 10) 2162FROM 2163 generate_series(1, 3) g (i); 2164 2165RESET enable_seqscan; 2166 2167RESET enable_indexscan; 2168 2169RESET enable_bitmapscan; 2170 2171-- 2172-- Check handling of a constant-null CHECK constraint 2173-- 2174CREATE TABLE cnullparent ( 2175 f1 int 2176); 2177 2178CREATE TABLE cnullchild ( 2179 CHECK (f1 = 1 OR f1 = NULL) 2180) 2181INHERITS ( 2182 cnullparent 2183); 2184 2185INSERT INTO cnullchild 2186 VALUES (1); 2187 2188INSERT INTO cnullchild 2189 VALUES (2); 2190 2191INSERT INTO cnullchild 2192 VALUES (NULL); 2193 2194SELECT 2195 * 2196FROM 2197 cnullparent; 2198 2199SELECT 2200 * 2201FROM 2202 cnullparent 2203WHERE 2204 f1 = 2; 2205 2206DROP TABLE cnullparent CASCADE; 2207 2208-- 2209-- Check use of temporary tables with inheritance trees 2210-- 2211CREATE TABLE inh_perm_parent ( 2212 a1 int 2213); 2214 2215CREATE temp TABLE inh_temp_parent ( 2216 a1 int 2217); 2218 2219CREATE temp TABLE inh_temp_child () 2220INHERITS ( 2221 inh_perm_parent 2222); 2223 2224-- ok 2225CREATE TABLE inh_perm_child () 2226INHERITS ( 2227 inh_temp_parent 2228); 2229 2230-- error 2231CREATE temp TABLE inh_temp_child_2 () 2232INHERITS ( 2233 inh_temp_parent 2234); 2235 2236-- ok 2237INSERT INTO inh_perm_parent 2238 VALUES (1); 2239 2240INSERT INTO inh_temp_parent 2241 VALUES (2); 2242 2243INSERT INTO inh_temp_child 2244 VALUES (3); 2245 2246INSERT INTO inh_temp_child_2 2247 VALUES (4); 2248 2249SELECT 2250 tableoid::regclass, 2251 a1 2252FROM 2253 inh_perm_parent; 2254 2255SELECT 2256 tableoid::regclass, 2257 a1 2258FROM 2259 inh_temp_parent; 2260 2261DROP TABLE inh_perm_parent CASCADE; 2262 2263DROP TABLE inh_temp_parent CASCADE; 2264 2265-- 2266-- Check that constraint exclusion works correctly with partitions using 2267-- implicit constraints generated from the partition bound information. 2268-- 2269CREATE TABLE list_parted ( 2270 a varchar 2271) 2272PARTITION BY LIST (a); 2273 2274CREATE TABLE part_ab_cd PARTITION OF list_parted 2275FOR VALUES IN ('ab', 'cd'); 2276 2277CREATE TABLE part_ef_gh PARTITION OF list_parted 2278FOR VALUES IN ('ef', 'gh'); 2279 2280CREATE TABLE part_null_xy PARTITION OF list_parted 2281FOR VALUES IN (NULL, 'xy'); 2282 2283EXPLAIN ( 2284 COSTS OFF 2285) 2286SELECT 2287 * 2288FROM 2289 list_parted; 2290 2291EXPLAIN ( 2292 COSTS OFF 2293) 2294SELECT 2295 * 2296FROM 2297 list_parted 2298WHERE 2299 a IS NULL; 2300 2301EXPLAIN ( 2302 COSTS OFF 2303) 2304SELECT 2305 * 2306FROM 2307 list_parted 2308WHERE 2309 a IS NOT NULL; 2310 2311EXPLAIN ( 2312 COSTS OFF 2313) 2314SELECT 2315 * 2316FROM 2317 list_parted 2318WHERE 2319 a IN ('ab', 'cd', 'ef'); 2320 2321EXPLAIN ( 2322 COSTS OFF 2323) 2324SELECT 2325 * 2326FROM 2327 list_parted 2328WHERE 2329 a = 'ab' 2330 OR a IN (NULL, 'cd'); 2331 2332EXPLAIN ( 2333 COSTS OFF 2334) 2335SELECT 2336 * 2337FROM 2338 list_parted 2339WHERE 2340 a = 'ab'; 2341 2342CREATE TABLE range_list_parted ( 2343 a int, 2344 b char(2) 2345) 2346PARTITION BY RANGE (a); 2347 2348CREATE TABLE part_1_10 PARTITION OF range_list_parted 2349FOR VALUES FROM (1) TO (10) 2350PARTITION BY LIST (b); 2351 2352CREATE TABLE part_1_10_ab PARTITION OF part_1_10 2353FOR VALUES IN ('ab'); 2354 2355CREATE TABLE part_1_10_cd PARTITION OF part_1_10 2356FOR VALUES IN ('cd'); 2357 2358CREATE TABLE part_10_20 PARTITION OF range_list_parted 2359FOR VALUES FROM (10) TO (20) 2360PARTITION BY LIST (b); 2361 2362CREATE TABLE part_10_20_ab PARTITION OF part_10_20 2363FOR VALUES IN ('ab'); 2364 2365CREATE TABLE part_10_20_cd PARTITION OF part_10_20 2366FOR VALUES IN ('cd'); 2367 2368CREATE TABLE part_21_30 PARTITION OF range_list_parted 2369FOR VALUES FROM (21) TO (30) 2370PARTITION BY LIST (b); 2371 2372CREATE TABLE part_21_30_ab PARTITION OF part_21_30 2373FOR VALUES IN ('ab'); 2374 2375CREATE TABLE part_21_30_cd PARTITION OF part_21_30 2376FOR VALUES IN ('cd'); 2377 2378CREATE TABLE part_40_inf PARTITION OF range_list_parted 2379FOR VALUES FROM (40) TO (MAXVALUE) 2380PARTITION BY LIST (b); 2381 2382CREATE TABLE part_40_inf_ab PARTITION OF part_40_inf 2383FOR VALUES IN ('ab'); 2384 2385CREATE TABLE part_40_inf_cd PARTITION OF part_40_inf 2386FOR VALUES IN ('cd'); 2387 2388CREATE TABLE part_40_inf_null PARTITION OF part_40_inf 2389FOR VALUES IN (NULL); 2390 2391EXPLAIN ( 2392 COSTS OFF 2393) 2394SELECT 2395 * 2396FROM 2397 range_list_parted; 2398 2399EXPLAIN ( 2400 COSTS OFF 2401) 2402SELECT 2403 * 2404FROM 2405 range_list_parted 2406WHERE 2407 a = 5; 2408 2409EXPLAIN ( 2410 COSTS OFF 2411) 2412SELECT 2413 * 2414FROM 2415 range_list_parted 2416WHERE 2417 b = 'ab'; 2418 2419EXPLAIN ( 2420 COSTS OFF 2421) 2422SELECT 2423 * 2424FROM 2425 range_list_parted 2426WHERE 2427 a BETWEEN 3 AND 23 2428 AND b IN ('ab'); 2429 2430 2431/* Should select no rows because range partition key cannot be null */ 2432EXPLAIN ( 2433 COSTS OFF 2434) 2435SELECT 2436 * 2437FROM 2438 range_list_parted 2439WHERE 2440 a IS NULL; 2441 2442 2443/* Should only select rows from the null-accepting partition */ 2444EXPLAIN ( 2445 COSTS OFF 2446) 2447SELECT 2448 * 2449FROM 2450 range_list_parted 2451WHERE 2452 b IS NULL; 2453 2454EXPLAIN ( 2455 COSTS OFF 2456) 2457SELECT 2458 * 2459FROM 2460 range_list_parted 2461WHERE 2462 a IS NOT NULL 2463 AND a < 67; 2464 2465EXPLAIN ( 2466 COSTS OFF 2467) 2468SELECT 2469 * 2470FROM 2471 range_list_parted 2472WHERE 2473 a >= 30; 2474 2475DROP TABLE list_parted; 2476 2477DROP TABLE range_list_parted; 2478 2479-- check that constraint exclusion is able to cope with the partition 2480-- constraint emitted for multi-column range partitioned tables 2481CREATE TABLE mcrparted ( 2482 a int, 2483 b int, 2484 c int 2485) 2486PARTITION BY RANGE (a, abs(b), c); 2487 2488CREATE TABLE mcrparted_def PARTITION OF mcrparted DEFAULT; 2489 2490CREATE TABLE mcrparted0 PARTITION OF mcrparted 2491FOR VALUES FROM (MINVALUE, 2492MINVALUE, 2493MINVALUE) TO (1, 1, 1); 2494 2495CREATE TABLE mcrparted1 PARTITION OF mcrparted 2496FOR VALUES FROM (1, 1, 1) TO (10, 5, 10); 2497 2498CREATE TABLE mcrparted2 PARTITION OF mcrparted 2499FOR VALUES FROM (10, 5, 10) TO (10, 10, 10); 2500 2501CREATE TABLE mcrparted3 PARTITION OF mcrparted 2502FOR VALUES FROM (11, 1, 1) TO (20, 10, 10); 2503 2504CREATE TABLE mcrparted4 PARTITION OF mcrparted 2505FOR VALUES FROM (20, 10, 10) TO (20, 20, 20); 2506 2507CREATE TABLE mcrparted5 PARTITION OF mcrparted 2508FOR VALUES FROM (20, 20, 20) TO (MAXVALUE, 2509MAXVALUE, 2510MAXVALUE); 2511 2512EXPLAIN ( 2513 COSTS OFF 2514) 2515SELECT 2516 * 2517FROM 2518 mcrparted 2519WHERE 2520 a = 0; 2521 2522-- scans mcrparted0, mcrparted_def 2523EXPLAIN ( 2524 COSTS OFF 2525) 2526SELECT 2527 * 2528FROM 2529 mcrparted 2530WHERE 2531 a = 10 2532 AND abs(b) < 5; 2533 2534-- scans mcrparted1, mcrparted_def 2535EXPLAIN ( 2536 COSTS OFF 2537) 2538SELECT 2539 * 2540FROM 2541 mcrparted 2542WHERE 2543 a = 10 2544 AND abs(b) = 5; 2545 2546-- scans mcrparted1, mcrparted2, mcrparted_def 2547EXPLAIN ( 2548 COSTS OFF 2549) 2550SELECT 2551 * 2552FROM 2553 mcrparted 2554WHERE 2555 abs(b) = 5; 2556 2557-- scans all partitions 2558EXPLAIN ( 2559 COSTS OFF 2560) 2561SELECT 2562 * 2563FROM 2564 mcrparted 2565WHERE 2566 a > - 1; 2567 2568-- scans all partitions 2569EXPLAIN ( 2570 COSTS OFF 2571) 2572SELECT 2573 * 2574FROM 2575 mcrparted 2576WHERE 2577 a = 20 2578 AND abs(b) = 10 2579 AND c > 10; 2580 2581-- scans mcrparted4 2582EXPLAIN ( 2583 COSTS OFF 2584) 2585SELECT 2586 * 2587FROM 2588 mcrparted 2589WHERE 2590 a = 20 2591 AND c > 20; 2592 2593-- scans mcrparted3, mcrparte4, mcrparte5, mcrparted_def 2594-- check that partitioned table Appends cope with being referenced in 2595-- subplans 2596CREATE TABLE parted_minmax ( 2597 a int, 2598 b varchar(16) 2599) 2600PARTITION BY RANGE (a); 2601 2602CREATE TABLE parted_minmax1 PARTITION OF parted_minmax 2603FOR VALUES FROM (1) TO (10); 2604 2605CREATE INDEX parted_minmax1i ON parted_minmax1 (a, b); 2606 2607INSERT INTO parted_minmax 2608 VALUES (1, '12345'); 2609 2610EXPLAIN ( 2611 COSTS OFF 2612) 2613SELECT 2614 min(a), 2615 max(a) 2616FROM 2617 parted_minmax 2618WHERE 2619 b = '12345'; 2620 2621SELECT 2622 min(a), 2623 max(a) 2624FROM 2625 parted_minmax 2626WHERE 2627 b = '12345'; 2628 2629DROP TABLE parted_minmax; 2630 2631-- Test code that uses Append nodes in place of MergeAppend when the 2632-- partition ordering matches the desired ordering. 2633CREATE INDEX mcrparted_a_abs_c_idx ON mcrparted (a, abs(b), c); 2634 2635-- MergeAppend must be used when a default partition exists 2636EXPLAIN ( 2637 COSTS OFF 2638) 2639SELECT 2640 * 2641FROM 2642 mcrparted 2643ORDER BY 2644 a, 2645 abs(b), 2646 c; 2647 2648DROP TABLE mcrparted_def; 2649 2650-- Append is used for a RANGE partitioned table with no default 2651-- and no subpartitions 2652EXPLAIN ( 2653 COSTS OFF 2654) 2655SELECT 2656 * 2657FROM 2658 mcrparted 2659ORDER BY 2660 a, 2661 abs(b), 2662 c; 2663 2664-- Append is used with subpaths in reverse order with backwards index scans 2665EXPLAIN ( 2666 COSTS OFF 2667) 2668SELECT 2669 * 2670FROM 2671 mcrparted 2672ORDER BY 2673 a DESC, 2674 abs(b) DESC, 2675 c DESC; 2676 2677-- check that Append plan is used containing a MergeAppend for sub-partitions 2678-- that are unordered. 2679DROP TABLE mcrparted5; 2680 2681CREATE TABLE mcrparted5 PARTITION OF mcrparted 2682FOR VALUES FROM (20, 20, 20) TO (MAXVALUE, 2683MAXVALUE, 2684MAXVALUE) 2685PARTITION BY LIST (a); 2686 2687CREATE TABLE mcrparted5a PARTITION OF mcrparted5 2688FOR VALUES IN (20); 2689 2690CREATE TABLE mcrparted5_def PARTITION OF mcrparted5 DEFAULT; 2691 2692EXPLAIN ( 2693 COSTS OFF 2694) 2695SELECT 2696 * 2697FROM 2698 mcrparted 2699ORDER BY 2700 a, 2701 abs(b), 2702 c; 2703 2704DROP TABLE mcrparted5_def; 2705 2706-- check that an Append plan is used and the sub-partitions are flattened 2707-- into the main Append when the sub-partition is unordered but contains 2708-- just a single sub-partition. 2709EXPLAIN ( 2710 COSTS OFF 2711) 2712SELECT 2713 a, 2714 abs(b) 2715FROM 2716 mcrparted 2717ORDER BY 2718 a, 2719 abs(b), 2720 c; 2721 2722-- check that Append is used when the sub-partitioned tables are pruned 2723-- during planning. 2724EXPLAIN ( 2725 COSTS OFF 2726) 2727SELECT 2728 * 2729FROM 2730 mcrparted 2731WHERE 2732 a < 20 2733ORDER BY 2734 a, 2735 abs(b), 2736 c; 2737 2738CREATE TABLE mclparted ( 2739 a int 2740) 2741PARTITION BY LIST (a); 2742 2743CREATE TABLE mclparted1 PARTITION OF mclparted 2744FOR VALUES IN (1); 2745 2746CREATE TABLE mclparted2 PARTITION OF mclparted 2747FOR VALUES IN (2); 2748 2749CREATE INDEX ON mclparted (a); 2750 2751-- Ensure an Append is used for a list partition with an order by. 2752EXPLAIN ( 2753 COSTS OFF 2754) 2755SELECT 2756 * 2757FROM 2758 mclparted 2759ORDER BY 2760 a; 2761 2762-- Ensure a MergeAppend is used when a partition exists with interleaved 2763-- datums in the partition bound. 2764CREATE TABLE mclparted3_5 PARTITION OF mclparted 2765FOR VALUES IN (3, 5); 2766 2767CREATE TABLE mclparted4 PARTITION OF mclparted 2768FOR VALUES IN (4); 2769 2770EXPLAIN ( 2771 COSTS OFF 2772) 2773SELECT 2774 * 2775FROM 2776 mclparted 2777ORDER BY 2778 a; 2779 2780DROP TABLE mclparted; 2781 2782-- Ensure subplans which don't have a path with the correct pathkeys get 2783-- sorted correctly. 2784DROP INDEX mcrparted_a_abs_c_idx; 2785 2786CREATE INDEX ON mcrparted1 (a, abs(b), c); 2787 2788CREATE INDEX ON mcrparted2 (a, abs(b), c); 2789 2790CREATE INDEX ON mcrparted3 (a, abs(b), c); 2791 2792CREATE INDEX ON mcrparted4 (a, abs(b), c); 2793 2794EXPLAIN ( 2795 COSTS OFF 2796) 2797SELECT 2798 * 2799FROM 2800 mcrparted 2801WHERE 2802 a < 20 2803ORDER BY 2804 a, 2805 abs(b), 2806 c 2807LIMIT 1; 2808 2809SET enable_bitmapscan = 0; 2810 2811-- Ensure Append node can be used when the partition is ordered by some 2812-- pathkeys which were deemed redundant. 2813EXPLAIN ( 2814 COSTS OFF 2815) 2816SELECT 2817 * 2818FROM 2819 mcrparted 2820WHERE 2821 a = 10 2822ORDER BY 2823 a, 2824 abs(b), 2825 c; 2826 2827RESET enable_bitmapscan; 2828 2829DROP TABLE mcrparted; 2830 2831-- Ensure LIST partitions allow an Append to be used instead of a MergeAppend 2832CREATE TABLE bool_lp ( 2833 b bool 2834) 2835PARTITION BY LIST (b); 2836 2837CREATE TABLE bool_lp_true PARTITION OF bool_lp 2838FOR VALUES IN (TRUE); 2839 2840CREATE TABLE bool_lp_false PARTITION OF bool_lp 2841FOR VALUES IN (FALSE); 2842 2843CREATE INDEX ON bool_lp (b); 2844 2845EXPLAIN ( 2846 COSTS OFF 2847) 2848SELECT 2849 * 2850FROM 2851 bool_lp 2852ORDER BY 2853 b; 2854 2855DROP TABLE bool_lp; 2856 2857-- Ensure const bool quals can be properly detected as redundant 2858CREATE TABLE bool_rp ( 2859 b bool, 2860 a int 2861) 2862PARTITION BY RANGE (b, a); 2863 2864CREATE TABLE bool_rp_false_1k PARTITION OF bool_rp 2865FOR VALUES FROM (FALSE, 0) TO (FALSE, 1000); 2866 2867CREATE TABLE bool_rp_true_1k PARTITION OF bool_rp 2868FOR VALUES FROM (TRUE, 0) TO (TRUE, 1000); 2869 2870CREATE TABLE bool_rp_false_2k PARTITION OF bool_rp 2871FOR VALUES FROM (FALSE, 1000) TO (FALSE, 2000); 2872 2873CREATE TABLE bool_rp_true_2k PARTITION OF bool_rp 2874FOR VALUES FROM (TRUE, 1000) TO (TRUE, 2000); 2875 2876CREATE INDEX ON bool_rp (b, a); 2877 2878EXPLAIN ( 2879 COSTS OFF 2880) 2881SELECT 2882 * 2883FROM 2884 bool_rp 2885WHERE 2886 b = TRUE 2887ORDER BY 2888 b, 2889 a; 2890 2891EXPLAIN ( 2892 COSTS OFF 2893) 2894SELECT 2895 * 2896FROM 2897 bool_rp 2898WHERE 2899 b = FALSE 2900ORDER BY 2901 b, 2902 a; 2903 2904EXPLAIN ( 2905 COSTS OFF 2906) 2907SELECT 2908 * 2909FROM 2910 bool_rp 2911WHERE 2912 b = TRUE 2913ORDER BY 2914 a; 2915 2916EXPLAIN ( 2917 COSTS OFF 2918) 2919SELECT 2920 * 2921FROM 2922 bool_rp 2923WHERE 2924 b = FALSE 2925ORDER BY 2926 a; 2927 2928DROP TABLE bool_rp; 2929 2930-- Ensure an Append scan is chosen when the partition order is a subset of 2931-- the required order. 2932CREATE TABLE range_parted ( 2933 a int, 2934 b int, 2935 c int 2936) 2937PARTITION BY RANGE (a, b); 2938 2939CREATE TABLE range_parted1 PARTITION OF range_parted 2940FOR VALUES FROM (0, 0) TO (10, 10); 2941 2942CREATE TABLE range_parted2 PARTITION OF range_parted 2943FOR VALUES FROM (10, 10) TO (20, 20); 2944 2945CREATE INDEX ON range_parted (a, b, c); 2946 2947EXPLAIN ( 2948 COSTS OFF 2949) 2950SELECT 2951 * 2952FROM 2953 range_parted 2954ORDER BY 2955 a, 2956 b, 2957 c; 2958 2959EXPLAIN ( 2960 COSTS OFF 2961) 2962SELECT 2963 * 2964FROM 2965 range_parted 2966ORDER BY 2967 a DESC, 2968 b DESC, 2969 c DESC; 2970 2971DROP TABLE range_parted; 2972 2973