ドキュメントによると、
順序に関係なく、conflict_targetで指定された列/式を正確に含むすべてのtable_name一意のインデックスは、arbiterindexesとして推測(選択)されます。 index_predicateが指定されている場合、推論のさらなる要件として、アービターインデックスを満たす必要があります。
ドキュメントは続けて言います、
[index_predicateは、部分的に一意のインデックスの推論を可能にするために使用されます
控えめに言って、ドキュメントは、部分インデックスを使用してON CONFLICTでアップサーティングする場合、index_predicateを指定する必要があると言っています。 。それはあなたのために推測されていません。私はここでこれを学びました、そして次の例はこれを示しています。
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;
その後、エラーは発生せず、何も尊重されません。