0001-refactor-ExecCheckPermissionsModified-for-ACL_SELECT.patch
text/x-patch
Filename: 0001-refactor-ExecCheckPermissionsModified-for-ACL_SELECT.patch
Type: text/x-patch
Part: 1
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: format-patch
Series: patch 0001
Subject: refactor ExecCheckPermissionsModified for ACL_SELECT
| File | + | − |
|---|---|---|
| src/backend/executor/execMain.c | 24 | 46 |
From 6111d2e02487e6de6726c6a5fe2746ce7f9d559f Mon Sep 17 00:00:00 2001
From: steve-chavez <stevechavezast@gmail.com>
Date: Mon, 23 Mar 2026 17:08:41 -0500
Subject: [PATCH] refactor ExecCheckPermissionsModified for ACL_SELECT
Currently the code on ExecCheckOneRelPerms duplicates the logic
in ExecCheckPermissionsModified.
This change accommodates ExecCheckPermissionsModified to handle
ACL_SELECT and makes ExecCheckOneRelPerms reuse code. It also merges
similar comments.
Main benefit is that it reduces LOCs and centralizes column privilege
logic.
---
src/backend/executor/execMain.c | 70 +++++++++++----------------------
1 file changed, 24 insertions(+), 46 deletions(-)
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 58b84955c2b..c1cc8251186 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -676,8 +676,6 @@ ExecCheckOneRelPerms(RTEPermissionInfo *perminfo)
remainingPerms = requiredPerms & ~relPerms;
if (remainingPerms != 0)
{
- int col = -1;
-
/*
* If we lack any permissions that exist only as relation permissions,
* we can fail straight away.
@@ -692,45 +690,13 @@ ExecCheckOneRelPerms(RTEPermissionInfo *perminfo)
* to report a column-level error if we have some but not all of the
* column privileges.
*/
- if (remainingPerms & ACL_SELECT)
- {
- /*
- * When the query doesn't explicitly reference any columns (for
- * example, SELECT COUNT(*) FROM table), allow the query if we
- * have SELECT on any column of the rel, as per SQL spec.
- */
- if (bms_is_empty(perminfo->selectedCols))
- {
- if (pg_attribute_aclcheck_all(relOid, userid, ACL_SELECT,
- ACLMASK_ANY) != ACLCHECK_OK)
- return false;
- }
-
- while ((col = bms_next_member(perminfo->selectedCols, col)) >= 0)
- {
- /* bit #s are offset by FirstLowInvalidHeapAttributeNumber */
- AttrNumber attno = col + FirstLowInvalidHeapAttributeNumber;
-
- if (attno == InvalidAttrNumber)
- {
- /* Whole-row reference, must have priv on all cols */
- if (pg_attribute_aclcheck_all(relOid, userid, ACL_SELECT,
- ACLMASK_ALL) != ACLCHECK_OK)
- return false;
- }
- else
- {
- if (pg_attribute_aclcheck(relOid, attno, userid,
- ACL_SELECT) != ACLCHECK_OK)
- return false;
- }
- }
- }
+ if (remainingPerms & ACL_SELECT &&
+ !ExecCheckPermissionsModified(relOid,
+ userid,
+ perminfo->selectedCols,
+ ACL_SELECT))
+ return false;
- /*
- * Basically the same for the mod columns, for both INSERT and UPDATE
- * privilege as specified by remainingPerms.
- */
if (remainingPerms & ACL_INSERT &&
!ExecCheckPermissionsModified(relOid,
userid,
@@ -750,7 +716,7 @@ ExecCheckOneRelPerms(RTEPermissionInfo *perminfo)
/*
* ExecCheckPermissionsModified
- * Check INSERT or UPDATE access permissions for a single relation (these
+ * Check SELECT, INSERT or UPDATE access permissions for a single relation (these
* are processed uniformly).
*/
static bool
@@ -760,9 +726,11 @@ ExecCheckPermissionsModified(Oid relOid, Oid userid, Bitmapset *modifiedCols,
int col = -1;
/*
- * When the query doesn't explicitly update any columns, allow the query
- * if we have permission on any column of the rel. This is to handle
- * SELECT FOR UPDATE as well as possible corner cases in UPDATE.
+ * When the query doesn't explicitly reference any columns (for
+ * example, SELECT COUNT(*) FROM table or INSERT DEFAULT VALUES),
+ * allow the query if we have permission on any column of the rel, as per SQL spec.
+ *
+ * This handles SELECT FOR UPDATE as well as possible corner cases in UPDATE.
*/
if (bms_is_empty(modifiedCols))
{
@@ -776,10 +744,20 @@ ExecCheckPermissionsModified(Oid relOid, Oid userid, Bitmapset *modifiedCols,
/* bit #s are offset by FirstLowInvalidHeapAttributeNumber */
AttrNumber attno = col + FirstLowInvalidHeapAttributeNumber;
+ /* Whole-row reference, must have priv on all cols */
if (attno == InvalidAttrNumber)
{
- /* whole-row reference can't happen here */
- elog(ERROR, "whole-row update is not implemented");
+
+ /* In the case of SELECT * we have to check for all column permissions */
+ if (requiredPerms == ACL_SELECT)
+ {
+ if (pg_attribute_aclcheck_all(relOid, userid, requiredPerms,
+ ACLMASK_ALL) != ACLCHECK_OK)
+ return false;
+ }
+ else
+ /* whole-row reference can't happen here */
+ elog(ERROR, "whole-row update is not implemented");
}
else
{
--
2.40.1