diff options
author | Bruce Momjian <bruce@momjian.us> | 2001-08-04 19:39:00 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 2001-08-04 19:39:00 +0000 |
commit | 16365ac75bc0089f6b1a3db537a58042caa38ab4 (patch) | |
tree | 1904bec6046528c3419bd50859a1183aadc14f37 /src/backend/commands/command.c | |
parent | 0bfc64b3875268c054b064d06165044caecfabf6 (diff) | |
download | postgresql-16365ac75bc0089f6b1a3db537a58042caa38ab4.tar.gz postgresql-16365ac75bc0089f6b1a3db537a58042caa38ab4.zip |
Add LOCK A,B,C functionality as LOCK A;LOCK B;LOCK C; as agreed.
Neil Padgett
Diffstat (limited to 'src/backend/commands/command.c')
-rw-r--r-- | src/backend/commands/command.c | 111 |
1 files changed, 94 insertions, 17 deletions
diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index 744129f726f..827608363cb 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.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) + { + + /* 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); + } } |