/* * InitCatalogCachePhase2 - finish initializing the caches * * Finish initializing all the caches, including necessary database * access. * * This is *not* essential; normally we allow syscaches to be initialized * on first use. However, it is useful as a mechanism to preload the * relcache with entries for the most-commonly-used system catalogs. * Therefore, we invoke this routine when we need to write a new relcache * init file. */ void InitCatalogCachePhase2(void) { int cacheId; Assert(CacheInitialized); for (cacheId = 0; cacheId < SysCacheSize; cacheId++) { /* * In order for upgrade to work successfully we must be able to run * in single user mode with a catalog like the GP 3.2 catalog. To * support this we must skip the optional syscache initialization * for catalog tables that did not exist in 3.2, otherwise we will * try to read the relation before we have created it and will fail * to startup. */ if ((IsBootstrapProcessingMode() || IsInitProcessingMode()) && ((cacheinfo[cacheId].reloid == ForeignDataWrapperRelationId) || (cacheinfo[cacheId].reloid == ForeignServerRelationId) || (cacheinfo[cacheId].reloid == UserMappingRelationId))) { continue; } InitCatCachePhase2(SysCache[cacheId], true); } }
/* * InitCatalogCachePhase2 - finish initializing the caches * * Finish initializing all the caches, including necessary database * access. * * This is *not* essential; normally we allow syscaches to be initialized * on first use. However, it is useful as a mechanism to preload the * relcache with entries for the most-commonly-used system catalogs. * Therefore, we invoke this routine when we need to write a new relcache * init file. */ void InitCatalogCachePhase2(void) { int cacheId; Assert(CacheInitialized); for (cacheId = 0; cacheId < SysCacheSize; cacheId++) InitCatCachePhase2(SysCache[cacheId], true); }
/* * SysCacheGetAttr * * Given a tuple previously fetched by SearchSysCache(), * extract a specific attribute. * * This is equivalent to using heap_getattr() on a tuple fetched * from a non-cached relation. Usually, this is only used for attributes * that could be NULL or variable length; the fixed-size attributes in * a system table are accessed just by mapping the tuple onto the C struct * declarations from include/catalog/. * * As with heap_getattr(), if the attribute is of a pass-by-reference type * then a pointer into the tuple data area is returned --- the caller must * not modify or pfree the datum! * * Note: it is legal to use SysCacheGetAttr() with a cacheId referencing * a different cache for the same catalog the tuple was fetched from. */ Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull) { /* * We just need to get the TupleDesc out of the cache entry, and then we * can apply heap_getattr(). Normally the cache control data is already * valid (because the caller recently fetched the tuple via this same * cache), but there are cases where we have to initialize the cache here. */ if (cacheId < 0 || cacheId >= SysCacheSize || !PointerIsValid(SysCache[cacheId])) elog(ERROR, "invalid cache id: %d", cacheId); if (!PointerIsValid(SysCache[cacheId]->cc_tupdesc)) { InitCatCachePhase2(SysCache[cacheId], false); Assert(PointerIsValid(SysCache[cacheId]->cc_tupdesc)); } return heap_getattr(tup, attributeNumber, SysCache[cacheId]->cc_tupdesc, isNull); }