Postgresql 创建更新策略的问题

Postgresql 创建更新策略的问题,postgresql,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 r

我想使用行级安全性来创建更新策略,如果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'
有两个问题:

  • 使用
    select*from tb
    时,会显示一个空表
  • 它允许使用idx=1 cls='great2'进行更新
  • 它显示了一张空桌子

    如果为表启用了行级安全性,但不存在适用的策略,则假定使用“默认拒绝”策略,这样就不会有可见或可更新的行

    因此,您需要创建一个允许选择以下内容的策略:

    create policy tb_select on tb
      for select
      using (true);
    

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

    根据使用中指定的表达式检查现有表行,同时根据使用检查中指定的表达式检查通过插入或更新创建的新行

    当您使用
    和(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
    的值对于
    cls='great2'
    的行总是大于2,那么检查约束可能是更好的选择:

    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');
    
    结果:

    错误:关系“tb”的新行违反了检查约束“check_idx”
    详细信息:失败的行包含(1,great2)。
    

    如果使用
    idx thx!更改行的
    cls
    值,也会发生同样的情况!在我的应用程序中,它还包括会话变量。当我输入set role user\u p;设置my.idx=2;设置我的.cls='great2';我可以选择tb表,并且输出不是空的,因为我有另一个用于选择的策略,但是当我使用上面的更新策略输入更新时,它总是显示更新0。
    update tb 
      set idx = 1
    where idx = 10
    
    update tb
      set cls = 'great2'
    where idx = 1;