为什么用于触发器的条件在 PostgreSQL 上从未满足?

Why is the condition used for the trigger never satisfied on PostgreSQL?

提问人:Zübeyir 提问时间:6/22/2023 更新时间:6/22/2023 访问量:33

问:

我正在尝试创建简单的触发器以确保“from”或“to”(数据库用户名)等于 current_user,然后可以删除记录。但它总是会引起一个例外。

表架构:

CREATE TABLE policy_test (
 id serial not null,
 val varchar not null,
 "from" varchar not null,
 "to" varchar not null
)

我授予所有数据库用户在表policy_test上选择、插入、更新、删除的权限。 我确保“from”和“to”列始终是数据库用户名。

我创建了一个触发函数:

CREATE OR REPLACE FUNCTION can_delete_policy_test()
  RETURNS TRIGGER AS $func$
BEGIN
  IF NEW."from" = current_user::varchar OR 
  NEW."to" = current_user::varchar THEN
    RETURN NEW;
  ELSE 
    RAISE EXCEPTION 'You have no permission to delete this record.';
  END IF;
END;
$func$ LANGUAGE plpgsql;

我这样做是为了在“policy_test”表上使用触发器:

CREATE TRIGGER policy_test_delete_trigger
BEFORE DELETE ON policy_test
FOR EACH ROW 
EXECUTE FUNCTION can_delete_policy_test();

在调用语句之前,我确保了policy_test表上某些记录中的连接数据库用户名。

然后我调用了这个语句来删除记录:

DELETE FROM policy_test
WHERE "from" = current_user
OR "to" = current_user;
SQL PostgreSQL 异常 触发 PLPGSQL

评论

1赞 Adrian Klaver 6/22/2023
为什么不使用内置的行级别安全性
0赞 Adrian Klaver 6/22/2023
这是对 的 DELETE 触发器/函数更改。 在每个 PLPGSQL 触发器的触发器中。NEWOLDNEWNULLDELETE
0赞 Zübeyir 6/22/2023
我知道我可以启用 RLS,但我不知道如何实现此条件。

答:

2赞 Laurenz Albe 6/22/2023 #1

问题是您正在使用 . 在触发器中为 NULL,并且从触发器函数返回 NULL 将中止操作。你必须看 和 和 .NEWNEWDELETEOLD."from"OLD."to"RETURN OLD;

0赞 Zübeyir 6/22/2023 #2

我使用 RLS 和 POLICY 来存档我想要的相同内容。

ALTER TABLE policy_test ENABLE ROW LEVEL SECURITY;

GRANT SELECT, DELETE ON TABLE policy_test TO "employee";

CREATE POLICY select_policy_test ON policy_test
FOR SELECT USING ( "to" = current_user::varchar );

CREATE POLICY delete_policy_test ON policy_test
FOR DELETE USING (
  "from" = current_user::varchar OR
  "to" = current_user::varchar    
);