Според документите,
Всички уникални индекси table_name, които, без оглед на реда, съдържат точно посочените отconflict_target колони/изрази, се извеждат (избират) като арбитражни индекси. Ако е посочен index_predicate, той трябва, като допълнително изискване за извод, да удовлетворява арбитражните индекси.
Документите продължават да казват,
[index_predicate] се използват, за да позволят извод за частични уникални индекси
По занижен начин документите казват, че когато се използва частичен индекс и се добавя с ON CONFLICT, предиката index_ трябва да бъде посочен . За вас не се предполага. Научих това тук и следващият пример демонстрира това.
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);
така че имаме:
unutbu=# select * from test.accounts;
+----+---------------+-----------+
| id | type | person_id |
+----+---------------+-----------+
| 1 | PersonAccount | 10 |
+----+---------------+-----------+
(1 row)
Без index_predicate
получаваме грешка:
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
Но ако вместо това включите index_predicate, 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;
тогава няма грешка и НЕ НАПРАВИ НИЩО се уважава.