Menurut dokumen,
Semua indeks unik nama_tabel yang, tanpa memperhatikan urutan, berisi persis kolom/ekspresi yang ditentukan-target_konflik disimpulkan (dipilih) sebagai indeks arbiter. Jika indeks_predikat ditentukan, itu harus, sebagai persyaratan lebih lanjut untuk inferensi, memenuhi indeks arbiter.
Dokumen selanjutnya mengatakan,
[index_predicate digunakan] untuk memungkinkan inferensi sebagian indeks unik
Secara sederhana, dokumen mengatakan bahwa saat menggunakan indeks parsial dan menyisipkan dengan ON CONFLICT, predikat_indeks harus ditentukan . Itu tidak disarankan untuk Anda. Saya mempelajari ini di sini, dan contoh berikut menunjukkan hal ini.
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);
sehingga kita memiliki:
unutbu=# select * from test.accounts;
+----+---------------+-----------+
| id | type | person_id |
+----+---------------+-----------+
| 1 | PersonAccount | 10 |
+----+---------------+-----------+
(1 row)
Tanpa index_predicate
kami mendapatkan kesalahan:
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
Tetapi jika Anda memasukkan indeks_predikat, 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;
maka tidak ada kesalahan dan DO NOTHING dihormati.