On Wed, 15 Jul 2026 at 22:02, Paul A Jungwirth
<[email protected]> wrote:
>
> Thanks for taking a look! Here is a v4 with those additions.
>
+ <entry><command>UPDATE ... FOR PORTION OF</command></entry>
+ <entry>
+ Filter existing row <footnoteref linkend="rls-select-priv"/> &
+ check new row <footnoteref linkend="rls-select-priv"/>
+ </entry>
+ <entry>
The footnote "rls-select-priv" reads "If read access is required to
either the existing or new row (for example, a WHERE or RETURNING
clause that refers to columns from the relation)." However, FOR
PORTION OF is guaranteed to require read access to the table, so as
with a few other entries in that column, the link to this footnote is
not needed -- it will unconditionally apply the SELECT policy to the
existing and new rows. Similarly for DELETE ... FOR PORTION OF.
+ /*
+ * As with regular INSERT/UPDATE above, if SELECT rights are needed
+ * for the statement, ensure the leftover row remains visible.
+ */
+ if (perminfo->requiredPerms & ACL_SELECT)
+ {
+ List *select_permissive_policies;
+ List *select_restrictive_policies;
+
+ get_policies_for_relation(rel, CMD_SELECT, user_id,
+ &select_permissive_policies,
+ &select_restrictive_policies);
+ add_with_check_options(rel, rt_index,
+ WCO_RLS_INSERT_CHECK,
+ select_permissive_policies,
+ select_restrictive_policies,
+ withCheckOptions,
+ hasSubLinks,
+ true);
+ }
Thinking some more about this, I'm not so sure it's right. For a plain
INSERT, we apply SELECT policies if SELECT permissions are required,
which only happens if there is a RETURNING clause. The reason is to
ensure the user has rights to see the row returned by the RETURNING
clause. However, for the auxiliary INSERTS for leftover portions in
UPDATE/DELETE ... FOR PORTION OF, even if there is a RETURNING clause,
it will only return the updated/deleted row, not the leftover rows.
The command never reads the leftover rows, so why do we need the
leftover rows to satisfy the SELECT policies?
Regards,
Dean