mirror of
https://github.com/postgres/postgres.git
synced 2025-11-07 19:06:32 +03:00
Add LOCK A,B,C functionality as LOCK A;LOCK B;LOCK C; as agreed.
Neil Padgett
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -1984,8 +1984,7 @@ needs_toast_table(Relation rel)
|
||||
MAXALIGN(data_length);
|
||||
return (tuple_length > TOAST_TUPLE_THRESHOLD);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* LOCK TABLE
|
||||
@@ -1994,26 +1993,104 @@ needs_toast_table(Relation rel)
|
||||
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)
|
||||
{
|
||||
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
elog(ERROR, "LOCK TABLE: permission denied");
|
||||
/* Locking a single table */
|
||||
|
||||
LockRelation(rel, lockstmt->mode);
|
||||
Relation rel;
|
||||
int aclresult;
|
||||
char *relname;
|
||||
|
||||
heap_close(rel, NoLock); /* close rel, keep lock */
|
||||
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;
|
||||
|
||||
/* Locking multiple tables */
|
||||
|
||||
/* Create an array of relations */
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user