Fix check_exclusion_or_unique_constraint for UNIQUE NULLS NOT DISTINCT.
Adjusting this function was overlooked in commit 94aa7cc5f
. The only
visible symptom (so far) is that INSERT ... ON CONFLICT could go into
an endless loop when inserting a null that has a conflict.
Richard Guo and Tom Lane, per bug #17558 from Andrew Kesper
Discussion: https://postgr.es/m/17558-3f6599ffcf52fd4a@postgresql.org
This commit is contained in:
parent
4c7b16312e
commit
3419d51e19
|
@ -699,13 +699,19 @@ check_exclusion_or_unique_constraint(Relation heap, Relation index,
|
|||
}
|
||||
|
||||
/*
|
||||
* If any of the input values are NULL, the constraint check is assumed to
|
||||
* pass (i.e., we assume the operators are strict).
|
||||
* If any of the input values are NULL, and the index uses the default
|
||||
* nulls-are-distinct mode, the constraint check is assumed to pass (i.e.,
|
||||
* we assume the operators are strict). Otherwise, we interpret the
|
||||
* constraint as specifying IS NULL for each column whose input value is
|
||||
* NULL.
|
||||
*/
|
||||
for (i = 0; i < indnkeyatts; i++)
|
||||
if (!indexInfo->ii_NullsNotDistinct)
|
||||
{
|
||||
if (isnull[i])
|
||||
return true;
|
||||
for (i = 0; i < indnkeyatts; i++)
|
||||
{
|
||||
if (isnull[i])
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -717,7 +723,7 @@ check_exclusion_or_unique_constraint(Relation heap, Relation index,
|
|||
for (i = 0; i < indnkeyatts; i++)
|
||||
{
|
||||
ScanKeyEntryInitialize(&scankeys[i],
|
||||
0,
|
||||
isnull[i] ? SK_ISNULL | SK_SEARCHNULL : 0,
|
||||
i + 1,
|
||||
constr_strats[i],
|
||||
InvalidOid,
|
||||
|
|
|
@ -449,15 +449,16 @@ DROP TABLE UNIQUE_TBL;
|
|||
CREATE TABLE UNIQUE_TBL (i int UNIQUE NULLS NOT DISTINCT, t text);
|
||||
INSERT INTO UNIQUE_TBL VALUES (1, 'one');
|
||||
INSERT INTO UNIQUE_TBL VALUES (2, 'two');
|
||||
INSERT INTO UNIQUE_TBL VALUES (1, 'three');
|
||||
INSERT INTO UNIQUE_TBL VALUES (1, 'three'); -- fail
|
||||
ERROR: duplicate key value violates unique constraint "unique_tbl_i_key"
|
||||
DETAIL: Key (i)=(1) already exists.
|
||||
INSERT INTO UNIQUE_TBL VALUES (4, 'four');
|
||||
INSERT INTO UNIQUE_TBL VALUES (5, 'one');
|
||||
INSERT INTO UNIQUE_TBL (t) VALUES ('six');
|
||||
INSERT INTO UNIQUE_TBL (t) VALUES ('seven');
|
||||
INSERT INTO UNIQUE_TBL (t) VALUES ('seven'); -- fail
|
||||
ERROR: duplicate key value violates unique constraint "unique_tbl_i_key"
|
||||
DETAIL: Key (i)=(null) already exists.
|
||||
INSERT INTO UNIQUE_TBL (t) VALUES ('eight') ON CONFLICT DO NOTHING; -- no-op
|
||||
SELECT * FROM UNIQUE_TBL;
|
||||
i | t
|
||||
---+------
|
||||
|
|
|
@ -310,11 +310,12 @@ CREATE TABLE UNIQUE_TBL (i int UNIQUE NULLS NOT DISTINCT, t text);
|
|||
|
||||
INSERT INTO UNIQUE_TBL VALUES (1, 'one');
|
||||
INSERT INTO UNIQUE_TBL VALUES (2, 'two');
|
||||
INSERT INTO UNIQUE_TBL VALUES (1, 'three');
|
||||
INSERT INTO UNIQUE_TBL VALUES (1, 'three'); -- fail
|
||||
INSERT INTO UNIQUE_TBL VALUES (4, 'four');
|
||||
INSERT INTO UNIQUE_TBL VALUES (5, 'one');
|
||||
INSERT INTO UNIQUE_TBL (t) VALUES ('six');
|
||||
INSERT INTO UNIQUE_TBL (t) VALUES ('seven');
|
||||
INSERT INTO UNIQUE_TBL (t) VALUES ('seven'); -- fail
|
||||
INSERT INTO UNIQUE_TBL (t) VALUES ('eight') ON CONFLICT DO NOTHING; -- no-op
|
||||
|
||||
SELECT * FROM UNIQUE_TBL;
|
||||
|
||||
|
|
Loading…
Reference in New Issue