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