Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 16365ac

Browse files
committed
Add LOCK A,B,C functionality as LOCK A;LOCK B;LOCK C; as agreed.
Neil Padgett
1 parent 0bfc64b commit 16365ac

File tree

7 files changed

+117
-32
lines changed

7 files changed

+117
-32
lines changed

doc/src/sgml/ref/lock.sgml

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/ref/lock.sgml,v 1.24 2001/07/09 22:18:33 tgl Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/ref/lock.sgml,v 1.25 2001/08/04 19:38:59 momjian Exp $
33
Postgres documentation
44
-->
55

@@ -15,16 +15,16 @@ Postgres documentation
1515
LOCK
1616
</refname>
1717
<refpurpose>
18-
Explicitly lock a table inside a transaction
18+
Explicitly lock a table / tables inside a transaction
1919
</refpurpose>
2020
</refnamediv>
2121
<refsynopsisdiv>
2222
<refsynopsisdivinfo>
2323
<date>2001-07-09</date>
2424
</refsynopsisdivinfo>
2525
<synopsis>
26-
LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable>
27-
LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> IN <replaceable class="PARAMETER">lockmode</replaceable> MODE
26+
LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> [,...]
27+
LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> [,...] IN <replaceable class="PARAMETER">lockmode</replaceable> MODE
2828

2929
where <replaceable class="PARAMETER">lockmode</replaceable> is one of:
3030

@@ -373,6 +373,7 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist.
373373
An example for this rule was given previously when discussing the
374374
use of SHARE ROW EXCLUSIVE mode rather than SHARE mode.
375375
</para>
376+
376377
</listitem>
377378
</itemizedlist>
378379

@@ -383,6 +384,12 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist.
383384
</para>
384385
</note>
385386

387+
<para>
388+
When locking multiple tables, the command LOCK a, b; is equivalent to LOCK
389+
a; LOCK b;. The tables are locked one-by-one in the order specified in the
390+
<command>LOCK</command> command.
391+
</para>
392+
386393
<refsect2 id="R2-SQL-LOCK-3">
387394
<refsect2info>
388395
<date>1999-06-08</date>
@@ -406,6 +413,7 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist.
406413
<para>
407414
<command>LOCK</command> works only inside transactions.
408415
</para>
416+
409417
</refsect2>
410418
</refsect1>
411419

src/backend/commands/command.c

+94-17
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.136 2001/07/16 05:06:57 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.137 2001/08/04 19:38:59 momjian Exp $
1212
*
1313
* NOTES
1414
* The PerformAddAttribute() code, like most of the relation
@@ -1984,8 +1984,7 @@ needs_toast_table(Relation rel)
19841984
MAXALIGN(data_length);
19851985
return (tuple_length > TOAST_TUPLE_THRESHOLD);
19861986
}
1987-
1988-
1987+
19891988
/*
19901989
*
19911990
* LOCK TABLE
@@ -1994,26 +1993,104 @@ needs_toast_table(Relation rel)
19941993
void
19951994
LockTableCommand(LockStmt *lockstmt)
19961995
{
1997-
Relation rel;
1998-
int aclresult;
1996+
int relCnt;
19991997

2000-
rel = heap_openr(lockstmt->relname, NoLock);
1998+
relCnt = length(lockstmt -> rellist);
20011999

2002-
if (rel->rd_rel->relkind != RELKIND_RELATION)
2003-
elog(ERROR, "LOCK TABLE: %s is not a table", lockstmt->relname);
2000+
/* Handle a single relation lock specially to avoid overhead on likely the
2001+
most common case */
20042002

2005-
if (lockstmt->mode == AccessShareLock)
2006-
aclresult = pg_aclcheck(lockstmt->relname, GetUserId(), ACL_SELECT);
2007-
else
2008-
aclresult = pg_aclcheck(lockstmt->relname, GetUserId(),
2009-
ACL_UPDATE | ACL_DELETE);
2003+
if(relCnt == 1)
2004+
{
2005+
2006+
/* Locking a single table */
2007+
2008+
Relation rel;
2009+
int aclresult;
2010+
char *relname;
2011+
2012+
relname = strVal(lfirst(lockstmt->rellist));
2013+
2014+
freeList(lockstmt->rellist);
2015+
2016+
rel = heap_openr(relname, NoLock);
2017+
2018+
if (rel->rd_rel->relkind != RELKIND_RELATION)
2019+
elog(ERROR, "LOCK TABLE: %s is not a table", relname);
2020+
2021+
if (lockstmt->mode == AccessShareLock)
2022+
aclresult = pg_aclcheck(relname, GetUserId(),
2023+
ACL_SELECT);
2024+
else
2025+
aclresult = pg_aclcheck(relname, GetUserId(),
2026+
ACL_UPDATE | ACL_DELETE);
2027+
2028+
if (aclresult != ACLCHECK_OK)
2029+
elog(ERROR, "LOCK TABLE: permission denied");
2030+
2031+
LockRelation(rel, lockstmt->mode);
2032+
2033+
pfree(relname);
2034+
2035+
heap_close(rel, NoLock); /* close rel, keep lock */
2036+
}
2037+
else
2038+
{
2039+
List *p;
2040+
Relation *RelationArray;
2041+
Relation *pRel;
20102042

2011-
if (aclresult != ACLCHECK_OK)
2012-
elog(ERROR, "LOCK TABLE: permission denied");
2043+
/* Locking multiple tables */
20132044

2014-
LockRelation(rel, lockstmt->mode);
2045+
/* Create an array of relations */
20152046

2016-
heap_close(rel, NoLock); /* close rel, keep lock */
2047+
RelationArray = palloc(relCnt * sizeof(Relation));
2048+
pRel = RelationArray;
2049+
2050+
/* Iterate over the list and populate the relation array */
2051+
2052+
foreach(p, lockstmt->rellist)
2053+
{
2054+
char* relname = strVal(lfirst(p));
2055+
int aclresult;
2056+
2057+
*pRel = heap_openr(relname, NoLock);
2058+
2059+
if ((*pRel)->rd_rel->relkind != RELKIND_RELATION)
2060+
elog(ERROR, "LOCK TABLE: %s is not a table",
2061+
relname);
2062+
2063+
if (lockstmt->mode == AccessShareLock)
2064+
aclresult = pg_aclcheck(relname, GetUserId(),
2065+
ACL_SELECT);
2066+
else
2067+
aclresult = pg_aclcheck(relname, GetUserId(),
2068+
ACL_UPDATE | ACL_DELETE);
2069+
2070+
if (aclresult != ACLCHECK_OK)
2071+
elog(ERROR, "LOCK TABLE: permission denied");
2072+
2073+
pRel++;
2074+
pfree(relname);
2075+
}
2076+
2077+
/* Now, lock all the relations, closing each after it is locked
2078+
(Keeping the locks)
2079+
*/
2080+
2081+
for(pRel = RelationArray;
2082+
pRel < RelationArray + relCnt;
2083+
pRel++)
2084+
{
2085+
LockRelation(*pRel, lockstmt->mode);
2086+
2087+
heap_close(*pRel, NoLock);
2088+
}
2089+
2090+
/* Free the relation array */
2091+
2092+
pfree(RelationArray);
2093+
}
20172094
}
20182095

20192096

src/backend/nodes/copyfuncs.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.148 2001/07/16 19:07:37 momjian Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.149 2001/08/04 19:38:59 momjian Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -2425,8 +2425,8 @@ _copyLockStmt(LockStmt *from)
24252425
{
24262426
LockStmt *newnode = makeNode(LockStmt);
24272427

2428-
if (from->relname)
2429-
newnode->relname = pstrdup(from->relname);
2428+
Node_Copy(from, newnode, rellist);
2429+
24302430
newnode->mode = from->mode;
24312431

24322432
return newnode;

src/backend/nodes/equalfuncs.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* Portions Copyright (c) 1994, Regents of the University of California
2121
*
2222
* IDENTIFICATION
23-
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.96 2001/07/16 19:07:38 momjian Exp $
23+
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.97 2001/08/04 19:38:59 momjian Exp $
2424
*
2525
*-------------------------------------------------------------------------
2626
*/
@@ -1283,7 +1283,7 @@ _equalDropUserStmt(DropUserStmt *a, DropUserStmt *b)
12831283
static bool
12841284
_equalLockStmt(LockStmt *a, LockStmt *b)
12851285
{
1286-
if (!equalstr(a->relname, b->relname))
1286+
if (!equal(a->rellist, b->rellist))
12871287
return false;
12881288
if (a->mode != b->mode)
12891289
return false;

src/backend/parser/gram.y

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.238 2001/07/16 19:07:40 momjian Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.239 2001/08/04 19:38:59 momjian Exp $
1515
*
1616
* HISTORY
1717
* AUTHOR DATE MAJOR EVENT
@@ -3280,11 +3280,11 @@ DeleteStmt: DELETE FROM relation_expr where_clause
32803280
}
32813281
;
32823282

3283-
LockStmt: LOCK_P opt_table relation_name opt_lock
3283+
LockStmt: LOCK_P opt_table relation_name_list opt_lock
32843284
{
32853285
LockStmt *n = makeNode(LockStmt);
32863286

3287-
n->relname = $3;
3287+
n->rellist = $3;
32883288
n->mode = $4;
32893289
$$ = (Node *)n;
32903290
}

src/include/nodes/parsenodes.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: parsenodes.h,v 1.136 2001/07/16 19:07:40 momjian Exp $
10+
* $Id: parsenodes.h,v 1.137 2001/08/04 19:38:59 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -760,7 +760,7 @@ typedef struct VariableResetStmt
760760
typedef struct LockStmt
761761
{
762762
NodeTag type;
763-
char *relname; /* relation to lock */
763+
List *rellist; /* relations to lock */
764764
int mode; /* lock mode */
765765
} LockStmt;
766766

src/interfaces/ecpg/preproc/preproc.y

+1-1
Original file line numberDiff line numberDiff line change
@@ -2421,7 +2421,7 @@ DeleteStmt: DELETE FROM relation_expr where_clause
24212421
}
24222422
;
24232423

2424-
LockStmt: LOCK_P opt_table relation_name opt_lock
2424+
LockStmt: LOCK_P opt_table relation_name_list opt_lock
24252425
{
24262426
$$ = cat_str(4, make_str("lock"), $2, $3, $4);
24272427
}

0 commit comments

Comments
 (0)