diff --git a/doc/src/sgml/ref/lock.sgml b/doc/src/sgml/ref/lock.sgml index e78ee548fc5a393508af76b5e6a56c612a16abec..a2c2a78a7aad29ebb9250399212527ac8c926754 100644 --- a/doc/src/sgml/ref/lock.sgml +++ b/doc/src/sgml/ref/lock.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/ref/lock.sgml,v 1.40 2003/12/14 00:05:29 neilc Exp $ +$PostgreSQL: pgsql/doc/src/sgml/ref/lock.sgml,v 1.41 2004/03/11 01:47:35 ishii Exp $ PostgreSQL documentation --> @@ -20,7 +20,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> -LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> [, ...] [ IN <replaceable class="PARAMETER">lockmode</replaceable> MODE ] +LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> [, ...] [ IN <replaceable class="PARAMETER">lockmode</replaceable> MODE ] [ NOWAIT ] where <replaceable class="PARAMETER">lockmode</replaceable> is one of: @@ -34,8 +34,10 @@ where <replaceable class="PARAMETER">lockmode</replaceable> is one of: <para> <command>LOCK TABLE</command> obtains a table-level lock, waiting if - necessary for any conflicting locks to be released. Once obtained, - the lock is held for the remainder of the current transaction. + necessary for any conflicting locks to be released. + If <literal>NOWAIT</literal> is given, <command>LOCK TABLE</command> + does not wait for acquiring lock, and throws an error instead. + Once obtained, the lock is held for the remainder of the current transaction. (There is no <command>UNLOCK TABLE</command> command; locks are always released at transaction end.) </para> diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index d98e3fd16c248308c5ce748c29c4fa27fcf55b07..902f0621377d89620d00aa6fd2c16d072ab1f634 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.162 2004/01/16 20:51:30 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.163 2004/03/11 01:47:35 ishii Exp $ * * * INTERFACE ROUTINES @@ -464,6 +464,33 @@ relation_open(Oid relationId, LOCKMODE lockmode) return r; } +Relation +conditional_relation_open(Oid relationId, LOCKMODE lockmode, bool nowait) +{ + Relation r; + + Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES); + + /* The relcache does all the real work... */ + r = RelationIdGetRelation(relationId); + + if (!RelationIsValid(r)) + elog(ERROR, "could not open relation with OID %u", relationId); + + if (lockmode != NoLock) + { + if (nowait) + { + if (!ConditionalLockRelation(r, lockmode)) + elog(ERROR, "could not aquire relation lock"); + } + else + LockRelation(r, lockmode); + } + + return r; +} + /* ---------------- * relation_openrv - open any relation specified by a RangeVar * diff --git a/src/backend/commands/lockcmds.c b/src/backend/commands/lockcmds.c index 4634593ada5d8262312a53d1926d96588141c356..58bee42f8fe8360d7539801285d9c7804edd1fe6 100644 --- a/src/backend/commands/lockcmds.c +++ b/src/backend/commands/lockcmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/lockcmds.c,v 1.8 2003/11/29 19:51:47 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/commands/lockcmds.c,v 1.9 2004/03/11 01:47:35 ishii Exp $ * *------------------------------------------------------------------------- */ @@ -59,7 +59,7 @@ LockTableCommand(LockStmt *lockstmt) aclcheck_error(aclresult, ACL_KIND_CLASS, get_rel_name(reloid)); - rel = relation_open(reloid, lockstmt->mode); + rel = conditional_relation_open(reloid, lockstmt->mode, lockstmt->nowait); /* Currently, we only allow plain tables to be locked */ if (rel->rd_rel->relkind != RELKIND_RELATION) diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 39f454fd3c9d38350ff8f0e63a6719e1173523c7..c1c4ddfed8b0fa919d3aebd312c76e31c1c1ce6b 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.277 2004/01/14 23:01:54 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.278 2004/03/11 01:47:35 ishii Exp $ * *------------------------------------------------------------------------- */ @@ -2316,6 +2316,7 @@ _copyLockStmt(LockStmt *from) COPY_NODE_FIELD(relations); COPY_SCALAR_FIELD(mode); + COPY_SCALAR_FIELD(nowait); return newnode; } diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 7951fad039c629baf39ea0b7e18e5674d3cc5e38..b23002ff9477c1796fc5cc62f4c8e7cfb74e42e8 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -18,7 +18,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.215 2004/01/14 23:01:55 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.216 2004/03/11 01:47:35 ishii Exp $ * *------------------------------------------------------------------------- */ @@ -1252,6 +1252,7 @@ _equalLockStmt(LockStmt *a, LockStmt *b) { COMPARE_NODE_FIELD(relations); COMPARE_SCALAR_FIELD(mode); + COMPARE_SCALAR_FIELD(nowait); return true; } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 20db7fc6213d280e046509af4fdc8b1a6a64527d..9fd2e5b5795e8d8726a01864658fd11e64def04a 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.447 2004/03/09 05:05:41 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.448 2004/03/11 01:47:37 ishii Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -169,6 +169,7 @@ static void doNegateFloat(Value *v); %type <ival> opt_lock lock_type cast_context %type <boolean> opt_force opt_or_replace transaction_access_mode opt_grant_grant_option opt_revoke_grant_option + opt_nowait %type <boolean> like_including_defaults @@ -375,7 +376,7 @@ static void doNegateFloat(Value *v); MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB - NOCREATEUSER NONE NOT NOTHING NOTIFY NOTNULL NULL_P + NOCREATEUSER NONE NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NUMERIC OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR @@ -4347,12 +4348,13 @@ DeleteStmt: DELETE_P FROM relation_expr where_clause } ; -LockStmt: LOCK_P opt_table qualified_name_list opt_lock +LockStmt: LOCK_P opt_table qualified_name_list opt_lock opt_nowait { LockStmt *n = makeNode(LockStmt); n->relations = $3; n->mode = $4; + n->nowait = $5; $$ = (Node *)n; } ; @@ -4371,6 +4373,10 @@ lock_type: ACCESS SHARE { $$ = AccessShareLock; } | ACCESS EXCLUSIVE { $$ = AccessExclusiveLock; } ; +opt_nowait: NOWAIT { $$ = TRUE; } + | /*EMPTY*/ { $$ = FALSE; } + ; + /***************************************************************************** * @@ -7683,6 +7689,7 @@ reserved_keyword: | LOCALTIMESTAMP | NEW | NOT + | NOWAIT | NULL_P | OFF | OFFSET diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index 24430a9cc603f386be3c55c6bf02182b06c65cfd..54ac767126f01f22789d62516d59ef1713c44671 100644 --- a/src/backend/parser/keywords.c +++ b/src/backend/parser/keywords.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.146 2004/03/09 05:05:41 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.147 2004/03/11 01:47:40 ishii Exp $ * *------------------------------------------------------------------------- */ @@ -213,6 +213,7 @@ static const ScanKeyword ScanKeywords[] = { {"nothing", NOTHING}, {"notify", NOTIFY}, {"notnull", NOTNULL}, + {"nowait", NOWAIT}, {"null", NULL_P}, {"nullif", NULLIF}, {"numeric", NUMERIC}, diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 1b7e19fe073ba1796878e93d6f88a651bbe01000..c6579ea246282c2adeb1b7a55c52558947251ad9 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.86 2003/11/29 22:40:55 pgsql Exp $ + * $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.87 2004/03/11 01:47:41 ishii Exp $ * *------------------------------------------------------------------------- */ @@ -129,6 +129,7 @@ extern Datum heap_getsysattr(HeapTuple tup, int attnum, bool *isnull); /* heapam.c */ extern Relation relation_open(Oid relationId, LOCKMODE lockmode); +extern Relation conditional_relation_open(Oid relationId, LOCKMODE lockmode, bool nowait); extern Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode); extern Relation relation_openr(const char *sysRelationName, LOCKMODE lockmode); extern void relation_close(Relation relation, LOCKMODE lockmode); diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 01ff239a444548c9ffd915768f21c43d6cdb8dcd..ab505939bc3b3a1fc79b81668e65465c1424ab6f 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.253 2004/01/14 23:01:55 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.254 2004/03/11 01:47:41 ishii Exp $ * *------------------------------------------------------------------------- */ @@ -1619,6 +1619,7 @@ typedef struct LockStmt NodeTag type; List *relations; /* relations to lock */ int mode; /* lock mode */ + bool nowait; /* no wait mode */ } LockStmt; /* ----------------------