-static void
-CatalogCacheInitializeCache(struct catcache * cache,
- Relation relation)
-{
- MemoryContext oldcxt;
- short didopen = 0;
- short i;
- TupleDesc tupdesc;
-
- CatalogCacheInitializeCache_DEBUG1;
-
- /* ----------------
- * first switch to the cache context so our allocations
- * do not vanish at the end of a transaction
- * ----------------
- */
- if (!CacheCxt)
- CacheCxt = CreateGlobalMemory("Cache");
- oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
-
- /* ----------------
- * If no relation was passed we must open it to get access to
- * its fields. If one of the other caches has already opened
- * it we use heap_open() instead of heap_openr()
- * ----------------
- */
- if (!RelationIsValid(relation))
- {
- struct catcache *cp;
-
- /* ----------------
- * scan the caches to see if any other cache has opened the relation
- * ----------------
- */
- for (cp = Caches; cp; cp = cp->cc_next)
- {
- if (strncmp(cp->cc_relname, cache->cc_relname, NAMEDATALEN) == 0)
- {
- if (cp->relationId != InvalidOid)
- break;
- }
- }
-
- /* ----------------
- * open the relation by name or by id
- * ----------------
- */
- if (cp)
- relation = heap_open(cp->relationId);
- else
- relation = heap_openr(cache->cc_relname);
-
- didopen = 1;
- }
-
- /* ----------------
- * initialize the cache's relation id
- * ----------------
- */
- Assert(RelationIsValid(relation));
- cache->relationId = RelationGetRelid(relation);
- tupdesc = cache->cc_tupdesc = RelationGetDescr(relation);
-
- CACHE3_elog(DEBUG, "CatalogCacheInitializeCache: relid %u, %d keys",
- cache->relationId, cache->cc_nkeys);
-
- /* ----------------
- * initialize cache's key information
- * ----------------
- */
- for (i = 0; i < cache->cc_nkeys; ++i)
- {
- CatalogCacheInitializeCache_DEBUG2;
-
- if (cache->cc_key[i] > 0)
- {
-
- /*
- * Yoiks. The implementation of the hashing code and the
- * implementation of int28's are at loggerheads. The right
- * thing to do is to throw out the implementation of int28's
- * altogether; until that happens, we do the right thing here
- * to guarantee that the hash key generator doesn't try to
- * dereference an int2 by mistake.
- */
-
- if (tupdesc->attrs[cache->cc_key[i] - 1]->atttypid == INT28OID)
- cache->cc_klen[i] = sizeof(short);
- else
- cache->cc_klen[i] = tupdesc->attrs[cache->cc_key[i] - 1]->attlen;
-
- cache->cc_skey[i].sk_procedure = EQPROC(tupdesc->attrs[cache->cc_key[i] - 1]->atttypid);
-
- fmgr_info(cache->cc_skey[i].sk_procedure,
- &cache->cc_skey[i].sk_func);
- cache->cc_skey[i].sk_nargs = cache->cc_skey[i].sk_func.fn_nargs;
-
- CACHE5_elog(DEBUG, "CatalogCacheInit %s %d %d %x",
- &relation->rd_rel->relname,
- i,
- tupdesc->attrs[cache->cc_key[i] - 1]->attlen,
- cache);
- }
- }
-
- /* ----------------
- * close the relation if we opened it
- * ----------------
- */
- if (didopen)
- heap_close(relation);
-
- /* ----------------
- * initialize index information for the cache. this
- * should only be done once per cache.
- * ----------------
- */
- if (cache->cc_indname != NULL && cache->indexId == InvalidOid)
- {
- if (RelationGetForm(relation)->relhasindex)
- {
-
- /*
- * If the index doesn't exist we are in trouble.
- */
- relation = index_openr(cache->cc_indname);
- Assert(relation);
- cache->indexId = RelationGetRelid(relation);
- index_close(relation);
- }
- else
- cache->cc_indname = NULL;
- }
-
- /* ----------------
- * return to the proper memory context
- * ----------------
- */
- MemoryContextSwitchTo(oldcxt);
-}