*** a/src/backend/commands/tablecmds.c --- b/src/backend/commands/tablecmds.c *************** *** 82,87 **** --- 82,88 ---- #include "storage/smgr.h" #include "utils/acl.h" #include "utils/builtins.h" + #include "utils/elog.h" #include "utils/fmgroids.h" #include "utils/inval.h" #include "utils/lsyscache.h" *************** *** 309,314 **** static void ATController(AlterTableStmt *parsetree, --- 310,316 ---- Relation rel, List *cmds, bool recurse, LOCKMODE lockmode); static void ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, bool recurse, bool recursing, LOCKMODE lockmode); + static void ATRewriteSubcommandErrorCallback(void *arg); static void ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode); static void ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd, LOCKMODE lockmode); *************** *** 3373,3378 **** ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, --- 3375,3399 ---- tab->subcmds[pass] = lappend(tab->subcmds[pass], cmd); } + static void + ATRewriteSubcommandErrorCallback(void *arg) + { + AlterTableCmd *subcmd = (AlterTableCmd *) arg; + + switch (subcmd->subtype) + { + case AT_ReAddIndex: + errcontext("while rebuilding index %s", subcmd->name); + break; + case AT_ReAddConstraint: + errcontext("while rebuilding constraint %s", subcmd->name); + break; + default: + /* keep compiler quiet */ + (void) 0; + } + } + /* * ATRewriteCatalogs * *************** *** 3402,3407 **** ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode) --- 3423,3429 ---- List *subcmds = tab->subcmds[pass]; Relation rel; ListCell *lcmd; + ErrorContextCallback errcallback; if (subcmds == NIL) continue; *************** *** 3411,3418 **** ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode) */ rel = relation_open(tab->relid, NoLock); foreach(lcmd, subcmds) ! ATExecCmd(wqueue, tab, rel, (AlterTableCmd *) lfirst(lcmd), lockmode); /* * After the ALTER TYPE pass, do cleanup work (this is not done in --- 3433,3451 ---- */ rel = relation_open(tab->relid, NoLock); + errcallback.callback = ATRewriteSubcommandErrorCallback; + errcallback.previous = error_context_stack; + error_context_stack = &errcallback; + foreach(lcmd, subcmds) ! { ! AlterTableCmd *subcmd = (AlterTableCmd *) lfirst(lcmd); ! ! errcallback.arg = subcmd; ! ATExecCmd(wqueue, tab, rel, subcmd, lockmode); ! } ! ! error_context_stack = errcallback.previous; /* * After the ALTER TYPE pass, do cleanup work (this is not done in *************** *** 8682,8687 **** ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, --- 8715,8721 ---- newcmd = makeNode(AlterTableCmd); newcmd->subtype = AT_ReAddIndex; + newcmd->name = stmt->idxname; newcmd->def = (Node *) stmt; tab->subcmds[AT_PASS_OLD_INDEX] = lappend(tab->subcmds[AT_PASS_OLD_INDEX], newcmd); *************** *** 8712,8717 **** ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, --- 8746,8752 ---- RelationRelationId, 0); cmd->subtype = AT_ReAddIndex; + cmd->name = indstmt->idxname; tab->subcmds[AT_PASS_OLD_INDEX] = lappend(tab->subcmds[AT_PASS_OLD_INDEX], cmd); *************** *** 8734,8739 **** ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, --- 8769,8775 ---- !rewrite && tab->rewrite == 0) TryReuseForeignKey(oldId, con); cmd->subtype = AT_ReAddConstraint; + cmd->name = con->conname; tab->subcmds[AT_PASS_OLD_CONSTR] = lappend(tab->subcmds[AT_PASS_OLD_CONSTR], cmd); *** a/src/test/regress/expected/alter_table.out --- b/src/test/regress/expected/alter_table.out *************** *** 1737,1742 **** alter table anothertab alter column atcol1 type boolean --- 1737,1743 ---- using case when atcol1 % 2 = 0 then true else false end; -- fails ERROR: operator does not exist: boolean <= integer HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. + CONTEXT: while rebuilding constraint anothertab_chk alter table anothertab drop constraint anothertab_chk; alter table anothertab drop constraint anothertab_chk; -- fails ERROR: constraint "anothertab_chk" of relation "anothertab" does not exist