* RelationGetIndexList -- get a list of OIDs of indexes on this relation * * The index list is created only if someone requests it. We scan pg_index * to find relevant indexes, and add the list to the relcache entry so that * we won't have to compute it again. Note that shared cache inval of a * relcache entry will delete the old list and set rd_indexvalid to false, * so that we must recom
| 4940 | * replication identity index, or InvalidOid if there is no such index. |
| 4941 | */ |
| 4942 | List * |
| 4943 | RelationGetIndexList(Relation relation) |
| 4944 | { |
| 4945 | Relation indrel; |
| 4946 | SysScanDesc indscan; |
| 4947 | ScanKeyData skey; |
| 4948 | HeapTuple htup; |
| 4949 | List *result; |
| 4950 | List *oldlist; |
| 4951 | char replident = relation->rd_rel->relreplident; |
| 4952 | Oid pkeyIndex = InvalidOid; |
| 4953 | Oid candidateIndex = InvalidOid; |
| 4954 | MemoryContext oldcxt; |
| 4955 | |
| 4956 | /* Quick exit if we already computed the list. */ |
| 4957 | if (relation->rd_indexvalid) |
| 4958 | return list_copy(relation->rd_indexlist); |
| 4959 | |
| 4960 | /* |
| 4961 | * We build the list we intend to return (in the caller's context) while |
| 4962 | * doing the scan. After successfully completing the scan, we copy that |
| 4963 | * list into the relcache entry. This avoids cache-context memory leakage |
| 4964 | * if we get some sort of error partway through. |
| 4965 | */ |
| 4966 | result = NIL; |
| 4967 | |
| 4968 | /* Prepare to scan pg_index for entries having indrelid = this rel. */ |
| 4969 | ScanKeyInit(&skey, |
| 4970 | Anum_pg_index_indrelid, |
| 4971 | BTEqualStrategyNumber, F_OIDEQ, |
| 4972 | ObjectIdGetDatum(RelationGetRelid(relation))); |
| 4973 | |
| 4974 | indrel = table_open(IndexRelationId, AccessShareLock); |
| 4975 | indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true, |
| 4976 | NULL, 1, &skey); |
| 4977 | |
| 4978 | while (HeapTupleIsValid(htup = systable_getnext(indscan))) |
| 4979 | { |
| 4980 | Form_pg_index index = (Form_pg_index) GETSTRUCT(htup); |
| 4981 | |
| 4982 | /* |
| 4983 | * Ignore any indexes that are currently being dropped. This will |
| 4984 | * prevent them from being searched, inserted into, or considered in |
| 4985 | * HOT-safety decisions. It's unsafe to touch such an index at all |
| 4986 | * since its catalog entries could disappear at any instant. |
| 4987 | */ |
| 4988 | if (!index->indislive) |
| 4989 | continue; |
| 4990 | |
| 4991 | /* add index's OID to result list */ |
| 4992 | result = lappend_oid(result, index->indexrelid); |
| 4993 | |
| 4994 | /* |
| 4995 | * Invalid, non-unique, non-immediate or predicate indexes aren't |
| 4996 | * interesting for either oid indexes or replication identity indexes, |
| 4997 | * so don't check them. |
| 4998 | */ |
| 4999 | if (!index->indisvalid || !index->indisunique || |
no test coverage detected