Skip to content

Commit ad57c2a

Browse files
committed
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
1 parent 8efa301 commit ad57c2a

File tree

1 file changed

+54
-2
lines changed

1 file changed

+54
-2
lines changed

src/backend/catalog/namespace.c

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,10 @@ static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames,
235235
* when a function has search_path set in proconfig. Add a search path cache
236236
* that can be used by recomputeNamespacePath().
237237
*
238+
* The cache is also used to remember already-validated strings in
239+
* check_search_path() to avoid the need to call SplitIdentifierString()
240+
* repeatedly.
241+
*
238242
* The search path cache is based on a wrapper around a simplehash hash table
239243
* (nsphash, defined below). The spcache wrapper deals with OOM while trying
240244
* to initialize a key, and also offers a more convenient API.
@@ -296,6 +300,21 @@ spcache_init(void)
296300
searchPathCacheValid = true;
297301
}
298302

303+
/*
304+
* Look up entry in search path cache without inserting. Returns NULL if not
305+
* present.
306+
*/
307+
static SearchPathCacheEntry *
308+
spcache_lookup(const char *searchPath, Oid roleid)
309+
{
310+
SearchPathCacheKey cachekey = {
311+
.searchPath = searchPath,
312+
.roleid = roleid
313+
};
314+
315+
return nsphash_lookup(SearchPathCache, cachekey);
316+
}
317+
299318
/*
300319
* Look up or insert entry in search path cache.
301320
*
@@ -4578,11 +4597,40 @@ ResetTempTableNamespace(void)
45784597
bool
45794598
check_search_path(char **newval, void **extra, GucSource source)
45804599
{
4600+
Oid roleid = InvalidOid;
4601+
const char *searchPath = *newval;
45814602
char *rawname;
45824603
List *namelist;
4604+
bool use_cache = (SearchPathCacheContext != NULL);
45834605

4584-
/* Need a modifiable copy of string */
4585-
rawname = pstrdup(*newval);
4606+
/*
4607+
* We used to try to check that the named schemas exist, but there are
4608+
* many valid use-cases for having search_path settings that include
4609+
* schemas that don't exist; and often, we are not inside a transaction
4610+
* here and so can't consult the system catalogs anyway. So now, the only
4611+
* requirement is syntactic validity of the identifier list.
4612+
*/
4613+
4614+
/*
4615+
* Checking only the syntactic validity also allows us to use the search
4616+
* path cache (if available) to avoid calling SplitIdentifierString() on
4617+
* the same string repeatedly.
4618+
*/
4619+
if (use_cache)
4620+
{
4621+
spcache_init();
4622+
4623+
roleid = GetUserId();
4624+
4625+
if (spcache_lookup(searchPath, roleid) != NULL)
4626+
return true;
4627+
}
4628+
4629+
/*
4630+
* Ensure validity check succeeds before creating cache entry.
4631+
*/
4632+
4633+
rawname = pstrdup(searchPath); /* need a modifiable copy */
45864634

45874635
/* Parse string into list of identifiers */
45884636
if (!SplitIdentifierString(rawname, ',', &namelist))
@@ -4605,6 +4653,10 @@ check_search_path(char **newval, void **extra, GucSource source)
46054653
pfree(rawname);
46064654
list_free(namelist);
46074655

4656+
/* create empty cache entry */
4657+
if (use_cache)
4658+
(void) spcache_insert(searchPath, roleid);
4659+
46084660
return true;
46094661
}
46104662

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy