Disallow NULLS NOT DISTINCT indexes for primary keys

A unique index which is created with non-distinct NULLS cannot be
used for backing a primary key constraint.  Make sure to disallow
such table alterations and teach pg_dump to drop the non-distinct
NULLS clause on indexes where this has been set.

Bug: 17720
Reported-by: Reiner Peterke <zedaardv@drizzle.com>
Reviewed-by: Peter Eisentraut <peter.eisentraut@enterprisedb.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/17720-dab8ee0fa85d316d@postgresql.org
This commit is contained in:
Daniel Gustafsson 2023-02-24 11:09:50 +01:00
parent 94851e4b90
commit d959523257
4 changed files with 31 additions and 1 deletions

View File

@ -225,6 +225,19 @@ index_check_primary_key(Relation heapRel,
RelationGetRelationName(heapRel))));
}
/*
* Indexes created with NULLS NOT DISTINCT cannot be used for primary key
* constraints. While there is no direct syntax to reach here, it can be
* done by creating a separate index and attaching it via ALTER TABLE ..
* USING INDEX.
*/
if (indexInfo->ii_NullsNotDistinct)
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("primary keys cannot use NULLS NOT DISTINCT indexes")));
}
/*
* Check that all of the attributes in a primary key are marked as not
* null. (We don't really expect to see that; it'd mean the parser messed

View File

@ -16431,7 +16431,12 @@ dumpConstraint(Archive *fout, const ConstraintInfo *coninfo)
{
appendPQExpBufferStr(q,
coninfo->contype == 'p' ? "PRIMARY KEY" : "UNIQUE");
if (indxinfo->indnullsnotdistinct)
/*
* PRIMARY KEY constraints should not be using NULLS NOT DISTINCT
* indexes. Being able to create this was fixed, but we need to
* make the index distinct in order to be able to restore the dump.
*/
if (indxinfo->indnullsnotdistinct && coninfo->contype != 'p')
appendPQExpBufferStr(q, " NULLS NOT DISTINCT");
appendPQExpBufferStr(q, " (");
for (k = 0; k < indxinfo->indnkeyattrs; k++)

View File

@ -1595,6 +1595,12 @@ create unique index on cwi_test (a);
alter table cwi_test add primary key using index cwi_test_a_idx ;
ERROR: ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables
DROP TABLE cwi_test;
-- PRIMARY KEY constraint cannot be backed by a NULLS NOT DISTINCT index
CREATE TABLE cwi_test(a int, b int);
CREATE UNIQUE INDEX cwi_a_nnd ON cwi_test (a) NULLS NOT DISTINCT;
ALTER TABLE cwi_test ADD PRIMARY KEY USING INDEX cwi_a_nnd;
ERROR: primary keys cannot use NULLS NOT DISTINCT indexes
DROP TABLE cwi_test;
--
-- Check handling of indexes on system columns
--

View File

@ -617,6 +617,12 @@ create unique index on cwi_test (a);
alter table cwi_test add primary key using index cwi_test_a_idx ;
DROP TABLE cwi_test;
-- PRIMARY KEY constraint cannot be backed by a NULLS NOT DISTINCT index
CREATE TABLE cwi_test(a int, b int);
CREATE UNIQUE INDEX cwi_a_nnd ON cwi_test (a) NULLS NOT DISTINCT;
ALTER TABLE cwi_test ADD PRIMARY KEY USING INDEX cwi_a_nnd;
DROP TABLE cwi_test;
--
-- Check handling of indexes on system columns
--