aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2017-01-04 18:00:11 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2017-01-04 18:00:11 -0500
commitd86f40009b6b019f794819a9af9038cff0cac6f3 (patch)
treeee8b80cde2d0d8060a88fbaa5fca2461f3c3e0fc /src/backend/commands/tablecmds.c
parent44f7afba79348883da110642d230a13003b75f62 (diff)
downloadpostgresql-d86f40009b6b019f794819a9af9038cff0cac6f3.tar.gz
postgresql-d86f40009b6b019f794819a9af9038cff0cac6f3.zip
Handle OID column inheritance correctly in ALTER TABLE ... INHERIT.
Inheritance operations must treat the OID column, if any, much like regular user columns. But MergeAttributesIntoExisting() neglected to do that, leading to weird results after a table with OIDs is associated to a parent with OIDs via ALTER TABLE ... INHERIT. Report and patch by Amit Langote, reviewed by Ashutosh Bapat, some adjustments by me. It's been broken all along, so back-patch to all supported branches. Discussion: https://postgr.es/m/cb13cfe7-a48c-5720-c383-bb843ab28298@lab.ntt.co.jp
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c44
1 files changed, 42 insertions, 2 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index f518c1371e6..c91bcb411a7 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);
}