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

Reply via email to