From 77a69a2ed165c31a981ac553f56c7b43e12d9ab5 Mon Sep 17 00:00:00 2001 From: Bruce Momjian <bruce@momjian.us> Date: Fri, 10 Aug 2001 14:30:15 +0000 Subject: [PATCH] Patch to LOCK multiple tables in one LOCK command. Neil Padgett --- doc/src/sgml/ref/lock.sgml | 16 ++++++--- src/backend/commands/command.c | 51 ++++++++++++++++----------- src/backend/nodes/copyfuncs.c | 6 ++-- src/backend/nodes/equalfuncs.c | 4 +-- src/backend/parser/gram.y | 6 ++-- src/include/nodes/parsenodes.h | 4 +-- src/interfaces/ecpg/preproc/preproc.y | 2 +- 7 files changed, 54 insertions(+), 35 deletions(-) diff --git a/doc/src/sgml/ref/lock.sgml b/doc/src/sgml/ref/lock.sgml index 20530d75d71..b66f42e7ebc 100644 --- a/doc/src/sgml/ref/lock.sgml +++ b/doc/src/sgml/ref/lock.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/lock.sgml,v 1.26 2001/08/04 22:01:38 momjian Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/lock.sgml,v 1.27 2001/08/10 14:30:14 momjian Exp $ Postgres documentation --> @@ -15,7 +15,7 @@ Postgres documentation LOCK </refname> <refpurpose> - Explicitly lock a table inside a transaction + Explicitly lock a table / tables inside a transaction </refpurpose> </refnamediv> <refsynopsisdiv> @@ -23,8 +23,8 @@ Postgres documentation <date>2001-07-09</date> </refsynopsisdivinfo> <synopsis> -LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> -LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> IN <replaceable class="PARAMETER">lockmode</replaceable> MODE +LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> [, ...] +LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> [, ...] IN <replaceable class="PARAMETER">lockmode</replaceable> MODE where <replaceable class="PARAMETER">lockmode</replaceable> is one of: @@ -373,6 +373,7 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist. An example for this rule was given previously when discussing the use of SHARE ROW EXCLUSIVE mode rather than SHARE mode. </para> + </listitem> </itemizedlist> @@ -383,6 +384,12 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist. </para> </note> + <para> + When locking multiple tables, the command LOCK a, b; is equivalent to LOCK + a; LOCK b;. The tables are locked one-by-one in the order specified in the + <command>LOCK</command> command. + </para> + <refsect2 id="R2-SQL-LOCK-3"> <refsect2info> <date>1999-06-08</date> @@ -406,6 +413,7 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist. <para> <command>LOCK</command> works only inside transactions. </para> + </refsect2> </refsect1> diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index 37814cdcd38..3d02fdb5fd2 100644 --- a/src/backend/commands/command.c +++ b/src/backend/commands/command.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.138 2001/08/04 22:01:38 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.139 2001/08/10 14:30:14 momjian Exp $ * * NOTES * The PerformAddAttribute() code, like most of the relation @@ -1984,8 +1984,7 @@ needs_toast_table(Relation rel) MAXALIGN(data_length); return (tuple_length > TOAST_TUPLE_THRESHOLD); } - - + /* * * LOCK TABLE @@ -1994,26 +1993,38 @@ needs_toast_table(Relation rel) void LockTableCommand(LockStmt *lockstmt) { - Relation rel; - int aclresult; - - rel = heap_openr(lockstmt->relname, NoLock); - - if (rel->rd_rel->relkind != RELKIND_RELATION) - elog(ERROR, "LOCK TABLE: %s is not a table", lockstmt->relname); - - if (lockstmt->mode == AccessShareLock) - aclresult = pg_aclcheck(lockstmt->relname, GetUserId(), ACL_SELECT); - else - aclresult = pg_aclcheck(lockstmt->relname, GetUserId(), - ACL_UPDATE | ACL_DELETE); + List *p; + Relation rel; + + /* Iterate over the list and open, lock, and close the relations + one at a time + */ - if (aclresult != ACLCHECK_OK) - elog(ERROR, "LOCK TABLE: permission denied"); + foreach(p, lockstmt->rellist) + { + char* relname = strVal(lfirst(p)); + int aclresult; + + rel = heap_openr(relname, NoLock); + + if (rel->rd_rel->relkind != RELKIND_RELATION) + elog(ERROR, "LOCK TABLE: %s is not a table", + relname); + + if (lockstmt->mode == AccessShareLock) + aclresult = pg_aclcheck(relname, GetUserId(), + ACL_SELECT); + else + aclresult = pg_aclcheck(relname, GetUserId(), + ACL_UPDATE | ACL_DELETE); - LockRelation(rel, lockstmt->mode); + if (aclresult != ACLCHECK_OK) + elog(ERROR, "LOCK TABLE: permission denied"); - heap_close(rel, NoLock); /* close rel, keep lock */ + LockRelation(rel, lockstmt->mode); + + heap_close(rel, NoLock); /* close rel, keep lock */ + } } diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 0d9aef03edf..ddb5822cde2 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 - * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.150 2001/08/04 22:01:38 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.151 2001/08/10 14:30:14 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -2425,8 +2425,8 @@ _copyLockStmt(LockStmt *from) { LockStmt *newnode = makeNode(LockStmt); - if (from->relname) - newnode->relname = pstrdup(from->relname); + Node_Copy(from, newnode, rellist); + newnode->mode = from->mode; return newnode; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 74a88555c5d..06cdeef9ad8 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -20,7 +20,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.98 2001/08/04 22:01:38 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.99 2001/08/10 14:30:14 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1283,7 +1283,7 @@ _equalDropUserStmt(DropUserStmt *a, DropUserStmt *b) static bool _equalLockStmt(LockStmt *a, LockStmt *b) { - if (!equalstr(a->relname, b->relname)) + if (!equal(a->rellist, b->rellist)) return false; if (a->mode != b->mode) return false; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 96690aa90cf..2a08413dafe 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.241 2001/08/06 05:42:48 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.242 2001/08/10 14:30:14 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -3281,11 +3281,11 @@ DeleteStmt: DELETE FROM relation_expr where_clause } ; -LockStmt: LOCK_P opt_table relation_name opt_lock +LockStmt: LOCK_P opt_table relation_name_list opt_lock { LockStmt *n = makeNode(LockStmt); - n->relname = $3; + n->rellist = $3; n->mode = $4; $$ = (Node *)n; } diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index ad7bcc2e0f3..704b8cab4a7 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parsenodes.h,v 1.138 2001/08/04 22:01:39 momjian Exp $ + * $Id: parsenodes.h,v 1.139 2001/08/10 14:30:15 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -760,7 +760,7 @@ typedef struct VariableResetStmt typedef struct LockStmt { NodeTag type; - char *relname; /* relation to lock */ + List *rellist; /* relations to lock */ int mode; /* lock mode */ } LockStmt; diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index 88330ad3c1d..09180f85c9c 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -2421,7 +2421,7 @@ DeleteStmt: DELETE FROM relation_expr where_clause } ; -LockStmt: LOCK_P opt_table relation_name opt_lock +LockStmt: LOCK_P opt_table relation_name_list opt_lock { $$ = cat_str(4, make_str("lock"), $2, $3, $4); } -- GitLab