diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index f518c1371e6a2aa7fcb5de3eff086ff3a4549483..c91bcb411a7dd593e22942c823c02de0c0afd20d 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -1605,8 +1605,8 @@ MergeAttributes(List *schema, List *supers, char relpersistence, * execute if the user attempts to create a table with hundreds of * thousands of columns. * - * Note that we also need to check that we do not exceed this figure - * after including columns from inherited relations. + * Note that we also need to check that we do not exceed this figure after + * including columns from inherited relations. */ if (list_length(schema) > MaxHeapAttributeNumber) ereport(ERROR, @@ -10902,6 +10902,46 @@ MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel) } } + /* + * If the parent has an OID column, so must the child, and we'd better + * update the child's attinhcount and attislocal the same as for normal + * columns. We needn't check data type or not-nullness though. + */ + if (tupleDesc->tdhasoid) + { + /* + * Here we match by column number not name; the match *must* be the + * system column, not some random column named "oid". + */ + tuple = SearchSysCacheCopy2(ATTNUM, + ObjectIdGetDatum(RelationGetRelid(child_rel)), + Int16GetDatum(ObjectIdAttributeNumber)); + if (HeapTupleIsValid(tuple)) + { + Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple); + + /* See comments above; these changes should be the same */ + childatt->attinhcount++; + + if (child_is_partition) + { + Assert(childatt->attinhcount == 1); + childatt->attislocal = false; + } + + simple_heap_update(attrrel, &tuple->t_self, tuple); + CatalogUpdateIndexes(attrrel, tuple); + heap_freetuple(tuple); + } + else + { + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("child table is missing column \"%s\"", + "oid"))); + } + } + heap_close(attrrel, RowExclusiveLock); } diff --git a/src/test/regress/expected/inherit.out b/src/test/regress/expected/inherit.out index 38ea8e86f3c2dad21d493a9dfc3e4f43b8c1d9f2..a8c8b28a75e7bc50cf45e884c74c5d7911c5e6d2 100644 --- a/src/test/regress/expected/inherit.out +++ b/src/test/regress/expected/inherit.out @@ -612,6 +612,55 @@ select * from d; 32 | one | two | three (1 row) +-- check that oid column is handled properly during alter table inherit +create table oid_parent (a int) with oids; +create table oid_child () inherits (oid_parent); +select attinhcount, attislocal from pg_attribute + where attrelid = 'oid_child'::regclass and attname = 'oid'; + attinhcount | attislocal +-------------+------------ + 1 | f +(1 row) + +drop table oid_child; +create table oid_child (a int) without oids; +alter table oid_child inherit oid_parent; -- fail +ERROR: table "oid_child" without OIDs cannot inherit from table "oid_parent" with OIDs +alter table oid_child set with oids; +select attinhcount, attislocal from pg_attribute + where attrelid = 'oid_child'::regclass and attname = 'oid'; + attinhcount | attislocal +-------------+------------ + 0 | t +(1 row) + +alter table oid_child inherit oid_parent; +select attinhcount, attislocal from pg_attribute + where attrelid = 'oid_child'::regclass and attname = 'oid'; + attinhcount | attislocal +-------------+------------ + 1 | t +(1 row) + +alter table oid_child set without oids; -- fail +ERROR: cannot drop inherited column "oid" +alter table oid_parent set without oids; +select attinhcount, attislocal from pg_attribute + where attrelid = 'oid_child'::regclass and attname = 'oid'; + attinhcount | attislocal +-------------+------------ + 0 | t +(1 row) + +alter table oid_child set without oids; +select attinhcount, attislocal from pg_attribute + where attrelid = 'oid_child'::regclass and attname = 'oid'; + attinhcount | attislocal +-------------+------------ +(0 rows) + +drop table oid_parent cascade; +NOTICE: drop cascades to table oid_child -- Test non-inheritable parent constraints create table p1(ff1 int); alter table p1 add constraint p1chk check (ff1 > 0) no inherit; diff --git a/src/test/regress/sql/inherit.sql b/src/test/regress/sql/inherit.sql index e22a14ebda89ebe3b04b6cb04c51173bc06ac281..a8b7eb1c8da4c6d6b87dc1324d9daf6683b54187 100644 --- a/src/test/regress/sql/inherit.sql +++ b/src/test/regress/sql/inherit.sql @@ -145,6 +145,32 @@ insert into d values('test','one','two','three'); alter table a alter column aa type integer using bit_length(aa); select * from d; +-- check that oid column is handled properly during alter table inherit +create table oid_parent (a int) with oids; + +create table oid_child () inherits (oid_parent); +select attinhcount, attislocal from pg_attribute + where attrelid = 'oid_child'::regclass and attname = 'oid'; +drop table oid_child; + +create table oid_child (a int) without oids; +alter table oid_child inherit oid_parent; -- fail +alter table oid_child set with oids; +select attinhcount, attislocal from pg_attribute + where attrelid = 'oid_child'::regclass and attname = 'oid'; +alter table oid_child inherit oid_parent; +select attinhcount, attislocal from pg_attribute + where attrelid = 'oid_child'::regclass and attname = 'oid'; +alter table oid_child set without oids; -- fail +alter table oid_parent set without oids; +select attinhcount, attislocal from pg_attribute + where attrelid = 'oid_child'::regclass and attname = 'oid'; +alter table oid_child set without oids; +select attinhcount, attislocal from pg_attribute + where attrelid = 'oid_child'::regclass and attname = 'oid'; + +drop table oid_parent cascade; + -- Test non-inheritable parent constraints create table p1(ff1 int); alter table p1 add constraint p1chk check (ff1 > 0) no inherit;