patternsqlMinor
ON CONFLICT on two columns where one can be null
Viewed 0 times
cancolumnsnullwhereonetwoconflict
Problem
I'm trying to use
ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification
ON CONFLICT on two columns where one can be null. Unfortunatelly with partial index I don't seem to be able to do it.create table tbl( col1 int, col2 int, col3 boolean);
CREATE UNIQUE INDEX ON tbl (col1, col2)
WHERE col2 IS NOT NULL; -- NOT NULL
CREATE UNIQUE INDEX ON tbl (col1, col2)
WHERE col2 IS NULL; -- NULL
INSERT INTO tbl(col1, col2)
values(1, 3)
ON CONFLICT(col1, col2) DO UPDATE SET col3 = true;ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification
Solution
Because PostgreSQL can not infer it from the values, you need the index_predicate
index_predicate
Used to allow inference of partial unique indexes. Any indexes that satisfy the predicate (which need not actually be partial indexes) can be inferred. Follows CREATE INDEX format. SELECT privilege on any column appearing within index_predicate is required.
Sample Data
Test
index_predicate
Used to allow inference of partial unique indexes. Any indexes that satisfy the predicate (which need not actually be partial indexes) can be inferred. Follows CREATE INDEX format. SELECT privilege on any column appearing within index_predicate is required.
Sample Data
CREATE TABLE tbl( col1 int, col2 int, col3 boolean);
CREATE UNIQUE INDEX ON tbl (col1, col2)
WHERE col2 IS NOT NULL; -- NOT NULL
CREATE UNIQUE INDEX ON tbl (col1, col2)
WHERE col2 IS NULL; -- NULL
INSERT INTO tbl(col1, col2)
VALUES (1, 3, false); -- set value to falseTest
INSERT INTO tbl(col1, col2)
VALUES (1, 3)
ON CONFLICT(col1, col2)
WHERE col2 IS NOT NULL -- predicate here
DO UPDATE SET col3 = true;
TABLE tbl;
col1 | col2 | col3
------+------+------
1 | 3 | t
(1 row)Code Snippets
CREATE TABLE tbl( col1 int, col2 int, col3 boolean);
CREATE UNIQUE INDEX ON tbl (col1, col2)
WHERE col2 IS NOT NULL; -- NOT NULL
CREATE UNIQUE INDEX ON tbl (col1, col2)
WHERE col2 IS NULL; -- NULL
INSERT INTO tbl(col1, col2)
VALUES (1, 3, false); -- set value to falseINSERT INTO tbl(col1, col2)
VALUES (1, 3)
ON CONFLICT(col1, col2)
WHERE col2 IS NOT NULL -- predicate here
DO UPDATE SET col3 = true;
TABLE tbl;
col1 | col2 | col3
------+------+------
1 | 3 | t
(1 row)Context
StackExchange Database Administrators Q#175182, answer score: 4
Revisions (0)
No revisions yet.