行级安全性已启用的更新不起作用,而标准更新确实使用相同的逻辑 [英] Row Level Security Enabled update is not working while standard update does using the same logic
问题描述
在postgres 10.4上工作(如果有区别,请在RDS上工作)我正在尝试使用行级安全性来强制应用程序用户权限.
我有一个权限表,看起来像
user_group_id | entity1 | entity2 | entity3 | permission
==============|=========|=========|=========|============
1 |1 |null |null | write
1 |1 |1 |null | read
-
entity1(root)-entity2-entity3(leaf)是存储在不同表中的项目的层次结构.实体1包含实体2项,实体2包含实体3项.
-
权限被继承,这意味着entry3继承了entity2的权限,entry2继承了entity1的权限,除非:
-
具有匹配的entity3的行将覆盖具有匹配的entity2的行,这些行将覆盖具有匹配的entity1的行.
在上面的示例中,用户组1在实体1 = 1(第一行)下的所有实体2/实体3上都有写入,除了实体2 = 1和实体2 = 1下的所有实体3(已在其上读取(第二行)等).>
我已经使用dense_rank - which is a window function
作为单个查询编写了逻辑(我认为这与实际问题无关,因此不粘贴).
当我直接将此逻辑与UPDATE一起使用时-它可以完美地工作.
当我嵌入与行级安全策略的WITH CHECK
相同的逻辑时-update拒绝更新行(我在相关表上启用了ROW LEVEL SECURITY-就是这样).
我试图将逻辑嵌入函数中,而不是直接嵌入策略中-但是得到了相同的结果,这意味着有效:
--not as table owner
update entity1
set col1=1
where entity1_id=10
and check_access(entity1_id); --updates 1 row
但这不是:
--as table owner
alter table entity1 enable row level security;
CREATE POLICY entity1_update
ON entity1
AS permissive
FOR UPDATE
TO some_role
WITH CHECK ( check_access(entity1_id) );
--not as table owner
update entity1
set col1=1
where entity1_id=10; --updates no rows
阅读文档:
The conditional expression cannot contain any aggregate or window functions
-这是原因吗?如果是这样的话-我希望在尝试创建策略或实际运行更新时会抛出错误-但什么都不会发生.
我还尝试使用带有ORDER BY的子查询重写我的访问检查逻辑,并用LIMIT包装它-没有帮助.
我错过了什么吗?可以解决这个问题吗?
我认为我发现了问题-我在同一张表上有另一个FOR SELECT
策略,并且我认为它的USING
子句就足够了(有一个AND在不同的FOR
类型的策略之间)-所以我没有在FOR UPDATE
策略中包含USING
子句.一旦在FOR UPDATE
策略上添加了USING (true)
,事情就开始正常工作(至少目前为止-我需要做更多的实验).
似乎与使用窗口函数无关.
-
我认为postgres允许我创建一个不带
USING
子句的FOR UPDATE
策略,因为它允许多个相同类型的策略-但也许文档中应注意,只有一个FOR UPDATE
规定必须同时包含这两个条款? 更新:我不是唯一出于相同原因而更新失败的人- PostgreSQL,无法更新行(具有行级安全性) -
这使我想问
The conditional expression cannot contain any aggregate or window functions
限制是什么意思-如果它似乎可以使用dense_rank() over (order by...)
......凸起 解决方案
I think I found the problem - I have another FOR SELECT
policy on the same table and I assumed its USING
clause would be sufficient (there's an AND between policies of different FOR
types) - so I did not include a USING
clause in the FOR UPDATE
policy. Once I added a USING (true)
on the FOR UPDATE
policy things started working normally (for now at least - I need to do more experiments).
Seems like it has no relation to using a window function.
I assume postgres allowed me to create a
FOR UPDATE
policy without aUSING
clause since it allows multiple policies of the same type - but maybe the documentation should have a note that when having a singleFOR UPDATE
policy it MUST include both clauses? UPDATE: I'm not the only one who's update failed for the same reason - PostgreSQL, unable to update row ( with row level security )This leads me to ask what does the
The conditional expression cannot contain any aggregate or window functions
restriction mean - if it seems to work with usingdense_rank() over (order by...)
... raised Aggregate/Window functions restriction in Postgres Row Level Security Policy conditions
这篇关于行级安全性已启用的更新不起作用,而标准更新确实使用相同的逻辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!