diff --git a/doc/src/sgml/ref/lock.sgml b/doc/src/sgml/ref/lock.sgml
index 913afe76dd4..b946eab3039 100644
--- a/doc/src/sgml/ref/lock.sgml
+++ b/doc/src/sgml/ref/lock.sgml
@@ -161,9 +161,11 @@ LOCK [ TABLE ] [ ONLY ] name [ * ]
LOCK TABLE ... IN ACCESS SHARE MODE> requires SELECT>
- privileges on the target table. All other forms of LOCK>
- require table-level UPDATE>, DELETE>, or
- TRUNCATE> privileges.
+ privileges on the target table. LOCK TABLE ... IN ROW EXCLUSIVE
+ MODE> requires INSERT>, UPDATE>, DELETE>,
+ or TRUNCATE> privileges on the target table. All other forms of
+ LOCK> require table-level UPDATE>, DELETE>,
+ or TRUNCATE> privileges.
diff --git a/src/backend/commands/lockcmds.c b/src/backend/commands/lockcmds.c
index bdec2ff545c..a1670821aa4 100644
--- a/src/backend/commands/lockcmds.c
+++ b/src/backend/commands/lockcmds.c
@@ -169,13 +169,17 @@ static AclResult
LockTableAclCheck(Oid reloid, LOCKMODE lockmode)
{
AclResult aclresult;
+ AclMode aclmask;
/* Verify adequate privilege */
if (lockmode == AccessShareLock)
- aclresult = pg_class_aclcheck(reloid, GetUserId(),
- ACL_SELECT);
+ aclmask = ACL_SELECT;
+ else if (lockmode == RowExclusiveLock)
+ aclmask = ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE;
else
- aclresult = pg_class_aclcheck(reloid, GetUserId(),
- ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE);
+ aclmask = ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE;
+
+ aclresult = pg_class_aclcheck(reloid, GetUserId(), aclmask);
+
return aclresult;
}