From 12e9589a8edb11b51c3b1725e7653733b82d4e34 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Mon, 21 Oct 2002 20:31:52 +0000 Subject: [PATCH] Fix ALTER TABLE ... ADD COLUMN for inheritance cases. Alvaro Herrera --- src/backend/commands/tablecmds.c | 48 ++++++++++++++++++++++------- src/backend/tcop/utility.c | 1 - src/include/commands/tablecmds.h | 3 +- src/test/regress/output/misc.source | 1 + 4 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index f70a3e7bfa..c6b82b5829 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -1584,7 +1584,6 @@ update_ri_trigger_args(Oid relid, void AlterTableAddColumn(Oid myrelid, bool recurse, - bool recursing, ColumnDef *colDef) { Relation rel, @@ -1643,22 +1642,50 @@ AlterTableAddColumn(Oid myrelid, colDefChild->inhcount = 1; colDefChild->is_local = false; - /* this routine is actually in the planner */ - children = find_all_inheritors(myrelid); + /* We only want direct inheritors */ + children = find_inheritance_children(myrelid); - /* - * 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) { Oid childrelid = lfirsti(child); + HeapTuple tuple; + Form_pg_attribute childatt; + Relation childrel; if (childrelid == myrelid) continue; - AlterTableAddColumn(childrelid, false, true, colDefChild); + attrdesc = heap_openr(AttributeRelationName, RowExclusiveLock); + tuple = SearchSysCacheCopyAttName(childrelid, colDef->colname); + if (!HeapTupleIsValid(tuple)) + { + heap_close(attrdesc, RowExclusiveLock); + AlterTableAddColumn(childrelid, true, colDefChild); + continue; + } + childatt = (Form_pg_attribute) GETSTRUCT(tuple); + + typeTuple = typenameType(colDef->typename); + + if (HeapTupleGetOid(typeTuple) != childatt->atttypid || + colDef->typename->typmod != childatt->atttypmod) + elog(ERROR, "ALTER TABLE: child table %u has different " + "type for column \"%s\"", + childrelid, colDef->colname); + + childatt->attinhcount++; + simple_heap_update(attrdesc, &tuple->t_self, tuple); + CatalogUpdateIndexes(attrdesc, tuple); + + childrel = RelationIdGetRelation(childrelid); + elog(NOTICE, "ALTER TABLE: merging definition of column " + "\"%s\" for child %s", colDef->colname, + RelationGetRelationName(childrel)); + RelationClose(childrel); + + heap_close(attrdesc, RowExclusiveLock); + heap_freetuple(tuple); + ReleaseSysCache(typeTuple); } } else @@ -1667,8 +1694,7 @@ AlterTableAddColumn(Oid myrelid, * If we are told not to recurse, there had better not be any * child tables; else the addition would put them out of step. */ - if (!recursing && - find_inheritance_children(myrelid) != NIL) + if (find_inheritance_children(myrelid) != NIL) elog(ERROR, "Attribute must be added to child tables too"); } diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 25f5300d1c..11860a56c9 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -475,7 +475,6 @@ ProcessUtility(Node *parsetree, */ AlterTableAddColumn(relid, interpretInhOption(stmt->relation->inhOpt), - false, (ColumnDef *) stmt->def); break; case 'T': /* ALTER COLUMN DEFAULT */ diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h index 3283eb654e..45cd0c72ee 100644 --- a/src/include/commands/tablecmds.h +++ b/src/include/commands/tablecmds.h @@ -16,8 +16,7 @@ #include "nodes/parsenodes.h" -extern void AlterTableAddColumn(Oid myrelid, bool recurse, bool recursing, - ColumnDef *colDef); +extern void AlterTableAddColumn(Oid myrelid, bool recurse, ColumnDef *colDef); extern void AlterTableAlterColumnDropNotNull(Oid myrelid, bool recurse, const char *colName); diff --git a/src/test/regress/output/misc.source b/src/test/regress/output/misc.source index 971ccfca10..01b88045ac 100644 --- a/src/test/regress/output/misc.source +++ b/src/test/regress/output/misc.source @@ -373,6 +373,7 @@ SELECT * FROM e_star*; (23 rows) ALTER TABLE a_star* ADD COLUMN a text; +NOTICE: ALTER TABLE: merging definition of column "a" for child d_star --UPDATE b_star* -- SET a = text 'gazpacho' -- WHERE aa > 4; -- 2.39.5