PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Índice exclusivo parcial do PostgreSQL e upsert


Não acho que seja possível usar vários índices parciais como alvo de conflito. Você deve tentar obter o comportamento desejado usando um único índice. A única maneira que posso ver é usar um índice exclusivo em expressões:
drop table if exists test;
create table test (
    p text not null,
    q text,
    r text,
    txt text
);

create unique index test_unique_idx on test (p, coalesce(q, ''), coalesce(r, ''));

Agora todos os três testes (executados duas vezes) violam o mesmo índice:
insert into test(p,q,r,txt) values ('p',null,null,'a'); -- violates test_unique_idx
insert into test(p,q,r,txt) values ('p','q',null,'b');  -- violates test_unique_idx
insert into test(p,q,r,txt) values ('p',null, 'r','c'); -- violates test_unique_idx

No comando insert você deve passar as expressões usadas na definição do índice:
insert into test as u (p,q,r,txt) 
values ('p',null,'r','d') 
on conflict (p, coalesce(q, ''), coalesce(r, '')) do update 
set txt = excluded.txt;