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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers