@ -5986,6 +5986,26 @@ transformFkeyCheckAttrs(Relation pkrel,
bool found_deferrable = false ;
List * indexoidlist ;
ListCell * indexoidscan ;
int i ,
j ;
/*
* Reject duplicate appearances of columns in the referenced - columns list .
* Such a case is forbidden by the SQL standard , and even if we thought it
* useful to allow it , there would be ambiguity about how to match the
* list to unique indexes ( in particular , it ' d be unclear which index
* opclass goes with which FK column ) .
*/
for ( i = 0 ; i < numattrs ; i + + )
{
for ( j = i + 1 ; j < numattrs ; j + + )
{
if ( attnums [ i ] = = attnums [ j ] )
ereport ( ERROR ,
( errcode ( ERRCODE_INVALID_FOREIGN_KEY ) ,
errmsg ( " foreign key referenced-columns list must not contain duplicates " ) ) ) ;
}
}
/*
* Get the list of index OIDs for the table from the relcache , and look up
@ -5998,8 +6018,6 @@ transformFkeyCheckAttrs(Relation pkrel,
{
HeapTuple indexTuple ;
Form_pg_index indexStruct ;
int i ,
j ;
indexoid = lfirst_oid ( indexoidscan ) ;
indexTuple = SearchSysCache1 ( INDEXRELID , ObjectIdGetDatum ( indexoid ) ) ;
@ -6018,11 +6036,11 @@ transformFkeyCheckAttrs(Relation pkrel,
heap_attisnull ( indexTuple , Anum_pg_index_indpred ) & &
heap_attisnull ( indexTuple , Anum_pg_index_indexprs ) )
{
/* Must get indclass the hard way */
Datum indclassDatum ;
bool isnull ;
oidvector * indclass ;
/* Must get indclass the hard way */
indclassDatum = SysCacheGetAttr ( INDEXRELID , indexTuple ,
Anum_pg_index_indclass , & isnull ) ;
Assert ( ! isnull ) ;
@ -6030,7 +6048,13 @@ transformFkeyCheckAttrs(Relation pkrel,
/*
* The given attnum list may match the index columns in any order .
* Check that each list is a subset of the other .
* Check for a match , and extract the appropriate opclasses while
* we ' re at it .
*
* We know that attnums [ ] is duplicate - free per the test at the
* start of this function , and we checked above that the number of
* index columns agrees , so if we find a match for each attnums [ ]
* entry then we must have a one - to - one match in some order .
*/
for ( i = 0 ; i < numattrs ; i + + )
{
@ -6039,6 +6063,7 @@ transformFkeyCheckAttrs(Relation pkrel,
{
if ( attnums [ i ] = = indexStruct - > indkey . values [ j ] )
{
opclasses [ i ] = indclass - > values [ j ] ;
found = true ;
break ;
}
@ -6046,24 +6071,6 @@ transformFkeyCheckAttrs(Relation pkrel,
if ( ! found )
break ;
}
if ( found )
{
for ( i = 0 ; i < numattrs ; i + + )
{
found = false ;
for ( j = 0 ; j < numattrs ; j + + )
{
if ( attnums [ j ] = = indexStruct - > indkey . values [ i ] )
{
opclasses [ j ] = indclass - > values [ i ] ;
found = true ;
break ;
}
}
if ( ! found )
break ;
}
}
/*
* Refuse to use a deferrable unique / primary key . This is per SQL