*/
CommandCounterIncrement();
-#ifdef PGXC
/*
* Add to pgxc_class.
* we need to do this after CommandCounterIncrement
/* Make sure locator info gets rebuilt */
RelationCacheInvalidateEntry(relationId);
}
-#endif
+
/*
* Open the new relation and acquire exclusive lock on it. This isn't
* really necessary for locking out other backends (since they can't see
*/
rel = relation_open(relationId, AccessExclusiveLock);
+ /*
+ * If we are inheriting from more than one parent, ensure that the
+ * distribution strategy of the child table and each of the parent table
+ * satisfies various limitations imposed by XL. Any violation will be
+ * reported as ERROR by MergeDistributionIntoExisting.
+ */
+ if (IS_PGXC_COORDINATOR && list_length(inheritOids) > 1)
+ {
+ ListCell *entry;
+ foreach(entry, inheritOids)
+ {
+ Oid parentOid = lfirst_oid(entry);
+ Relation parent_rel = heap_open(parentOid, ShareUpdateExclusiveLock);
+
+ MergeDistributionIntoExisting(rel, parent_rel);
+ heap_close(parent_rel, NoLock);
+ }
+ }
+
+
/* Process and store partition bound, if any. */
if (stmt->partbound)
{
errdetail("Distribution type for the child must be same as the parent")));
- /* Same attribute number? */
+ /*
+ * Same attribute number?
+ *
+ * For table distributed by roundrobin or replication, the partAttrNum will
+ * be -1 and inheritance is allowed for tables distributed by roundrobin or
+ * replication, as long as the distribution type matches (i.e. all tables
+ * are either roundrobin or all tables are replicated).
+ *
+ * Tables distributed by roundrobin or replication do not have partAttrName
+ * set. We should have checked for distribution type above. So if the
+ * partAttrNum does not match below, we must be dealing with either modulo
+ * or hash distributed tables and partAttrName must be set in both the
+ * cases.
+ */
if (parent_locinfo->partAttrNum != child_locinfo->partAttrNum)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
parent_locinfo->partAttrName),
errdetail("Distribution column for the child must be same as the parent")));
+ /*
+ * Same attribute name? partAttrName could be NULL if we are dealing with
+ * roundrobin or replicated tables. So check for that.
+ */
+ if (parent_locinfo->partAttrName &&
+ child_locinfo->partAttrName &&
+ strcmp(parent_locinfo->partAttrName, child_locinfo->partAttrName) != 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("table \"%s\" is distributed on column \"%s\", but the "
+ "parent table \"%s\" is distributed on column \"%s\"",
+ RelationGetRelationName(child_rel),
+ child_locinfo->partAttrName,
+ RelationGetRelationName(parent_rel),
+ parent_locinfo->partAttrName),
+ errdetail("Distribution column for the child must be same as the parent")));
+
+
/* Same node list? */
if (list_difference_int(nodeList1, nodeList2) != NIL ||
list_difference_int(nodeList2, nodeList1) != NIL)
DETAIL: Failing row contains (4, 3).
drop table atacc1;
-- inheritance related tests
-create table atacc1 (test int);
-create table atacc2 (test2 int);
+create table atacc1 (test int) distribute by roundrobin;
+create table atacc2 (test2 int) distribute by roundrobin;
create table atacc3 (test3 int) inherits (atacc1, atacc2);
alter table atacc2 add constraint foo check (test2>0);
-- fail and then succeed on atacc2
drop table atacc3;
drop table atacc2;
drop table atacc1;
--- same things with one created with INHERIT
create table atacc1 (test int);
-create table atacc2 (test2 int);
+create table atacc2 (test int);
+-- fail due to missing constraint
+alter table atacc1 add constraint foo check (test>0);
+alter table atacc2 inherit atacc1;
+ERROR: child table is missing constraint "foo"
+-- fail due to not-matching constraint
+alter table atacc2 add constraint foo check (test>10);
+alter table atacc2 inherit atacc1;
+ERROR: child table "atacc2" has different definition for check constraint "foo"
+-- succeed
+alter table atacc2 drop constraint foo;
+alter table atacc2 add constraint foo check (test>0);
+alter table atacc2 inherit atacc1;
+drop table atacc1 cascade;
+NOTICE: drop cascades to table atacc2
+-- same things with one created with INHERIT
+create table atacc1 (test int) distribute by roundrobin;
+create table atacc2 (test2 int) distribute by roundrobin;
create table atacc3 (test3 int) inherits (atacc1, atacc2);
alter table atacc3 no inherit atacc2;
-- fail
-------
(0 rows)
--- fail due to missing constraint
-alter table atacc2 add constraint foo check (test2>0);
-alter table atacc3 inherit atacc2;
-ERROR: child table is missing constraint "foo"
-- fail due to missing column
alter table atacc3 rename test2 to testx;
alter table atacc3 inherit atacc2;
alter table atacc3 add test2 int;
update atacc3 set test2 = 4 where test2 is null;
alter table atacc3 add constraint foo check (test2>0);
+-- XXX fails in XL because of column position mismatch
alter table atacc3 inherit atacc2;
+ERROR: table "atacc3" contains column "test2" at position 5, but parent "atacc2" has it at position 1
+DETAIL: Postgres-XL requires attribute positions to match
+HINT: Check for column ordering and dropped columns, if any
-- fail due to duplicates and circular inheritance
alter table atacc3 inherit atacc2;
-ERROR: relation "atacc2" would be inherited from more than once
+ERROR: table "atacc3" contains column "test2" at position 5, but parent "atacc2" has it at position 1
+DETAIL: Postgres-XL requires attribute positions to match
+HINT: Check for column ordering and dropped columns, if any
alter table atacc2 inherit atacc3;
-ERROR: circular inheritance not allowed
-DETAIL: "atacc3" is already a child of "atacc2".
+ERROR: child table is missing column "test"
alter table atacc2 inherit atacc2;
ERROR: circular inheritance not allowed
DETAIL: "atacc2" is already a child of "atacc2".
-- test that we really are a child now (should see 4 not 3 and cascade should go through)
+-- XXX fails in XL because the previous alter table failed
select test2 from atacc2;
test2
-------
- 4
-(1 row)
+(0 rows)
drop table atacc2 cascade;
+-- XXX needs a cascade drop in XL because atacc3 is still a child of atacc1
+drop table atacc1 cascade;
NOTICE: drop cascades to table atacc3
-drop table atacc1;
-- adding only to a parent is allowed as of 9.2
create table atacc1 (test int);
create table atacc2 (test2 int) inherits (atacc1);
alter table c1 drop column f1;
drop table p1 cascade;
NOTICE: drop cascades to table c1
-create table p1(id int, name text);
-create table p2(id2 int, name text, height int);
+create table p1(id int, name text) distribute by roundrobin;
+create table p2(id2 int, name text, height int) distribute by roundrobin;
create table c1(age int) inherits(p1,p2);
NOTICE: merging multiple inherited definitions of column "name"
create table gc1() inherits (c1);
CREATE TABLE test_type_diff2_c2 (int_eight int8, int_two int2, int_four int4);
CREATE TABLE test_type_diff2_c3 (int_two int2, int_four int4, int_eight int8);
ALTER TABLE test_type_diff2_c1 INHERIT test_type_diff2;
+ERROR: table "test_type_diff2_c1" contains column "int_two" at position 3, but parent "test_type_diff2" has it at position 1
+DETAIL: Postgres-XL requires attribute positions to match
+HINT: Check for column ordering and dropped columns, if any
ALTER TABLE test_type_diff2_c2 INHERIT test_type_diff2;
+ERROR: table "test_type_diff2_c2" contains column "int_two" at position 2, but parent "test_type_diff2" has it at position 1
+DETAIL: Postgres-XL requires attribute positions to match
+HINT: Check for column ordering and dropped columns, if any
ALTER TABLE test_type_diff2_c3 INHERIT test_type_diff2;
INSERT INTO test_type_diff2_c1 VALUES (1, 2, 3);
INSERT INTO test_type_diff2_c2 VALUES (4, 5, 6);
^
-- cannot drop column that is part of the partition key
ALTER TABLE partitioned DROP COLUMN a;
-ERROR: cannot drop column named in partition key
+ERROR: Distribution column cannot be dropped
ALTER TABLE partitioned ALTER COLUMN a TYPE char(5);
ERROR: cannot alter type of column named in partition key
ALTER TABLE partitioned DROP COLUMN b;
CREATE TABLE perm_part (a int);
ALTER TABLE temp_parted ATTACH PARTITION perm_part FOR VALUES IN (1);
ERROR: cannot attach a permanent relation as partition of temporary relation "temp_parted"
+-- XXX fail in XL because temp and regular tables can't be dropped together
DROP TABLE temp_parted, perm_part;
+ERROR: DROP not supported for TEMP and non-TEMP objects
+DETAIL: You should separate TEMP and non-TEMP objects
+DROP TABLE temp_parted;
+DROP TABLE perm_part;
-- check that the table being attached is not a typed table
CREATE TYPE mytype AS (a int);
CREATE TABLE fail_part OF mytype;
a int NOT NULL
);
ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
-ERROR: child table "fail_part" has different type for column "b"
+ERROR: table "fail_part" contains column "a" at position 2, but parent "list_parted" has it at position 1
+DETAIL: Postgres-XL requires attribute positions to match
+HINT: Check for column ordering and dropped columns, if any
ALTER TABLE fail_part ALTER b TYPE char (2) COLLATE "POSIX";
ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
-ERROR: child table "fail_part" has different collation for column "b"
+ERROR: table "fail_part" contains column "a" at position 2, but parent "list_parted" has it at position 1
+DETAIL: Postgres-XL requires attribute positions to match
+HINT: Check for column ordering and dropped columns, if any
DROP TABLE fail_part;
-- check that the table being attached has all constraints of the parent
CREATE TABLE fail_part (
a int NOT NULL
);
ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
-ERROR: child table is missing constraint "check_a"
+ERROR: table "fail_part" contains column "a" at position 2, but parent "list_parted" has it at position 1
+DETAIL: Postgres-XL requires attribute positions to match
+HINT: Check for column ordering and dropped columns, if any
-- check that the constraint matches in definition with parent's constraint
ALTER TABLE fail_part ADD CONSTRAINT check_a CHECK (a >= 0);
ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
-ERROR: child table "fail_part" has different definition for check constraint "check_a"
+ERROR: table "fail_part" contains column "a" at position 2, but parent "list_parted" has it at position 1
+DETAIL: Postgres-XL requires attribute positions to match
+HINT: Check for column ordering and dropped columns, if any
DROP TABLE fail_part;
-- check the attributes and constraints after partition is attached
CREATE TABLE part_1 (
(3 rows)
alter table p1 attach partition p11 for values from (2) to (5);
+ERROR: table "p11" contains column "a" at position 4, but parent "p1" has it at position 2
+DETAIL: Postgres-XL requires attribute positions to match
+HINT: Check for column ordering and dropped columns, if any
insert into p1 (a, b) values (2, 3);
+ERROR: no partition of relation "p1" found for row
+DETAIL: Partition key of the failing row contains (b) = (3).
-- check that partition validation scan correctly detects violating rows
alter table p attach partition p1 for values from (1, 2) to (1, 10);
-ERROR: partition constraint is violated by some row
+ERROR: table "p1" contains column "a" at position 2, but parent "p" has it at position 1
+DETAIL: Postgres-XL requires attribute positions to match
+HINT: Check for column ordering and dropped columns, if any
-- cleanup
drop table p;
drop table p1;
drop table derived;
drop table base;
-create table p1(ff1 int);
-create table p2(f1 text);
+create table p1(ff1 int) distribute by roundrobin;
+create table p2(f1 text) distribute by roundrobin;
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);
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 ac (a int constraint check_a check (a <> 0)) distribute by roundrobin;
+create table bc (b int constraint check_b check (b <> 0)) distribute by roundrobin;
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
drop table cc;
drop table bc;
drop table ac;
-create table p1(f1 int);
-create table p2(f2 int);
+create table p1(f1 int) distribute by roundrobin;
+create table p2(f2 int) distribute by roundrobin;
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
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 inht1 (a int, b int) distribute by roundrobin;
+CREATE TABLE inhs1 (b int, c int) distribute by roundrobin;
CREATE TABLE inhts (d int) INHERITS (inht1, inhs1);
NOTICE: merging multiple inherited definitions of column "b"
ALTER TABLE inht1 RENAME a TO aa;
dd | integer | | | | plain | |
Inherits: inht1,
inhs1
-Distribute By: HASH(aa)
+Distribute By: ROUND ROBIN
Location Nodes: ALL DATANODES
DROP TABLE inhts;
z | integer | | | | plain | |
Inherits: inht2,
inht3
-Distribute By: HASH(aaa)
+Distribute By: ROUND ROBIN
Location Nodes: ALL DATANODES
CREATE TABLE inhts (d int) INHERITS (inht2, inhs1);
d | integer | | | | plain | |
Inherits: inht2,
inhs1
-Distribute By: HASH(aaaa)
+Distribute By: ROUND ROBIN
Location Nodes: ALL DATANODES
WITH RECURSIVE r AS (
DELETE FROM atest5 WHERE two = 2; -- ok
-- check inheritance cases
SET SESSION AUTHORIZATION regress_user1;
-CREATE TABLE atestp1 (f1 int, f2 int) WITH OIDS;
-CREATE TABLE atestp2 (fx int, fy int) WITH OIDS;
+CREATE TABLE atestp1 (f1 int, f2 int) WITH OIDS DISTRIBUTE BY ROUNDROBIN;
+CREATE TABLE atestp2 (fx int, fy int) WITH OIDS DISTRIBUTE BY ROUNDROBIN;
CREATE TABLE atestc (fz int) INHERITS (atestp1, atestp2);
GRANT SELECT(fx,fy,oid) ON atestp2 TO regress_user2;
GRANT SELECT(fx) ON atestc TO regress_user2;
drop table atacc1;
-- inheritance related tests
-create table atacc1 (test int);
-create table atacc2 (test2 int);
+create table atacc1 (test int) distribute by roundrobin;
+create table atacc2 (test2 int) distribute by roundrobin;
create table atacc3 (test3 int) inherits (atacc1, atacc2);
alter table atacc2 add constraint foo check (test2>0);
-- fail and then succeed on atacc2
drop table atacc2;
drop table atacc1;
--- same things with one created with INHERIT
create table atacc1 (test int);
-create table atacc2 (test2 int);
+create table atacc2 (test int);
+-- fail due to missing constraint
+alter table atacc1 add constraint foo check (test>0);
+alter table atacc2 inherit atacc1;
+-- fail due to not-matching constraint
+alter table atacc2 add constraint foo check (test>10);
+alter table atacc2 inherit atacc1;
+-- succeed
+alter table atacc2 drop constraint foo;
+alter table atacc2 add constraint foo check (test>0);
+alter table atacc2 inherit atacc1;
+drop table atacc1 cascade;
+
+-- same things with one created with INHERIT
+create table atacc1 (test int) distribute by roundrobin;
+create table atacc2 (test2 int) distribute by roundrobin;
create table atacc3 (test3 int) inherits (atacc1, atacc2);
alter table atacc3 no inherit atacc2;
-- fail
-- make sure it really isn't a child
insert into atacc3 (test2) values (3);
select test2 from atacc2;
--- fail due to missing constraint
-alter table atacc2 add constraint foo check (test2>0);
-alter table atacc3 inherit atacc2;
-- fail due to missing column
alter table atacc3 rename test2 to testx;
alter table atacc3 inherit atacc2;
alter table atacc3 add test2 int;
update atacc3 set test2 = 4 where test2 is null;
alter table atacc3 add constraint foo check (test2>0);
+-- XXX fails in XL because of column position mismatch
alter table atacc3 inherit atacc2;
-- fail due to duplicates and circular inheritance
alter table atacc3 inherit atacc2;
alter table atacc2 inherit atacc3;
alter table atacc2 inherit atacc2;
-- test that we really are a child now (should see 4 not 3 and cascade should go through)
+-- XXX fails in XL because the previous alter table failed
select test2 from atacc2;
drop table atacc2 cascade;
-drop table atacc1;
+-- XXX needs a cascade drop in XL because atacc3 is still a child of atacc1
+drop table atacc1 cascade;
-- adding only to a parent is allowed as of 9.2
drop table p1 cascade;
-create table p1(id int, name text);
-create table p2(id2 int, name text, height int);
+create table p1(id int, name text) distribute by roundrobin;
+create table p2(id2 int, name text, height int) distribute by roundrobin;
create table c1(age int) inherits(p1,p2);
create table gc1() inherits (c1);
CREATE TEMP TABLE temp_parted (a int) PARTITION BY LIST (a);
CREATE TABLE perm_part (a int);
ALTER TABLE temp_parted ATTACH PARTITION perm_part FOR VALUES IN (1);
+-- XXX fail in XL because temp and regular tables can't be dropped together
DROP TABLE temp_parted, perm_part;
+DROP TABLE temp_parted;
+DROP TABLE perm_part;
-- check that the table being attached is not a typed table
CREATE TYPE mytype AS (a int);
drop table derived;
drop table base;
-create table p1(ff1 int);
-create table p2(f1 text);
+create table p1(ff1 int) distribute by roundrobin;
+create table p2(f1 text) distribute by roundrobin;
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);
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 ac (a int constraint check_a check (a <> 0)) distribute by roundrobin;
+create table bc (b int constraint check_b check (b <> 0)) distribute by roundrobin;
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;
drop table bc;
drop table ac;
-create table p1(f1 int);
-create table p2(f2 int);
+create table p1(f1 int) distribute by roundrobin;
+create table p2(f2 int) distribute by roundrobin;
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
drop table pp1 cascade;
-- Test for renaming in simple multiple inheritance
-CREATE TABLE inht1 (a int, b int);
-CREATE TABLE inhs1 (b int, c int);
+CREATE TABLE inht1 (a int, b int) distribute by roundrobin;
+CREATE TABLE inhs1 (b int, c int) distribute by roundrobin;
CREATE TABLE inhts (d int) INHERITS (inht1, inhs1);
ALTER TABLE inht1 RENAME a TO aa;
-- check inheritance cases
SET SESSION AUTHORIZATION regress_user1;
-CREATE TABLE atestp1 (f1 int, f2 int) WITH OIDS;
-CREATE TABLE atestp2 (fx int, fy int) WITH OIDS;
+CREATE TABLE atestp1 (f1 int, f2 int) WITH OIDS DISTRIBUTE BY ROUNDROBIN;
+CREATE TABLE atestp2 (fx int, fy int) WITH OIDS DISTRIBUTE BY ROUNDROBIN;
CREATE TABLE atestc (fz int) INHERITS (atestp1, atestp2);
GRANT SELECT(fx,fy,oid) ON atestp2 TO regress_user2;
GRANT SELECT(fx) ON atestc TO regress_user2;