column_level_lock.patch

application/octet-stream

Filename: column_level_lock.patch
Type: application/octet-stream
Part: 0
Message: Re: [GENERAL] column-level update privs + lock table

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
File+
doc/src/sgml/ref/lock.sgml 0 0
src/backend/commands/lockcmds.c 0 0
src/test/regress/expected/privileges.out 0 0
src/test/regress/sql/privileges.sql 0 0
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 ] <replaceable cla
*** 158,165 ****
     <para>
      <literal>LOCK TABLE ... IN ACCESS SHARE MODE</> requires <literal>SELECT</>
      privileges on the target table.  All other forms of <command>LOCK</>
!     require at least one of <literal>UPDATE</>, <literal>DELETE</>, or
!     <literal>TRUNCATE</> privileges.
     </para>
  
     <para>
--- 158,165 ----
     <para>
      <literal>LOCK TABLE ... IN ACCESS SHARE MODE</> requires <literal>SELECT</>
      privileges on the target table.  All other forms of <command>LOCK</>
!     require either table-level <literal>UPDATE</>, <literal>DELETE</>, or
!     <literal>TRUNCATE</> privileges, or UPDATE privileges on one or more columns.
     </para>
  
     <para>
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;