<!--
-$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
-->
LOCK
</refname>
<refpurpose>
- Explicitly lock a table inside a transaction
+ Explicitly lock a table / tables inside a transaction
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<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:
An example for this rule was given previously when discussing the
use of SHARE ROW EXCLUSIVE mode rather than SHARE mode.
</para>
+
</listitem>
</itemizedlist>
</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>
<para>
<command>LOCK</command> works only inside transactions.
</para>
+
</refsect2>
</refsect1>
*
*
* 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
* The PerformAddAttribute() code, like most of the relation
MAXALIGN(data_length);
return (tuple_length > TOAST_TUPLE_THRESHOLD);
}
-
-
+
/*
*
* LOCK TABLE
void
LockTableCommand(LockStmt *lockstmt)
{
- Relation rel;
- int aclresult;
+ int relCnt;
- rel = heap_openr(lockstmt->relname, NoLock);
+ relCnt = length(lockstmt -> rellist);
- if (rel->rd_rel->relkind != RELKIND_RELATION)
- elog(ERROR, "LOCK TABLE: %s is not a table", lockstmt->relname);
+ /* Handle a single relation lock specially to avoid overhead on likely the
+ most common case */
- if (lockstmt->mode == AccessShareLock)
- aclresult = pg_aclcheck(lockstmt->relname, GetUserId(), ACL_SELECT);
- else
- aclresult = pg_aclcheck(lockstmt->relname, GetUserId(),
- ACL_UPDATE | ACL_DELETE);
+ if(relCnt == 1)
+ {
+
+ /* Locking a single table */
+
+ 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)
- elog(ERROR, "LOCK TABLE: permission denied");
+ /* Locking multiple tables */
- 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);
+ }
}