Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b6bde52

Browse files
committed
Improve error message for the case where a requested foreign key constraint
does match some unique index on the referenced table, but that index is only deferrably unique. We were doing this nicely for the default-to-primary-key case, but were being lazy for the other case. Dean Rasheed
1 parent 5d3e232 commit b6bde52

File tree

1 file changed

+32
-9
lines changed

1 file changed

+32
-9
lines changed

src/backend/commands/tablecmds.c

+32-9
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.296 2009/08/07 15:27:56 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.297 2009/08/12 23:00:12 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -5117,6 +5117,7 @@ transformFkeyCheckAttrs(Relation pkrel,
51175117
{
51185118
Oid indexoid = InvalidOid;
51195119
bool found = false;
5120+
bool found_deferrable = false;
51205121
List *indexoidlist;
51215122
ListCell *indexoidscan;
51225123

@@ -5143,12 +5144,11 @@ transformFkeyCheckAttrs(Relation pkrel,
51435144
indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
51445145

51455146
/*
5146-
* Must have the right number of columns; must be unique (non
5147-
* deferrable) and not a partial index; forget it if there are any
5148-
* expressions, too
5147+
* Must have the right number of columns; must be unique and not a
5148+
* partial index; forget it if there are any expressions, too
51495149
*/
51505150
if (indexStruct->indnatts == numattrs &&
5151-
indexStruct->indisunique && indexStruct->indimmediate &&
5151+
indexStruct->indisunique &&
51525152
heap_attisnull(indexTuple, Anum_pg_index_indpred) &&
51535153
heap_attisnull(indexTuple, Anum_pg_index_indexprs))
51545154
{
@@ -5198,17 +5198,40 @@ transformFkeyCheckAttrs(Relation pkrel,
51985198
break;
51995199
}
52005200
}
5201+
5202+
/*
5203+
* Refuse to use a deferrable unique/primary key. This is per
5204+
* SQL spec, and there would be a lot of interesting semantic
5205+
* problems if we tried to allow it.
5206+
*/
5207+
if (found && !indexStruct->indimmediate)
5208+
{
5209+
/*
5210+
* Remember that we found an otherwise matching index, so
5211+
* that we can generate a more appropriate error message.
5212+
*/
5213+
found_deferrable = true;
5214+
found = false;
5215+
}
52015216
}
52025217
ReleaseSysCache(indexTuple);
52035218
if (found)
52045219
break;
52055220
}
52065221

52075222
if (!found)
5208-
ereport(ERROR,
5209-
(errcode(ERRCODE_INVALID_FOREIGN_KEY),
5210-
errmsg("there is no unique constraint matching given keys for referenced table \"%s\"",
5211-
RelationGetRelationName(pkrel))));
5223+
{
5224+
if (found_deferrable)
5225+
ereport(ERROR,
5226+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
5227+
errmsg("cannot use a deferrable unique constraint for referenced table \"%s\"",
5228+
RelationGetRelationName(pkrel))));
5229+
else
5230+
ereport(ERROR,
5231+
(errcode(ERRCODE_INVALID_FOREIGN_KEY),
5232+
errmsg("there is no unique constraint matching given keys for referenced table \"%s\"",
5233+
RelationGetRelationName(pkrel))));
5234+
}
52125235

52135236
list_free(indexoidlist);
52145237

0 commit comments

Comments
 (0)