diff options
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r-- | src/backend/commands/tablecmds.c | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index fb2be10794b..cceefbdd49f 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -10279,7 +10279,11 @@ ATPrepAlterColumnType(List **wqueue, errmsg("cannot alter system column \"%s\"", colName))); - /* Don't alter inherited columns */ + /* + * Don't alter inherited columns. At outer level, there had better not be + * any inherited definition; when recursing, we assume this was checked at + * the parent level (see below). + */ if (attTup->attinhcount > 0 && !recursing) ereport(ERROR, (errcode(ERRCODE_INVALID_TABLE_DEFINITION), @@ -10405,20 +10409,26 @@ ATPrepAlterColumnType(List **wqueue, if (recurse) { Oid relid = RelationGetRelid(rel); - ListCell *child; - List *children; + List *child_oids, + *child_numparents; + ListCell *lo, + *li; - children = find_all_inheritors(relid, lockmode, NULL); + child_oids = find_all_inheritors(relid, lockmode, + &child_numparents); /* * find_all_inheritors does the recursive search of the inheritance * hierarchy, so all we have to do is process all of the relids in the * list that it returns. */ - foreach(child, children) + forboth(lo, child_oids, li, child_numparents) { - Oid childrelid = lfirst_oid(child); + Oid childrelid = lfirst_oid(lo); + int numparents = lfirst_int(li); Relation childrel; + HeapTuple childtuple; + Form_pg_attribute childattTup; if (childrelid == relid) continue; @@ -10428,6 +10438,29 @@ ATPrepAlterColumnType(List **wqueue, CheckTableNotInUse(childrel, "ALTER TABLE"); /* + * Verify that the child doesn't have any inherited definitions of + * this column that came from outside this inheritance hierarchy. + * (renameatt makes a similar test, though in a different way + * because of its different recursion mechanism.) + */ + childtuple = SearchSysCacheAttName(RelationGetRelid(childrel), + colName); + if (!HeapTupleIsValid(childtuple)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" of relation \"%s\" does not exist", + colName, RelationGetRelationName(childrel)))); + childattTup = (Form_pg_attribute) GETSTRUCT(childtuple); + + if (childattTup->attinhcount > numparents) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TABLE_DEFINITION), + errmsg("cannot alter inherited column \"%s\" of relation \"%s\"", + colName, RelationGetRelationName(childrel)))); + + ReleaseSysCache(childtuple); + + /* * Remap the attribute numbers. If no USING expression was * specified, there is no need for this step. */ |