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{
51185118Oid indexoid = InvalidOid ;
51195119bool found = false;
5120+ bool found_deferrable = false;
51205121List * indexoidlist ;
51215122ListCell * indexoidscan ;
51225123
@@ -5143,12 +5144,11 @@ transformFkeyCheckAttrs(Relation pkrel,
51435144indexStruct = (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 */
51505150if (indexStruct -> indnatts == numattrs &&
5151- indexStruct -> indisunique && indexStruct -> indimmediate &&
5151+ indexStruct -> indisunique &&
51525152heap_attisnull (indexTuple ,Anum_pg_index_indpred )&&
51535153heap_attisnull (indexTuple ,Anum_pg_index_indexprs ))
51545154{
@@ -5198,17 +5198,40 @@ transformFkeyCheckAttrs(Relation pkrel,
51985198break ;
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}
52025217ReleaseSysCache (indexTuple );
52035218if (found )
52045219break ;
52055220}
52065221
52075222if (!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
52135236list_free (indexoidlist );
52145237