Improve test coverage of CLOBBER_CACHE_ALWAYS by having it also force
reloading of operator class information on each use of LookupOpclassInfo. Had this been in place a year ago, it would have helped me find a bug in the then-new 'operator family' code. Now that we have a build farm member testing CLOBBER_CACHE_ALWAYS on a regular basis, it seems worth expending a little bit of effort here.
This commit is contained in:
parent
62312ce36d
commit
03ffc4d6d5
68
src/backend/utils/cache/relcache.c
vendored
68
src/backend/utils/cache/relcache.c
vendored
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.264 2007/11/15 21:14:40 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.265 2007/11/28 20:44:26 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1133,9 +1133,13 @@ IndexSupportInitialize(oidvector *indclass,
|
|||||||
* numbers is passed in, rather than being looked up, mainly because the
|
* numbers is passed in, rather than being looked up, mainly because the
|
||||||
* caller will have it already.
|
* caller will have it already.
|
||||||
*
|
*
|
||||||
* XXX There isn't any provision for flushing the cache. However, there
|
* Note there is no provision for flushing the cache. This is OK at the
|
||||||
* isn't any provision for flushing relcache entries when opclass info
|
* moment because there is no way to ALTER any interesting properties of an
|
||||||
* changes, either :-(
|
* existing opclass --- all you can do is drop it, which will result in
|
||||||
|
* a useless but harmless dead entry in the cache. To support altering
|
||||||
|
* opclass membership (not the same as opfamily membership!), we'd need to
|
||||||
|
* be able to flush this cache as well as the contents of relcache entries
|
||||||
|
* for indexes.
|
||||||
*/
|
*/
|
||||||
static OpClassCacheEnt *
|
static OpClassCacheEnt *
|
||||||
LookupOpclassInfo(Oid operatorClassOid,
|
LookupOpclassInfo(Oid operatorClassOid,
|
||||||
@ -1170,34 +1174,50 @@ LookupOpclassInfo(Oid operatorClassOid,
|
|||||||
(void *) &operatorClassOid,
|
(void *) &operatorClassOid,
|
||||||
HASH_ENTER, &found);
|
HASH_ENTER, &found);
|
||||||
|
|
||||||
if (found && opcentry->valid)
|
if (!found)
|
||||||
|
{
|
||||||
|
/* Need to allocate memory for new entry */
|
||||||
|
opcentry->valid = false; /* until known OK */
|
||||||
|
opcentry->numStrats = numStrats;
|
||||||
|
opcentry->numSupport = numSupport;
|
||||||
|
|
||||||
|
if (numStrats > 0)
|
||||||
|
opcentry->operatorOids = (Oid *)
|
||||||
|
MemoryContextAllocZero(CacheMemoryContext,
|
||||||
|
numStrats * sizeof(Oid));
|
||||||
|
else
|
||||||
|
opcentry->operatorOids = NULL;
|
||||||
|
|
||||||
|
if (numSupport > 0)
|
||||||
|
opcentry->supportProcs = (RegProcedure *)
|
||||||
|
MemoryContextAllocZero(CacheMemoryContext,
|
||||||
|
numSupport * sizeof(RegProcedure));
|
||||||
|
else
|
||||||
|
opcentry->supportProcs = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* Already made an entry for it */
|
|
||||||
Assert(numStrats == opcentry->numStrats);
|
Assert(numStrats == opcentry->numStrats);
|
||||||
Assert(numSupport == opcentry->numSupport);
|
Assert(numSupport == opcentry->numSupport);
|
||||||
return opcentry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Need to fill in new entry */
|
/*
|
||||||
opcentry->valid = false; /* until known OK */
|
* When testing for cache-flush hazards, we intentionally disable the
|
||||||
opcentry->numStrats = numStrats;
|
* operator class cache and force reloading of the info on each call.
|
||||||
opcentry->numSupport = numSupport;
|
* This is helpful because we want to test the case where a cache flush
|
||||||
|
* occurs while we are loading the info, and it's very hard to provoke
|
||||||
|
* that if this happens only once per opclass per backend.
|
||||||
|
*/
|
||||||
|
#if defined(CLOBBER_CACHE_ALWAYS)
|
||||||
|
opcentry->valid = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (numStrats > 0)
|
if (opcentry->valid)
|
||||||
opcentry->operatorOids = (Oid *)
|
return opcentry;
|
||||||
MemoryContextAllocZero(CacheMemoryContext,
|
|
||||||
numStrats * sizeof(Oid));
|
|
||||||
else
|
|
||||||
opcentry->operatorOids = NULL;
|
|
||||||
|
|
||||||
if (numSupport > 0)
|
|
||||||
opcentry->supportProcs = (RegProcedure *)
|
|
||||||
MemoryContextAllocZero(CacheMemoryContext,
|
|
||||||
numSupport * sizeof(RegProcedure));
|
|
||||||
else
|
|
||||||
opcentry->supportProcs = NULL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* Need to fill in new entry.
|
||||||
|
*
|
||||||
* To avoid infinite recursion during startup, force heap scans if we're
|
* To avoid infinite recursion during startup, force heap scans if we're
|
||||||
* looking up info for the opclasses used by the indexes we would like to
|
* looking up info for the opclasses used by the indexes we would like to
|
||||||
* reference here.
|
* reference here.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user