如何比较 postgres 策略中行的旧值和新值以进行更新

Ami*_*ren 5 sql postgresql row-level-security

我有一个权限结构,因此特定权限仅允许编辑表中 5 个字段中的 2 个。我的整个系统中有 RLS,因此我需要在策略内执行上述操作。

起初,我想到编写一个函数来检查用户是否更新了他们没有更新权限的字段,并在策略中使用它的返回值。但我找不到一种无需定义变量即可在策略内使用返回值的方法,这显然不能在策略内定义。

这是所说的功能:

CREATE OR REPLACE FUNCTION is_user_updating_non_permitted_fields(id uuid, fieldA integer, fieldB text...)
.....
 DECLARE
  old_row MY_TABLE
 BEGIN
  SELECT * FROM MY_TABLE m WHERE id = m.id INTO old_row;
  IF (fieldA != old_row.fieldA OR fieldB != old_row.fieldB)
    THEN RETURN 1;
    ELSE RETURN 0;
  ENDIF;
 END;
....
Run Code Online (Sandbox Code Playgroud)

该政策将类似于:

CREATE POLICY my_table_update ON MY_TABLE FOR UPDATE
WITH CHECK (
 (SELECT CASE WHEN (
    ''use function here''
   ) = 1 THEN false ELSE true END;
 )
)
Run Code Online (Sandbox Code Playgroud)

作为最后的手段,我想到在更新和使用之前进行触发ROLLBACK TRANSACTION,但我真的不想那样做。

Lau*_*lbe 4

根据文档,这是不可能的:

仅允许表达式计算结果为 true 的行。如果插入的任何记录或更新产生的任何记录的表达式计算结果为 false 或 null,则会引发错误。请注意,check_expression是根据该行建议的新内容而不是原始内容进行评估的。

毕竟你必须使用触发器。