aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c45
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.
*/