mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	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 | ||||
|  *	  $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 | ||||
|  * caller will have it already. | ||||
|  * | ||||
|  * XXX There isn't any provision for flushing the cache.  However, there | ||||
|  * isn't any provision for flushing relcache entries when opclass info | ||||
|  * changes, either :-( | ||||
|  * Note there is no provision for flushing the cache.  This is OK at the | ||||
|  * moment because there is no way to ALTER any interesting properties of an | ||||
|  * 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 * | ||||
| LookupOpclassInfo(Oid operatorClassOid, | ||||
| @ -1170,34 +1174,50 @@ LookupOpclassInfo(Oid operatorClassOid, | ||||
| 											   (void *) &operatorClassOid, | ||||
| 											   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(numSupport == opcentry->numSupport); | ||||
| 		return opcentry; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Need to fill in new entry */ | ||||
| 	opcentry->valid = false;	/* until known OK */ | ||||
| 	opcentry->numStrats = numStrats; | ||||
| 	opcentry->numSupport = numSupport; | ||||
| 	/*
 | ||||
| 	 * When testing for cache-flush hazards, we intentionally disable the | ||||
| 	 * operator class cache and force reloading of the info on each call. | ||||
| 	 * 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) | ||||
| 		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; | ||||
| 	if (opcentry->valid) | ||||
| 		return opcentry; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Need to fill in new entry. | ||||
| 	 * | ||||
| 	 * 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 | ||||
| 	 * reference here. | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user