mirror of
https://github.com/postgres/postgres.git
synced 2025-05-06 19:59:18 +03:00
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…
x
Reference in New Issue
Block a user