I recently had a puzzler, which involved this sort of accidental parser error:
CREATE TABLE foo (a int, b text, PRIMARY KEY (a, b)); CREATE TABLE bar (x int, y text, FOREIGN KEY (q, r) REFERENCES foo (m, n)); ERROR: column "q" referenced in foreign key constraint does not exist versus CREATE TABLE bar (x int, y text, FOREIGN KEY (x, y) REFERENCES foo (m, n)); ERROR: column "m" referenced in foreign key constraint does not exist This example has been simplified for clarity, but the original case involved a bunch of "id" columns everywhere. What's confusing is that "q" is not actually referenced by the foreign key constraint, but referenced in the statement that attempts to define the foreign key constraint, so I was looking on the wrong side of the constraint there. Attached is a small patch that separates those error messages into: ERROR: column "q" specified as a constrained column in foreign key constraint does not exist ERROR: column "m" specified as a referenced column in foreign key constraint does not exist Details may be debatable. Comments?
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 7afe6e7..a253fd8 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -238,7 +238,7 @@ static void AlterSeqNamespaces(Relation classRel, Relation rel, Oid oldNspOid, Oid newNspOid, const char *newNspName); static int transformColumnNameList(Oid relId, List *colList, - int16 *attnums, Oid *atttypids); + int16 *attnums, Oid *atttypids, bool is_source); static int transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid, List **attnamelist, int16 *attnums, Oid *atttypids, @@ -4641,7 +4641,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, numfks = transformColumnNameList(RelationGetRelid(rel), fkconstraint->fk_attrs, - fkattnum, fktypoid); + fkattnum, fktypoid, true); /* * If the attribute list for the referenced table was omitted, lookup the @@ -4660,7 +4660,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, { numpks = transformColumnNameList(RelationGetRelid(pkrel), fkconstraint->pk_attrs, - pkattnum, pktypoid); + pkattnum, pktypoid, false); /* Look for an index matching the column list */ indexOid = transformFkeyCheckAttrs(pkrel, numpks, pkattnum, opclasses); @@ -4855,7 +4855,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, */ static int transformColumnNameList(Oid relId, List *colList, - int16 *attnums, Oid *atttypids) + int16 *attnums, Oid *atttypids, bool is_source) { ListCell *l; int attnum; @@ -4868,10 +4868,18 @@ transformColumnNameList(Oid relId, List *colList, atttuple = SearchSysCacheAttName(relId, attname); if (!HeapTupleIsValid(atttuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_COLUMN), - errmsg("column \"%s\" referenced in foreign key constraint does not exist", - attname))); + { + if (is_source) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" specified as a constrained column in foreign key constraint does not exist", + attname))); + else + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" specified as a referenced column in foreign key constraint does not exist", + attname))); + } if (attnum >= INDEX_MAX_KEYS) ereport(ERROR, (errcode(ERRCODE_TOO_MANY_COLUMNS),
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers