* transformFkeyGetPrimaryKey - * * Look up the names, attnums, and types of the primary key attributes * for the pkrel. Also return the index OID and index opclasses of the * index supporting the primary key. * * All parameters except pkrel are output parameters. Also, the function * return value is the number of attributes in the primary key. * * Used when the column list in the REFERE
| 12869 | * Used when the column list in the REFERENCES specification is omitted. |
| 12870 | */ |
| 12871 | static int |
| 12872 | transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid, |
| 12873 | List **attnamelist, |
| 12874 | int16 *attnums, Oid *atttypids, |
| 12875 | Oid *opclasses) |
| 12876 | { |
| 12877 | List *indexoidlist; |
| 12878 | ListCell *indexoidscan; |
| 12879 | HeapTuple indexTuple = NULL; |
| 12880 | Form_pg_index indexStruct = NULL; |
| 12881 | Datum indclassDatum; |
| 12882 | bool isnull; |
| 12883 | oidvector *indclass; |
| 12884 | int i; |
| 12885 | |
| 12886 | /* |
| 12887 | * Get the list of index OIDs for the table from the relcache, and look up |
| 12888 | * each one in the pg_index syscache until we find one marked primary key |
| 12889 | * (hopefully there isn't more than one such). Insist it's valid, too. |
| 12890 | */ |
| 12891 | *indexOid = InvalidOid; |
| 12892 | |
| 12893 | indexoidlist = RelationGetIndexList(pkrel); |
| 12894 | |
| 12895 | foreach(indexoidscan, indexoidlist) |
| 12896 | { |
| 12897 | Oid indexoid = lfirst_oid(indexoidscan); |
| 12898 | |
| 12899 | indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexoid)); |
| 12900 | if (!HeapTupleIsValid(indexTuple)) |
| 12901 | elog(ERROR, "cache lookup failed for index %u", indexoid); |
| 12902 | indexStruct = (Form_pg_index) GETSTRUCT(indexTuple); |
| 12903 | if (indexStruct->indisprimary && indexStruct->indisvalid) |
| 12904 | { |
| 12905 | /* |
| 12906 | * Refuse to use a deferrable primary key. This is per SQL spec, |
| 12907 | * and there would be a lot of interesting semantic problems if we |
| 12908 | * tried to allow it. |
| 12909 | */ |
| 12910 | if (!indexStruct->indimmediate) |
| 12911 | ereport(ERROR, |
| 12912 | (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), |
| 12913 | errmsg("cannot use a deferrable primary key for referenced table \"%s\"", |
| 12914 | RelationGetRelationName(pkrel)))); |
| 12915 | |
| 12916 | *indexOid = indexoid; |
| 12917 | break; |
| 12918 | } |
| 12919 | ReleaseSysCache(indexTuple); |
| 12920 | } |
| 12921 | |
| 12922 | list_free(indexoidlist); |
| 12923 | |
| 12924 | /* |
| 12925 | * Check that we found it |
| 12926 | */ |
| 12927 | if (!OidIsValid(*indexOid)) |
| 12928 | ereport(ERROR, |
no test coverage detected