/* The above four values are valid only if baseSearchPathValid */
static bool baseSearchPathValid = true;
+
+/*
+ * Storage for search path cache. Clear searchPathCacheValid as a simple
+ * way to invalidate *all* the cache entries, not just the active one.
+ */
static bool searchPathCacheValid = false;
static MemoryContext SearchPathCacheContext = NULL;
{
const char *searchPath;
Oid roleid;
-} SearchPathCacheKey;
+} SearchPathCacheKey;
typedef struct SearchPathCacheEntry
{
/* needed for simplehash */
char status;
-} SearchPathCacheEntry;
+} SearchPathCacheEntry;
/*
* myTempNamespace is InvalidOid until and unless a TEMP namespace is set up
*/
#define SPCACHE_RESET_THRESHOLD 256
-static nsphash_hash * SearchPathCache = NULL;
-static SearchPathCacheEntry * LastSearchPathCacheEntry = NULL;
+static nsphash_hash *SearchPathCache = NULL;
+static SearchPathCacheEntry *LastSearchPathCacheEntry = NULL;
/*
* Create or reset search_path cache as necessary.
SearchPathCache->members < SPCACHE_RESET_THRESHOLD)
return;
- MemoryContextReset(SearchPathCacheContext);
+ /* make sure we don't leave dangling pointers if nsphash_create fails */
+ SearchPathCache = NULL;
LastSearchPathCacheEntry = NULL;
+
+ MemoryContextReset(SearchPathCacheContext);
/* arbitrary initial starting size of 16 elements */
SearchPathCache = nsphash_create(SearchPathCacheContext, 16, NULL);
searchPathCacheValid = true;
};
entry = nsphash_lookup(SearchPathCache, cachekey);
-
- LastSearchPathCacheEntry = entry;
+ if (entry)
+ LastSearchPathCacheEntry = entry;
return entry;
}
}
{
Oid roleid = GetUserId();
bool pathChanged;
- const SearchPathCacheEntry *entry;
+ const SearchPathCacheEntry *entry;
/* Do nothing if path is already valid. */
if (baseSearchPathValid && namespaceUser == roleid)
* schemas that don't exist; and often, we are not inside a transaction
* here and so can't consult the system catalogs anyway. So now, the only
* requirement is syntactic validity of the identifier list.
- */
-
- /*
+ *
* Checking only the syntactic validity also allows us to use the search
* path cache (if available) to avoid calling SplitIdentifierString() on
* the same string repeatedly.
list_free(namelist);
return false;
}
-
- /*
- * We used to try to check that the named schemas exist, but there are
- * many valid use-cases for having search_path settings that include
- * schemas that don't exist; and often, we are not inside a transaction
- * here and so can't consult the system catalogs anyway. So now, the only
- * requirement is syntactic validity of the identifier list.
- */
-
pfree(rawname);
list_free(namelist);
- /* create empty cache entry */
+ /* OK to create empty cache entry */
if (use_cache)
(void) spcache_insert(searchPath, roleid);
}
else
{
- SearchPathCacheContext = AllocSetContextCreate(
- TopMemoryContext, "search_path processing cache",
+ /* Make the context we'll keep search path cache hashtable in */
+ SearchPathCacheContext = AllocSetContextCreate(TopMemoryContext,
+ "search_path processing cache",
ALLOCSET_DEFAULT_SIZES);
/*