Según los documentos,
Todos los índices únicos de table_name que, independientemente del orden, contienen exactamente las columnas/expresiones especificadas en conflicto_objetivo se infieren (se eligen) como índices de árbitro. Si se especifica un predicado_índice, debe, como requisito adicional para la inferencia, satisfacer los índices del árbitro.
Los documentos continúan diciendo,
[index_predicate are u]sed para permitir la inferencia de índices únicos parciales
De una manera discreta, los documentos dicen que cuando se usa un índice parcial y se actualiza con ON CONFLICT, se debe especificar el predicado_índice . No se infiere para usted. Aprendí esto aquí, y el siguiente ejemplo lo demuestra.
CREATE TABLE test.accounts (
id int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
type text,
person_id int);
CREATE UNIQUE INDEX accounts_note_idx on accounts (type, person_id) WHERE ((type)::text = 'PersonAccount'::text);
INSERT INTO test.accounts (type, person_id) VALUES ('PersonAccount', 10);
para que tengamos:
unutbu=# select * from test.accounts;
+----+---------------+-----------+
| id | type | person_id |
+----+---------------+-----------+
| 1 | PersonAccount | 10 |
+----+---------------+-----------+
(1 row)
Sin index_predicate
obtenemos un error:
INSERT INTO test.accounts (type, person_id) VALUES ('PersonAccount', 10) ON CONFLICT (type, person_id) DO NOTHING;
-- ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification
Pero si en su lugar incluye el predicado_índice, WHERE ((type)::text = 'PersonAccount'::text)
:
INSERT INTO test.accounts (type, person_id) VALUES ('PersonAccount', 10)
ON CONFLICT (type, person_id)
WHERE ((type)::text = 'PersonAccount'::text) DO NOTHING;
entonces no hay error y se respeta NO HACER NADA.