+ class="parameter">lockmode is permitted. If the user has
+ INSERT privileges on the table, ROW EXCLUSIVE
+ MODE (or a less-conflicting mode as described in
+ linkend="explicit-locking"/>) is permitted. If a user has
+ SELECT privileges on the table, ACCESS SHARE
+ MODE is permitted.
AclResult aclresult;
AclMode aclmask;
- /* Verify adequate privilege */
- if (lockmode == AccessShareLock)
- aclmask = ACL_SELECT;
- else if (lockmode == RowExclusiveLock)
- aclmask = ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE;
- else
- aclmask = ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE;
+ /* any of these privileges permit any lock mode */
+ aclmask = ACL_MAINTAIN | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE;
+
+ /* SELECT privileges also permit ACCESS SHARE and below */
+ if (lockmode <= AccessShareLock)
+ aclmask |= ACL_SELECT;
- /* MAINTAIN privilege allows all lock modes */
- aclmask |= ACL_MAINTAIN;
+ /* INSERT privileges also permit ROW EXCLUSIVE and below */
+ if (lockmode <= RowExclusiveLock)
+ aclmask |= ACL_INSERT;
aclresult = pg_class_aclcheck(reloid, userid, aclmask);
GRANT SELECT ON lock_table TO regress_locktable_user;
SET SESSION AUTHORIZATION regress_locktable_user;
BEGIN;
+LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
+COMMIT;
+BEGIN;
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should fail
ERROR: permission denied for table lock_table
ROLLBACK;
BEGIN;
-LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
-COMMIT;
-BEGIN;
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should fail
ERROR: permission denied for table lock_table
ROLLBACK;
GRANT INSERT ON lock_table TO regress_locktable_user;
SET SESSION AUTHORIZATION regress_locktable_user;
BEGIN;
+LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
+ROLLBACK;
+BEGIN;
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
COMMIT;
BEGIN;
-LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
-ERROR: permission denied for table lock_table
-ROLLBACK;
-BEGIN;
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should fail
ERROR: permission denied for table lock_table
ROLLBACK;
GRANT UPDATE ON lock_table TO regress_locktable_user;
SET SESSION AUTHORIZATION regress_locktable_user;
BEGIN;
+LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
+ROLLBACK;
+BEGIN;
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
COMMIT;
BEGIN;
-LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
-ERROR: permission denied for table lock_table
-ROLLBACK;
-BEGIN;
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
COMMIT;
\c
GRANT DELETE ON lock_table TO regress_locktable_user;
SET SESSION AUTHORIZATION regress_locktable_user;
BEGIN;
+LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
+ROLLBACK;
+BEGIN;
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
COMMIT;
BEGIN;
-LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
-ERROR: permission denied for table lock_table
-ROLLBACK;
-BEGIN;
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
COMMIT;
\c
GRANT TRUNCATE ON lock_table TO regress_locktable_user;
SET SESSION AUTHORIZATION regress_locktable_user;
BEGIN;
+LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
+ROLLBACK;
+BEGIN;
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
COMMIT;
BEGIN;
-LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
-ERROR: permission denied for table lock_table
+LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
+COMMIT;
+\c
+REVOKE TRUNCATE ON lock_table FROM regress_locktable_user;
+-- LOCK TABLE and MAINTAIN permission
+GRANT MAINTAIN ON lock_table TO regress_locktable_user;
+SET SESSION AUTHORIZATION regress_locktable_user;
+BEGIN;
+LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
ROLLBACK;
BEGIN;
+LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
+COMMIT;
+BEGIN;
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
COMMIT;
\c
-REVOKE TRUNCATE ON lock_table FROM regress_locktable_user;
+REVOKE MAINTAIN ON lock_table FROM regress_locktable_user;
-- clean up
DROP TABLE lock_table;
DROP USER regress_locktable_user;
ERROR: must be owner of index maintain_test_a_idx
REINDEX SCHEMA reindex_test;
ERROR: must be owner of schema reindex_test
-BEGIN;
-LOCK TABLE maintain_test IN ACCESS SHARE MODE;
-ERROR: permission denied for table maintain_test
-COMMIT;
-BEGIN;
-LOCK TABLE maintain_test IN ACCESS EXCLUSIVE MODE;
-ERROR: permission denied for table maintain_test
-COMMIT;
RESET ROLE;
SET ROLE regress_maintain;
VACUUM maintain_test;
REINDEX INDEX maintain_test_a_idx;
REINDEX SCHEMA reindex_test;
ERROR: must be owner of schema reindex_test
-BEGIN;
-LOCK TABLE maintain_test IN ACCESS SHARE MODE;
-COMMIT;
-BEGIN;
-LOCK TABLE maintain_test IN ACCESS EXCLUSIVE MODE;
-COMMIT;
RESET ROLE;
SET ROLE regress_maintain_all;
VACUUM maintain_test;
REINDEX TABLE maintain_test;
REINDEX INDEX maintain_test_a_idx;
REINDEX SCHEMA reindex_test;
-BEGIN;
-LOCK TABLE maintain_test IN ACCESS SHARE MODE;
-COMMIT;
-BEGIN;
-LOCK TABLE maintain_test IN ACCESS EXCLUSIVE MODE;
-COMMIT;
RESET ROLE;
DROP TABLE maintain_test;
DROP MATERIALIZED VIEW refresh_test;
GRANT SELECT ON lock_table TO regress_locktable_user;
SET SESSION AUTHORIZATION regress_locktable_user;
BEGIN;
-LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should fail
-ROLLBACK;
-BEGIN;
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
COMMIT;
BEGIN;
+LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should fail
+ROLLBACK;
+BEGIN;
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should fail
ROLLBACK;
\c
GRANT INSERT ON lock_table TO regress_locktable_user;
SET SESSION AUTHORIZATION regress_locktable_user;
BEGIN;
+LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
+ROLLBACK;
+BEGIN;
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
COMMIT;
BEGIN;
-LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
-ROLLBACK;
-BEGIN;
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should fail
ROLLBACK;
\c
GRANT UPDATE ON lock_table TO regress_locktable_user;
SET SESSION AUTHORIZATION regress_locktable_user;
BEGIN;
+LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
+ROLLBACK;
+BEGIN;
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
COMMIT;
BEGIN;
-LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
-ROLLBACK;
-BEGIN;
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
COMMIT;
\c
GRANT DELETE ON lock_table TO regress_locktable_user;
SET SESSION AUTHORIZATION regress_locktable_user;
BEGIN;
+LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
+ROLLBACK;
+BEGIN;
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
COMMIT;
BEGIN;
-LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
-ROLLBACK;
-BEGIN;
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
COMMIT;
\c
GRANT TRUNCATE ON lock_table TO regress_locktable_user;
SET SESSION AUTHORIZATION regress_locktable_user;
BEGIN;
+LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
+ROLLBACK;
+BEGIN;
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
COMMIT;
BEGIN;
-LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
+LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
+COMMIT;
+\c
+REVOKE TRUNCATE ON lock_table FROM regress_locktable_user;
+
+-- LOCK TABLE and MAINTAIN permission
+GRANT MAINTAIN ON lock_table TO regress_locktable_user;
+SET SESSION AUTHORIZATION regress_locktable_user;
+BEGIN;
+LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
ROLLBACK;
BEGIN;
+LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
+COMMIT;
+BEGIN;
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
COMMIT;
\c
-REVOKE TRUNCATE ON lock_table FROM regress_locktable_user;
+REVOKE MAINTAIN ON lock_table FROM regress_locktable_user;
-- clean up
DROP TABLE lock_table;
REINDEX TABLE maintain_test;
REINDEX INDEX maintain_test_a_idx;
REINDEX SCHEMA reindex_test;
-BEGIN;
-LOCK TABLE maintain_test IN ACCESS SHARE MODE;
-COMMIT;
-BEGIN;
-LOCK TABLE maintain_test IN ACCESS EXCLUSIVE MODE;
-COMMIT;
RESET ROLE;
SET ROLE regress_maintain;
REINDEX TABLE maintain_test;
REINDEX INDEX maintain_test_a_idx;
REINDEX SCHEMA reindex_test;
-BEGIN;
-LOCK TABLE maintain_test IN ACCESS SHARE MODE;
-COMMIT;
-BEGIN;
-LOCK TABLE maintain_test IN ACCESS EXCLUSIVE MODE;
-COMMIT;
RESET ROLE;
SET ROLE regress_maintain_all;
REINDEX TABLE maintain_test;
REINDEX INDEX maintain_test_a_idx;
REINDEX SCHEMA reindex_test;
-BEGIN;
-LOCK TABLE maintain_test IN ACCESS SHARE MODE;
-COMMIT;
-BEGIN;
-LOCK TABLE maintain_test IN ACCESS EXCLUSIVE MODE;
-COMMIT;
RESET ROLE;
DROP TABLE maintain_test;