v7-0004-Optimize-check_search_path-by-using-SearchPathCac.patch
text/x-patch
Filename: v7-0004-Optimize-check_search_path-by-using-SearchPathCac.patch
Type: text/x-patch
Part: 1
Message:
Re: Faster "SET search_path"
Patch
Format: format-patch
Series: patch v7-0004
Subject: Optimize check_search_path() by using SearchPathCache.
| File | + | − |
|---|---|---|
| src/backend/catalog/namespace.c | 47 | 3 |
From 46d51755859746789aa073625fd5570f2d01be0c Mon Sep 17 00:00:00 2001
From: Jeff Davis <jeff@j-davis.com>
Date: Thu, 19 Oct 2023 15:19:05 -0700
Subject: [PATCH v7 4/6] 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
---
src/backend/catalog/namespace.c | 50 +++++++++++++++++++++++++++++++--
1 file changed, 47 insertions(+), 3 deletions(-)
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 258c97b590..68deb86554 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -234,6 +234,10 @@ static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames,
* when a function has search_path set in proconfig. Add a search path cache
* 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. In this case, the caller uses roleid=InvalidOid.
+ *
* 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
* to initialize a key, and also offers a more convenient API.
@@ -314,6 +318,21 @@ spcache_members(void)
return SearchPathCache->members;
}
+/*
+ * 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.
*
@@ -4633,9 +4652,10 @@ ResetTempTableNamespace(void)
bool
check_search_path(char **newval, void **extra, GucSource source)
{
- const char *searchPath = *newval;
- char *rawname;
- List *namelist;
+ Oid roleid = InvalidOid;
+ const char *searchPath = *newval;
+ char *rawname;
+ List *namelist;
/*
* We used to try to check that the named schemas exist, but there are
@@ -4645,6 +4665,24 @@ check_search_path(char **newval, void **extra, GucSource source)
* 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 (SearchPathCacheContext != NULL)
+ {
+ spcache_init();
+
+ roleid = GetUserId();
+
+ if (spcache_lookup(searchPath, roleid) != NULL)
+ return true;
+
+ if (spcache_members() >= SPCACHE_RESET_THRESHOLD)
+ spcache_reset();
+ }
+
/*
* Ensure validity check succeeds before creating cache entry.
*/
@@ -4664,6 +4702,12 @@ check_search_path(char **newval, void **extra, GucSource source)
pfree(rawname);
list_free(namelist);
+ /* create empty cache entry */
+ if (SearchPathCacheContext != NULL)
+ {
+ (void) spcache_insert(searchPath, roleid);
+ }
+
return true;
}
--
2.34.1