@@ -235,6 +235,10 @@ static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames,
235
235
* when a function has search_path set in proconfig. Add a search path cache
236
236
* that can be used by recomputeNamespacePath().
237
237
*
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
+ *
238
242
* The search path cache is based on a wrapper around a simplehash hash table
239
243
* (nsphash, defined below). The spcache wrapper deals with OOM while trying
240
244
* to initialize a key, and also offers a more convenient API.
@@ -296,6 +300,21 @@ spcache_init(void)
296
300
searchPathCacheValid = true;
297
301
}
298
302
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
+
299
318
/*
300
319
* Look up or insert entry in search path cache.
301
320
*
@@ -4578,11 +4597,40 @@ ResetTempTableNamespace(void)
4578
4597
bool
4579
4598
check_search_path (char * * newval , void * * extra , GucSource source )
4580
4599
{
4600
+ Oid roleid = InvalidOid ;
4601
+ const char * searchPath = * newval ;
4581
4602
char * rawname ;
4582
4603
List * namelist ;
4604
+ bool use_cache = (SearchPathCacheContext != NULL );
4583
4605
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 */
4586
4634
4587
4635
/* Parse string into list of identifiers */
4588
4636
if (!SplitIdentifierString (rawname , ',' , & namelist ))
@@ -4605,6 +4653,10 @@ check_search_path(char **newval, void **extra, GucSource source)
4605
4653
pfree (rawname );
4606
4654
list_free (namelist );
4607
4655
4656
+ /* create empty cache entry */
4657
+ if (use_cache )
4658
+ (void ) spcache_insert (searchPath , roleid );
4659
+
4608
4660
return true;
4609
4661
}
4610
4662
0 commit comments