* RelationReloadIndexInfo - reload minimal information for an open index * * This function is used only for indexes. A relcache inval on an index * can mean that its pg_class or pg_index row changed. There are only * very limited changes that are allowed to an existing index's schema, * so we can update the relcache entry without a complete rebuild; which * is fortunate because we can't re
| 2332 | * only applying this to indexes being opened or having positive refcount. |
| 2333 | */ |
| 2334 | static void |
| 2335 | RelationReloadIndexInfo(Relation relation) |
| 2336 | { |
| 2337 | bool indexOK; |
| 2338 | HeapTuple pg_class_tuple; |
| 2339 | Form_pg_class relp; |
| 2340 | |
| 2341 | /* Should be called only for invalidated, live indexes */ |
| 2342 | Assert((relation->rd_rel->relkind == RELKIND_INDEX || |
| 2343 | relation->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) && |
| 2344 | !relation->rd_isvalid && |
| 2345 | relation->rd_droppedSubid == InvalidSubTransactionId); |
| 2346 | |
| 2347 | /* Ensure it's closed at smgr level */ |
| 2348 | RelationCloseSmgr(relation); |
| 2349 | |
| 2350 | /* Must free any AM cached data upon relcache flush */ |
| 2351 | if (relation->rd_amcache) |
| 2352 | pfree(relation->rd_amcache); |
| 2353 | relation->rd_amcache = NULL; |
| 2354 | |
| 2355 | /* |
| 2356 | * If it's a shared index, we might be called before backend startup has |
| 2357 | * finished selecting a database, in which case we have no way to read |
| 2358 | * pg_class yet. However, a shared index can never have any significant |
| 2359 | * schema updates, so it's okay to ignore the invalidation signal. Just |
| 2360 | * mark it valid and return without doing anything more. |
| 2361 | */ |
| 2362 | if (relation->rd_rel->relisshared && !criticalRelcachesBuilt) |
| 2363 | { |
| 2364 | relation->rd_isvalid = true; |
| 2365 | return; |
| 2366 | } |
| 2367 | |
| 2368 | /* |
| 2369 | * Read the pg_class row |
| 2370 | * |
| 2371 | * Don't try to use an indexscan of pg_class_oid_index to reload the info |
| 2372 | * for pg_class_oid_index ... |
| 2373 | */ |
| 2374 | indexOK = (RelationGetRelid(relation) != ClassOidIndexId); |
| 2375 | pg_class_tuple = ScanPgRelation(RelationGetRelid(relation), indexOK, false); |
| 2376 | if (!HeapTupleIsValid(pg_class_tuple)) |
| 2377 | elog(ERROR, "could not find pg_class tuple for index %u", |
| 2378 | RelationGetRelid(relation)); |
| 2379 | relp = (Form_pg_class) GETSTRUCT(pg_class_tuple); |
| 2380 | memcpy(relation->rd_rel, relp, CLASS_TUPLE_SIZE); |
| 2381 | /* Reload reloptions in case they changed */ |
| 2382 | if (relation->rd_options) |
| 2383 | pfree(relation->rd_options); |
| 2384 | RelationParseRelOptions(relation, pg_class_tuple); |
| 2385 | /* done with pg_class tuple */ |
| 2386 | heap_freetuple(pg_class_tuple); |
| 2387 | /* We must recalculate physical address in case it changed */ |
| 2388 | RelationInitPhysicalAddr(relation); |
| 2389 | |
| 2390 | /* |
| 2391 | * For a non-system index, there are fields of the pg_index row that are |
no test coverage detected