Change /*---- commants to /* where appropriate. pgindent will tighten
up the comments later.
This commit is contained in:
parent
a69f81c202
commit
660ca3e01c
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.75 2001/01/24 19:43:14 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.76 2001/02/22 18:39:19 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -37,9 +37,9 @@ static Index CatalogCacheComputeTupleHashIndex(CatCache *cache,
|
||||||
static void CatalogCacheInitializeCache(CatCache *cache);
|
static void CatalogCacheInitializeCache(CatCache *cache);
|
||||||
static Datum cc_hashname(PG_FUNCTION_ARGS);
|
static Datum cc_hashname(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* variables, macros and other stuff
|
* variables, macros and other stuff
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CACHEDEBUG
|
#ifdef CACHEDEBUG
|
||||||
|
@ -61,14 +61,14 @@ static Datum cc_hashname(PG_FUNCTION_ARGS);
|
||||||
static CatCache *Caches = NULL; /* head of list of caches */
|
static CatCache *Caches = NULL; /* head of list of caches */
|
||||||
|
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* EQPROC is used in CatalogCacheInitializeCache to find the equality
|
* EQPROC is used in CatalogCacheInitializeCache to find the equality
|
||||||
* functions for system types that are used as cache key fields.
|
* functions for system types that are used as cache key fields.
|
||||||
* See also GetCCHashFunc, which should support the same set of types.
|
* See also GetCCHashFunc, which should support the same set of types.
|
||||||
*
|
*
|
||||||
* XXX this should be replaced by catalog lookups,
|
* XXX this should be replaced by catalog lookups,
|
||||||
* but that seems to pose considerable risk of circularity...
|
* but that seems to pose considerable risk of circularity...
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
static const Oid eqproc[] = {
|
static const Oid eqproc[] = {
|
||||||
F_BOOLEQ, InvalidOid, F_CHAREQ, F_NAMEEQ, InvalidOid,
|
F_BOOLEQ, InvalidOid, F_CHAREQ, F_NAMEEQ, InvalidOid,
|
||||||
|
@ -78,9 +78,9 @@ static const Oid eqproc[] = {
|
||||||
|
|
||||||
#define EQPROC(SYSTEMTYPEOID) eqproc[(SYSTEMTYPEOID)-BOOLOID]
|
#define EQPROC(SYSTEMTYPEOID) eqproc[(SYSTEMTYPEOID)-BOOLOID]
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/*
|
||||||
* internal support functions
|
* internal support functions
|
||||||
* ----------------------------------------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static PGFunction
|
static PGFunction
|
||||||
|
@ -153,13 +153,13 @@ CreateCacheMemoryContext(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* CatalogCacheInitializeCache
|
* CatalogCacheInitializeCache
|
||||||
*
|
*
|
||||||
* This function does final initialization of a catcache: obtain the tuple
|
* This function does final initialization of a catcache: obtain the tuple
|
||||||
* descriptor and set up the hash and equality function links. We assume
|
* descriptor and set up the hash and equality function links. We assume
|
||||||
* that the relcache entry can be opened at this point!
|
* that the relcache entry can be opened at this point!
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef CACHEDEBUG
|
#ifdef CACHEDEBUG
|
||||||
#define CatalogCacheInitializeCache_DEBUG1 \
|
#define CatalogCacheInitializeCache_DEBUG1 \
|
||||||
|
@ -200,25 +200,25 @@ CatalogCacheInitializeCache(CatCache *cache)
|
||||||
relation = heap_openr(cache->cc_relname, NoLock);
|
relation = heap_openr(cache->cc_relname, NoLock);
|
||||||
Assert(RelationIsValid(relation));
|
Assert(RelationIsValid(relation));
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* switch to the cache context so our allocations
|
* switch to the cache context so our allocations
|
||||||
* do not vanish at the end of a transaction
|
* do not vanish at the end of a transaction
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
if (!CacheMemoryContext)
|
if (!CacheMemoryContext)
|
||||||
CreateCacheMemoryContext();
|
CreateCacheMemoryContext();
|
||||||
|
|
||||||
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
|
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* copy the relcache's tuple descriptor to permanent cache storage
|
* copy the relcache's tuple descriptor to permanent cache storage
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
tupdesc = CreateTupleDescCopyConstr(RelationGetDescr(relation));
|
tupdesc = CreateTupleDescCopyConstr(RelationGetDescr(relation));
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* return to the caller's memory context and close the rel
|
* return to the caller's memory context and close the rel
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
MemoryContextSwitchTo(oldcxt);
|
MemoryContextSwitchTo(oldcxt);
|
||||||
|
|
||||||
|
@ -227,9 +227,9 @@ CatalogCacheInitializeCache(CatCache *cache)
|
||||||
CACHE3_elog(DEBUG, "CatalogCacheInitializeCache: %s, %d keys",
|
CACHE3_elog(DEBUG, "CatalogCacheInitializeCache: %s, %d keys",
|
||||||
cache->cc_relname, cache->cc_nkeys);
|
cache->cc_relname, cache->cc_nkeys);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize cache's key information
|
* initialize cache's key information
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < cache->cc_nkeys; ++i)
|
for (i = 0; i < cache->cc_nkeys; ++i)
|
||||||
{
|
{
|
||||||
|
@ -267,16 +267,16 @@ CatalogCacheInitializeCache(CatCache *cache)
|
||||||
cache);
|
cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* mark this cache fully initialized
|
* mark this cache fully initialized
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
cache->cc_tupdesc = tupdesc;
|
cache->cc_tupdesc = tupdesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* CatalogCacheComputeHashIndex
|
* CatalogCacheComputeHashIndex
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static Index
|
static Index
|
||||||
CatalogCacheComputeHashIndex(CatCache *cache, ScanKey cur_skey)
|
CatalogCacheComputeHashIndex(CatCache *cache, ScanKey cur_skey)
|
||||||
|
@ -318,9 +318,9 @@ CatalogCacheComputeHashIndex(CatCache *cache, ScanKey cur_skey)
|
||||||
return (Index) hashIndex;
|
return (Index) hashIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* CatalogCacheComputeTupleHashIndex
|
* CatalogCacheComputeTupleHashIndex
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static Index
|
static Index
|
||||||
CatalogCacheComputeTupleHashIndex(CatCache *cache,
|
CatalogCacheComputeTupleHashIndex(CatCache *cache,
|
||||||
|
@ -384,9 +384,9 @@ CatalogCacheComputeTupleHashIndex(CatCache *cache,
|
||||||
return CatalogCacheComputeHashIndex(cache, cur_skey);
|
return CatalogCacheComputeHashIndex(cache, cur_skey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* CatCacheRemoveCTup
|
* CatCacheRemoveCTup
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
|
CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
|
||||||
|
@ -405,14 +405,14 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
|
||||||
--cache->cc_ntup;
|
--cache->cc_ntup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* CatalogCacheIdInvalidate()
|
* CatalogCacheIdInvalidate()
|
||||||
*
|
*
|
||||||
* Invalidate a tuple given a cache id. In this case the id should always
|
* Invalidate a tuple given a cache id. In this case the id should always
|
||||||
* be found (whether the cache has opened its relation or not). Of course,
|
* be found (whether the cache has opened its relation or not). Of course,
|
||||||
* if the cache has yet to open its relation, there will be no tuples so
|
* if the cache has yet to open its relation, there will be no tuples so
|
||||||
* no problem.
|
* no problem.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
CatalogCacheIdInvalidate(int cacheId,
|
CatalogCacheIdInvalidate(int cacheId,
|
||||||
|
@ -421,17 +421,17 @@ CatalogCacheIdInvalidate(int cacheId,
|
||||||
{
|
{
|
||||||
CatCache *ccp;
|
CatCache *ccp;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* sanity checks
|
* sanity checks
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
Assert(hashIndex < NCCBUCK);
|
Assert(hashIndex < NCCBUCK);
|
||||||
Assert(ItemPointerIsValid(pointer));
|
Assert(ItemPointerIsValid(pointer));
|
||||||
CACHE1_elog(DEBUG, "CatalogCacheIdInvalidate: called");
|
CACHE1_elog(DEBUG, "CatalogCacheIdInvalidate: called");
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* inspect caches to find the proper cache
|
* inspect caches to find the proper cache
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
for (ccp = Caches; ccp; ccp = ccp->cc_next)
|
for (ccp = Caches; ccp; ccp = ccp->cc_next)
|
||||||
{
|
{
|
||||||
|
@ -440,9 +440,9 @@ CatalogCacheIdInvalidate(int cacheId,
|
||||||
|
|
||||||
if (cacheId != ccp->id)
|
if (cacheId != ccp->id)
|
||||||
continue;
|
continue;
|
||||||
/* ----------------
|
/*
|
||||||
* inspect the hash bucket until we find a match or exhaust
|
* inspect the hash bucket until we find a match or exhaust
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
for (elt = DLGetHead(&ccp->cc_cache[hashIndex]); elt; elt = nextelt)
|
for (elt = DLGetHead(&ccp->cc_cache[hashIndex]); elt; elt = nextelt)
|
||||||
{
|
{
|
||||||
|
@ -477,7 +477,7 @@ CatalogCacheIdInvalidate(int cacheId,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* AtEOXact_CatCache
|
* AtEOXact_CatCache
|
||||||
*
|
*
|
||||||
* Clean up catcaches at end of transaction (either commit or abort)
|
* Clean up catcaches at end of transaction (either commit or abort)
|
||||||
|
@ -486,7 +486,7 @@ CatalogCacheIdInvalidate(int cacheId,
|
||||||
* necessary in the abort case, since elog() may have interrupted routines.
|
* necessary in the abort case, since elog() may have interrupted routines.
|
||||||
* In the commit case, any nonzero counts indicate failure to call
|
* In the commit case, any nonzero counts indicate failure to call
|
||||||
* ReleaseSysCache, so we put out a notice for debugging purposes.
|
* ReleaseSysCache, so we put out a notice for debugging purposes.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
AtEOXact_CatCache(bool isCommit)
|
AtEOXact_CatCache(bool isCommit)
|
||||||
|
@ -521,11 +521,11 @@ AtEOXact_CatCache(bool isCommit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* ResetSystemCache
|
* ResetSystemCache
|
||||||
*
|
*
|
||||||
* Reset caches when a shared cache inval event forces it
|
* Reset caches when a shared cache inval event forces it
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ResetSystemCache(void)
|
ResetSystemCache(void)
|
||||||
|
@ -563,7 +563,7 @@ ResetSystemCache(void)
|
||||||
CACHE1_elog(DEBUG, "end of ResetSystemCache call");
|
CACHE1_elog(DEBUG, "end of ResetSystemCache call");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* SystemCacheRelationFlushed
|
* SystemCacheRelationFlushed
|
||||||
*
|
*
|
||||||
* This is called by RelationFlushRelation() to clear out cached information
|
* This is called by RelationFlushRelation() to clear out cached information
|
||||||
|
@ -583,7 +583,7 @@ ResetSystemCache(void)
|
||||||
* We now avoid the need to do it by copying cc_tupdesc out of the relcache,
|
* We now avoid the need to do it by copying cc_tupdesc out of the relcache,
|
||||||
* rather than relying on the relcache to keep a tupdesc for us. Of course
|
* rather than relying on the relcache to keep a tupdesc for us. Of course
|
||||||
* this assumes the tupdesc of a cachable system table will not change...)
|
* this assumes the tupdesc of a cachable system table will not change...)
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
SystemCacheRelationFlushed(Oid relId)
|
SystemCacheRelationFlushed(Oid relId)
|
||||||
|
@ -597,14 +597,14 @@ SystemCacheRelationFlushed(Oid relId)
|
||||||
ResetSystemCache();
|
ResetSystemCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* InitCatCache
|
* InitCatCache
|
||||||
*
|
*
|
||||||
* This allocates and initializes a cache for a system catalog relation.
|
* This allocates and initializes a cache for a system catalog relation.
|
||||||
* Actually, the cache is only partially initialized to avoid opening the
|
* Actually, the cache is only partially initialized to avoid opening the
|
||||||
* relation. The relation will be opened and the rest of the cache
|
* relation. The relation will be opened and the rest of the cache
|
||||||
* structure initialized on the first access.
|
* structure initialized on the first access.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef CACHEDEBUG
|
#ifdef CACHEDEBUG
|
||||||
#define InitCatCache_DEBUG1 \
|
#define InitCatCache_DEBUG1 \
|
||||||
|
@ -628,45 +628,45 @@ InitCatCache(int id,
|
||||||
MemoryContext oldcxt;
|
MemoryContext oldcxt;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* first switch to the cache context so our allocations
|
* first switch to the cache context so our allocations
|
||||||
* do not vanish at the end of a transaction
|
* do not vanish at the end of a transaction
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
if (!CacheMemoryContext)
|
if (!CacheMemoryContext)
|
||||||
CreateCacheMemoryContext();
|
CreateCacheMemoryContext();
|
||||||
|
|
||||||
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
|
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* allocate a new cache structure
|
* allocate a new cache structure
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
cp = (CatCache *) palloc(sizeof(CatCache));
|
cp = (CatCache *) palloc(sizeof(CatCache));
|
||||||
MemSet((char *) cp, 0, sizeof(CatCache));
|
MemSet((char *) cp, 0, sizeof(CatCache));
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize the cache buckets (each bucket is a list header)
|
* initialize the cache buckets (each bucket is a list header)
|
||||||
* and the LRU tuple list
|
* and the LRU tuple list
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
DLInitList(&cp->cc_lrulist);
|
DLInitList(&cp->cc_lrulist);
|
||||||
for (i = 0; i < NCCBUCK; ++i)
|
for (i = 0; i < NCCBUCK; ++i)
|
||||||
DLInitList(&cp->cc_cache[i]);
|
DLInitList(&cp->cc_cache[i]);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* Caches is the pointer to the head of the list of all the
|
* Caches is the pointer to the head of the list of all the
|
||||||
* system caches. here we add the new cache to the top of the list.
|
* system caches. here we add the new cache to the top of the list.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
cp->cc_next = Caches; /* list of caches (single link) */
|
cp->cc_next = Caches; /* list of caches (single link) */
|
||||||
Caches = cp;
|
Caches = cp;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize the cache's relation information for the relation
|
* initialize the cache's relation information for the relation
|
||||||
* corresponding to this cache, and initialize some of the new
|
* corresponding to this cache, and initialize some of the new
|
||||||
* cache's other internal fields. But don't open the relation yet.
|
* cache's other internal fields. But don't open the relation yet.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
cp->cc_relname = relname;
|
cp->cc_relname = relname;
|
||||||
cp->cc_indname = indname;
|
cp->cc_indname = indname;
|
||||||
|
@ -678,16 +678,16 @@ InitCatCache(int id,
|
||||||
for (i = 0; i < nkeys; ++i)
|
for (i = 0; i < nkeys; ++i)
|
||||||
cp->cc_key[i] = key[i];
|
cp->cc_key[i] = key[i];
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* all done. new cache is initialized. print some debugging
|
* all done. new cache is initialized. print some debugging
|
||||||
* information, if appropriate.
|
* information, if appropriate.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
InitCatCache_DEBUG1;
|
InitCatCache_DEBUG1;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* back to the old context before we return...
|
* back to the old context before we return...
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
MemoryContextSwitchTo(oldcxt);
|
MemoryContextSwitchTo(oldcxt);
|
||||||
|
|
||||||
|
@ -695,7 +695,7 @@ InitCatCache(int id,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* IndexScanOK
|
* IndexScanOK
|
||||||
*
|
*
|
||||||
* This function checks for tuples that will be fetched by
|
* This function checks for tuples that will be fetched by
|
||||||
|
@ -703,7 +703,7 @@ InitCatCache(int id,
|
||||||
* certain system indexes that support critical syscaches.
|
* certain system indexes that support critical syscaches.
|
||||||
* We can't use an indexscan to fetch these, else we'll get into
|
* We can't use an indexscan to fetch these, else we'll get into
|
||||||
* infinite recursion. A plain heap scan will work, however.
|
* infinite recursion. A plain heap scan will work, however.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
IndexScanOK(CatCache *cache, ScanKey cur_skey)
|
IndexScanOK(CatCache *cache, ScanKey cur_skey)
|
||||||
|
@ -751,12 +751,12 @@ IndexScanOK(CatCache *cache, ScanKey cur_skey)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* SearchCatCache
|
* SearchCatCache
|
||||||
*
|
*
|
||||||
* This call searches a system cache for a tuple, opening the relation
|
* This call searches a system cache for a tuple, opening the relation
|
||||||
* if necessary (the first access to a particular cache).
|
* if necessary (the first access to a particular cache).
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
HeapTuple
|
HeapTuple
|
||||||
SearchCatCache(CatCache *cache,
|
SearchCatCache(CatCache *cache,
|
||||||
|
@ -773,16 +773,16 @@ SearchCatCache(CatCache *cache,
|
||||||
Relation relation;
|
Relation relation;
|
||||||
MemoryContext oldcxt;
|
MemoryContext oldcxt;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* one-time startup overhead
|
* one-time startup overhead
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
if (cache->cc_tupdesc == NULL)
|
if (cache->cc_tupdesc == NULL)
|
||||||
CatalogCacheInitializeCache(cache);
|
CatalogCacheInitializeCache(cache);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize the search key information
|
* initialize the search key information
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
memcpy(cur_skey, cache->cc_skey, sizeof(cur_skey));
|
memcpy(cur_skey, cache->cc_skey, sizeof(cur_skey));
|
||||||
cur_skey[0].sk_argument = v1;
|
cur_skey[0].sk_argument = v1;
|
||||||
|
@ -790,15 +790,15 @@ SearchCatCache(CatCache *cache,
|
||||||
cur_skey[2].sk_argument = v3;
|
cur_skey[2].sk_argument = v3;
|
||||||
cur_skey[3].sk_argument = v4;
|
cur_skey[3].sk_argument = v4;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* find the hash bucket in which to look for the tuple
|
* find the hash bucket in which to look for the tuple
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
hash = CatalogCacheComputeHashIndex(cache, cur_skey);
|
hash = CatalogCacheComputeHashIndex(cache, cur_skey);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* scan the hash bucket until we find a match or exhaust our tuples
|
* scan the hash bucket until we find a match or exhaust our tuples
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
for (elt = DLGetHead(&cache->cc_cache[hash]);
|
for (elt = DLGetHead(&cache->cc_cache[hash]);
|
||||||
elt;
|
elt;
|
||||||
|
@ -811,10 +811,10 @@ SearchCatCache(CatCache *cache,
|
||||||
if (ct->dead)
|
if (ct->dead)
|
||||||
continue; /* ignore dead entries */
|
continue; /* ignore dead entries */
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* see if the cached tuple matches our key.
|
* see if the cached tuple matches our key.
|
||||||
* (should we be worried about time ranges? -cim 10/2/90)
|
* (should we be worried about time ranges? -cim 10/2/90)
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
HeapKeyTest(&ct->tuple,
|
HeapKeyTest(&ct->tuple,
|
||||||
cache->cc_tupdesc,
|
cache->cc_tupdesc,
|
||||||
|
@ -824,14 +824,14 @@ SearchCatCache(CatCache *cache,
|
||||||
if (! res)
|
if (! res)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* we found a tuple in the cache: bump its refcount, move it to
|
* we found a tuple in the cache: bump its refcount, move it to
|
||||||
* the front of the LRU list, and return it. We also move it
|
* the front of the LRU list, and return it. We also move it
|
||||||
* to the front of the list for its hashbucket, in order to speed
|
* to the front of the list for its hashbucket, in order to speed
|
||||||
* subsequent searches. (The most frequently accessed elements
|
* subsequent searches. (The most frequently accessed elements
|
||||||
* in any hashbucket will tend to be near the front of the
|
* in any hashbucket will tend to be near the front of the
|
||||||
* hashbucket's list.)
|
* hashbucket's list.)
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
ct->refcount++;
|
ct->refcount++;
|
||||||
|
|
||||||
|
@ -846,7 +846,7 @@ SearchCatCache(CatCache *cache,
|
||||||
return &ct->tuple;
|
return &ct->tuple;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* Tuple was not found in cache, so we have to try and
|
* Tuple was not found in cache, so we have to try and
|
||||||
* retrieve it directly from the relation. If it's found,
|
* retrieve it directly from the relation. If it's found,
|
||||||
* we add it to the cache.
|
* we add it to the cache.
|
||||||
|
@ -860,19 +860,19 @@ SearchCatCache(CatCache *cache,
|
||||||
* first copy will never be referenced again, and will eventually
|
* first copy will never be referenced again, and will eventually
|
||||||
* age out of the cache, so there's no functional problem. This case
|
* age out of the cache, so there's no functional problem. This case
|
||||||
* is rare enough that it's not worth expending extra cycles to detect.
|
* is rare enough that it's not worth expending extra cycles to detect.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* open the relation associated with the cache
|
* open the relation associated with the cache
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
relation = heap_openr(cache->cc_relname, AccessShareLock);
|
relation = heap_openr(cache->cc_relname, AccessShareLock);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* Scan the relation to find the tuple. If there's an index, and
|
* Scan the relation to find the tuple. If there's an index, and
|
||||||
* if it's safe to do so, use the index. Else do a heap scan.
|
* if it's safe to do so, use the index. Else do a heap scan.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
ct = NULL;
|
ct = NULL;
|
||||||
|
|
||||||
|
@ -947,23 +947,23 @@ SearchCatCache(CatCache *cache,
|
||||||
heap_endscan(sd);
|
heap_endscan(sd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* close the relation
|
* close the relation
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
heap_close(relation, AccessShareLock);
|
heap_close(relation, AccessShareLock);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* scan is complete. if tup was found, we can add it to the cache.
|
* scan is complete. if tup was found, we can add it to the cache.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
if (ct == NULL)
|
if (ct == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* Finish initializing the CatCTup header, and add it to the
|
* Finish initializing the CatCTup header, and add it to the
|
||||||
* linked lists.
|
* linked lists.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
CACHE1_elog(DEBUG, "SearchCatCache: found tuple");
|
CACHE1_elog(DEBUG, "SearchCatCache: found tuple");
|
||||||
|
|
||||||
|
@ -976,10 +976,10 @@ SearchCatCache(CatCache *cache,
|
||||||
DLAddHead(&cache->cc_lrulist, &ct->lrulist_elem);
|
DLAddHead(&cache->cc_lrulist, &ct->lrulist_elem);
|
||||||
DLAddHead(&cache->cc_cache[hash], &ct->cache_elem);
|
DLAddHead(&cache->cc_cache[hash], &ct->cache_elem);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* If we've exceeded the desired size of this cache,
|
* If we've exceeded the desired size of this cache,
|
||||||
* try to throw away the least recently used entry.
|
* try to throw away the least recently used entry.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
if (++cache->cc_ntup > cache->cc_maxtup)
|
if (++cache->cc_ntup > cache->cc_maxtup)
|
||||||
{
|
{
|
||||||
|
@ -1007,7 +1007,7 @@ SearchCatCache(CatCache *cache,
|
||||||
return &ct->tuple;
|
return &ct->tuple;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* ReleaseCatCache()
|
* ReleaseCatCache()
|
||||||
*
|
*
|
||||||
* Decrement the reference count of a catcache entry (releasing the
|
* Decrement the reference count of a catcache entry (releasing the
|
||||||
|
@ -1017,7 +1017,7 @@ SearchCatCache(CatCache *cache,
|
||||||
* will be freed as soon as their refcount goes to zero. In combination
|
* will be freed as soon as their refcount goes to zero. In combination
|
||||||
* with aset.c's CLOBBER_FREED_MEMORY option, this provides a good test
|
* with aset.c's CLOBBER_FREED_MEMORY option, this provides a good test
|
||||||
* to catch references to already-released catcache entries.
|
* to catch references to already-released catcache entries.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ReleaseCatCache(HeapTuple tuple)
|
ReleaseCatCache(HeapTuple tuple)
|
||||||
|
@ -1046,7 +1046,7 @@ ReleaseCatCache(HeapTuple tuple)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* PrepareToInvalidateCacheTuple()
|
* PrepareToInvalidateCacheTuple()
|
||||||
*
|
*
|
||||||
* This is part of a rather subtle chain of events, so pay attention:
|
* This is part of a rather subtle chain of events, so pay attention:
|
||||||
|
@ -1072,7 +1072,7 @@ ReleaseCatCache(HeapTuple tuple)
|
||||||
* specified relation. inval.c doesn't know exactly which rels have
|
* specified relation. inval.c doesn't know exactly which rels have
|
||||||
* catcaches --- it will call this routine for any tuple that's in a
|
* catcaches --- it will call this routine for any tuple that's in a
|
||||||
* system relation.
|
* system relation.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
PrepareToInvalidateCacheTuple(Relation relation,
|
PrepareToInvalidateCacheTuple(Relation relation,
|
||||||
|
@ -1081,9 +1081,9 @@ PrepareToInvalidateCacheTuple(Relation relation,
|
||||||
{
|
{
|
||||||
CatCache *ccp;
|
CatCache *ccp;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* sanity checks
|
* sanity checks
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
Assert(RelationIsValid(relation));
|
Assert(RelationIsValid(relation));
|
||||||
Assert(HeapTupleIsValid(tuple));
|
Assert(HeapTupleIsValid(tuple));
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.40 2001/01/24 19:43:14 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.41 2001/02/22 18:39:19 momjian Exp $
|
||||||
*
|
*
|
||||||
* Note - this code is real crufty... badly needs a rewrite to improve
|
* Note - this code is real crufty... badly needs a rewrite to improve
|
||||||
* readability and portability. (Shouldn't assume Oid == Index, for example)
|
* readability and portability. (Shouldn't assume Oid == Index, for example)
|
||||||
|
@ -51,9 +51,9 @@
|
||||||
#include "utils/relcache.h"
|
#include "utils/relcache.h"
|
||||||
|
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* private invalidation structures
|
* private invalidation structures
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct InvalidationUserData
|
typedef struct InvalidationUserData
|
||||||
|
@ -100,9 +100,9 @@ typedef struct InvalidationMessageData
|
||||||
|
|
||||||
typedef InvalidationMessageData *InvalidationMessage;
|
typedef InvalidationMessageData *InvalidationMessage;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* variables and macros
|
* variables and macros
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -149,10 +149,10 @@ static void InvalidationMessageRegisterSharedInvalid(InvalidationMessage message
|
||||||
* ----------------------------------------------------------------
|
* ----------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* InvalidationEntryAllocate
|
* InvalidationEntryAllocate
|
||||||
* Allocates an invalidation entry.
|
* Allocates an invalidation entry.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static InvalidationEntry
|
static InvalidationEntry
|
||||||
InvalidationEntryAllocate(uint16 size)
|
InvalidationEntryAllocate(uint16 size)
|
||||||
|
@ -165,11 +165,11 @@ InvalidationEntryAllocate(uint16 size)
|
||||||
return (Pointer) &entryDataP->userData;
|
return (Pointer) &entryDataP->userData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* LocalInvalidRegister
|
* LocalInvalidRegister
|
||||||
* Link an invalidation entry into a chain of them. Really ugly
|
* Link an invalidation entry into a chain of them. Really ugly
|
||||||
* coding here.
|
* coding here.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static LocalInvalid
|
static LocalInvalid
|
||||||
LocalInvalidRegister(LocalInvalid invalid,
|
LocalInvalidRegister(LocalInvalid invalid,
|
||||||
|
@ -183,11 +183,11 @@ LocalInvalidRegister(LocalInvalid invalid,
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* LocalInvalidInvalidate
|
* LocalInvalidInvalidate
|
||||||
* Processes, then frees all entries in a local cache
|
* Processes, then frees all entries in a local cache
|
||||||
* invalidation list unless freemember parameter is false.
|
* invalidation list unless freemember parameter is false.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
LocalInvalidInvalidate(LocalInvalid invalid,
|
LocalInvalidInvalidate(LocalInvalid invalid,
|
||||||
|
@ -256,9 +256,9 @@ elog(DEBUG, "CacheIdRegisterLocalRollback(%d, %d, [%d, %d])", \
|
||||||
#define CacheIdRegisterLocalRollback_DEBUG1
|
#define CacheIdRegisterLocalRollback_DEBUG1
|
||||||
#endif /* INVALIDDEBUG */
|
#endif /* INVALIDDEBUG */
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* CacheIdRegisterSpecifiedLocalInvalid
|
* CacheIdRegisterSpecifiedLocalInvalid
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static LocalInvalid
|
static LocalInvalid
|
||||||
CacheIdRegisterSpecifiedLocalInvalid(LocalInvalid invalid,
|
CacheIdRegisterSpecifiedLocalInvalid(LocalInvalid invalid,
|
||||||
|
@ -268,16 +268,16 @@ CacheIdRegisterSpecifiedLocalInvalid(LocalInvalid invalid,
|
||||||
{
|
{
|
||||||
InvalidationMessage message;
|
InvalidationMessage message;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* debugging stuff
|
* debugging stuff
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
CacheIdRegisterSpecifiedLocalInvalid_DEBUG1;
|
CacheIdRegisterSpecifiedLocalInvalid_DEBUG1;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* create a message describing the system catalog tuple
|
* create a message describing the system catalog tuple
|
||||||
* we wish to invalidate.
|
* we wish to invalidate.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
message = (InvalidationMessage)
|
message = (InvalidationMessage)
|
||||||
InvalidationEntryAllocate(sizeof(InvalidationMessageData));
|
InvalidationEntryAllocate(sizeof(InvalidationMessageData));
|
||||||
|
@ -288,46 +288,46 @@ CacheIdRegisterSpecifiedLocalInvalid(LocalInvalid invalid,
|
||||||
|
|
||||||
ItemPointerCopy(pointer, &message->any.catalog.pointerData);
|
ItemPointerCopy(pointer, &message->any.catalog.pointerData);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* Add message to linked list of unprocessed messages.
|
* Add message to linked list of unprocessed messages.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
invalid = LocalInvalidRegister(invalid, (InvalidationEntry) message);
|
invalid = LocalInvalidRegister(invalid, (InvalidationEntry) message);
|
||||||
return invalid;
|
return invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* CacheIdRegisterLocalInvalid
|
* CacheIdRegisterLocalInvalid
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
CacheIdRegisterLocalInvalid(int cacheId,
|
CacheIdRegisterLocalInvalid(int cacheId,
|
||||||
Index hashIndex,
|
Index hashIndex,
|
||||||
ItemPointer pointer)
|
ItemPointer pointer)
|
||||||
{
|
{
|
||||||
/* ----------------
|
/*
|
||||||
* debugging stuff
|
* debugging stuff
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
CacheIdRegisterLocalInvalid_DEBUG1;
|
CacheIdRegisterLocalInvalid_DEBUG1;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* Add message to InvalidForall linked list.
|
* Add message to InvalidForall linked list.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
InvalidForall = CacheIdRegisterSpecifiedLocalInvalid(InvalidForall,
|
InvalidForall = CacheIdRegisterSpecifiedLocalInvalid(InvalidForall,
|
||||||
cacheId, hashIndex, pointer);
|
cacheId, hashIndex, pointer);
|
||||||
/* ----------------
|
/*
|
||||||
* Add message to InvalidLocal linked list.
|
* Add message to InvalidLocal linked list.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
InvalidLocal = CacheIdRegisterSpecifiedLocalInvalid(InvalidLocal,
|
InvalidLocal = CacheIdRegisterSpecifiedLocalInvalid(InvalidLocal,
|
||||||
cacheId, hashIndex, pointer);
|
cacheId, hashIndex, pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* CacheIdRegisterLocalRollback
|
* CacheIdRegisterLocalRollback
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
CacheIdRegisterLocalRollback(int cacheId,
|
CacheIdRegisterLocalRollback(int cacheId,
|
||||||
|
@ -335,23 +335,23 @@ CacheIdRegisterLocalRollback(int cacheId,
|
||||||
ItemPointer pointer)
|
ItemPointer pointer)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* debugging stuff
|
* debugging stuff
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
CacheIdRegisterLocalRollback_DEBUG1;
|
CacheIdRegisterLocalRollback_DEBUG1;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* Add message to RollbackStack linked list.
|
* Add message to RollbackStack linked list.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
RollbackStack = CacheIdRegisterSpecifiedLocalInvalid(
|
RollbackStack = CacheIdRegisterSpecifiedLocalInvalid(
|
||||||
RollbackStack, cacheId, hashIndex, pointer);
|
RollbackStack, cacheId, hashIndex, pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationIdRegisterSpecifiedLocalInvalid
|
* RelationIdRegisterSpecifiedLocalInvalid
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static LocalInvalid
|
static LocalInvalid
|
||||||
RelationIdRegisterSpecifiedLocalInvalid(LocalInvalid invalid,
|
RelationIdRegisterSpecifiedLocalInvalid(LocalInvalid invalid,
|
||||||
|
@ -359,19 +359,19 @@ RelationIdRegisterSpecifiedLocalInvalid(LocalInvalid invalid,
|
||||||
{
|
{
|
||||||
InvalidationMessage message;
|
InvalidationMessage message;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* debugging stuff
|
* debugging stuff
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef INVALIDDEBUG
|
#ifdef INVALIDDEBUG
|
||||||
elog(DEBUG, "RelationRegisterSpecifiedLocalInvalid(%u, %u)", relationId,
|
elog(DEBUG, "RelationRegisterSpecifiedLocalInvalid(%u, %u)", relationId,
|
||||||
objectId);
|
objectId);
|
||||||
#endif /* defined(INVALIDDEBUG) */
|
#endif /* defined(INVALIDDEBUG) */
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* create a message describing the relation descriptor
|
* create a message describing the relation descriptor
|
||||||
* we wish to invalidate.
|
* we wish to invalidate.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
message = (InvalidationMessage)
|
message = (InvalidationMessage)
|
||||||
InvalidationEntryAllocate(sizeof(InvalidationMessageData));
|
InvalidationEntryAllocate(sizeof(InvalidationMessageData));
|
||||||
|
@ -380,76 +380,76 @@ RelationIdRegisterSpecifiedLocalInvalid(LocalInvalid invalid,
|
||||||
message->any.relation.relationId = relationId;
|
message->any.relation.relationId = relationId;
|
||||||
message->any.relation.objectId = objectId;
|
message->any.relation.objectId = objectId;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* Add message to linked list of unprocessed messages.
|
* Add message to linked list of unprocessed messages.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
invalid = LocalInvalidRegister(invalid, (InvalidationEntry) message);
|
invalid = LocalInvalidRegister(invalid, (InvalidationEntry) message);
|
||||||
return invalid;
|
return invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationIdRegisterLocalInvalid
|
* RelationIdRegisterLocalInvalid
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
RelationIdRegisterLocalInvalid(Oid relationId, Oid objectId)
|
RelationIdRegisterLocalInvalid(Oid relationId, Oid objectId)
|
||||||
{
|
{
|
||||||
/* ----------------
|
/*
|
||||||
* debugging stuff
|
* debugging stuff
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef INVALIDDEBUG
|
#ifdef INVALIDDEBUG
|
||||||
elog(DEBUG, "RelationRegisterLocalInvalid(%u, %u)", relationId,
|
elog(DEBUG, "RelationRegisterLocalInvalid(%u, %u)", relationId,
|
||||||
objectId);
|
objectId);
|
||||||
#endif /* defined(INVALIDDEBUG) */
|
#endif /* defined(INVALIDDEBUG) */
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* Add message to InvalidForall linked list.
|
* Add message to InvalidForall linked list.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
InvalidForall = RelationIdRegisterSpecifiedLocalInvalid(InvalidForall,
|
InvalidForall = RelationIdRegisterSpecifiedLocalInvalid(InvalidForall,
|
||||||
relationId, objectId);
|
relationId, objectId);
|
||||||
/* ----------------
|
/*
|
||||||
* Add message to InvalidLocal linked list.
|
* Add message to InvalidLocal linked list.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
InvalidLocal = RelationIdRegisterSpecifiedLocalInvalid(InvalidLocal,
|
InvalidLocal = RelationIdRegisterSpecifiedLocalInvalid(InvalidLocal,
|
||||||
relationId, objectId);
|
relationId, objectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationIdRegisterLocalRollback
|
* RelationIdRegisterLocalRollback
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
RelationIdRegisterLocalRollback(Oid relationId, Oid objectId)
|
RelationIdRegisterLocalRollback(Oid relationId, Oid objectId)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* debugging stuff
|
* debugging stuff
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef INVALIDDEBUG
|
#ifdef INVALIDDEBUG
|
||||||
elog(DEBUG, "RelationRegisterLocalRollback(%u, %u)", relationId,
|
elog(DEBUG, "RelationRegisterLocalRollback(%u, %u)", relationId,
|
||||||
objectId);
|
objectId);
|
||||||
#endif /* defined(INVALIDDEBUG) */
|
#endif /* defined(INVALIDDEBUG) */
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* Add message to RollbackStack linked list.
|
* Add message to RollbackStack linked list.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
RollbackStack = RelationIdRegisterSpecifiedLocalInvalid(
|
RollbackStack = RelationIdRegisterSpecifiedLocalInvalid(
|
||||||
RollbackStack, relationId, objectId);
|
RollbackStack, relationId, objectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* CacheIdInvalidate
|
* CacheIdInvalidate
|
||||||
*
|
*
|
||||||
* This routine can invalidate a tuple in a system catalog cache
|
* This routine can invalidate a tuple in a system catalog cache
|
||||||
* or a cached relation descriptor. You pay your money and you
|
* or a cached relation descriptor. You pay your money and you
|
||||||
* take your chances...
|
* take your chances...
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef INVALIDDEBUG
|
#ifdef INVALIDDEBUG
|
||||||
#define CacheIdInvalidate_DEBUG1 \
|
#define CacheIdInvalidate_DEBUG1 \
|
||||||
|
@ -464,10 +464,10 @@ CacheIdInvalidate(Index cacheId,
|
||||||
Index hashIndex,
|
Index hashIndex,
|
||||||
ItemPointer pointer)
|
ItemPointer pointer)
|
||||||
{
|
{
|
||||||
/* ----------------
|
/*
|
||||||
* assume that if the item pointer is valid, then we are
|
* assume that if the item pointer is valid, then we are
|
||||||
* invalidating an item in the specified system catalog cache.
|
* invalidating an item in the specified system catalog cache.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
if (ItemPointerIsValid(pointer))
|
if (ItemPointerIsValid(pointer))
|
||||||
{
|
{
|
||||||
|
@ -477,10 +477,10 @@ CacheIdInvalidate(Index cacheId,
|
||||||
|
|
||||||
CacheIdInvalidate_DEBUG1;
|
CacheIdInvalidate_DEBUG1;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* if the cacheId is the oid of any of the following system relations,
|
* if the cacheId is the oid of any of the following system relations,
|
||||||
* then assume we are invalidating a relation descriptor
|
* then assume we are invalidating a relation descriptor
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
if (cacheId == RelOid_pg_class)
|
if (cacheId == RelOid_pg_class)
|
||||||
{
|
{
|
||||||
|
@ -494,20 +494,20 @@ CacheIdInvalidate(Index cacheId,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* Yow! the caller asked us to invalidate something else.
|
* Yow! the caller asked us to invalidate something else.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
elog(FATAL, "CacheIdInvalidate: cacheId=%d relation id?", cacheId);
|
elog(FATAL, "CacheIdInvalidate: cacheId=%d relation id?", cacheId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* ResetSystemCaches
|
* ResetSystemCaches
|
||||||
*
|
*
|
||||||
* This blows away all tuples in the system catalog caches and
|
* This blows away all tuples in the system catalog caches and
|
||||||
* all the cached relation descriptors (and closes their files too).
|
* all the cached relation descriptors (and closes their files too).
|
||||||
* Relation descriptors that have positive refcounts are then rebuilt.
|
* Relation descriptors that have positive refcounts are then rebuilt.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
ResetSystemCaches(void)
|
ResetSystemCaches(void)
|
||||||
|
@ -516,9 +516,9 @@ ResetSystemCaches(void)
|
||||||
RelationCacheInvalidate();
|
RelationCacheInvalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* InvalidationMessageRegisterSharedInvalid
|
* InvalidationMessageRegisterSharedInvalid
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef INVALIDDEBUG
|
#ifdef INVALIDDEBUG
|
||||||
#define InvalidationMessageRegisterSharedInvalid_DEBUG1 \
|
#define InvalidationMessageRegisterSharedInvalid_DEBUG1 \
|
||||||
|
@ -568,9 +568,9 @@ InvalidationMessageRegisterSharedInvalid(InvalidationMessage message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* InvalidationMessageCacheInvalidate
|
* InvalidationMessageCacheInvalidate
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef INVALIDDEBUG
|
#ifdef INVALIDDEBUG
|
||||||
#define InvalidationMessageCacheInvalidate_DEBUG1 \
|
#define InvalidationMessageCacheInvalidate_DEBUG1 \
|
||||||
|
@ -617,9 +617,9 @@ InvalidationMessageCacheInvalidate(InvalidationMessage message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* PrepareToInvalidateRelationCache
|
* PrepareToInvalidateRelationCache
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
PrepareToInvalidateRelationCache(Relation relation,
|
PrepareToInvalidateRelationCache(Relation relation,
|
||||||
|
@ -629,15 +629,15 @@ PrepareToInvalidateRelationCache(Relation relation,
|
||||||
Oid relationId;
|
Oid relationId;
|
||||||
Oid objectId;
|
Oid objectId;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* get the relation object id
|
* get the relation object id
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
relationId = RelationGetRelid(relation);
|
relationId = RelationGetRelid(relation);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* is it one of the ones we need to send an SI message for?
|
* is it one of the ones we need to send an SI message for?
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
if (relationId == RelOid_pg_class)
|
if (relationId == RelOid_pg_class)
|
||||||
objectId = tuple->t_data->t_oid;
|
objectId = tuple->t_data->t_oid;
|
||||||
|
@ -646,9 +646,9 @@ PrepareToInvalidateRelationCache(Relation relation,
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* register the relcache-invalidation action in the appropriate list
|
* register the relcache-invalidation action in the appropriate list
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
Assert(PointerIsValid(function));
|
Assert(PointerIsValid(function));
|
||||||
|
|
||||||
|
@ -666,9 +666,9 @@ PrepareToInvalidateRelationCache(Relation relation,
|
||||||
void
|
void
|
||||||
DiscardInvalid(void)
|
DiscardInvalid(void)
|
||||||
{
|
{
|
||||||
/* ----------------
|
/*
|
||||||
* debugging stuff
|
* debugging stuff
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef INVALIDDEBUG
|
#ifdef INVALIDDEBUG
|
||||||
elog(DEBUG, "DiscardInvalid called");
|
elog(DEBUG, "DiscardInvalid called");
|
||||||
|
@ -689,17 +689,17 @@ RegisterInvalid(bool send)
|
||||||
{
|
{
|
||||||
LocalInvalid invalid;
|
LocalInvalid invalid;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* debugging stuff
|
* debugging stuff
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef INVALIDDEBUG
|
#ifdef INVALIDDEBUG
|
||||||
elog(DEBUG, "RegisterInvalid(%d) called", send);
|
elog(DEBUG, "RegisterInvalid(%d) called", send);
|
||||||
#endif /* defined(INVALIDDEBUG) */
|
#endif /* defined(INVALIDDEBUG) */
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* Process and free the current list of inval messages.
|
* Process and free the current list of inval messages.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DiscardInvalidStack(&InvalidLocal);
|
DiscardInvalidStack(&InvalidLocal);
|
||||||
|
@ -733,17 +733,17 @@ ImmediateLocalInvalidation(bool send)
|
||||||
{
|
{
|
||||||
LocalInvalid invalid;
|
LocalInvalid invalid;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* debugging stuff
|
* debugging stuff
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef INVALIDDEBUG
|
#ifdef INVALIDDEBUG
|
||||||
elog(DEBUG, "ImmediateLocalInvalidation(%d) called", send);
|
elog(DEBUG, "ImmediateLocalInvalidation(%d) called", send);
|
||||||
#endif /* defined(INVALIDDEBUG) */
|
#endif /* defined(INVALIDDEBUG) */
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* Process and free the local list of inval messages.
|
* Process and free the local list of inval messages.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (send)
|
if (send)
|
||||||
|
@ -792,9 +792,9 @@ PrepareForTupleInvalidation(Relation relation, HeapTuple tuple,
|
||||||
void (*RelationIdRegisterFunc) (Oid, Oid),
|
void (*RelationIdRegisterFunc) (Oid, Oid),
|
||||||
const char *funcname)
|
const char *funcname)
|
||||||
{
|
{
|
||||||
/* ----------------
|
/*
|
||||||
* sanity checks
|
* sanity checks
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
Assert(RelationIsValid(relation));
|
Assert(RelationIsValid(relation));
|
||||||
Assert(HeapTupleIsValid(tuple));
|
Assert(HeapTupleIsValid(tuple));
|
||||||
|
@ -802,18 +802,18 @@ PrepareForTupleInvalidation(Relation relation, HeapTuple tuple,
|
||||||
if (IsBootstrapProcessingMode())
|
if (IsBootstrapProcessingMode())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* We only need to worry about invalidation for tuples that are in
|
* We only need to worry about invalidation for tuples that are in
|
||||||
* system relations; user-relation tuples are never in catcaches
|
* system relations; user-relation tuples are never in catcaches
|
||||||
* and can't affect the relcache either.
|
* and can't affect the relcache either.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
if (!IsSystemRelationName(NameStr(RelationGetForm(relation)->relname)))
|
if (!IsSystemRelationName(NameStr(RelationGetForm(relation)->relname)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* debugging stuff
|
* debugging stuff
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
PrepareForTupleInvalidation_DEBUG1;
|
PrepareForTupleInvalidation_DEBUG1;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.127 2001/01/24 19:43:15 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.128 2001/02/22 18:39:19 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -62,9 +62,9 @@
|
||||||
#include "utils/temprel.h"
|
#include "utils/temprel.h"
|
||||||
|
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* hardcoded tuple descriptors. see lib/backend/catalog/pg_attribute.h
|
* hardcoded tuple descriptors. see lib/backend/catalog/pg_attribute.h
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
static FormData_pg_attribute Desc_pg_class[Natts_pg_class] = {Schema_pg_class};
|
static FormData_pg_attribute Desc_pg_class[Natts_pg_class] = {Schema_pg_class};
|
||||||
static FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = {Schema_pg_attribute};
|
static FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = {Schema_pg_attribute};
|
||||||
|
@ -73,12 +73,12 @@ static FormData_pg_attribute Desc_pg_type[Natts_pg_type] = {Schema_pg_type};
|
||||||
static FormData_pg_attribute Desc_pg_variable[Natts_pg_variable] = {Schema_pg_variable};
|
static FormData_pg_attribute Desc_pg_variable[Natts_pg_variable] = {Schema_pg_variable};
|
||||||
static FormData_pg_attribute Desc_pg_log[Natts_pg_log] = {Schema_pg_log};
|
static FormData_pg_attribute Desc_pg_log[Natts_pg_log] = {Schema_pg_log};
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* Hash tables that index the relation cache
|
* Hash tables that index the relation cache
|
||||||
*
|
*
|
||||||
* Relations are looked up two ways, by name and by id,
|
* Relations are looked up two ways, by name and by id,
|
||||||
* thus there are two hash tables for referencing them.
|
* thus there are two hash tables for referencing them.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
static HTAB *RelationNameCache;
|
static HTAB *RelationNameCache;
|
||||||
static HTAB *RelationIdCache;
|
static HTAB *RelationIdCache;
|
||||||
|
@ -104,10 +104,10 @@ static List *newlyCreatedRelns = NULL;
|
||||||
static bool criticalRelcachesBuilt = false;
|
static bool criticalRelcachesBuilt = false;
|
||||||
|
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* RelationBuildDescInfo exists so code can be shared
|
* RelationBuildDescInfo exists so code can be shared
|
||||||
* between RelationIdGetRelation() and RelationNameGetRelation()
|
* between RelationIdGetRelation() and RelationNameGetRelation()
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct RelationBuildDescInfo
|
typedef struct RelationBuildDescInfo
|
||||||
{
|
{
|
||||||
|
@ -139,9 +139,9 @@ typedef struct relnodecacheent
|
||||||
Relation reldesc;
|
Relation reldesc;
|
||||||
} RelNodeCacheEnt;
|
} RelNodeCacheEnt;
|
||||||
|
|
||||||
/* -----------------
|
/*
|
||||||
* macros to manipulate name cache and id cache
|
* macros to manipulate name cache and id cache
|
||||||
* -----------------
|
*
|
||||||
*/
|
*/
|
||||||
#define RelationCacheInsert(RELATION) \
|
#define RelationCacheInsert(RELATION) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -282,14 +282,14 @@ static void RelCheckFetch(Relation relation);
|
||||||
static List *insert_ordered_oid(List *list, Oid datum);
|
static List *insert_ordered_oid(List *list, Oid datum);
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/*
|
||||||
* RelationIdGetRelation() and RelationNameGetRelation()
|
* RelationIdGetRelation() and RelationNameGetRelation()
|
||||||
* support functions
|
* support functions
|
||||||
* ----------------------------------------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* ScanPgRelation
|
* ScanPgRelation
|
||||||
*
|
*
|
||||||
* this is used by RelationBuildDesc to find a pg_class
|
* this is used by RelationBuildDesc to find a pg_class
|
||||||
|
@ -298,7 +298,7 @@ static List *insert_ordered_oid(List *list, Oid datum);
|
||||||
*
|
*
|
||||||
* NB: the returned tuple has been copied into palloc'd storage
|
* NB: the returned tuple has been copied into palloc'd storage
|
||||||
* and must eventually be freed with heap_freetuple.
|
* and must eventually be freed with heap_freetuple.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static HeapTuple
|
static HeapTuple
|
||||||
ScanPgRelation(RelationBuildDescInfo buildinfo)
|
ScanPgRelation(RelationBuildDescInfo buildinfo)
|
||||||
|
@ -325,9 +325,9 @@ scan_pg_rel_seq(RelationBuildDescInfo buildinfo)
|
||||||
HeapScanDesc pg_class_scan;
|
HeapScanDesc pg_class_scan;
|
||||||
ScanKeyData key;
|
ScanKeyData key;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* form a scan key
|
* form a scan key
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
switch (buildinfo.infotype)
|
switch (buildinfo.infotype)
|
||||||
{
|
{
|
||||||
|
@ -350,28 +350,28 @@ scan_pg_rel_seq(RelationBuildDescInfo buildinfo)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* open pg_class and fetch a tuple
|
* open pg_class and fetch a tuple
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
pg_class_desc = heap_openr(RelationRelationName, AccessShareLock);
|
pg_class_desc = heap_openr(RelationRelationName, AccessShareLock);
|
||||||
pg_class_scan = heap_beginscan(pg_class_desc, 0, SnapshotNow, 1, &key);
|
pg_class_scan = heap_beginscan(pg_class_desc, 0, SnapshotNow, 1, &key);
|
||||||
pg_class_tuple = heap_getnext(pg_class_scan, 0);
|
pg_class_tuple = heap_getnext(pg_class_scan, 0);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* get set to return tuple
|
* get set to return tuple
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
if (!HeapTupleIsValid(pg_class_tuple))
|
if (!HeapTupleIsValid(pg_class_tuple))
|
||||||
return_tuple = pg_class_tuple;
|
return_tuple = pg_class_tuple;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* ------------------
|
/*
|
||||||
* a satanic bug used to live here: pg_class_tuple used to be
|
* a satanic bug used to live here: pg_class_tuple used to be
|
||||||
* returned here without having the corresponding buffer pinned.
|
* returned here without having the corresponding buffer pinned.
|
||||||
* so when the buffer gets replaced, all hell breaks loose.
|
* so when the buffer gets replaced, all hell breaks loose.
|
||||||
* this bug is discovered and killed by wei on 9/27/91.
|
* this bug is discovered and killed by wei on 9/27/91.
|
||||||
* -------------------
|
*
|
||||||
*/
|
*/
|
||||||
return_tuple = heap_copytuple(pg_class_tuple);
|
return_tuple = heap_copytuple(pg_class_tuple);
|
||||||
}
|
}
|
||||||
|
@ -424,7 +424,7 @@ scan_pg_rel_ind(RelationBuildDescInfo buildinfo)
|
||||||
return return_tuple;
|
return return_tuple;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* AllocateRelationDesc
|
* AllocateRelationDesc
|
||||||
*
|
*
|
||||||
* This is used to allocate memory for a new relation descriptor
|
* This is used to allocate memory for a new relation descriptor
|
||||||
|
@ -433,7 +433,7 @@ scan_pg_rel_ind(RelationBuildDescInfo buildinfo)
|
||||||
* If 'relation' is NULL, allocate a new RelationData object.
|
* If 'relation' is NULL, allocate a new RelationData object.
|
||||||
* If not, reuse the given object (that path is taken only when
|
* If not, reuse the given object (that path is taken only when
|
||||||
* we have to rebuild a relcache entry during RelationClearRelation).
|
* we have to rebuild a relcache entry during RelationClearRelation).
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
static Relation
|
static Relation
|
||||||
AllocateRelationDesc(Relation relation, Form_pg_class relp)
|
AllocateRelationDesc(Relation relation, Form_pg_class relp)
|
||||||
|
@ -444,23 +444,23 @@ AllocateRelationDesc(Relation relation, Form_pg_class relp)
|
||||||
/* Relcache entries must live in CacheMemoryContext */
|
/* Relcache entries must live in CacheMemoryContext */
|
||||||
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
|
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* allocate space for new relation descriptor, if needed
|
* allocate space for new relation descriptor, if needed
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
if (relation == NULL)
|
if (relation == NULL)
|
||||||
relation = (Relation) palloc(sizeof(RelationData));
|
relation = (Relation) palloc(sizeof(RelationData));
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* clear all fields of reldesc
|
* clear all fields of reldesc
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
MemSet((char *) relation, 0, sizeof(RelationData));
|
MemSet((char *) relation, 0, sizeof(RelationData));
|
||||||
|
|
||||||
/* make sure relation is marked as having no open file yet */
|
/* make sure relation is marked as having no open file yet */
|
||||||
relation->rd_fd = -1;
|
relation->rd_fd = -1;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* Copy the relation tuple form
|
* Copy the relation tuple form
|
||||||
*
|
*
|
||||||
* We only allocate space for the fixed fields, ie, CLASS_TUPLE_SIZE.
|
* We only allocate space for the fixed fields, ie, CLASS_TUPLE_SIZE.
|
||||||
|
@ -469,7 +469,7 @@ AllocateRelationDesc(Relation relation, Form_pg_class relp)
|
||||||
* wouldn't know if the value is valid ... bottom line is that relacl
|
* wouldn't know if the value is valid ... bottom line is that relacl
|
||||||
* *cannot* be retrieved from the relcache. Get it from the syscache
|
* *cannot* be retrieved from the relcache. Get it from the syscache
|
||||||
* if you need it.
|
* if you need it.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
relationForm = (Form_pg_class) palloc(CLASS_TUPLE_SIZE);
|
relationForm = (Form_pg_class) palloc(CLASS_TUPLE_SIZE);
|
||||||
|
|
||||||
|
@ -486,12 +486,12 @@ AllocateRelationDesc(Relation relation, Form_pg_class relp)
|
||||||
return relation;
|
return relation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationBuildTupleDesc
|
* RelationBuildTupleDesc
|
||||||
*
|
*
|
||||||
* Form the relation's tuple descriptor from information in
|
* Form the relation's tuple descriptor from information in
|
||||||
* the pg_attribute, pg_attrdef & pg_relcheck system cataloges.
|
* the pg_attribute, pg_attrdef & pg_relcheck system cataloges.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
|
RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
|
||||||
|
@ -570,25 +570,25 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
|
||||||
sizeof(TupleConstr));
|
sizeof(TupleConstr));
|
||||||
constr->has_not_null = false;
|
constr->has_not_null = false;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* form a scan key
|
* form a scan key
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyEntryInitialize(&key, 0,
|
||||||
Anum_pg_attribute_attrelid,
|
Anum_pg_attribute_attrelid,
|
||||||
F_OIDEQ,
|
F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelationGetRelid(relation)));
|
ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* open pg_attribute and begin a scan
|
* open pg_attribute and begin a scan
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
pg_attribute_desc = heap_openr(AttributeRelationName, AccessShareLock);
|
pg_attribute_desc = heap_openr(AttributeRelationName, AccessShareLock);
|
||||||
pg_attribute_scan = heap_beginscan(pg_attribute_desc, 0, SnapshotNow, 1, &key);
|
pg_attribute_scan = heap_beginscan(pg_attribute_desc, 0, SnapshotNow, 1, &key);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* add attribute data to relation->rd_att
|
* add attribute data to relation->rd_att
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
need = relation->rd_rel->relnatts;
|
need = relation->rd_rel->relnatts;
|
||||||
|
|
||||||
|
@ -635,18 +635,18 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
|
||||||
elog(ERROR, "catalog is missing %d attribute%s for relid %u",
|
elog(ERROR, "catalog is missing %d attribute%s for relid %u",
|
||||||
need, (need == 1 ? "" : "s"), RelationGetRelid(relation));
|
need, (need == 1 ? "" : "s"), RelationGetRelid(relation));
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* end the scan and close the attribute relation
|
* end the scan and close the attribute relation
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
heap_endscan(pg_attribute_scan);
|
heap_endscan(pg_attribute_scan);
|
||||||
heap_close(pg_attribute_desc, AccessShareLock);
|
heap_close(pg_attribute_desc, AccessShareLock);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* The attcacheoff values we read from pg_attribute should all be -1
|
* The attcacheoff values we read from pg_attribute should all be -1
|
||||||
* ("unknown"). Verify this if assert checking is on. They will be
|
* ("unknown"). Verify this if assert checking is on. They will be
|
||||||
* computed when and if needed during tuple access.
|
* computed when and if needed during tuple access.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef USE_ASSERT_CHECKING
|
#ifdef USE_ASSERT_CHECKING
|
||||||
{
|
{
|
||||||
|
@ -659,12 +659,12 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* However, we can easily set the attcacheoff value for the first
|
* However, we can easily set the attcacheoff value for the first
|
||||||
* attribute: it must be zero. This eliminates the need for special
|
* attribute: it must be zero. This eliminates the need for special
|
||||||
* cases for attnum=1 that used to exist in fastgetattr() and
|
* cases for attnum=1 that used to exist in fastgetattr() and
|
||||||
* index_getattr().
|
* index_getattr().
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
relation->rd_att->attrs[0]->attcacheoff = 0;
|
relation->rd_att->attrs[0]->attcacheoff = 0;
|
||||||
|
|
||||||
|
@ -753,11 +753,11 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
|
||||||
|
|
||||||
heap_close(attrel, AccessShareLock);
|
heap_close(attrel, AccessShareLock);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* The attcacheoff values we read from pg_attribute should all be -1
|
* The attcacheoff values we read from pg_attribute should all be -1
|
||||||
* ("unknown"). Verify this if assert checking is on. They will be
|
* ("unknown"). Verify this if assert checking is on. They will be
|
||||||
* computed when and if needed during tuple access.
|
* computed when and if needed during tuple access.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef USE_ASSERT_CHECKING
|
#ifdef USE_ASSERT_CHECKING
|
||||||
for (i = 0; i < relation->rd_rel->relnatts; i++)
|
for (i = 0; i < relation->rd_rel->relnatts; i++)
|
||||||
|
@ -766,19 +766,19 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* However, we can easily set the attcacheoff value for the first
|
* However, we can easily set the attcacheoff value for the first
|
||||||
* attribute: it must be zero. This eliminates the need for special
|
* attribute: it must be zero. This eliminates the need for special
|
||||||
* cases for attnum=1 that used to exist in fastgetattr() and
|
* cases for attnum=1 that used to exist in fastgetattr() and
|
||||||
* index_getattr().
|
* index_getattr().
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
relation->rd_att->attrs[0]->attcacheoff = 0;
|
relation->rd_att->attrs[0]->attcacheoff = 0;
|
||||||
|
|
||||||
SetConstrOfRelation(relation, constr, ndef, attrdef);
|
SetConstrOfRelation(relation, constr, ndef, attrdef);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationBuildRuleLock
|
* RelationBuildRuleLock
|
||||||
*
|
*
|
||||||
* Form the relation's rewrite rules from information in
|
* Form the relation's rewrite rules from information in
|
||||||
|
@ -792,7 +792,7 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
|
||||||
* entry, because that keeps the update logic in RelationClearRelation()
|
* entry, because that keeps the update logic in RelationClearRelation()
|
||||||
* manageable. The other subsidiary data structures are simple enough
|
* manageable. The other subsidiary data structures are simple enough
|
||||||
* to be easy to free explicitly, anyway.
|
* to be easy to free explicitly, anyway.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
RelationBuildRuleLock(Relation relation)
|
RelationBuildRuleLock(Relation relation)
|
||||||
|
@ -820,28 +820,28 @@ RelationBuildRuleLock(Relation relation)
|
||||||
1024); /* maxsize */
|
1024); /* maxsize */
|
||||||
relation->rd_rulescxt = rulescxt;
|
relation->rd_rulescxt = rulescxt;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* form an array to hold the rewrite rules (the array is extended if
|
* form an array to hold the rewrite rules (the array is extended if
|
||||||
* necessary)
|
* necessary)
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
maxlocks = 4;
|
maxlocks = 4;
|
||||||
rules = (RewriteRule **)
|
rules = (RewriteRule **)
|
||||||
MemoryContextAlloc(rulescxt, sizeof(RewriteRule *) * maxlocks);
|
MemoryContextAlloc(rulescxt, sizeof(RewriteRule *) * maxlocks);
|
||||||
numlocks = 0;
|
numlocks = 0;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* form a scan key
|
* form a scan key
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyEntryInitialize(&key, 0,
|
||||||
Anum_pg_rewrite_ev_class,
|
Anum_pg_rewrite_ev_class,
|
||||||
F_OIDEQ,
|
F_OIDEQ,
|
||||||
ObjectIdGetDatum(RelationGetRelid(relation)));
|
ObjectIdGetDatum(RelationGetRelid(relation)));
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* open pg_rewrite and begin a scan
|
* open pg_rewrite and begin a scan
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
pg_rewrite_desc = heap_openr(RewriteRelationName, AccessShareLock);
|
pg_rewrite_desc = heap_openr(RewriteRelationName, AccessShareLock);
|
||||||
pg_rewrite_scan = heap_beginscan(pg_rewrite_desc, 0, SnapshotNow, 1, &key);
|
pg_rewrite_scan = heap_beginscan(pg_rewrite_desc, 0, SnapshotNow, 1, &key);
|
||||||
|
@ -907,16 +907,16 @@ RelationBuildRuleLock(Relation relation)
|
||||||
rules[numlocks++] = rule;
|
rules[numlocks++] = rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* end the scan and close the attribute relation
|
* end the scan and close the attribute relation
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
heap_endscan(pg_rewrite_scan);
|
heap_endscan(pg_rewrite_scan);
|
||||||
heap_close(pg_rewrite_desc, AccessShareLock);
|
heap_close(pg_rewrite_desc, AccessShareLock);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* form a RuleLock and insert into relation
|
* form a RuleLock and insert into relation
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
rulelock = (RuleLock *) MemoryContextAlloc(rulescxt, sizeof(RuleLock));
|
rulelock = (RuleLock *) MemoryContextAlloc(rulescxt, sizeof(RuleLock));
|
||||||
rulelock->numLocks = numlocks;
|
rulelock->numLocks = numlocks;
|
||||||
|
@ -925,13 +925,13 @@ RelationBuildRuleLock(Relation relation)
|
||||||
relation->rd_rules = rulelock;
|
relation->rd_rules = rulelock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* equalRuleLocks
|
* equalRuleLocks
|
||||||
*
|
*
|
||||||
* Determine whether two RuleLocks are equivalent
|
* Determine whether two RuleLocks are equivalent
|
||||||
*
|
*
|
||||||
* Probably this should be in the rules code someplace...
|
* Probably this should be in the rules code someplace...
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
equalRuleLocks(RuleLock *rlock1, RuleLock *rlock2)
|
equalRuleLocks(RuleLock *rlock1, RuleLock *rlock2)
|
||||||
|
@ -982,7 +982,7 @@ equalRuleLocks(RuleLock *rlock1, RuleLock *rlock2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------
|
/* ----------------------------------
|
||||||
* RelationBuildDesc
|
* RelationBuildDesc
|
||||||
*
|
*
|
||||||
* Build a relation descriptor --- either a new one, or by
|
* Build a relation descriptor --- either a new one, or by
|
||||||
|
@ -1021,75 +1021,75 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
|
||||||
Form_pg_class relp;
|
Form_pg_class relp;
|
||||||
MemoryContext oldcxt;
|
MemoryContext oldcxt;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* find the tuple in pg_class corresponding to the given relation id
|
* find the tuple in pg_class corresponding to the given relation id
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
pg_class_tuple = ScanPgRelation(buildinfo);
|
pg_class_tuple = ScanPgRelation(buildinfo);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* if no such tuple exists, return NULL
|
* if no such tuple exists, return NULL
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
if (!HeapTupleIsValid(pg_class_tuple))
|
if (!HeapTupleIsValid(pg_class_tuple))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* get information from the pg_class_tuple
|
* get information from the pg_class_tuple
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
relid = pg_class_tuple->t_data->t_oid;
|
relid = pg_class_tuple->t_data->t_oid;
|
||||||
relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
|
relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* allocate storage for the relation descriptor,
|
* allocate storage for the relation descriptor,
|
||||||
* and copy pg_class_tuple to relation->rd_rel.
|
* and copy pg_class_tuple to relation->rd_rel.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
relation = AllocateRelationDesc(oldrelation, relp);
|
relation = AllocateRelationDesc(oldrelation, relp);
|
||||||
|
|
||||||
/* -------------------
|
/*
|
||||||
* now we can free the memory allocated for pg_class_tuple
|
* now we can free the memory allocated for pg_class_tuple
|
||||||
* -------------------
|
*
|
||||||
*/
|
*/
|
||||||
heap_freetuple(pg_class_tuple);
|
heap_freetuple(pg_class_tuple);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize the relation's relation id (relation->rd_id)
|
* initialize the relation's relation id (relation->rd_id)
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
RelationGetRelid(relation) = relid;
|
RelationGetRelid(relation) = relid;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize relation->rd_refcnt
|
* initialize relation->rd_refcnt
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
RelationSetReferenceCount(relation, 1);
|
RelationSetReferenceCount(relation, 1);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* normal relations are not nailed into the cache
|
* normal relations are not nailed into the cache
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
relation->rd_isnailed = false;
|
relation->rd_isnailed = false;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize the access method information (relation->rd_am)
|
* initialize the access method information (relation->rd_am)
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
relam = relation->rd_rel->relam;
|
relam = relation->rd_rel->relam;
|
||||||
if (OidIsValid(relam))
|
if (OidIsValid(relam))
|
||||||
relation->rd_am = AccessMethodObjectIdGetForm(relam,
|
relation->rd_am = AccessMethodObjectIdGetForm(relam,
|
||||||
CacheMemoryContext);
|
CacheMemoryContext);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize the tuple descriptor (relation->rd_att).
|
* initialize the tuple descriptor (relation->rd_att).
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
RelationBuildTupleDesc(buildinfo, relation);
|
RelationBuildTupleDesc(buildinfo, relation);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* Fetch rules and triggers that affect this relation
|
* Fetch rules and triggers that affect this relation
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
if (relation->rd_rel->relhasrules)
|
if (relation->rd_rel->relhasrules)
|
||||||
RelationBuildRuleLock(relation);
|
RelationBuildRuleLock(relation);
|
||||||
|
@ -1104,16 +1104,16 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
|
||||||
else
|
else
|
||||||
relation->trigdesc = NULL;
|
relation->trigdesc = NULL;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize index strategy and support information for this relation
|
* initialize index strategy and support information for this relation
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
if (OidIsValid(relam))
|
if (OidIsValid(relam))
|
||||||
IndexedAccessMethodInitialize(relation);
|
IndexedAccessMethodInitialize(relation);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize the relation lock manager information
|
* initialize the relation lock manager information
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
RelationInitLockInfo(relation); /* see lmgr.c */
|
RelationInitLockInfo(relation); /* see lmgr.c */
|
||||||
|
|
||||||
|
@ -1123,20 +1123,20 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
|
||||||
relation->rd_node.tblNode = MyDatabaseId;
|
relation->rd_node.tblNode = MyDatabaseId;
|
||||||
relation->rd_node.relNode = relation->rd_rel->relfilenode;
|
relation->rd_node.relNode = relation->rd_rel->relfilenode;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* open the relation and assign the file descriptor returned
|
* open the relation and assign the file descriptor returned
|
||||||
* by the storage manager code to rd_fd.
|
* by the storage manager code to rd_fd.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
if (relation->rd_rel->relkind != RELKIND_VIEW)
|
if (relation->rd_rel->relkind != RELKIND_VIEW)
|
||||||
relation->rd_fd = smgropen(DEFAULT_SMGR, relation, false);
|
relation->rd_fd = smgropen(DEFAULT_SMGR, relation, false);
|
||||||
else
|
else
|
||||||
relation->rd_fd = -1;
|
relation->rd_fd = -1;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* insert newly created relation into proper relcaches,
|
* insert newly created relation into proper relcaches,
|
||||||
* restore memory context and return the new reldesc.
|
* restore memory context and return the new reldesc.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
|
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
|
||||||
RelationCacheInsert(relation);
|
RelationCacheInsert(relation);
|
||||||
|
@ -1181,7 +1181,7 @@ IndexedAccessMethodInitialize(Relation relation)
|
||||||
RelationSetIndexSupport(relation, strategy, support);
|
RelationSetIndexSupport(relation, strategy, support);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* formrdesc
|
* formrdesc
|
||||||
*
|
*
|
||||||
* This is a special cut-down version of RelationBuildDesc()
|
* This is a special cut-down version of RelationBuildDesc()
|
||||||
|
@ -1192,7 +1192,7 @@ IndexedAccessMethodInitialize(Relation relation)
|
||||||
* catalogs...
|
* catalogs...
|
||||||
*
|
*
|
||||||
* NOTE: we assume we are already switched into CacheMemoryContext.
|
* NOTE: we assume we are already switched into CacheMemoryContext.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
formrdesc(char *relationName,
|
formrdesc(char *relationName,
|
||||||
|
@ -1202,38 +1202,38 @@ formrdesc(char *relationName,
|
||||||
Relation relation;
|
Relation relation;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* allocate new relation desc
|
* allocate new relation desc
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
relation = (Relation) palloc(sizeof(RelationData));
|
relation = (Relation) palloc(sizeof(RelationData));
|
||||||
MemSet((char *) relation, 0, sizeof(RelationData));
|
MemSet((char *) relation, 0, sizeof(RelationData));
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* don't open the unix file yet..
|
* don't open the unix file yet..
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
relation->rd_fd = -1;
|
relation->rd_fd = -1;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize reference count
|
* initialize reference count
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
RelationSetReferenceCount(relation, 1);
|
RelationSetReferenceCount(relation, 1);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* all entries built with this routine are nailed-in-cache
|
* all entries built with this routine are nailed-in-cache
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
relation->rd_isnailed = true;
|
relation->rd_isnailed = true;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize relation tuple form
|
* initialize relation tuple form
|
||||||
*
|
*
|
||||||
* The data we insert here is pretty incomplete/bogus, but it'll
|
* The data we insert here is pretty incomplete/bogus, but it'll
|
||||||
* serve to get us launched. RelationCacheInitializePhase2() will
|
* serve to get us launched. RelationCacheInitializePhase2() will
|
||||||
* read the real data from pg_class and replace what we've done here.
|
* read the real data from pg_class and replace what we've done here.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
relation->rd_rel = (Form_pg_class) palloc(CLASS_TUPLE_SIZE);
|
relation->rd_rel = (Form_pg_class) palloc(CLASS_TUPLE_SIZE);
|
||||||
MemSet(relation->rd_rel, 0, CLASS_TUPLE_SIZE);
|
MemSet(relation->rd_rel, 0, CLASS_TUPLE_SIZE);
|
||||||
|
@ -1256,15 +1256,15 @@ formrdesc(char *relationName,
|
||||||
relation->rd_rel->relkind = RELKIND_RELATION;
|
relation->rd_rel->relkind = RELKIND_RELATION;
|
||||||
relation->rd_rel->relnatts = (int16) natts;
|
relation->rd_rel->relnatts = (int16) natts;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize attribute tuple form
|
* initialize attribute tuple form
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
relation->rd_att = CreateTemplateTupleDesc(natts);
|
relation->rd_att = CreateTemplateTupleDesc(natts);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize tuple desc info
|
* initialize tuple desc info
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < natts; i++)
|
for (i = 0; i < natts; i++)
|
||||||
{
|
{
|
||||||
|
@ -1274,15 +1274,15 @@ formrdesc(char *relationName,
|
||||||
ATTRIBUTE_TUPLE_SIZE);
|
ATTRIBUTE_TUPLE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize relation id
|
* initialize relation id
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
RelationGetRelid(relation) = relation->rd_att->attrs[0]->attrelid;
|
RelationGetRelid(relation) = relation->rd_att->attrs[0]->attrelid;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize the relation's lock manager and RelFileNode information
|
* initialize the relation's lock manager and RelFileNode information
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
RelationInitLockInfo(relation); /* see lmgr.c */
|
RelationInitLockInfo(relation); /* see lmgr.c */
|
||||||
|
|
||||||
|
@ -1293,9 +1293,9 @@ formrdesc(char *relationName,
|
||||||
relation->rd_node.relNode =
|
relation->rd_node.relNode =
|
||||||
relation->rd_rel->relfilenode = RelationGetRelid(relation);
|
relation->rd_rel->relfilenode = RelationGetRelid(relation);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize the rel-has-index flag, using hardwired knowledge
|
* initialize the rel-has-index flag, using hardwired knowledge
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
relation->rd_rel->relhasindex = false;
|
relation->rd_rel->relhasindex = false;
|
||||||
|
|
||||||
|
@ -1312,20 +1312,20 @@ formrdesc(char *relationName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* add new reldesc to relcache
|
* add new reldesc to relcache
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
RelationCacheInsert(relation);
|
RelationCacheInsert(relation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* fixrdesc
|
* fixrdesc
|
||||||
*
|
*
|
||||||
* Update the phony data inserted by formrdesc() with real info
|
* Update the phony data inserted by formrdesc() with real info
|
||||||
* from pg_class.
|
* from pg_class.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
fixrdesc(char *relationName)
|
fixrdesc(char *relationName)
|
||||||
|
@ -1335,9 +1335,9 @@ fixrdesc(char *relationName)
|
||||||
Form_pg_class relp;
|
Form_pg_class relp;
|
||||||
Relation relation;
|
Relation relation;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* find the tuple in pg_class corresponding to the given relation name
|
* find the tuple in pg_class corresponding to the given relation name
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
buildinfo.infotype = INFO_RELNAME;
|
buildinfo.infotype = INFO_RELNAME;
|
||||||
buildinfo.i.info_name = relationName;
|
buildinfo.i.info_name = relationName;
|
||||||
|
@ -1349,19 +1349,19 @@ fixrdesc(char *relationName)
|
||||||
relationName);
|
relationName);
|
||||||
relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
|
relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* find the pre-made relcache entry (better be there!)
|
* find the pre-made relcache entry (better be there!)
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
relation = RelationNameCacheGetRelation(relationName);
|
relation = RelationNameCacheGetRelation(relationName);
|
||||||
if (!RelationIsValid(relation))
|
if (!RelationIsValid(relation))
|
||||||
elog(FATAL, "fixrdesc: no existing relcache entry for %s",
|
elog(FATAL, "fixrdesc: no existing relcache entry for %s",
|
||||||
relationName);
|
relationName);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* and copy pg_class_tuple to relation->rd_rel.
|
* and copy pg_class_tuple to relation->rd_rel.
|
||||||
* (See notes in AllocateRelationDesc())
|
* (See notes in AllocateRelationDesc())
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
Assert(relation->rd_rel != NULL);
|
Assert(relation->rd_rel != NULL);
|
||||||
memcpy((char *) relation->rd_rel, (char *) relp, CLASS_TUPLE_SIZE);
|
memcpy((char *) relation->rd_rel, (char *) relp, CLASS_TUPLE_SIZE);
|
||||||
|
@ -1375,7 +1375,7 @@ fixrdesc(char *relationName)
|
||||||
* ----------------------------------------------------------------
|
* ----------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationIdCacheGetRelation
|
* RelationIdCacheGetRelation
|
||||||
*
|
*
|
||||||
* Lookup an existing reldesc by OID.
|
* Lookup an existing reldesc by OID.
|
||||||
|
@ -1386,7 +1386,7 @@ fixrdesc(char *relationName)
|
||||||
* NB: relation ref count is incremented if successful.
|
* NB: relation ref count is incremented if successful.
|
||||||
* Caller should eventually decrement count. (Usually,
|
* Caller should eventually decrement count. (Usually,
|
||||||
* that happens by calling RelationClose().)
|
* that happens by calling RelationClose().)
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
Relation
|
Relation
|
||||||
RelationIdCacheGetRelation(Oid relationId)
|
RelationIdCacheGetRelation(Oid relationId)
|
||||||
|
@ -1407,11 +1407,11 @@ RelationIdCacheGetRelation(Oid relationId)
|
||||||
return rd;
|
return rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationNameCacheGetRelation
|
* RelationNameCacheGetRelation
|
||||||
*
|
*
|
||||||
* As above, but lookup by name.
|
* As above, but lookup by name.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static Relation
|
static Relation
|
||||||
RelationNameCacheGetRelation(const char *relationName)
|
RelationNameCacheGetRelation(const char *relationName)
|
||||||
|
@ -1457,7 +1457,7 @@ RelationNodeCacheGetRelation(RelFileNode rnode)
|
||||||
return rd;
|
return rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationIdGetRelation
|
* RelationIdGetRelation
|
||||||
*
|
*
|
||||||
* Lookup a reldesc by OID; make one if not already in cache.
|
* Lookup a reldesc by OID; make one if not already in cache.
|
||||||
|
@ -1465,7 +1465,7 @@ RelationNodeCacheGetRelation(RelFileNode rnode)
|
||||||
* NB: relation ref count is incremented, or set to 1 if new entry.
|
* NB: relation ref count is incremented, or set to 1 if new entry.
|
||||||
* Caller should eventually decrement count. (Usually,
|
* Caller should eventually decrement count. (Usually,
|
||||||
* that happens by calling RelationClose().)
|
* that happens by calling RelationClose().)
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
Relation
|
Relation
|
||||||
RelationIdGetRelation(Oid relationId)
|
RelationIdGetRelation(Oid relationId)
|
||||||
|
@ -1473,25 +1473,25 @@ RelationIdGetRelation(Oid relationId)
|
||||||
Relation rd;
|
Relation rd;
|
||||||
RelationBuildDescInfo buildinfo;
|
RelationBuildDescInfo buildinfo;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* increment access statistics
|
* increment access statistics
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
IncrHeapAccessStat(local_RelationIdGetRelation);
|
IncrHeapAccessStat(local_RelationIdGetRelation);
|
||||||
IncrHeapAccessStat(global_RelationIdGetRelation);
|
IncrHeapAccessStat(global_RelationIdGetRelation);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* first try and get a reldesc from the cache
|
* first try and get a reldesc from the cache
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
rd = RelationIdCacheGetRelation(relationId);
|
rd = RelationIdCacheGetRelation(relationId);
|
||||||
if (RelationIsValid(rd))
|
if (RelationIsValid(rd))
|
||||||
return rd;
|
return rd;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* no reldesc in the cache, so have RelationBuildDesc()
|
* no reldesc in the cache, so have RelationBuildDesc()
|
||||||
* build one and add it.
|
* build one and add it.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
buildinfo.infotype = INFO_RELID;
|
buildinfo.infotype = INFO_RELID;
|
||||||
buildinfo.i.info_id = relationId;
|
buildinfo.i.info_id = relationId;
|
||||||
|
@ -1500,11 +1500,11 @@ RelationIdGetRelation(Oid relationId)
|
||||||
return rd;
|
return rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationNameGetRelation
|
* RelationNameGetRelation
|
||||||
*
|
*
|
||||||
* As above, but lookup by name.
|
* As above, but lookup by name.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
Relation
|
Relation
|
||||||
RelationNameGetRelation(const char *relationName)
|
RelationNameGetRelation(const char *relationName)
|
||||||
|
@ -1513,34 +1513,34 @@ RelationNameGetRelation(const char *relationName)
|
||||||
Relation rd;
|
Relation rd;
|
||||||
RelationBuildDescInfo buildinfo;
|
RelationBuildDescInfo buildinfo;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* increment access statistics
|
* increment access statistics
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
IncrHeapAccessStat(local_RelationNameGetRelation);
|
IncrHeapAccessStat(local_RelationNameGetRelation);
|
||||||
IncrHeapAccessStat(global_RelationNameGetRelation);
|
IncrHeapAccessStat(global_RelationNameGetRelation);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* if caller is looking for a temp relation, substitute its real name;
|
* if caller is looking for a temp relation, substitute its real name;
|
||||||
* we only index temp rels by their real names.
|
* we only index temp rels by their real names.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
temprelname = get_temp_rel_by_username(relationName);
|
temprelname = get_temp_rel_by_username(relationName);
|
||||||
if (temprelname != NULL)
|
if (temprelname != NULL)
|
||||||
relationName = temprelname;
|
relationName = temprelname;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* first try and get a reldesc from the cache
|
* first try and get a reldesc from the cache
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
rd = RelationNameCacheGetRelation(relationName);
|
rd = RelationNameCacheGetRelation(relationName);
|
||||||
if (RelationIsValid(rd))
|
if (RelationIsValid(rd))
|
||||||
return rd;
|
return rd;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* no reldesc in the cache, so have RelationBuildDesc()
|
* no reldesc in the cache, so have RelationBuildDesc()
|
||||||
* build one and add it.
|
* build one and add it.
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
buildinfo.infotype = INFO_RELNAME;
|
buildinfo.infotype = INFO_RELNAME;
|
||||||
buildinfo.i.info_name = (char *) relationName;
|
buildinfo.i.info_name = (char *) relationName;
|
||||||
|
@ -1554,7 +1554,7 @@ RelationNameGetRelation(const char *relationName)
|
||||||
* ----------------------------------------------------------------
|
* ----------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationClose - close an open relation
|
* RelationClose - close an open relation
|
||||||
*
|
*
|
||||||
* Actually, we just decrement the refcount.
|
* Actually, we just decrement the refcount.
|
||||||
|
@ -1564,7 +1564,7 @@ RelationNameGetRelation(const char *relationName)
|
||||||
* with aset.c's CLOBBER_FREED_MEMORY option, this provides a good test
|
* with aset.c's CLOBBER_FREED_MEMORY option, this provides a good test
|
||||||
* to catch references to already-released relcache entries. It slows
|
* to catch references to already-released relcache entries. It slows
|
||||||
* things down quite a bit, however.
|
* things down quite a bit, however.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
RelationClose(Relation relation)
|
RelationClose(Relation relation)
|
||||||
|
@ -1579,13 +1579,13 @@ RelationClose(Relation relation)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_REINDEX_NAILED_RELATIONS
|
#ifdef ENABLE_REINDEX_NAILED_RELATIONS
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationReloadClassinfo
|
* RelationReloadClassinfo
|
||||||
*
|
*
|
||||||
* This function is especially for nailed relations.
|
* This function is especially for nailed relations.
|
||||||
* relhasindex/relfilenode could be changed even for
|
* relhasindex/relfilenode could be changed even for
|
||||||
* nailed relations.
|
* nailed relations.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
RelationReloadClassinfo(Relation relation)
|
RelationReloadClassinfo(Relation relation)
|
||||||
|
@ -1615,7 +1615,7 @@ RelationReloadClassinfo(Relation relation)
|
||||||
}
|
}
|
||||||
#endif /* ENABLE_REINDEX_NAILED_RELATIONS */
|
#endif /* ENABLE_REINDEX_NAILED_RELATIONS */
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationClearRelation
|
* RelationClearRelation
|
||||||
*
|
*
|
||||||
* Physically blow away a relation cache entry, or reset it and rebuild
|
* Physically blow away a relation cache entry, or reset it and rebuild
|
||||||
|
@ -1623,7 +1623,7 @@ RelationReloadClassinfo(Relation relation)
|
||||||
* usually used when we are notified of a change to an open relation
|
* usually used when we are notified of a change to an open relation
|
||||||
* (one with refcount > 0). However, this routine just does whichever
|
* (one with refcount > 0). However, this routine just does whichever
|
||||||
* it's told to do; callers must determine which they want.
|
* it's told to do; callers must determine which they want.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
RelationClearRelation(Relation relation, bool rebuildIt)
|
RelationClearRelation(Relation relation, bool rebuildIt)
|
||||||
|
@ -1774,11 +1774,11 @@ RelationClearRelation(Relation relation, bool rebuildIt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationFlushRelation
|
* RelationFlushRelation
|
||||||
*
|
*
|
||||||
* Rebuild the relation if it is open (refcount > 0), else blow it away.
|
* Rebuild the relation if it is open (refcount > 0), else blow it away.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
RelationFlushRelation(Relation relation)
|
RelationFlushRelation(Relation relation)
|
||||||
|
@ -1805,13 +1805,13 @@ RelationFlushRelation(Relation relation)
|
||||||
RelationClearRelation(relation, rebuildIt);
|
RelationClearRelation(relation, rebuildIt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationForgetRelation -
|
* RelationForgetRelation -
|
||||||
*
|
*
|
||||||
* RelationClearRelation + if the relation is myxactonly then
|
* RelationClearRelation + if the relation is myxactonly then
|
||||||
* remove the relation descriptor from the newly created
|
* remove the relation descriptor from the newly created
|
||||||
* relation list.
|
* relation list.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
RelationForgetRelation(Oid rid)
|
RelationForgetRelation(Oid rid)
|
||||||
|
@ -1851,7 +1851,7 @@ RelationForgetRelation(Oid rid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationIdInvalidateRelationCacheByRelationId
|
* RelationIdInvalidateRelationCacheByRelationId
|
||||||
*
|
*
|
||||||
* This routine is invoked for SI cache flush messages.
|
* This routine is invoked for SI cache flush messages.
|
||||||
|
@ -1861,7 +1861,7 @@ RelationForgetRelation(Oid rid)
|
||||||
* safer to process them, so that our *own* SI update messages will
|
* safer to process them, so that our *own* SI update messages will
|
||||||
* have the same effects during CommandCounterIncrement for both
|
* have the same effects during CommandCounterIncrement for both
|
||||||
* local and nonlocal relations.
|
* local and nonlocal relations.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
RelationIdInvalidateRelationCacheByRelationId(Oid relationId)
|
RelationIdInvalidateRelationCacheByRelationId(Oid relationId)
|
||||||
|
@ -1995,11 +1995,11 @@ RelationCacheAbortWalker(Relation *relationPtr, Datum dummy)
|
||||||
RelationSetReferenceCount(relation, 0);
|
RelationSetReferenceCount(relation, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationRegisterRelation -
|
* RelationRegisterRelation -
|
||||||
* register the Relation descriptor of a newly created relation
|
* register the Relation descriptor of a newly created relation
|
||||||
* with the relation descriptor Cache.
|
* with the relation descriptor Cache.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
RelationRegisterRelation(Relation relation)
|
RelationRegisterRelation(Relation relation)
|
||||||
|
@ -2054,11 +2054,11 @@ RelationPurgeLocalRelation(bool xactCommitted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationCacheInitialize
|
* RelationCacheInitialize
|
||||||
*
|
*
|
||||||
* This initializes the relation descriptor cache.
|
* This initializes the relation descriptor cache.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define INITRELCACHESIZE 400
|
#define INITRELCACHESIZE 400
|
||||||
|
@ -2069,18 +2069,18 @@ RelationCacheInitialize(void)
|
||||||
MemoryContext oldcxt;
|
MemoryContext oldcxt;
|
||||||
HASHCTL ctl;
|
HASHCTL ctl;
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* switch to cache memory context
|
* switch to cache memory context
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
if (!CacheMemoryContext)
|
if (!CacheMemoryContext)
|
||||||
CreateCacheMemoryContext();
|
CreateCacheMemoryContext();
|
||||||
|
|
||||||
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
|
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* create global caches
|
* create global caches
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
MemSet(&ctl, 0, (int) sizeof(ctl));
|
MemSet(&ctl, 0, (int) sizeof(ctl));
|
||||||
ctl.keysize = sizeof(NameData);
|
ctl.keysize = sizeof(NameData);
|
||||||
|
@ -2097,13 +2097,13 @@ RelationCacheInitialize(void)
|
||||||
RelationNodeCache = hash_create(INITRELCACHESIZE, &ctl,
|
RelationNodeCache = hash_create(INITRELCACHESIZE, &ctl,
|
||||||
HASH_ELEM | HASH_FUNCTION);
|
HASH_ELEM | HASH_FUNCTION);
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* initialize the cache with pre-made relation descriptors
|
* initialize the cache with pre-made relation descriptors
|
||||||
* for some of the more important system relations. These
|
* for some of the more important system relations. These
|
||||||
* relations should always be in the cache.
|
* relations should always be in the cache.
|
||||||
*
|
*
|
||||||
* NB: see also the list in RelationCacheInitializePhase2().
|
* NB: see also the list in RelationCacheInitializePhase2().
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
formrdesc(RelationRelationName, Natts_pg_class, Desc_pg_class);
|
formrdesc(RelationRelationName, Natts_pg_class, Desc_pg_class);
|
||||||
formrdesc(AttributeRelationName, Natts_pg_attribute, Desc_pg_attribute);
|
formrdesc(AttributeRelationName, Natts_pg_attribute, Desc_pg_attribute);
|
||||||
|
@ -2121,12 +2121,12 @@ RelationCacheInitialize(void)
|
||||||
MemoryContextSwitchTo(oldcxt);
|
MemoryContextSwitchTo(oldcxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationCacheInitializePhase2
|
* RelationCacheInitializePhase2
|
||||||
*
|
*
|
||||||
* This completes initialization of the relcache after catcache
|
* This completes initialization of the relcache after catcache
|
||||||
* is functional and we are able to actually load data from pg_class.
|
* is functional and we are able to actually load data from pg_class.
|
||||||
* --------------------------------
|
*
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
RelationCacheInitializePhase2(void)
|
RelationCacheInitializePhase2(void)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.58 2001/01/24 19:43:15 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.59 2001/02/22 18:39:20 momjian Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* These routines allow the parser/planner/executor to perform
|
* These routines allow the parser/planner/executor to perform
|
||||||
|
@ -75,9 +75,9 @@
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* struct cachedesc: information defining a single syscache
|
* struct cachedesc: information defining a single syscache
|
||||||
* ----------------
|
*
|
||||||
*/
|
*/
|
||||||
struct cachedesc
|
struct cachedesc
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: shmem.h,v 1.26 2001/01/24 19:43:28 momjian Exp $
|
* $Id: shmem.h,v 1.27 2001/02/22 18:39:20 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -28,8 +28,8 @@
|
||||||
*/
|
*/
|
||||||
typedef unsigned long SHMEM_OFFSET;
|
typedef unsigned long SHMEM_OFFSET;
|
||||||
|
|
||||||
#define INVALID_OFFSET (-1)
|
#define INVALID_OFFSET (-1)
|
||||||
#define BAD_LOCATION (-1)
|
#define BAD_LOCATION (-1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start of the primary shared memory region, in this process' address space.
|
* Start of the primary shared memory region, in this process' address space.
|
||||||
|
|
Loading…
Reference in New Issue