@@ -156,14 +156,19 @@ static Oid namespaceUser = InvalidOid;
156
156
157
157
/* The above four values are valid only if baseSearchPathValid */
158
158
static bool baseSearchPathValid = true;
159
+
160
+ /*
161
+ * Storage for search path cache. Clear searchPathCacheValid as a simple
162
+ * way to invalidate *all* the cache entries, not just the active one.
163
+ */
159
164
static bool searchPathCacheValid = false;
160
165
static MemoryContext SearchPathCacheContext = NULL ;
161
166
162
167
typedef struct SearchPathCacheKey
163
168
{
164
169
const char * searchPath ;
165
170
Oid roleid ;
166
- } SearchPathCacheKey ;
171
+ } SearchPathCacheKey ;
167
172
168
173
typedef struct SearchPathCacheEntry
169
174
{
@@ -176,7 +181,7 @@ typedef struct SearchPathCacheEntry
176
181
177
182
/* needed for simplehash */
178
183
char status ;
179
- } SearchPathCacheEntry ;
184
+ } SearchPathCacheEntry ;
180
185
181
186
/*
182
187
* myTempNamespace is InvalidOid until and unless a TEMP namespace is set up
@@ -281,8 +286,8 @@ spcachekey_equal(SearchPathCacheKey a, SearchPathCacheKey b)
281
286
*/
282
287
#define SPCACHE_RESET_THRESHOLD 256
283
288
284
- static nsphash_hash * SearchPathCache = NULL ;
285
- static SearchPathCacheEntry * LastSearchPathCacheEntry = NULL ;
289
+ static nsphash_hash * SearchPathCache = NULL ;
290
+ static SearchPathCacheEntry * LastSearchPathCacheEntry = NULL ;
286
291
287
292
/*
288
293
* Create or reset search_path cache as necessary.
@@ -296,8 +301,11 @@ spcache_init(void)
296
301
SearchPathCache -> members < SPCACHE_RESET_THRESHOLD )
297
302
return ;
298
303
299
- MemoryContextReset (SearchPathCacheContext );
304
+ /* make sure we don't leave dangling pointers if nsphash_create fails */
305
+ SearchPathCache = NULL ;
300
306
LastSearchPathCacheEntry = NULL ;
307
+
308
+ MemoryContextReset (SearchPathCacheContext );
301
309
/* arbitrary initial starting size of 16 elements */
302
310
SearchPathCache = nsphash_create (SearchPathCacheContext , 16 , NULL );
303
311
searchPathCacheValid = true;
@@ -325,8 +333,8 @@ spcache_lookup(const char *searchPath, Oid roleid)
325
333
};
326
334
327
335
entry = nsphash_lookup (SearchPathCache , cachekey );
328
-
329
- LastSearchPathCacheEntry = entry ;
336
+ if ( entry )
337
+ LastSearchPathCacheEntry = entry ;
330
338
return entry ;
331
339
}
332
340
}
@@ -4267,7 +4275,7 @@ recomputeNamespacePath(void)
4267
4275
{
4268
4276
Oid roleid = GetUserId ();
4269
4277
bool pathChanged ;
4270
- const SearchPathCacheEntry * entry ;
4278
+ const SearchPathCacheEntry * entry ;
4271
4279
4272
4280
/* Do nothing if path is already valid. */
4273
4281
if (baseSearchPathValid && namespaceUser == roleid )
@@ -4635,9 +4643,7 @@ check_search_path(char **newval, void **extra, GucSource source)
4635
4643
* schemas that don't exist; and often, we are not inside a transaction
4636
4644
* here and so can't consult the system catalogs anyway. So now, the only
4637
4645
* requirement is syntactic validity of the identifier list.
4638
- */
4639
-
4640
- /*
4646
+ *
4641
4647
* Checking only the syntactic validity also allows us to use the search
4642
4648
* path cache (if available) to avoid calling SplitIdentifierString() on
4643
4649
* the same string repeatedly.
@@ -4667,19 +4673,10 @@ check_search_path(char **newval, void **extra, GucSource source)
4667
4673
list_free (namelist );
4668
4674
return false;
4669
4675
}
4670
-
4671
- /*
4672
- * We used to try to check that the named schemas exist, but there are
4673
- * many valid use-cases for having search_path settings that include
4674
- * schemas that don't exist; and often, we are not inside a transaction
4675
- * here and so can't consult the system catalogs anyway. So now, the only
4676
- * requirement is syntactic validity of the identifier list.
4677
- */
4678
-
4679
4676
pfree (rawname );
4680
4677
list_free (namelist );
4681
4678
4682
- /* create empty cache entry */
4679
+ /* OK to create empty cache entry */
4683
4680
if (use_cache )
4684
4681
(void ) spcache_insert (searchPath , roleid );
4685
4682
@@ -4732,8 +4729,9 @@ InitializeSearchPath(void)
4732
4729
}
4733
4730
else
4734
4731
{
4735
- SearchPathCacheContext = AllocSetContextCreate (
4736
- TopMemoryContext , "search_path processing cache" ,
4732
+ /* Make the context we'll keep search path cache hashtable in */
4733
+ SearchPathCacheContext = AllocSetContextCreate (TopMemoryContext ,
4734
+ "search_path processing cache" ,
4737
4735
ALLOCSET_DEFAULT_SIZES );
4738
4736
4739
4737
/*
0 commit comments