diff --git a/doc/src/sgml/ref/lock.sgml b/doc/src/sgml/ref/lock.sgml index baaf31a..e4b41fd 100644 *** a/doc/src/sgml/ref/lock.sgml --- b/doc/src/sgml/ref/lock.sgml *************** LOCK [ TABLE ] [ ONLY ] LOCK TABLE ... IN ACCESS SHARE MODE requires SELECT privileges on the target table. All other forms of LOCK ! require at least one of UPDATE, DELETE, or ! TRUNCATE privileges. --- 158,165 ---- LOCK TABLE ... IN ACCESS SHARE MODE requires SELECT privileges on the target table. All other forms of LOCK ! require either table-level UPDATE, DELETE, or ! TRUNCATE privileges, or UPDATE privileges on one or more columns. diff --git a/src/backend/commands/lockcmds.c b/src/backend/commands/lockcmds.c index 35fc1b3..610805d 100644 *** a/src/backend/commands/lockcmds.c --- b/src/backend/commands/lockcmds.c *************** LockTableRecurse(Oid reloid, RangeVar *r *** 135,143 **** if (lockmode == AccessShareLock) aclresult = pg_class_aclcheck(reloid, GetUserId(), ACL_SELECT); ! else aclresult = pg_class_aclcheck(reloid, GetUserId(), ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_CLASS, RelationGetRelationName(rel)); --- 135,150 ---- if (lockmode == AccessShareLock) aclresult = pg_class_aclcheck(reloid, GetUserId(), ACL_SELECT); ! else { ! /* check table-level privileges */ aclresult = pg_class_aclcheck(reloid, GetUserId(), ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE); + if (aclresult != ACLCHECK_OK) { + /* No column-level TRUNCATE or DELETE privileges to check for */ + aclresult = pg_attribute_aclcheck_all(reloid, GetUserId(), + ACL_UPDATE , ACLMASK_ANY); + } + } if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_CLASS, RelationGetRelationName(rel)); diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out index 5cda230..f26bbfe 100644 *** a/src/test/regress/expected/privileges.out --- b/src/test/regress/expected/privileges.out *************** CREATE USER regressuser4; *** 26,31 **** --- 26,32 ---- CREATE USER regressuser5; CREATE USER regressuser5; -- duplicate ERROR: role "regressuser5" already exists + CREATE USER regressuser6; CREATE GROUP regressgroup1; CREATE GROUP regressgroup2 WITH USER regressuser1, regressuser2; ALTER GROUP regressgroup1 ADD USER regressuser4; *************** GRANT SELECT ON atest2 TO regressuser2; *** 72,77 **** --- 73,79 ---- GRANT UPDATE ON atest2 TO regressuser3; GRANT INSERT ON atest2 TO regressuser4; GRANT TRUNCATE ON atest2 TO regressuser5; + GRANT UPDATE (col2) ON atest2 TO regressuser6; SET SESSION AUTHORIZATION regressuser2; SELECT session_user, current_user; session_user | current_user *************** SELECT * FROM atest1; -- ok *** 184,189 **** --- 186,195 ---- 1 | two (2 rows) + SET SESSION AUTHORIZATION regressuser6; + BEGIN; + LOCK TABLE atest2 IN EXCLUSIVE MODE; -- ok + ROLLBACK; -- groups SET SESSION AUTHORIZATION regressuser3; CREATE TABLE atest3 (one int, two int, three int); *************** DROP USER regressuser3; *** 1259,1262 **** DROP USER regressuser4; DROP USER regressuser5; DROP USER regressuser6; ! ERROR: role "regressuser6" does not exist --- 1265,1269 ---- DROP USER regressuser4; DROP USER regressuser5; DROP USER regressuser6; ! DROP USER regressuserX; ! ERROR: role "regressuserx" does not exist diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql index a87ce77..6cb178a 100644 *** a/src/test/regress/sql/privileges.sql --- b/src/test/regress/sql/privileges.sql *************** CREATE USER regressuser3; *** 29,34 **** --- 29,35 ---- CREATE USER regressuser4; CREATE USER regressuser5; CREATE USER regressuser5; -- duplicate + CREATE USER regressuser6; CREATE GROUP regressgroup1; CREATE GROUP regressgroup2 WITH USER regressuser1, regressuser2; *************** GRANT SELECT ON atest2 TO regressuser2; *** 66,72 **** GRANT UPDATE ON atest2 TO regressuser3; GRANT INSERT ON atest2 TO regressuser4; GRANT TRUNCATE ON atest2 TO regressuser5; ! SET SESSION AUTHORIZATION regressuser2; SELECT session_user, current_user; --- 67,73 ---- GRANT UPDATE ON atest2 TO regressuser3; GRANT INSERT ON atest2 TO regressuser4; GRANT TRUNCATE ON atest2 TO regressuser5; ! GRANT UPDATE (col2) ON atest2 TO regressuser6; SET SESSION AUTHORIZATION regressuser2; SELECT session_user, current_user; *************** bar true *** 126,131 **** --- 127,137 ---- \. SELECT * FROM atest1; -- ok + SET SESSION AUTHORIZATION regressuser6; + BEGIN; + LOCK TABLE atest2 IN EXCLUSIVE MODE; -- ok + ROLLBACK; + -- groups *************** DROP USER regressuser3; *** 712,714 **** --- 718,721 ---- DROP USER regressuser4; DROP USER regressuser5; DROP USER regressuser6; + DROP USER regressuserX;