创建更新策略的问题

时间:2018-06-06 03:03:59

标签: postgresql

我想使用行级安全性来创建更新策略,如果cls =' great2':

,tb.idx永远不会更新到小于2
 create table tb (
 idx integer,
 cls text);
create role user1;
grant all on tb to user1;
......
create policy up_p on tb for update
using(true)
with check (idx >2 and cls='great2');

output:
set role user1;
select * from tb; 
update tb set idx=1 cls='great2'

有两个问题:

  1. 使用select * from tb时,会显示一个空表。
  2. 它允许使用idx = 1 cls =' great2'。
  3. 进行更新

1 个答案:

答案 0 :(得分:0)

  

它显示一个空表。

Quote from the manual

  

如果为表启用了行级安全性,但没有适用的策略,则假定使用“默认拒绝”策略,以便不会显示任何行或可以更新。

因此,您需要创建一个允许选择的政策:

$ sudo chmod -R 777 /var/www/html/YOURFOLDER/*
  

它允许使用idx = 1 cls ='great2'进行更新。

Quote from the manual

  

根据USING中指定的表达式检查现有表行,而根据WITH CHECK中指定的表达式检查将通过INSERT或UPDATE创建的新行

当您使用create policy tb_select on tb for select using (true); 创建策略时,这意味着可以更新所有行。

所以你需要:

using (true)

假设 create policy up_p on tb for update using (idx > 2 and cls='great2'); ,则以下更新不会更新任何内容:

(1, 'great2')

注意,要使策略实际处于活动状态,您还需要:

update stuff.tb 
  set cls = 'great2'
where idx = 1;

但是,如果您只是想确保alter table tb enable row level security; 的值对idx的行总是大于2,那么检查约束可能是更好的选择:

cls = 'great2'

现在正在运行:

create table tb 
(
   idx integer,
   cls text,
   constraint check_idx check ( (idx > 2 and cls = 'great2') or (cls <> 'great2'))
);

insert into tb 
values 
  (10, 'great2'), 
  (1, 'foo');

结果:

update tb 
  set idx = 1
where idx = 10

如果您使用ERROR: new row for relation "tb" violates check constraint "check_idx" Detail: Failing row contains (1, great2).

更改行的cls值,也会发生同样的情况
idx <= 2