While looking at this report http://archives.postgresql.org/pgsql-bugs/2009-08/msg00083.php
I spotted another error message which could use improvement: CREATE TABLE foo(a int PRIMARY KEY DEFERRABLE); CREATE TABLE bar(a int REFERENCES foo(a)); ERROR: there is no unique constraint matching given keys for referenced table "foo" Whereas if you define the FK slightly differently so that it goes through transformFkeyGetPrimaryKey() instead, you get a much better error message: CREATE TABLE bar(a int REFERENCES foo); ERROR: cannot use a deferrable primary key for referenced table "foo" The attached patch to transformFkeyCheckAttrs() makes the former case generate a similar error to the latter. - Dean
*** ./src/backend/commands/tablecmds.c.orig 2009-08-12 09:47:34.000000000 +0100 --- ./src/backend/commands/tablecmds.c 2009-08-12 10:08:13.000000000 +0100 *************** *** 5117,5122 **** --- 5117,5123 ---- { Oid indexoid = InvalidOid; bool found = false; + bool found_deferrable = false; List *indexoidlist; ListCell *indexoidscan; *************** *** 5148,5154 **** * expressions, too */ if (indexStruct->indnatts == numattrs && ! indexStruct->indisunique && indexStruct->indimmediate && heap_attisnull(indexTuple, Anum_pg_index_indpred) && heap_attisnull(indexTuple, Anum_pg_index_indexprs)) { --- 5149,5155 ---- * expressions, too */ if (indexStruct->indnatts == numattrs && ! indexStruct->indisunique && heap_attisnull(indexTuple, Anum_pg_index_indpred) && heap_attisnull(indexTuple, Anum_pg_index_indexprs)) { *************** *** 5198,5203 **** --- 5199,5219 ---- break; } } + + /* + * Refuse to use a deferrable unique/primary key. This is per + * SQL spec, and there would be a lot of interesting semantic + * problems if we tried to allow it. + */ + if (found && !indexStruct->indimmediate) + { + /* + * Remember that we found an otherwise matching index, so + * that we can generate a more appropriate error message. + */ + found_deferrable = true; + found = false; + } } ReleaseSysCache(indexTuple); if (found) *************** *** 5205,5214 **** } if (!found) ! ereport(ERROR, ! (errcode(ERRCODE_INVALID_FOREIGN_KEY), ! errmsg("there is no unique constraint matching given keys for referenced table \"%s\"", ! RelationGetRelationName(pkrel)))); list_free(indexoidlist); --- 5221,5238 ---- } if (!found) ! { ! if (found_deferrable) ! ereport(ERROR, ! (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), ! errmsg("cannot use a deferrable unique constraint for referenced table \"%s\"", ! RelationGetRelationName(pkrel)))); ! else ! ereport(ERROR, ! (errcode(ERRCODE_INVALID_FOREIGN_KEY), ! errmsg("there is no unique constraint matching given keys for referenced table \"%s\"", ! RelationGetRelationName(pkrel)))); ! } list_free(indexoidlist);
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers