Postgresql规则和返回子句

Postgresql规则和返回子句,postgresql,postgresql-9.5,Postgresql,Postgresql 9.5,我是Postgresql的新手,我正在深入研究它的特性。 对于每个更新/删除查询,带有条件“do-It-nothing”的更新/删除规则似乎会破坏“returning子句”。 从postgresql 9.5开始,是否有解决方案 下面是我为测试而运行的简单sql代码段: -- clear && dropdb --if-exists graph && createdb graph -E UTF8 -T template0 && psql graph &

我是Postgresql的新手,我正在深入研究它的特性。 对于每个更新/删除查询,带有条件“do-It-nothing”的更新/删除规则似乎会破坏“returning子句”。 从postgresql 9.5开始,是否有解决方案

下面是我为测试而运行的简单sql代码段:

-- clear && dropdb --if-exists graph && createdb graph -E UTF8 -T template0 && psql graph < schema.sql

create table vertices (
    id bigserial not null primary key,
    hash char(32),
    label varchar(128) not null,
    data jsonb default '{}'
);

-- default groups and users cannot be updated or deleted --
create or replace rule preventDefaultVtxUpdate as
    on update to vertices
    where ( old.label in ('group', 'user') and old.data->>'name' in ('superadmin', 'guest') )
    do instead nothing;

create or replace rule preventDefaultVtxDelete as
    on delete to vertices
    where ( old.label in ('group', 'user') and old.data->>'name' in ('superadmin', 'guest') )
    do instead nothing;

-- default groups and users
insert into vertices (label, data) values ('group', '{"name":"superadmin"}');
insert into vertices (label, data) values ('group', '{"name":"guest"}');

insert into vertices (label, data) values ('user', '{"name":"superadmin"}');
insert into vertices (label, data) values ('user', '{"name":"guest"}');

-- try
update vertices set data = '{}' returning *;
delete from vertices returning *;
使用当前解决方案编辑: 如前所述,我解决了重写规则作为触发器的问题。这更难看,但却有效。
使用以下触发器而不是规则是否会影响性能

create table vertices (
    id bigserial not null primary key,
    hash char(32),
    label varchar(128) not null,
    data jsonb default '{}'
);

create or replace function preventDefaultVtxUpdateAndDelete() returns trigger AS $preventDefaultVtxUpdateAndDelete$
    begin
        return null;
    end
$preventDefaultVtxUpdateAndDelete$ language plpgsql;

create trigger preventDefaultVtxUpdateAndDelete
    before update or delete on vertices
    for each row
        when ( old.label in ('group', 'user') and old.data->>'name' in ('superadmin', 'guest') )
        execute procedure preventDefaultVtxUpdateAndDelete();

-- default groups and users
insert into vertices (label, data) values ('group', '{"name":"superadmin"}');
insert into vertices (label, data) values ('group', '{"name":"guest"}');

insert into vertices (label, data) values ('user', '{"name":"superadmin"}');
insert into vertices (label, data) values ('user', '{"name":"guest"}');

    insert into vertices (label, data) values ('user', '{"name":"ciao"}');

-- try
select * from vertices;
update vertices set data = '{}' returning *;
delete from vertices returning *;
select * from vertices;

您可以尝试在触发器中实现规则行为。不鼓励使用或使用规则,因为这样会造成限制和无法控制的副作用。根据我的建议,使用触发器代替。在使用下列触发器而不是规则时有什么性能含义?
create table vertices (
    id bigserial not null primary key,
    hash char(32),
    label varchar(128) not null,
    data jsonb default '{}'
);

create or replace function preventDefaultVtxUpdateAndDelete() returns trigger AS $preventDefaultVtxUpdateAndDelete$
    begin
        return null;
    end
$preventDefaultVtxUpdateAndDelete$ language plpgsql;

create trigger preventDefaultVtxUpdateAndDelete
    before update or delete on vertices
    for each row
        when ( old.label in ('group', 'user') and old.data->>'name' in ('superadmin', 'guest') )
        execute procedure preventDefaultVtxUpdateAndDelete();

-- default groups and users
insert into vertices (label, data) values ('group', '{"name":"superadmin"}');
insert into vertices (label, data) values ('group', '{"name":"guest"}');

insert into vertices (label, data) values ('user', '{"name":"superadmin"}');
insert into vertices (label, data) values ('user', '{"name":"guest"}');

    insert into vertices (label, data) values ('user', '{"name":"ciao"}');

-- try
select * from vertices;
update vertices set data = '{}' returning *;
delete from vertices returning *;
select * from vertices;