Idea is to reduce lock level of ADD/DROP COLUMN from AccessExclusiveLock down to ShareRowExclusiveLock.
To make it work, we need to recognise that we are adding a column without rewriting the table. That's a simple test at post parse analysis stage, but what I can't do is work out whether the column name used is a domain name which contains a constraint. So if we want this, then it seems we need to add a separate subcommand, so we can then throw an error if a domain is specified. ALTER TABLE foo ADD [COLUMN] colname CONCURRENTLY; Or other ideas? Do we really care? DROP ... RESTRICT works fine at reduced lock level, assuming I'm not missing anything... ALTER TABLE foo DROP [COLUMN] colname RESTRICT; Patch needs docs, tests and a check for the domain, so just a quick hack just to get my dev muscles back in shape after Christmas. (Jokes please). Comments? -- Simon Riggs http://www.2ndQuadrant.com/books/ PostgreSQL Development, 24x7 Support, Training and Services
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 6729d83..96bd135 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -2512,7 +2512,6 @@ AlterTableGetLockLevel(List *cmds) * New subcommand types should be added here by default. */ case AT_AddColumn: /* may rewrite heap, in some cases and visible to SELECT */ - case AT_DropColumn: /* change visible to SELECT */ case AT_AddColumnToView: /* CREATE VIEW */ case AT_AlterColumnType: /* must rewrite heap */ case AT_DropConstraint: /* as DROP INDEX */ @@ -2530,8 +2529,19 @@ AlterTableGetLockLevel(List *cmds) break; /* + * DROP can use a lower level of locking, if aren't using CASCADE + */ + case AT_DropColumn: /* change visible to SELECT */ + if (stmt->behavior == DROP_CASCADE) + cmd_lockmode = AccessExclusiveLock; + else + cmd_lockmode = ShareRowExclusiveLock; + break; + + /* * These subcommands affect write operations only. */ + case AT_AddColumnNoQuals: /* must never rewrite heap */ case AT_ColumnDefault: case AT_ProcessedConstraint: /* becomes AT_AddConstraint */ case AT_AddConstraintRecurse: /* becomes AT_AddConstraint */ diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 8fc79b6..48a7b8c 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -1633,6 +1633,14 @@ alter_table_cmd: n->def = $3; $$ = (Node *)n; } + /* ALTER TABLE <name> ADD COLUMN <coldef> */ + | ADD_P COLUMN columnDefNoQuals CONCURRENTLY + { + AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_AddColumnNoQuals; + n->def = $3; + $$ = (Node *)n; + } /* ALTER TABLE <name> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */ | ALTER opt_column ColId alter_column_default { @@ -2412,6 +2420,16 @@ columnDef: ColId Typename ColQualList } ; +columnDefNoQuals: ColId Typename + { + ColumnDef *n = makeNode(ColumnDef); + n->colname = $1; + n->typeName = $2; + n->is_local = true; + $$ = (Node *)n; + } + ; + columnOptions: ColId WITH OPTIONS ColQualList { ColumnDef *n = makeNode(ColumnDef);
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers