@yakovenkodenis
JavaScript, Node.js, React, PostgreSQL

Возможно ли обновлять строки, защищенные Row Level Security, не будучи superuser?

Я пытаюсь обновлять значения в таблице, строки которой защищены политиками row level security (делать soft delete).
Однако, при обновлении получаю ошибку:
new row violates row-level security policy for table "my_table".

По сути, мне нужно производить удаление строк (soft delete) путем обновления поля deleted. И при этом мне нужно, чтобы current_user (который еще и owner таблицы, но не superuser) не видел строки, у которых флаг deleted установлен в true.

Вот, как я задаю row level security:
alter table my_table enable row level security;
alter table my_table force row level security;

create policy select_policy on my_table for select to public using (deleted is false);
create policy insert_policy on my_table for insert to public with check (true);
create policy delete_policy on my_table for delete to public using (true);
create policy update_policy on my_table for update to public using (true) with check (true);

И вот так пытаюсь обновить строку:
update my_table set deleted = true where id = 1;
__________

Возможно ли это вообще реализовать? Если да, то что я делаю не так и что нужно исправить?

Как воспроизвести:

Нужно зайти в базу не как superuser.
create table if not exists my_table (
    "name" varchar(40),
    deleted boolean default false
);

insert into my_table (name) values ('John'), ('Alice'), ('Bob');

alter table my_table enable row level security;
alter table my_table force row level security;

drop policy if exists my_table_select_policy on my_table;
drop policy if exists my_table_insert_policy on my_table;
drop policy if exists my_table_delete_policy on my_table;
drop policy if exists my_table_update_policy on my_table;

create policy my_table_select_policy on my_table for select to public using (deleted is false);
create policy my_table_insert_policy on my_table for insert to public with check (true);
create policy my_table_delete_policy on my_table for delete to public using (true);
create policy my_table_update_policy on my_table for update to public using (true);

update my_table set deleted = true where name = 'John'; -- кидает ошибку
  • Вопрос задан
  • 260 просмотров
Пригласить эксперта
Ответы на вопрос 1
@galaxy
Ну тут у вас не работает конкретно потому, что UPDATE с WHERE также смотрит на политику для SELECT применительно в том числе и к обновленной строке (в документации мутновато, но это упомянуто).

Вообще, на мой взгляд, вы не тот инструмент выбрали. Вьюха + триггеры будет понятнее и надежнее.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы