提交 16365ac7 编写于 作者: B Bruce Momjian

Add LOCK A,B,C functionality as LOCK A;LOCK B;LOCK C; as agreed.

Neil Padgett
上级 0bfc64b3
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/lock.sgml,v 1.24 2001/07/09 22:18:33 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/lock.sgml,v 1.25 2001/08/04 19:38:59 momjian Exp $
Postgres documentation Postgres documentation
--> -->
...@@ -15,7 +15,7 @@ Postgres documentation ...@@ -15,7 +15,7 @@ Postgres documentation
LOCK LOCK
</refname> </refname>
<refpurpose> <refpurpose>
Explicitly lock a table inside a transaction Explicitly lock a table / tables inside a transaction
</refpurpose> </refpurpose>
</refnamediv> </refnamediv>
<refsynopsisdiv> <refsynopsisdiv>
...@@ -23,8 +23,8 @@ Postgres documentation ...@@ -23,8 +23,8 @@ Postgres documentation
<date>2001-07-09</date> <date>2001-07-09</date>
</refsynopsisdivinfo> </refsynopsisdivinfo>
<synopsis> <synopsis>
LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> 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> [,...] IN <replaceable class="PARAMETER">lockmode</replaceable> MODE
where <replaceable class="PARAMETER">lockmode</replaceable> is one of: where <replaceable class="PARAMETER">lockmode</replaceable> is one of:
...@@ -373,6 +373,7 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist. ...@@ -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 An example for this rule was given previously when discussing the
use of SHARE ROW EXCLUSIVE mode rather than SHARE mode. use of SHARE ROW EXCLUSIVE mode rather than SHARE mode.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
...@@ -383,6 +384,12 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist. ...@@ -383,6 +384,12 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist.
</para> </para>
</note> </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"> <refsect2 id="R2-SQL-LOCK-3">
<refsect2info> <refsect2info>
<date>1999-06-08</date> <date>1999-06-08</date>
...@@ -406,6 +413,7 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist. ...@@ -406,6 +413,7 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist.
<para> <para>
<command>LOCK</command> works only inside transactions. <command>LOCK</command> works only inside transactions.
</para> </para>
</refsect2> </refsect2>
</refsect1> </refsect1>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.136 2001/07/16 05:06:57 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.137 2001/08/04 19:38:59 momjian Exp $
* *
* NOTES * NOTES
* The PerformAddAttribute() code, like most of the relation * The PerformAddAttribute() code, like most of the relation
...@@ -1984,8 +1984,7 @@ needs_toast_table(Relation rel) ...@@ -1984,8 +1984,7 @@ needs_toast_table(Relation rel)
MAXALIGN(data_length); MAXALIGN(data_length);
return (tuple_length > TOAST_TUPLE_THRESHOLD); return (tuple_length > TOAST_TUPLE_THRESHOLD);
} }
/* /*
* *
* LOCK TABLE * LOCK TABLE
...@@ -1994,26 +1993,104 @@ needs_toast_table(Relation rel) ...@@ -1994,26 +1993,104 @@ needs_toast_table(Relation rel)
void void
LockTableCommand(LockStmt *lockstmt) LockTableCommand(LockStmt *lockstmt)
{ {
Relation rel; int relCnt;
int aclresult;
rel = heap_openr(lockstmt->relname, NoLock); relCnt = length(lockstmt -> rellist);
if (rel->rd_rel->relkind != RELKIND_RELATION) /* Handle a single relation lock specially to avoid overhead on likely the
elog(ERROR, "LOCK TABLE: %s is not a table", lockstmt->relname); most common case */
if (lockstmt->mode == AccessShareLock) if(relCnt == 1)
aclresult = pg_aclcheck(lockstmt->relname, GetUserId(), ACL_SELECT); {
else
aclresult = pg_aclcheck(lockstmt->relname, GetUserId(), /* Locking a single table */
ACL_UPDATE | ACL_DELETE);
Relation rel;
int aclresult;
char *relname;
relname = strVal(lfirst(lockstmt->rellist));
freeList(lockstmt->rellist);
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);
if (aclresult != ACLCHECK_OK)
elog(ERROR, "LOCK TABLE: permission denied");
LockRelation(rel, lockstmt->mode);
pfree(relname);
heap_close(rel, NoLock); /* close rel, keep lock */
}
else
{
List *p;
Relation *RelationArray;
Relation *pRel;
if (aclresult != ACLCHECK_OK) /* Locking multiple tables */
elog(ERROR, "LOCK TABLE: permission denied");
LockRelation(rel, lockstmt->mode); /* Create an array of relations */
heap_close(rel, NoLock); /* close rel, keep lock */ RelationArray = palloc(relCnt * sizeof(Relation));
pRel = RelationArray;
/* Iterate over the list and populate the relation array */
foreach(p, lockstmt->rellist)
{
char* relname = strVal(lfirst(p));
int aclresult;
*pRel = heap_openr(relname, NoLock);
if ((*pRel)->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);
if (aclresult != ACLCHECK_OK)
elog(ERROR, "LOCK TABLE: permission denied");
pRel++;
pfree(relname);
}
/* Now, lock all the relations, closing each after it is locked
(Keeping the locks)
*/
for(pRel = RelationArray;
pRel < RelationArray + relCnt;
pRel++)
{
LockRelation(*pRel, lockstmt->mode);
heap_close(*pRel, NoLock);
}
/* Free the relation array */
pfree(RelationArray);
}
} }
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.148 2001/07/16 19:07:37 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.149 2001/08/04 19:38:59 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -2425,8 +2425,8 @@ _copyLockStmt(LockStmt *from) ...@@ -2425,8 +2425,8 @@ _copyLockStmt(LockStmt *from)
{ {
LockStmt *newnode = makeNode(LockStmt); LockStmt *newnode = makeNode(LockStmt);
if (from->relname) Node_Copy(from, newnode, rellist);
newnode->relname = pstrdup(from->relname);
newnode->mode = from->mode; newnode->mode = from->mode;
return newnode; return newnode;
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.96 2001/07/16 19:07:38 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.97 2001/08/04 19:38:59 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1283,7 +1283,7 @@ _equalDropUserStmt(DropUserStmt *a, DropUserStmt *b) ...@@ -1283,7 +1283,7 @@ _equalDropUserStmt(DropUserStmt *a, DropUserStmt *b)
static bool static bool
_equalLockStmt(LockStmt *a, LockStmt *b) _equalLockStmt(LockStmt *a, LockStmt *b)
{ {
if (!equalstr(a->relname, b->relname)) if (!equal(a->rellist, b->rellist))
return false; return false;
if (a->mode != b->mode) if (a->mode != b->mode)
return false; return false;
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.238 2001/07/16 19:07:40 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.239 2001/08/04 19:38:59 momjian Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -3280,11 +3280,11 @@ DeleteStmt: DELETE FROM relation_expr where_clause ...@@ -3280,11 +3280,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); LockStmt *n = makeNode(LockStmt);
n->relname = $3; n->rellist = $3;
n->mode = $4; n->mode = $4;
$$ = (Node *)n; $$ = (Node *)n;
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: parsenodes.h,v 1.136 2001/07/16 19:07:40 momjian Exp $ * $Id: parsenodes.h,v 1.137 2001/08/04 19:38:59 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -760,7 +760,7 @@ typedef struct VariableResetStmt ...@@ -760,7 +760,7 @@ typedef struct VariableResetStmt
typedef struct LockStmt typedef struct LockStmt
{ {
NodeTag type; NodeTag type;
char *relname; /* relation to lock */ List *rellist; /* relations to lock */
int mode; /* lock mode */ int mode; /* lock mode */
} LockStmt; } LockStmt;
......
...@@ -2421,7 +2421,7 @@ DeleteStmt: DELETE FROM relation_expr where_clause ...@@ -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); $$ = cat_str(4, make_str("lock"), $2, $3, $4);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册