* RelationDestroyRelation * * Physically delete a relation cache entry and all subsidiary data. * Caller must already have unhooked the entry from the hash table. */
| 2516 | * Caller must already have unhooked the entry from the hash table. |
| 2517 | */ |
| 2518 | static void |
| 2519 | RelationDestroyRelation(Relation relation, bool remember_tupdesc) |
| 2520 | { |
| 2521 | Assert(RelationHasReferenceCountZero(relation)); |
| 2522 | |
| 2523 | /* |
| 2524 | * Make sure smgr and lower levels close the relation's files, if they |
| 2525 | * weren't closed already. (This was probably done by caller, but let's |
| 2526 | * just be real sure.) |
| 2527 | */ |
| 2528 | RelationCloseSmgr(relation); |
| 2529 | |
| 2530 | /* |
| 2531 | * Free all the subsidiary data structures of the relcache entry, then the |
| 2532 | * entry itself. |
| 2533 | */ |
| 2534 | if (relation->rd_rel) |
| 2535 | pfree(relation->rd_rel); |
| 2536 | /* can't use DecrTupleDescRefCount here */ |
| 2537 | Assert(relation->rd_att->tdrefcount > 0); |
| 2538 | if (--relation->rd_att->tdrefcount == 0) |
| 2539 | { |
| 2540 | /* |
| 2541 | * If we Rebuilt a relcache entry during a transaction then its |
| 2542 | * possible we did that because the TupDesc changed as the result of |
| 2543 | * an ALTER TABLE that ran at less than AccessExclusiveLock. It's |
| 2544 | * possible someone copied that TupDesc, in which case the copy would |
| 2545 | * point to free'd memory. So if we rebuild an entry we keep the |
| 2546 | * TupDesc around until end of transaction, to be safe. |
| 2547 | */ |
| 2548 | if (remember_tupdesc) |
| 2549 | RememberToFreeTupleDescAtEOX(relation->rd_att); |
| 2550 | else |
| 2551 | FreeTupleDesc(relation->rd_att); |
| 2552 | } |
| 2553 | FreeTriggerDesc(relation->trigdesc); |
| 2554 | list_free_deep(relation->rd_fkeylist); |
| 2555 | list_free(relation->rd_indexlist); |
| 2556 | list_free(relation->rd_statlist); |
| 2557 | bms_free(relation->rd_indexattr); |
| 2558 | bms_free(relation->rd_keyattr); |
| 2559 | bms_free(relation->rd_pkattr); |
| 2560 | bms_free(relation->rd_idattr); |
| 2561 | if (relation->rd_pubactions) |
| 2562 | pfree(relation->rd_pubactions); |
| 2563 | if (relation->rd_options) |
| 2564 | pfree(relation->rd_options); |
| 2565 | if (relation->rd_indextuple) |
| 2566 | pfree(relation->rd_indextuple); |
| 2567 | if (relation->rd_aotuple) |
| 2568 | pfree(relation->rd_aotuple); |
| 2569 | if (relation->rd_amcache) |
| 2570 | pfree(relation->rd_amcache); |
| 2571 | if (relation->rd_fdwroutine) |
| 2572 | pfree(relation->rd_fdwroutine); |
| 2573 | if (relation->rd_indexcxt) |
| 2574 | MemoryContextDelete(relation->rd_indexcxt); |
| 2575 | if (relation->rd_rulescxt) |
no test coverage detected