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
index 41b16cb89bc3edad917c5ab3f62e38adc01a86f5..7777e7ec7700860e69e84cd5d23f722f492210a2 100644 (file)
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
index cc424fd3b29030335336460e60ce62800496b136..24ba936332d2f1455059c57bbd3224eb8bf49932 100644 (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++)
index 6cd57e3eaa700bc2e849d02dc06e57a80650ff4d..acfd9d1f4f7cfc7bec71f456b5f2c4ed852bea68 100644 (file)
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
--
index a3738833b28a81b9d57b38ee47f17f6db3e3bd0b..d49ce9f3007a87a1e123d911234dba3260014f28 100644 (file)
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
--