mirror of
https://github.com/postgres/postgres.git
synced 2025-05-20 05:13:53 +03:00
Optimize check_search_path() by using SearchPathCache.
A hash lookup is faster than re-validating the string, particularly because we use SplitIdentifierString() for validation. Important when search_path changes frequently. Discussion: https://postgr.es/m/04c8592dbd694e4114a3ed87139a7a04e4363030.camel%40j-davis.com
This commit is contained in:
parent
8efa301532
commit
ad57c2a7c5
@ -235,6 +235,10 @@ static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames,
|
|||||||
* when a function has search_path set in proconfig. Add a search path cache
|
* when a function has search_path set in proconfig. Add a search path cache
|
||||||
* that can be used by recomputeNamespacePath().
|
* that can be used by recomputeNamespacePath().
|
||||||
*
|
*
|
||||||
|
* The cache is also used to remember already-validated strings in
|
||||||
|
* check_search_path() to avoid the need to call SplitIdentifierString()
|
||||||
|
* repeatedly.
|
||||||
|
*
|
||||||
* The search path cache is based on a wrapper around a simplehash hash table
|
* The search path cache is based on a wrapper around a simplehash hash table
|
||||||
* (nsphash, defined below). The spcache wrapper deals with OOM while trying
|
* (nsphash, defined below). The spcache wrapper deals with OOM while trying
|
||||||
* to initialize a key, and also offers a more convenient API.
|
* to initialize a key, and also offers a more convenient API.
|
||||||
@ -296,6 +300,21 @@ spcache_init(void)
|
|||||||
searchPathCacheValid = true;
|
searchPathCacheValid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look up entry in search path cache without inserting. Returns NULL if not
|
||||||
|
* present.
|
||||||
|
*/
|
||||||
|
static SearchPathCacheEntry *
|
||||||
|
spcache_lookup(const char *searchPath, Oid roleid)
|
||||||
|
{
|
||||||
|
SearchPathCacheKey cachekey = {
|
||||||
|
.searchPath = searchPath,
|
||||||
|
.roleid = roleid
|
||||||
|
};
|
||||||
|
|
||||||
|
return nsphash_lookup(SearchPathCache, cachekey);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look up or insert entry in search path cache.
|
* Look up or insert entry in search path cache.
|
||||||
*
|
*
|
||||||
@ -4578,11 +4597,40 @@ ResetTempTableNamespace(void)
|
|||||||
bool
|
bool
|
||||||
check_search_path(char **newval, void **extra, GucSource source)
|
check_search_path(char **newval, void **extra, GucSource source)
|
||||||
{
|
{
|
||||||
|
Oid roleid = InvalidOid;
|
||||||
|
const char *searchPath = *newval;
|
||||||
char *rawname;
|
char *rawname;
|
||||||
List *namelist;
|
List *namelist;
|
||||||
|
bool use_cache = (SearchPathCacheContext != NULL);
|
||||||
|
|
||||||
/* Need a modifiable copy of string */
|
/*
|
||||||
rawname = pstrdup(*newval);
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
if (use_cache)
|
||||||
|
{
|
||||||
|
spcache_init();
|
||||||
|
|
||||||
|
roleid = GetUserId();
|
||||||
|
|
||||||
|
if (spcache_lookup(searchPath, roleid) != NULL)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure validity check succeeds before creating cache entry.
|
||||||
|
*/
|
||||||
|
|
||||||
|
rawname = pstrdup(searchPath); /* need a modifiable copy */
|
||||||
|
|
||||||
/* Parse string into list of identifiers */
|
/* Parse string into list of identifiers */
|
||||||
if (!SplitIdentifierString(rawname, ',', &namelist))
|
if (!SplitIdentifierString(rawname, ',', &namelist))
|
||||||
@ -4605,6 +4653,10 @@ check_search_path(char **newval, void **extra, GucSource source)
|
|||||||
pfree(rawname);
|
pfree(rawname);
|
||||||
list_free(namelist);
|
list_free(namelist);
|
||||||
|
|
||||||
|
/* create empty cache entry */
|
||||||
|
if (use_cache)
|
||||||
|
(void) spcache_insert(searchPath, roleid);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user