* RelationGetStatExtList * get a list of OIDs of statistics objects on this relation * * The statistics list is created only if someone requests it, in a way * similar to RelationGetIndexList(). We scan pg_statistic_ext to find * relevant statistics, 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
| 5059 | * statistics, and syscache lookup could cause SI messages to be processed! |
| 5060 | */ |
| 5061 | List * |
| 5062 | RelationGetStatExtList(Relation relation) |
| 5063 | { |
| 5064 | Relation indrel; |
| 5065 | SysScanDesc indscan; |
| 5066 | ScanKeyData skey; |
| 5067 | HeapTuple htup; |
| 5068 | List *result; |
| 5069 | List *oldlist; |
| 5070 | MemoryContext oldcxt; |
| 5071 | |
| 5072 | /* Quick exit if we already computed the list. */ |
| 5073 | if (relation->rd_statvalid != 0) |
| 5074 | return list_copy(relation->rd_statlist); |
| 5075 | |
| 5076 | /* |
| 5077 | * We build the list we intend to return (in the caller's context) while |
| 5078 | * doing the scan. After successfully completing the scan, we copy that |
| 5079 | * list into the relcache entry. This avoids cache-context memory leakage |
| 5080 | * if we get some sort of error partway through. |
| 5081 | */ |
| 5082 | result = NIL; |
| 5083 | |
| 5084 | /* |
| 5085 | * Prepare to scan pg_statistic_ext for entries having stxrelid = this |
| 5086 | * rel. |
| 5087 | */ |
| 5088 | ScanKeyInit(&skey, |
| 5089 | Anum_pg_statistic_ext_stxrelid, |
| 5090 | BTEqualStrategyNumber, F_OIDEQ, |
| 5091 | ObjectIdGetDatum(RelationGetRelid(relation))); |
| 5092 | |
| 5093 | indrel = table_open(StatisticExtRelationId, AccessShareLock); |
| 5094 | indscan = systable_beginscan(indrel, StatisticExtRelidIndexId, true, |
| 5095 | NULL, 1, &skey); |
| 5096 | |
| 5097 | while (HeapTupleIsValid(htup = systable_getnext(indscan))) |
| 5098 | { |
| 5099 | Oid oid = ((Form_pg_statistic_ext) GETSTRUCT(htup))->oid; |
| 5100 | |
| 5101 | result = lappend_oid(result, oid); |
| 5102 | } |
| 5103 | |
| 5104 | systable_endscan(indscan); |
| 5105 | |
| 5106 | table_close(indrel, AccessShareLock); |
| 5107 | |
| 5108 | /* Sort the result list into OID order, per API spec. */ |
| 5109 | list_sort(result, list_oid_cmp); |
| 5110 | |
| 5111 | /* Now save a copy of the completed list in the relcache entry. */ |
| 5112 | oldcxt = MemoryContextSwitchTo(CacheMemoryContext); |
| 5113 | oldlist = relation->rd_statlist; |
| 5114 | relation->rd_statlist = list_copy(result); |
| 5115 | |
| 5116 | relation->rd_statvalid = true; |
| 5117 | MemoryContextSwitchTo(oldcxt); |
| 5118 |
no test coverage detected