diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 970abd4..0bcdd76 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -2807,7 +2807,8 @@ AlterTableInternal(Oid relid, List *cmds, bool recurse) * Function is called before and after parsing, so it must give same * answer each time it is called. Some subcommands are transformed * into other subcommand types, so the transform must never be made to a - * lower lock level than previously assigned. All transforms are noted below. + * lock level different than previously assigned. All transforms are noted + * below. * * Since this is called before we lock the table we cannot use table metadata * to influence the type of lock we acquire. @@ -2837,6 +2838,7 @@ AlterTableGetLockLevel(List *cmds) */ ListCell *lcmd; LOCKMODE lockmode = ShareUpdateExclusiveLock; + bool is_init = false; foreach(lcmd, cmds) { @@ -3057,10 +3059,22 @@ AlterTableGetLockLevel(List *cmds) } /* - * Take the greatest lockmode from any subcommand + * At the first command evaluated, take the lock corresponding to + * it. When looking at the next commands, check if the lock taken + * is different than the first one taken and enforce it to + * AccessExclusiveLock, which is the only lock super-seeding all + * the others. */ - if (cmd_lockmode > lockmode) + if (!is_init) + { lockmode = cmd_lockmode; + is_init = true; + } + else + { + if (cmd_lockmode != lockmode) + lockmode = AccessExclusiveLock; + } } return lockmode;