--- /dev/null
+--
+-- Test inheritance features
+--
+CREATE TABLE a (aa TEXT) distribute by roundrobin;
+CREATE TABLE b (bb TEXT) INHERITS (a) distribute by roundrobin;
+CREATE TABLE c (cc TEXT) INHERITS (a) distribute by roundrobin;
+CREATE TABLE d (dd TEXT) INHERITS (b,c,a) distribute by roundrobin;
+NOTICE: merging multiple inherited definitions of column "aa"
+NOTICE: merging multiple inherited definitions of column "aa"
+INSERT INTO a(aa) VALUES('aaa');
+INSERT INTO a(aa) VALUES('aaaa');
+INSERT INTO a(aa) VALUES('aaaaa');
+INSERT INTO a(aa) VALUES('aaaaaa');
+INSERT INTO a(aa) VALUES('aaaaaaa');
+INSERT INTO a(aa) VALUES('aaaaaaaa');
+INSERT INTO b(aa) VALUES('bbb');
+INSERT INTO b(aa) VALUES('bbbb');
+INSERT INTO b(aa) VALUES('bbbbb');
+INSERT INTO b(aa) VALUES('bbbbbb');
+INSERT INTO b(aa) VALUES('bbbbbbb');
+INSERT INTO b(aa) VALUES('bbbbbbbb');
+INSERT INTO c(aa) VALUES('ccc');
+INSERT INTO c(aa) VALUES('cccc');
+INSERT INTO c(aa) VALUES('ccccc');
+INSERT INTO c(aa) VALUES('cccccc');
+INSERT INTO c(aa) VALUES('ccccccc');
+INSERT INTO c(aa) VALUES('cccccccc');
+INSERT INTO d(aa) VALUES('ddd');
+INSERT INTO d(aa) VALUES('dddd');
+INSERT INTO d(aa) VALUES('ddddd');
+INSERT INTO d(aa) VALUES('dddddd');
+INSERT INTO d(aa) VALUES('ddddddd');
+INSERT INTO d(aa) VALUES('dddddddd');
+SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
+ relname | aa
+---------+----
+(0 rows)
+
+SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
+ relname | aa | bb
+---------+----+----
+(0 rows)
+
+SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
+ relname | aa | cc
+---------+----+----
+(0 rows)
+
+SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
+ relname | aa | bb | cc | dd
+---------+----+----+----+----
+(0 rows)
+
+SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
+ relname | aa
+---------+----
+(0 rows)
+
+SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
+ relname | aa | bb
+---------+----+----
+(0 rows)
+
+SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
+ relname | aa | cc
+---------+----+----
+(0 rows)
+
+SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
+ relname | aa | bb | cc | dd
+---------+----+----+----+----
+(0 rows)
+
+-- In Postgres-XL OIDs are not consistent across the cluster. Hence above
+-- queries do not show any result. Hence in order to ensure data consistency, we
+-- add following SQLs. In case above set of queries start producing valid
+-- results in XC, we should remove the following set
+SELECT * FROM a ORDER BY a.aa;
+ aa
+----------
+ aaa
+ aaaa
+ aaaaa
+ aaaaaa
+ aaaaaaa
+ aaaaaaaa
+ bbb
+ bbbb
+ bbbbb
+ bbbbbb
+ bbbbbbb
+ bbbbbbbb
+ ccc
+ cccc
+ ccccc
+ cccccc
+ ccccccc
+ cccccccc
+ ddd
+ dddd
+ ddddd
+ dddddd
+ ddddddd
+ dddddddd
+(24 rows)
+
+SELECT * from b ORDER BY b.aa;
+ aa | bb
+----------+----
+ bbb |
+ bbbb |
+ bbbbb |
+ bbbbbb |
+ bbbbbbb |
+ bbbbbbbb |
+ ddd |
+ dddd |
+ ddddd |
+ dddddd |
+ ddddddd |
+ dddddddd |
+(12 rows)
+
+SELECT * FROM c ORDER BY c.aa;
+ aa | cc
+----------+----
+ ccc |
+ cccc |
+ ccccc |
+ cccccc |
+ ccccccc |
+ cccccccc |
+ ddd |
+ dddd |
+ ddddd |
+ dddddd |
+ ddddddd |
+ dddddddd |
+(12 rows)
+
+SELECT * from d ORDER BY d.aa;
+ aa | bb | cc | dd
+----------+----+----+----
+ ddd | | |
+ dddd | | |
+ ddddd | | |
+ dddddd | | |
+ ddddddd | | |
+ dddddddd | | |
+(6 rows)
+
+SELECT * FROM ONLY a ORDER BY a.aa;
+ aa
+----------
+ aaa
+ aaaa
+ aaaaa
+ aaaaaa
+ aaaaaaa
+ aaaaaaaa
+(6 rows)
+
+SELECT * from ONLY b ORDER BY b.aa;
+ aa | bb
+----------+----
+ bbb |
+ bbbb |
+ bbbbb |
+ bbbbbb |
+ bbbbbbb |
+ bbbbbbbb |
+(6 rows)
+
+SELECT * FROM ONLY c ORDER BY c.aa;
+ aa | cc
+----------+----
+ ccc |
+ cccc |
+ ccccc |
+ cccccc |
+ ccccccc |
+ cccccccc |
+(6 rows)
+
+SELECT * from ONLY d ORDER BY d.aa;
+ aa | bb | cc | dd
+----------+----+----+----
+ ddd | | |
+ dddd | | |
+ ddddd | | |
+ dddddd | | |
+ ddddddd | | |
+ dddddddd | | |
+(6 rows)
+
+UPDATE a SET aa='zzzz' WHERE aa='aaaa';
+UPDATE ONLY a SET aa='zzzzz' WHERE aa='aaaaa';
+UPDATE b SET aa='zzz' WHERE aa='aaa';
+UPDATE ONLY b SET aa='zzz' WHERE aa='aaa';
+UPDATE a SET aa='zzzzzz' WHERE aa LIKE 'aaa%';
+SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
+ relname | aa
+---------+----
+(0 rows)
+
+SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
+ relname | aa | bb
+---------+----+----
+(0 rows)
+
+SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
+ relname | aa | cc
+---------+----+----
+(0 rows)
+
+SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
+ relname | aa | bb | cc | dd
+---------+----+----+----+----
+(0 rows)
+
+SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
+ relname | aa
+---------+----
+(0 rows)
+
+SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
+ relname | aa | bb
+---------+----+----
+(0 rows)
+
+SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
+ relname | aa | cc
+---------+----+----
+(0 rows)
+
+SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
+ relname | aa | bb | cc | dd
+---------+----+----+----+----
+(0 rows)
+
+-- In Postgres-XL OIDs are not consistent across the cluster. Hence above
+-- queries do not show any result. Hence in order to ensure data consistency, we
+-- add following SQLs. In case above set of queries start producing valid
+-- results in XC, we should remove the following set
+SELECT * FROM a ORDER BY a.aa;
+ aa
+----------
+ bbb
+ bbbb
+ bbbbb
+ bbbbbb
+ bbbbbbb
+ bbbbbbbb
+ ccc
+ cccc
+ ccccc
+ cccccc
+ ccccccc
+ cccccccc
+ ddd
+ dddd
+ ddddd
+ dddddd
+ ddddddd
+ dddddddd
+ zzzz
+ zzzzz
+ zzzzzz
+ zzzzzz
+ zzzzzz
+ zzzzzz
+(24 rows)
+
+SELECT * from b ORDER BY b.aa;
+ aa | bb
+----------+----
+ bbb |
+ bbbb |
+ bbbbb |
+ bbbbbb |
+ bbbbbbb |
+ bbbbbbbb |
+ ddd |
+ dddd |
+ ddddd |
+ dddddd |
+ ddddddd |
+ dddddddd |
+(12 rows)
+
+SELECT * FROM c ORDER BY c.aa;
+ aa | cc
+----------+----
+ ccc |
+ cccc |
+ ccccc |
+ cccccc |
+ ccccccc |
+ cccccccc |
+ ddd |
+ dddd |
+ ddddd |
+ dddddd |
+ ddddddd |
+ dddddddd |
+(12 rows)
+
+SELECT * from d ORDER BY d.aa;
+ aa | bb | cc | dd
+----------+----+----+----
+ ddd | | |
+ dddd | | |
+ ddddd | | |
+ dddddd | | |
+ ddddddd | | |
+ dddddddd | | |
+(6 rows)
+
+SELECT * FROM ONLY a ORDER BY a.aa;
+ aa
+--------
+ zzzz
+ zzzzz
+ zzzzzz
+ zzzzzz
+ zzzzzz
+ zzzzzz
+(6 rows)
+
+SELECT * from ONLY b ORDER BY b.aa;
+ aa | bb
+----------+----
+ bbb |
+ bbbb |
+ bbbbb |
+ bbbbbb |
+ bbbbbbb |
+ bbbbbbbb |
+(6 rows)
+
+SELECT * FROM ONLY c ORDER BY c.aa;
+ aa | cc
+----------+----
+ ccc |
+ cccc |
+ ccccc |
+ cccccc |
+ ccccccc |
+ cccccccc |
+(6 rows)
+
+SELECT * from ONLY d ORDER BY d.aa;
+ aa | bb | cc | dd
+----------+----+----+----
+ ddd | | |
+ dddd | | |
+ ddddd | | |
+ dddddd | | |
+ ddddddd | | |
+ dddddddd | | |
+(6 rows)
+
+UPDATE b SET aa='new';
+SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
+ relname | aa
+---------+----
+(0 rows)
+
+SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
+ relname | aa | bb
+---------+----+----
+(0 rows)
+
+SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
+ relname | aa | cc
+---------+----+----
+(0 rows)
+
+SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
+ relname | aa | bb | cc | dd
+---------+----+----+----+----
+(0 rows)
+
+SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
+ relname | aa
+---------+----
+(0 rows)
+
+SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
+ relname | aa | bb
+---------+----+----
+(0 rows)
+
+SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
+ relname | aa | cc
+---------+----+----
+(0 rows)
+
+SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
+ relname | aa | bb | cc | dd
+---------+----+----+----+----
+(0 rows)
+
+-- In Postgres-XL OIDs are not consistent across the cluster. Hence above
+-- queries do not show any result. Hence in order to ensure data consistency, we
+-- add following SQLs. In case above set of queries start producing valid
+-- results in XC, we should remove the following set
+SELECT * FROM a ORDER BY a.aa;
+ aa
+----------
+ ccc
+ cccc
+ ccccc
+ cccccc
+ ccccccc
+ cccccccc
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+ zzzz
+ zzzzz
+ zzzzzz
+ zzzzzz
+ zzzzzz
+ zzzzzz
+(24 rows)
+
+SELECT * from b ORDER BY b.aa;
+ aa | bb
+-----+----
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+(12 rows)
+
+SELECT * FROM c ORDER BY c.aa;
+ aa | cc
+----------+----
+ ccc |
+ cccc |
+ ccccc |
+ cccccc |
+ ccccccc |
+ cccccccc |
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+(12 rows)
+
+SELECT * from d ORDER BY d.aa;
+ aa | bb | cc | dd
+-----+----+----+----
+ new | | |
+ new | | |
+ new | | |
+ new | | |
+ new | | |
+ new | | |
+(6 rows)
+
+SELECT * FROM ONLY a ORDER BY a.aa;
+ aa
+--------
+ zzzz
+ zzzzz
+ zzzzzz
+ zzzzzz
+ zzzzzz
+ zzzzzz
+(6 rows)
+
+SELECT * from ONLY b ORDER BY b.aa;
+ aa | bb
+-----+----
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+(6 rows)
+
+SELECT * FROM ONLY c ORDER BY c.aa;
+ aa | cc
+----------+----
+ ccc |
+ cccc |
+ ccccc |
+ cccccc |
+ ccccccc |
+ cccccccc |
+(6 rows)
+
+SELECT * from ONLY d ORDER BY d.aa;
+ aa | bb | cc | dd
+-----+----+----+----
+ new | | |
+ new | | |
+ new | | |
+ new | | |
+ new | | |
+ new | | |
+(6 rows)
+
+UPDATE a SET aa='new';
+DELETE FROM ONLY c WHERE aa='new';
+SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
+ relname | aa
+---------+----
+(0 rows)
+
+SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
+ relname | aa | bb
+---------+----+----
+(0 rows)
+
+SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
+ relname | aa | cc
+---------+----+----
+(0 rows)
+
+SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
+ relname | aa | bb | cc | dd
+---------+----+----+----+----
+(0 rows)
+
+SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
+ relname | aa
+---------+----
+(0 rows)
+
+SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
+ relname | aa | bb
+---------+----+----
+(0 rows)
+
+SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
+ relname | aa | cc
+---------+----+----
+(0 rows)
+
+SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
+ relname | aa | bb | cc | dd
+---------+----+----+----+----
+(0 rows)
+
+-- In Postgres-XL OIDs are not consistent across the cluster. Hence above
+-- queries do not show any result. Hence in order to ensure data consistency, we
+-- add following SQLs. In case above set of queries start producing valid
+-- results in XC, we should remove the following set
+SELECT * FROM a ORDER BY a.aa;
+ aa
+-----
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+ new
+(18 rows)
+
+SELECT * from b ORDER BY b.aa;
+ aa | bb
+-----+----
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+(12 rows)
+
+SELECT * FROM c ORDER BY c.aa;
+ aa | cc
+-----+----
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+(6 rows)
+
+SELECT * from d ORDER BY d.aa;
+ aa | bb | cc | dd
+-----+----+----+----
+ new | | |
+ new | | |
+ new | | |
+ new | | |
+ new | | |
+ new | | |
+(6 rows)
+
+SELECT * FROM ONLY a ORDER BY a.aa;
+ aa
+-----
+ new
+ new
+ new
+ new
+ new
+ new
+(6 rows)
+
+SELECT * from ONLY b ORDER BY b.aa;
+ aa | bb
+-----+----
+ new |
+ new |
+ new |
+ new |
+ new |
+ new |
+(6 rows)
+
+SELECT * FROM ONLY c ORDER BY c.aa;
+ aa | cc
+----+----
+(0 rows)
+
+SELECT * from ONLY d ORDER BY d.aa;
+ aa | bb | cc | dd
+-----+----+----+----
+ new | | |
+ new | | |
+ new | | |
+ new | | |
+ new | | |
+ new | | |
+(6 rows)
+
+DELETE FROM a;
+SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
+ relname | aa
+---------+----
+(0 rows)
+
+SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
+ relname | aa | bb
+---------+----+----
+(0 rows)
+
+SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
+ relname | aa | cc
+---------+----+----
+(0 rows)
+
+SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
+ relname | aa | bb | cc | dd
+---------+----+----+----+----
+(0 rows)
+
+SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid ORDER BY relname, a.aa;
+ relname | aa
+---------+----
+(0 rows)
+
+SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid ORDER BY relname, b.aa;
+ relname | aa | bb
+---------+----+----
+(0 rows)
+
+SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid ORDER BY relname, c.aa;
+ relname | aa | cc
+---------+----+----
+(0 rows)
+
+SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid ORDER BY relname, d.aa;
+ relname | aa | bb | cc | dd
+---------+----+----+----+----
+(0 rows)
+
+-- In Postgres-XL OIDs are not consistent across the cluster. Hence above
+-- queries do not show any result. Hence in order to ensure data consistency, we
+-- add following SQLs. In case above set of queries start producing valid
+-- results in XC, we should remove the following set
+SELECT * FROM a ORDER BY a.aa;
+ aa
+----
+(0 rows)
+
+SELECT * from b ORDER BY b.aa;
+ aa | bb
+----+----
+(0 rows)
+
+SELECT * FROM c ORDER BY c.aa;
+ aa | cc
+----+----
+(0 rows)
+
+SELECT * from d ORDER BY d.aa;
+ aa | bb | cc | dd
+----+----+----+----
+(0 rows)
+
+SELECT * FROM ONLY a ORDER BY a.aa;
+ aa
+----
+(0 rows)
+
+SELECT * from ONLY b ORDER BY b.aa;
+ aa | bb
+----+----
+(0 rows)
+
+SELECT * FROM ONLY c ORDER BY c.aa;
+ aa | cc
+----+----
+(0 rows)
+
+SELECT * from ONLY d ORDER BY d.aa;
+ aa | bb | cc | dd
+----+----+----+----
+(0 rows)
+
+-- Confirm PRIMARY KEY adds NOT NULL constraint to child table
+CREATE TEMP TABLE z (b TEXT, PRIMARY KEY(aa, b)) inherits (a);
+INSERT INTO z VALUES (NULL, 'text'); -- should fail
+ERROR: null value in column "aa" violates not-null constraint
+DETAIL: Failing row contains (null, text).
+-- Check UPDATE with inherited target and an inherited source table
+create temp table foo(f1 int, f2 int);
+create temp table foo2(f3 int) inherits (foo);
+create temp table bar(f1 int, f2 int);
+create temp table bar2(f3 int) inherits (bar);
+insert into foo values(1,1);
+insert into foo values(3,3);
+insert into foo2 values(2,2,2);
+insert into foo2 values(3,3,3);
+insert into bar values(1,1);
+insert into bar values(2,2);
+insert into bar values(3,3);
+insert into bar values(4,4);
+insert into bar2 values(1,1,1);
+insert into bar2 values(2,2,2);
+insert into bar2 values(3,3,3);
+insert into bar2 values(4,4,4);
+update bar set f2 = f2 + 100 where f1 in (select f1 from foo);
+--select tableoid::regclass::text as relname, bar.* from bar order by 1,2;
+-- In Postgres-XL OIDs are not consistent across the cluster. Hence above
+-- queries do not show any result. Hence in order to ensure data consistency, we
+-- add following SQLs. In case above set of queries start producing valid
+-- results in XC, we should remove the following set
+SELECT * FROM bar ORDER BY f1, f2;
+ f1 | f2
+----+-----
+ 1 | 101
+ 1 | 101
+ 2 | 102
+ 2 | 102
+ 3 | 103
+ 3 | 103
+ 4 | 4
+ 4 | 4
+(8 rows)
+
+SELECT * FROM ONLY bar ORDER BY f1, f2;
+ f1 | f2
+----+-----
+ 1 | 101
+ 2 | 102
+ 3 | 103
+ 4 | 4
+(4 rows)
+
+SELECT * FROM bar2 ORDER BY f1, f2;
+ f1 | f2 | f3
+----+-----+----
+ 1 | 101 | 1
+ 2 | 102 | 2
+ 3 | 103 | 3
+ 4 | 4 | 4
+(4 rows)
+
+-- Check UPDATE with inherited target and an appendrel subquery
+update bar set f2 = f2 + 100
+from
+ ( select f1 from foo union all select f1+3 from foo ) ss
+where bar.f1 = ss.f1;
+--select tableoid::regclass::text as relname, bar.* from bar order by 1,2;
+/* Test multiple inheritance of column defaults */
+CREATE TABLE firstparent (tomorrow date default now()::date + 1);
+CREATE TABLE secondparent (tomorrow date default now() :: date + 1);
+CREATE TABLE jointchild () INHERITS (firstparent, secondparent); -- ok
+NOTICE: merging multiple inherited definitions of column "tomorrow"
+CREATE TABLE thirdparent (tomorrow date default now()::date - 1);
+CREATE TABLE otherchild () INHERITS (firstparent, thirdparent); -- not ok
+NOTICE: merging multiple inherited definitions of column "tomorrow"
+ERROR: column "tomorrow" inherits conflicting default values
+HINT: To resolve the conflict, specify a default explicitly.
+CREATE TABLE otherchild (tomorrow date default now())
+ INHERITS (firstparent, thirdparent); -- ok, child resolves ambiguous default
+NOTICE: merging multiple inherited definitions of column "tomorrow"
+NOTICE: merging column "tomorrow" with inherited definition
+DROP TABLE firstparent, secondparent, jointchild, thirdparent, otherchild;
+-- Test changing the type of inherited columns
+insert into d values('test','one','two','three');
+alter table a alter column aa type integer using bit_length(aa);
+select * from d;
+ aa | bb | cc | dd
+----+-----+-----+-------
+ 32 | one | two | three
+(1 row)
+
+-- Test non-inheritable parent constraints
+create table p1(ff1 int);
+alter table p1 add constraint p1chk check (ff1 > 0) no inherit;
+alter table p1 add constraint p2chk check (ff1 > 10);
+-- connoinherit should be true for NO INHERIT constraint
+select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.connoinherit from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname = 'p1' order by 1,2;
+ relname | conname | contype | conislocal | coninhcount | connoinherit
+---------+---------+---------+------------+-------------+--------------
+ p1 | p1chk | c | t | 0 | t
+ p1 | p2chk | c | t | 0 | f
+(2 rows)
+
+-- Test that child does not inherit NO INHERIT constraints
+create table c1 () inherits (p1);
+\d p1
+ Table "public.p1"
+ Column | Type | Modifiers
+--------+---------+-----------
+ ff1 | integer |
+Check constraints:
+ "p1chk" CHECK (ff1 > 0) NO INHERIT
+ "p2chk" CHECK (ff1 > 10)
+Number of child tables: 1 (Use \d+ to list them.)
+
+\d c1
+ Table "public.c1"
+ Column | Type | Modifiers
+--------+---------+-----------
+ ff1 | integer |
+Check constraints:
+ "p2chk" CHECK (ff1 > 10)
+Inherits: p1
+
+drop table p1 cascade;
+NOTICE: drop cascades to table c1
+-- Tests for casting between the rowtypes of parent and child
+-- tables. See the pgsql-hackers thread beginning Dec. 4/04
+create table base (i integer);
+create table derived () inherits (base);
+insert into derived (i) values (0);
+select derived::base from derived;
+ derived
+---------
+ (0)
+(1 row)
+
+drop table derived;
+drop table base;
+create table p1(ff1 int);
+create table p2(f1 text);
+create function p2text(p2) returns text as 'select $1.f1' language sql;
+create table c1(f3 int) inherits(p1,p2);
+insert into c1 values(123456789, 'hi', 42);
+select p2text(c1.*) from c1;
+ p2text
+--------
+ hi
+(1 row)
+
+drop function p2text(p2);
+drop table c1;
+drop table p2;
+drop table p1;
+CREATE TABLE ac (aa TEXT);
+alter table ac add constraint ac_check check (aa is not null);
+CREATE TABLE bc (bb TEXT) INHERITS (ac);
+select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2;
+ relname | conname | contype | conislocal | coninhcount | consrc
+---------+----------+---------+------------+-------------+------------------
+ ac | ac_check | c | t | 0 | (aa IS NOT NULL)
+ bc | ac_check | c | f | 1 | (aa IS NOT NULL)
+(2 rows)
+
+insert into ac (aa) values (NULL);
+ERROR: new row for relation "ac" violates check constraint "ac_check"
+DETAIL: Failing row contains (null).
+insert into bc (aa) values (NULL);
+ERROR: new row for relation "bc" violates check constraint "ac_check"
+DETAIL: Failing row contains (null, null).
+alter table bc drop constraint ac_check; -- fail, disallowed
+ERROR: cannot drop inherited constraint "ac_check" of relation "bc"
+alter table ac drop constraint ac_check;
+select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2;
+ relname | conname | contype | conislocal | coninhcount | consrc
+---------+---------+---------+------------+-------------+--------
+(0 rows)
+
+-- try the unnamed-constraint case
+alter table ac add check (aa is not null);
+select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2;
+ relname | conname | contype | conislocal | coninhcount | consrc
+---------+-------------+---------+------------+-------------+------------------
+ ac | ac_aa_check | c | t | 0 | (aa IS NOT NULL)
+ bc | ac_aa_check | c | f | 1 | (aa IS NOT NULL)
+(2 rows)
+
+insert into ac (aa) values (NULL);
+ERROR: new row for relation "ac" violates check constraint "ac_aa_check"
+DETAIL: Failing row contains (null).
+insert into bc (aa) values (NULL);
+ERROR: new row for relation "bc" violates check constraint "ac_aa_check"
+DETAIL: Failing row contains (null, null).
+alter table bc drop constraint ac_aa_check; -- fail, disallowed
+ERROR: cannot drop inherited constraint "ac_aa_check" of relation "bc"
+alter table ac drop constraint ac_aa_check;
+select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2;
+ relname | conname | contype | conislocal | coninhcount | consrc
+---------+---------+---------+------------+-------------+--------
+(0 rows)
+
+alter table ac add constraint ac_check check (aa is not null);
+alter table bc no inherit ac;
+select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2;
+ relname | conname | contype | conislocal | coninhcount | consrc
+---------+----------+---------+------------+-------------+------------------
+ ac | ac_check | c | t | 0 | (aa IS NOT NULL)
+ bc | ac_check | c | t | 0 | (aa IS NOT NULL)
+(2 rows)
+
+alter table bc drop constraint ac_check;
+select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2;
+ relname | conname | contype | conislocal | coninhcount | consrc
+---------+----------+---------+------------+-------------+------------------
+ ac | ac_check | c | t | 0 | (aa IS NOT NULL)
+(1 row)
+
+alter table ac drop constraint ac_check;
+select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2;
+ relname | conname | contype | conislocal | coninhcount | consrc
+---------+---------+---------+------------+-------------+--------
+(0 rows)
+
+drop table bc;
+drop table ac;
+create table ac (a int constraint check_a check (a <> 0));
+create table bc (a int constraint check_a check (a <> 0), b int constraint check_b check (b <> 0)) inherits (ac);
+NOTICE: merging column "a" with inherited definition
+NOTICE: merging constraint "check_a" with inherited definition
+select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2;
+ relname | conname | contype | conislocal | coninhcount | consrc
+---------+---------+---------+------------+-------------+----------
+ ac | check_a | c | t | 0 | (a <> 0)
+ bc | check_a | c | t | 1 | (a <> 0)
+ bc | check_b | c | t | 0 | (b <> 0)
+(3 rows)
+
+drop table bc;
+drop table ac;
+create table ac (a int constraint check_a check (a <> 0));
+create table bc (b int constraint check_b check (b <> 0));
+create table cc (c int constraint check_c check (c <> 0)) inherits (ac, bc);
+select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2;
+ relname | conname | contype | conislocal | coninhcount | consrc
+---------+---------+---------+------------+-------------+----------
+ ac | check_a | c | t | 0 | (a <> 0)
+ bc | check_b | c | t | 0 | (b <> 0)
+ cc | check_a | c | f | 1 | (a <> 0)
+ cc | check_b | c | f | 1 | (b <> 0)
+ cc | check_c | c | t | 0 | (c <> 0)
+(5 rows)
+
+alter table cc no inherit bc;
+select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2;
+ relname | conname | contype | conislocal | coninhcount | consrc
+---------+---------+---------+------------+-------------+----------
+ ac | check_a | c | t | 0 | (a <> 0)
+ bc | check_b | c | t | 0 | (b <> 0)
+ cc | check_a | c | f | 1 | (a <> 0)
+ cc | check_b | c | t | 0 | (b <> 0)
+ cc | check_c | c | t | 0 | (c <> 0)
+(5 rows)
+
+drop table cc;
+drop table bc;
+drop table ac;
+create table p1(f1 int);
+create table p2(f2 int);
+create table c1(f3 int) inherits(p1,p2);
+insert into c1 values(1,-1,2);
+alter table p2 add constraint cc check (f2>0); -- fail
+ERROR: check constraint "cc" is violated by some row
+alter table p2 add check (f2>0); -- check it without a name, too
+ERROR: check constraint "p2_f2_check" is violated by some row
+delete from c1;
+insert into c1 values(1,1,2);
+alter table p2 add check (f2>0);
+insert into c1 values(1,-1,2); -- fail
+ERROR: new row for relation "c1" violates check constraint "p2_f2_check"
+DETAIL: Failing row contains (1, -1, 2).
+create table c2(f3 int) inherits(p1,p2);
+\d c2
+ Table "public.c2"
+ Column | Type | Modifiers
+--------+---------+-----------
+ f1 | integer |
+ f2 | integer |
+ f3 | integer |
+Check constraints:
+ "p2_f2_check" CHECK (f2 > 0)
+Inherits: p1,
+ p2
+
+create table c3 (f4 int) inherits(c1,c2);
+NOTICE: merging multiple inherited definitions of column "f1"
+NOTICE: merging multiple inherited definitions of column "f2"
+NOTICE: merging multiple inherited definitions of column "f3"
+\d c3
+ Table "public.c3"
+ Column | Type | Modifiers
+--------+---------+-----------
+ f1 | integer |
+ f2 | integer |
+ f3 | integer |
+ f4 | integer |
+Check constraints:
+ "p2_f2_check" CHECK (f2 > 0)
+Inherits: c1,
+ c2
+
+drop table p1 cascade;
+NOTICE: drop cascades to 3 other objects
+DETAIL: drop cascades to table c1
+drop cascades to table c2
+drop cascades to table c3
+drop table p2 cascade;
+create table pp1 (f1 int);
+create table cc1 (f2 text, f3 int) inherits (pp1);
+alter table pp1 add column a1 int check (a1 > 0);
+\d cc1
+ Table "public.cc1"
+ Column | Type | Modifiers
+--------+---------+-----------
+ f1 | integer |
+ f2 | text |
+ f3 | integer |
+ a1 | integer |
+Check constraints:
+ "pp1_a1_check" CHECK (a1 > 0)
+Inherits: pp1
+
+create table cc2(f4 float) inherits(pp1,cc1);
+NOTICE: merging multiple inherited definitions of column "f1"
+NOTICE: merging multiple inherited definitions of column "a1"
+\d cc2
+ Table "public.cc2"
+ Column | Type | Modifiers
+--------+------------------+-----------
+ f1 | integer |
+ a1 | integer |
+ f2 | text |
+ f3 | integer |
+ f4 | double precision |
+Check constraints:
+ "pp1_a1_check" CHECK (a1 > 0)
+Inherits: pp1,
+ cc1
+
+alter table pp1 add column a2 int check (a2 > 0);
+NOTICE: merging definition of column "a2" for child "cc2"
+NOTICE: merging constraint "pp1_a2_check" with inherited definition
+\d cc2
+ Table "public.cc2"
+ Column | Type | Modifiers
+--------+------------------+-----------
+ f1 | integer |
+ a1 | integer |
+ f2 | text |
+ f3 | integer |
+ f4 | double precision |
+ a2 | integer |
+Check constraints:
+ "pp1_a1_check" CHECK (a1 > 0)
+ "pp1_a2_check" CHECK (a2 > 0)
+Inherits: pp1,
+ cc1
+
+drop table pp1 cascade;
+NOTICE: drop cascades to 2 other objects
+DETAIL: drop cascades to table cc1
+drop cascades to table cc2
+-- Test for renaming in simple multiple inheritance
+CREATE TABLE inht1 (a int, b int);
+CREATE TABLE inhs1 (b int, c int);
+CREATE TABLE inhts (d int) INHERITS (inht1, inhs1);
+NOTICE: merging multiple inherited definitions of column "b"
+ALTER TABLE inht1 RENAME a TO aa;
+ALTER TABLE inht1 RENAME b TO bb; -- to be failed
+ERROR: cannot rename inherited column "b"
+ALTER TABLE inhts RENAME aa TO aaa; -- to be failed
+ERROR: cannot rename inherited column "aa"
+ALTER TABLE inhts RENAME d TO dd;
+\d+ inhts
+ Table "public.inhts"
+ Column | Type | Modifiers | Storage | Stats target | Description
+--------+---------+-----------+---------+--------------+-------------
+ aa | integer | | plain | |
+ b | integer | | plain | |
+ c | integer | | plain | |
+ dd | integer | | plain | |
+Inherits: inht1,
+ inhs1
+Distribute By: HASH(aa)
+Location Nodes: ALL DATANODES
+
+DROP TABLE inhts;
+-- Test for renaming in diamond inheritance
+CREATE TABLE inht2 (x int) INHERITS (inht1);
+CREATE TABLE inht3 (y int) INHERITS (inht1);
+CREATE TABLE inht4 (z int) INHERITS (inht2, inht3);
+NOTICE: merging multiple inherited definitions of column "aa"
+NOTICE: merging multiple inherited definitions of column "b"
+ALTER TABLE inht1 RENAME aa TO aaa;
+\d+ inht4
+ Table "public.inht4"
+ Column | Type | Modifiers | Storage | Stats target | Description
+--------+---------+-----------+---------+--------------+-------------
+ aaa | integer | | plain | |
+ b | integer | | plain | |
+ x | integer | | plain | |
+ y | integer | | plain | |
+ z | integer | | plain | |
+Inherits: inht2,
+ inht3
+Distribute By: HASH(aaa)
+Location Nodes: ALL DATANODES
+
+CREATE TABLE inhts (d int) INHERITS (inht2, inhs1);
+NOTICE: merging multiple inherited definitions of column "b"
+ALTER TABLE inht1 RENAME aaa TO aaaa;
+ALTER TABLE inht1 RENAME b TO bb; -- to be failed
+ERROR: cannot rename inherited column "b"
+\d+ inhts
+ Table "public.inhts"
+ Column | Type | Modifiers | Storage | Stats target | Description
+--------+---------+-----------+---------+--------------+-------------
+ aaaa | integer | | plain | |
+ b | integer | | plain | |
+ x | integer | | plain | |
+ c | integer | | plain | |
+ d | integer | | plain | |
+Inherits: inht2,
+ inhs1
+Distribute By: HASH(aaaa)
+Location Nodes: ALL DATANODES
+
+WITH RECURSIVE r AS (
+ SELECT 'inht1'::regclass AS inhrelid
+UNION ALL
+ SELECT c.inhrelid FROM pg_inherits c, r WHERE r.inhrelid = c.inhparent
+)
+SELECT a.attrelid::regclass, a.attname, a.attinhcount, e.expected
+ FROM (SELECT inhrelid, count(*) AS expected FROM pg_inherits
+ WHERE inhparent IN (SELECT inhrelid FROM r) GROUP BY inhrelid) e
+ JOIN pg_attribute a ON e.inhrelid = a.attrelid WHERE NOT attislocal
+ ORDER BY a.attrelid::regclass::name, a.attnum;
+ attrelid | attname | attinhcount | expected
+----------+---------+-------------+----------
+ inht2 | aaaa | 1 | 1
+ inht2 | b | 1 | 1
+ inht3 | aaaa | 1 | 1
+ inht3 | b | 1 | 1
+ inht4 | aaaa | 2 | 2
+ inht4 | b | 2 | 2
+ inht4 | x | 1 | 2
+ inht4 | y | 1 | 2
+ inhts | aaaa | 1 | 1
+ inhts | b | 2 | 1
+ inhts | x | 1 | 1
+ inhts | c | 1 | 1
+(12 rows)
+
+DROP TABLE inht1, inhs1 CASCADE;
+NOTICE: drop cascades to 4 other objects
+DETAIL: drop cascades to table inht2
+drop cascades to table inhts
+drop cascades to table inht3
+drop cascades to table inht4
+-- Test non-inheritable indices [UNIQUE, EXCLUDE] contraints
+CREATE TABLE test_constraints (id int, val1 varchar, val2 int, UNIQUE(val1, val2));
+CREATE TABLE test_constraints_inh () INHERITS (test_constraints);
+\d+ test_constraints
+ Table "public.test_constraints"
+ Column | Type | Modifiers | Storage | Stats target | Description
+--------+-------------------+-----------+----------+--------------+-------------
+ id | integer | | plain | |
+ val1 | character varying | | extended | |
+ val2 | integer | | plain | |
+Indexes:
+ "test_constraints_val1_val2_key" UNIQUE CONSTRAINT, btree (val1, val2)
+Child tables: test_constraints_inh
+Distribute By: HASH(val1)
+Location Nodes: ALL DATANODES
+
+ALTER TABLE ONLY test_constraints DROP CONSTRAINT test_constraints_val1_val2_key;
+\d+ test_constraints
+ Table "public.test_constraints"
+ Column | Type | Modifiers | Storage | Stats target | Description
+--------+-------------------+-----------+----------+--------------+-------------
+ id | integer | | plain | |
+ val1 | character varying | | extended | |
+ val2 | integer | | plain | |
+Child tables: test_constraints_inh
+Distribute By: HASH(val1)
+Location Nodes: ALL DATANODES
+
+\d+ test_constraints_inh
+ Table "public.test_constraints_inh"
+ Column | Type | Modifiers | Storage | Stats target | Description
+--------+-------------------+-----------+----------+--------------+-------------
+ id | integer | | plain | |
+ val1 | character varying | | extended | |
+ val2 | integer | | plain | |
+Inherits: test_constraints
+Distribute By: HASH(val1)
+Location Nodes: ALL DATANODES
+
+DROP TABLE test_constraints_inh;
+DROP TABLE test_constraints;
+CREATE TABLE test_ex_constraints (
+ c circle,
+ EXCLUDE USING gist (c WITH &&)
+);
+CREATE TABLE test_ex_constraints_inh () INHERITS (test_ex_constraints);
+\d+ test_ex_constraints
+ Table "public.test_ex_constraints"
+ Column | Type | Modifiers | Storage | Stats target | Description
+--------+--------+-----------+---------+--------------+-------------
+ c | circle | | plain | |
+Indexes:
+ "test_ex_constraints_c_excl" EXCLUDE USING gist (c WITH &&)
+Child tables: test_ex_constraints_inh
+Distribute By: ROUND ROBIN
+Location Nodes: ALL DATANODES
+
+ALTER TABLE test_ex_constraints DROP CONSTRAINT test_ex_constraints_c_excl;
+\d+ test_ex_constraints
+ Table "public.test_ex_constraints"
+ Column | Type | Modifiers | Storage | Stats target | Description
+--------+--------+-----------+---------+--------------+-------------
+ c | circle | | plain | |
+Child tables: test_ex_constraints_inh
+Distribute By: ROUND ROBIN
+Location Nodes: ALL DATANODES
+
+\d+ test_ex_constraints_inh
+ Table "public.test_ex_constraints_inh"
+ Column | Type | Modifiers | Storage | Stats target | Description
+--------+--------+-----------+---------+--------------+-------------
+ c | circle | | plain | |
+Inherits: test_ex_constraints
+Distribute By: ROUND ROBIN
+Location Nodes: ALL DATANODES
+
+DROP TABLE test_ex_constraints_inh;
+DROP TABLE test_ex_constraints;
+-- Test non-inheritable foreign key contraints
+CREATE TABLE test_primary_constraints(id int PRIMARY KEY);
+CREATE TABLE test_foreign_constraints(id1 int REFERENCES test_primary_constraints(id));
+CREATE TABLE test_foreign_constraints_inh () INHERITS (test_foreign_constraints);
+\d+ test_primary_constraints
+ Table "public.test_primary_constraints"
+ Column | Type | Modifiers | Storage | Stats target | Description
+--------+---------+-----------+---------+--------------+-------------
+ id | integer | not null | plain | |
+Indexes:
+ "test_primary_constraints_pkey" PRIMARY KEY, btree (id)
+Referenced by:
+ TABLE "test_foreign_constraints" CONSTRAINT "test_foreign_constraints_id1_fkey" FOREIGN KEY (id1) REFERENCES test_primary_constraints(id)
+Distribute By: HASH(id)
+Location Nodes: ALL DATANODES
+
+\d+ test_foreign_constraints
+ Table "public.test_foreign_constraints"
+ Column | Type | Modifiers | Storage | Stats target | Description
+--------+---------+-----------+---------+--------------+-------------
+ id1 | integer | | plain | |
+Foreign-key constraints:
+ "test_foreign_constraints_id1_fkey" FOREIGN KEY (id1) REFERENCES test_primary_constraints(id)
+Child tables: test_foreign_constraints_inh
+Distribute By: HASH(id1)
+Location Nodes: ALL DATANODES
+
+ALTER TABLE test_foreign_constraints DROP CONSTRAINT test_foreign_constraints_id1_fkey;
+\d+ test_foreign_constraints
+ Table "public.test_foreign_constraints"
+ Column | Type | Modifiers | Storage | Stats target | Description
+--------+---------+-----------+---------+--------------+-------------
+ id1 | integer | | plain | |
+Child tables: test_foreign_constraints_inh
+Distribute By: HASH(id1)
+Location Nodes: ALL DATANODES
+
+\d+ test_foreign_constraints_inh
+ Table "public.test_foreign_constraints_inh"
+ Column | Type | Modifiers | Storage | Stats target | Description
+--------+---------+-----------+---------+--------------+-------------
+ id1 | integer | | plain | |
+Inherits: test_foreign_constraints
+Distribute By: HASH(id1)
+Location Nodes: ALL DATANODES
+
+DROP TABLE test_foreign_constraints_inh;
+DROP TABLE test_foreign_constraints;
+DROP TABLE test_primary_constraints;
+--
+-- Test parameterized append plans for inheritance trees
+--
+create temp table patest0 (id, x) as
+ select x, x from generate_series(0,1000) x;
+create temp table patest1() inherits (patest0);
+insert into patest1
+ select x, x from generate_series(0,1000) x;
+create temp table patest2() inherits (patest0);
+insert into patest2
+ select x, x from generate_series(0,1000) x;
+create index patest0i on patest0(id);
+create index patest1i on patest1(id);
+create index patest2i on patest2(id);
+analyze patest0;
+analyze patest1;
+analyze patest2;
+analyze int4_tbl;
+explain (costs off, num_nodes off, nodes off)
+select * from patest0 join (select f1 from int4_tbl where f1 = 0 limit 1) ss on id = f1;
+ QUERY PLAN
+----------------------------------------------------------------
+ Nested Loop
+ -> Limit
+ -> Remote Subquery Scan on all
+ -> Limit
+ -> Seq Scan on int4_tbl
+ Filter: (f1 = 0)
+ -> Materialize
+ -> Remote Subquery Scan on all
+ -> Append
+ -> Bitmap Heap Scan on patest0
+ Recheck Cond: (id = int4_tbl.f1)
+ -> Bitmap Index Scan on patest0i
+ Index Cond: (id = int4_tbl.f1)
+ -> Index Scan using patest1i on patest1
+ Index Cond: (id = int4_tbl.f1)
+ -> Index Scan using patest2i on patest2
+ Index Cond: (id = int4_tbl.f1)
+(17 rows)
+
+select * from patest0 join (select f1 from int4_tbl where f1 = 0 limit 1) ss on id = f1;
+ id | x | f1
+----+---+----
+ 0 | 0 | 0
+ 0 | 0 | 0
+ 0 | 0 | 0
+(3 rows)
+
+drop index patest2i;
+explain (costs off, num_nodes off, nodes off)
+select * from patest0 join (select f1 from int4_tbl where f1 = 0 limit 1) ss on id = f1;
+ QUERY PLAN
+----------------------------------------------------------------
+ Nested Loop
+ -> Limit
+ -> Remote Subquery Scan on all
+ -> Limit
+ -> Seq Scan on int4_tbl
+ Filter: (f1 = 0)
+ -> Materialize
+ -> Remote Subquery Scan on all
+ -> Append
+ -> Bitmap Heap Scan on patest0
+ Recheck Cond: (id = int4_tbl.f1)
+ -> Bitmap Index Scan on patest0i
+ Index Cond: (id = int4_tbl.f1)
+ -> Index Scan using patest1i on patest1
+ Index Cond: (id = int4_tbl.f1)
+ -> Seq Scan on patest2
+ Filter: (int4_tbl.f1 = id)
+(17 rows)
+
+select * from patest0 join (select f1 from int4_tbl where f1 = 0 limit 1) ss on id = f1;
+ id | x | f1
+----+---+----
+ 0 | 0 | 0
+ 0 | 0 | 0
+ 0 | 0 | 0
+(3 rows)
+
+drop table patest0 cascade;
+NOTICE: drop cascades to 2 other objects
+DETAIL: drop cascades to table patest1
+drop cascades to table patest2
+--
+-- Test merge-append plans for inheritance trees
+--
+create table matest0 (id serial primary key, name text);
+create table matest1 (id integer primary key) inherits (matest0);
+NOTICE: merging column "id" with inherited definition
+create table matest2 (id integer primary key) inherits (matest0);
+NOTICE: merging column "id" with inherited definition
+create table matest3 (id integer primary key) inherits (matest0);
+NOTICE: merging column "id" with inherited definition
+create index matest0i on matest0 ((1-id));
+create index matest1i on matest1 ((1-id));
+-- create index matest2i on matest2 ((1-id)); -- intentionally missing
+create index matest3i on matest3 ((1-id));
+insert into matest1 (name) values ('Test 1');
+insert into matest1 (name) values ('Test 2');
+insert into matest2 (name) values ('Test 3');
+insert into matest2 (name) values ('Test 4');
+insert into matest3 (name) values ('Test 5');
+insert into matest3 (name) values ('Test 6');
+set enable_indexscan = off; -- force use of seqscan/sort, so no merge
+explain (verbose, costs off, nodes off) select * from matest0 order by 1-id;
+ QUERY PLAN
+------------------------------------------------------------------
+ Remote Subquery Scan on all
+ Output: id, name, (1 - id)
+ -> Sort
+ Output: matest0.id, matest0.name, ((1 - matest0.id))
+ Sort Key: ((1 - matest0.id))
+ -> Result
+ Output: matest0.id, matest0.name, (1 - matest0.id)
+ -> Append
+ -> Seq Scan on public.matest0
+ Output: matest0.id, matest0.name
+ -> Seq Scan on public.matest1
+ Output: matest1.id, matest1.name
+ -> Seq Scan on public.matest2
+ Output: matest2.id, matest2.name
+ -> Seq Scan on public.matest3
+ Output: matest3.id, matest3.name
+(16 rows)
+
+select * from matest0 order by 1-id;
+ id | name
+----+--------
+ 6 | Test 6
+ 5 | Test 5
+ 4 | Test 4
+ 3 | Test 3
+ 2 | Test 2
+ 1 | Test 1
+(6 rows)
+
+explain (verbose, costs off) select min(1-id) from matest0;
+ QUERY PLAN
+-----------------------------------------------------------
+ Aggregate
+ Output: min((min((1 - id))))
+ -> Remote Subquery Scan on all (datanode_1,datanode_2)
+ Output: min((1 - id))
+ -> Aggregate
+ Output: min((1 - matest0.id))
+ -> Append
+ -> Seq Scan on public.matest0
+ Output: matest0.id
+ -> Seq Scan on public.matest1
+ Output: matest1.id
+ -> Seq Scan on public.matest2
+ Output: matest2.id
+ -> Seq Scan on public.matest3
+ Output: matest3.id
+(15 rows)
+
+select min(1-id) from matest0;
+ min
+-----
+ -5
+(1 row)
+
+reset enable_indexscan;
+set enable_seqscan = off; -- plan with fewest seqscans should be merge
+explain (verbose, costs off, nodes off) select * from matest0 order by 1-id;
+ QUERY PLAN
+---------------------------------------------------------------------
+ Remote Subquery Scan on all
+ Output: id, name, (1 - id)
+ -> Sort
+ Output: matest0.id, matest0.name, ((1 - matest0.id))
+ Sort Key: ((1 - matest0.id))
+ -> Result
+ Output: matest0.id, matest0.name, (1 - matest0.id)
+ -> Append
+ -> Index Scan using matest0i on public.matest0
+ Output: matest0.id, matest0.name
+ -> Index Scan using matest1i on public.matest1
+ Output: matest1.id, matest1.name
+ -> Seq Scan on public.matest2
+ Output: matest2.id, matest2.name
+ -> Index Scan using matest3i on public.matest3
+ Output: matest3.id, matest3.name
+(16 rows)
+
+select * from matest0 order by 1-id;
+ id | name
+----+--------
+ 6 | Test 6
+ 5 | Test 5
+ 4 | Test 4
+ 3 | Test 3
+ 2 | Test 2
+ 1 | Test 1
+(6 rows)
+
+explain (verbose, costs off) select min(1-id) from matest0;
+ QUERY PLAN
+------------------------------------------------------------------------------
+ Aggregate
+ Output: min((min((1 - id))))
+ -> Remote Subquery Scan on all (datanode_1,datanode_2)
+ Output: min((1 - id))
+ -> Aggregate
+ Output: min((1 - matest0.id))
+ -> Append
+ -> Index Only Scan using matest0_pkey on public.matest0
+ Output: matest0.id
+ -> Bitmap Heap Scan on public.matest1
+ Output: matest1.id
+ -> Bitmap Index Scan on matest1_pkey
+ -> Bitmap Heap Scan on public.matest2
+ Output: matest2.id
+ -> Bitmap Index Scan on matest2_pkey
+ -> Bitmap Heap Scan on public.matest3
+ Output: matest3.id
+ -> Bitmap Index Scan on matest3_pkey
+(18 rows)
+
+select min(1-id) from matest0;
+ min
+-----
+ -5
+(1 row)
+
+reset enable_seqscan;
+drop table matest0 cascade;
+NOTICE: drop cascades to 3 other objects
+DETAIL: drop cascades to table matest1
+drop cascades to table matest2
+drop cascades to table matest3
+--
+-- Check that use of an index with an extraneous column doesn't produce
+-- a plan with extraneous sorting
+--
+create table matest0 (a int, b int, c int, d int);
+create table matest1 () inherits(matest0);
+create index matest0i on matest0 (b, c);
+create index matest1i on matest1 (b, c);
+set enable_nestloop = off; -- we want a plan with two MergeAppends
+explain (costs off)
+select t1.* from matest0 t1, matest0 t2
+where t1.b = t2.b and t2.c = t2.d
+order by t1.b limit 10;
+ QUERY PLAN
+-----------------------------------------------------------------------------------------
+ Limit
+ -> Remote Subquery Scan on all (datanode_1,datanode_2)
+ -> Limit
+ -> Sort
+ Sort Key: b
+ -> Hash Join
+ Hash Cond: (b = b)
+ -> Remote Subquery Scan on all (datanode_1,datanode_2)
+ Distribute results by H: b
+ -> Append
+ -> Seq Scan on matest0 t1
+ -> Seq Scan on matest1 t1_1
+ -> Hash
+ -> Remote Subquery Scan on all (datanode_1,datanode_2)
+ Distribute results by H: b
+ -> Append
+ -> Seq Scan on matest0 t2
+ Filter: (c = d)
+ -> Seq Scan on matest1 t2_1
+ Filter: (c = d)
+(20 rows)
+
+reset enable_nestloop;
+drop table matest0 cascade;
+NOTICE: drop cascades to table matest1
+--
+-- Test merge-append for UNION ALL append relations
+--
+set enable_seqscan = off;
+set enable_indexscan = on;
+set enable_bitmapscan = off;
+-- Check handling of duplicated, constant, or volatile targetlist items
+explain (costs off, num_nodes off, nodes off)
+SELECT thousand, tenthous FROM tenk1
+UNION ALL
+SELECT thousand, thousand FROM tenk1
+ORDER BY thousand, tenthous;
+ QUERY PLAN
+-------------------------------------------------------------------------------
+ Merge Append
+ Sort Key: tenk1.thousand, tenk1.tenthous
+ -> Remote Subquery Scan on all
+ -> Index Only Scan using tenk1_thous_tenthous on tenk1
+ -> Remote Subquery Scan on all
+ -> Sort
+ Sort Key: tenk1_1.thousand, tenk1_1.thousand
+ -> Index Only Scan using tenk1_thous_tenthous on tenk1 tenk1_1
+(8 rows)
+
+explain (costs off, num_nodes off, nodes off)
+SELECT thousand, tenthous, thousand+tenthous AS x FROM tenk1
+UNION ALL
+SELECT 42, 42, hundred FROM tenk1
+ORDER BY thousand, tenthous;
+ QUERY PLAN
+------------------------------------------------------------------------
+ Remote Subquery Scan on all
+ -> Sort
+ Sort Key: tenk1.thousand, tenk1.tenthous
+ -> Append
+ -> Index Only Scan using tenk1_thous_tenthous on tenk1
+ -> Index Only Scan using tenk1_hundred on tenk1 tenk1_1
+(6 rows)
+
+explain (costs off, num_nodes off, nodes off)
+SELECT thousand, tenthous FROM tenk1
+UNION ALL
+SELECT thousand, random()::integer FROM tenk1
+ORDER BY thousand, tenthous;
+ QUERY PLAN
+-------------------------------------------------------------------------------
+ Merge Append
+ Sort Key: tenk1.thousand, tenk1.tenthous
+ -> Remote Subquery Scan on all
+ -> Index Only Scan using tenk1_thous_tenthous on tenk1
+ -> Remote Subquery Scan on all
+ -> Sort
+ Sort Key: tenk1_1.thousand, ((random())::integer)
+ -> Index Only Scan using tenk1_thous_tenthous on tenk1 tenk1_1
+(8 rows)
+
+-- Check min/max aggregate optimization
+explain (costs off, num_nodes off, nodes off)
+SELECT min(x) FROM
+ (SELECT unique1 AS x FROM tenk1 a
+ UNION ALL
+ SELECT unique2 AS x FROM tenk1 b) s;
+ QUERY PLAN
+--------------------------------------------------------------------------
+ Result
+ InitPlan 1 (returns $0)
+ -> Limit
+ -> Merge Append
+ Sort Key: a.unique1
+ -> Remote Subquery Scan on all
+ -> Index Only Scan using tenk1_unique1 on tenk1 a
+ Index Cond: (unique1 IS NOT NULL)
+ -> Remote Subquery Scan on all
+ -> Index Only Scan using tenk1_unique2 on tenk1 b
+ Index Cond: (unique2 IS NOT NULL)
+(11 rows)
+
+explain (costs off, num_nodes off, nodes off)
+SELECT min(y) FROM
+ (SELECT unique1 AS x, unique1 AS y FROM tenk1 a
+ UNION ALL
+ SELECT unique2 AS x, unique2 AS y FROM tenk1 b) s;
+ QUERY PLAN
+--------------------------------------------------------------------------
+ Result
+ InitPlan 1 (returns $0)
+ -> Limit
+ -> Merge Append
+ Sort Key: a.unique1
+ -> Remote Subquery Scan on all
+ -> Index Only Scan using tenk1_unique1 on tenk1 a
+ Index Cond: (unique1 IS NOT NULL)
+ -> Remote Subquery Scan on all
+ -> Index Only Scan using tenk1_unique2 on tenk1 b
+ Index Cond: (unique2 IS NOT NULL)
+(11 rows)
+
+-- XXX planner doesn't recognize that index on unique2 is sufficiently sorted
+explain (costs off, num_nodes off, nodes off)
+SELECT x, y FROM
+ (SELECT thousand AS x, tenthous AS y FROM tenk1 a
+ UNION ALL
+ SELECT unique2 AS x, unique2 AS y FROM tenk1 b) s
+ORDER BY x, y;
+ QUERY PLAN
+-------------------------------------------------------------------
+ Merge Append
+ Sort Key: a.thousand, a.tenthous
+ -> Remote Subquery Scan on all
+ -> Index Only Scan using tenk1_thous_tenthous on tenk1 a
+ -> Remote Subquery Scan on all
+ -> Sort
+ Sort Key: b.unique2, b.unique2
+ -> Index Only Scan using tenk1_unique2 on tenk1 b
+(8 rows)
+
+-- exercise rescan code path via a repeatedly-evaluated subquery
+explain (costs off)
+SELECT
+ ARRAY(SELECT f.i FROM (
+ (SELECT d + g.i FROM generate_series(4, 30, 3) d ORDER BY 1)
+ UNION ALL
+ (SELECT d + g.i FROM generate_series(0, 30, 5) d ORDER BY 1)
+ ) f(i)
+ ORDER BY f.i LIMIT 10)
+FROM generate_series(1, 3) g(i);
+ QUERY PLAN
+----------------------------------------------------------------
+ Function Scan on generate_series g
+ SubPlan 1
+ -> Limit
+ -> Merge Append
+ Sort Key: ((d.d + g.i))
+ -> Sort
+ Sort Key: ((d.d + g.i))
+ -> Function Scan on generate_series d
+ -> Sort
+ Sort Key: ((d_1.d + g.i))
+ -> Function Scan on generate_series d_1
+(11 rows)
+
+SELECT
+ ARRAY(SELECT f.i FROM (
+ (SELECT d + g.i FROM generate_series(4, 30, 3) d ORDER BY 1)
+ UNION ALL
+ (SELECT d + g.i FROM generate_series(0, 30, 5) d ORDER BY 1)
+ ) f(i)
+ ORDER BY f.i LIMIT 10)
+FROM generate_series(1, 3) g(i);
+ array
+------------------------------
+ {1,5,6,8,11,11,14,16,17,20}
+ {2,6,7,9,12,12,15,17,18,21}
+ {3,7,8,10,13,13,16,18,19,22}
+(3 rows)
+
+reset enable_seqscan;
+reset enable_indexscan;
+reset enable_bitmapscan;