diff options
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r-- | src/backend/commands/tablecmds.c | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index ba8f4459f3d..8d25d147729 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -401,7 +401,8 @@ static void ATPrepDropColumn(List **wqueue, Relation rel, bool recurse, bool rec static ObjectAddress ATExecDropColumn(List **wqueue, Relation rel, const char *colName, DropBehavior behavior, bool recurse, bool recursing, - bool missing_ok, LOCKMODE lockmode); + bool missing_ok, LOCKMODE lockmode, + ObjectAddresses *addrs); static ObjectAddress ATExecAddIndex(AlteredTableInfo *tab, Relation rel, IndexStmt *stmt, bool is_rebuild, LOCKMODE lockmode); static ObjectAddress ATExecAddConstraint(List **wqueue, @@ -4273,12 +4274,14 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, case AT_DropColumn: /* DROP COLUMN */ address = ATExecDropColumn(wqueue, rel, cmd->name, cmd->behavior, false, false, - cmd->missing_ok, lockmode); + cmd->missing_ok, lockmode, + NULL); break; case AT_DropColumnRecurse: /* DROP COLUMN with recursion */ address = ATExecDropColumn(wqueue, rel, cmd->name, cmd->behavior, true, false, - cmd->missing_ok, lockmode); + cmd->missing_ok, lockmode, + NULL); break; case AT_AddIndex: /* ADD INDEX */ address = ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, false, @@ -7013,13 +7016,22 @@ ATPrepDropColumn(List **wqueue, Relation rel, bool recurse, bool recursing, } /* - * Return value is the address of the dropped column. + * Drops column 'colName' from relation 'rel' and returns the address of the + * dropped column. The column is also dropped (or marked as no longer + * inherited from relation) from the relation's inheritance children, if any. + * + * In the recursive invocations for inheritance child relations, instead of + * dropping the column directly (if to be dropped at all), its object address + * is added to 'addrs', which must be non-NULL in such invocations. All + * columns are dropped at the same time after all the children have been + * checked recursively. */ static ObjectAddress ATExecDropColumn(List **wqueue, Relation rel, const char *colName, DropBehavior behavior, bool recurse, bool recursing, - bool missing_ok, LOCKMODE lockmode) + bool missing_ok, LOCKMODE lockmode, + ObjectAddresses *addrs) { HeapTuple tuple; Form_pg_attribute targetatt; @@ -7032,6 +7044,11 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName, if (recursing) ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE); + /* Initialize addrs on the first invocation */ + Assert(!recursing || addrs != NULL); + if (!recursing) + addrs = new_object_addresses(); + /* * get the number of the attribute */ @@ -7144,7 +7161,7 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName, /* Time to delete this child column, too */ ATExecDropColumn(wqueue, childrel, colName, behavior, true, true, - false, lockmode); + false, lockmode, addrs); } else { @@ -7180,14 +7197,18 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName, table_close(attr_rel, RowExclusiveLock); } - /* - * Perform the actual column deletion - */ + /* Add object to delete */ object.classId = RelationRelationId; object.objectId = RelationGetRelid(rel); object.objectSubId = attnum; + add_exact_object_address(&object, addrs); - performDeletion(&object, behavior, 0); + if (!recursing) + { + /* Recursion has ended, drop everything that was collected */ + performMultipleDeletions(addrs, behavior, 0); + free_object_addresses(addrs); + } return object; } |