aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2014-11-28 12:37:27 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2014-11-28 12:37:27 -0500
commit96d66bcfc60d9bcb7db767f23d33abf4d8bc7021 (patch)
treea707fb3a8fc6bf29ba20aecaaf9f71d9f21d3faa
parente384ed6cdec691e0f7c9a077d0fb2a357763c335 (diff)
downloadpostgresql-96d66bcfc60d9bcb7db767f23d33abf4d8bc7021.tar.gz
postgresql-96d66bcfc60d9bcb7db767f23d33abf4d8bc7021.zip
Improve performance of OverrideSearchPathMatchesCurrent().
This function was initially coded on the assumption that it would not be performance-critical, but that turns out to be wrong in workloads that are heavily dependent on the speed of plpgsql functions. Speed it up by hard-coding the comparison rules, thereby avoiding palloc/pfree traffic from creating and immediately freeing an OverrideSearchPath object. Per report from Scott Marlowe.
-rw-r--r--src/backend/catalog/namespace.c50
1 files changed, 37 insertions, 13 deletions
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 911f015f27e..7a063329fe1 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -3145,20 +3145,44 @@ CopyOverrideSearchPath(OverrideSearchPath *path)
bool
OverrideSearchPathMatchesCurrent(OverrideSearchPath *path)
{
- /* Easiest way to do this is GetOverrideSearchPath() and compare */
- bool result;
- OverrideSearchPath *cur;
+ ListCell *lc,
+ *lcp;
- cur = GetOverrideSearchPath(CurrentMemoryContext);
- if (path->addCatalog == cur->addCatalog &&
- path->addTemp == cur->addTemp &&
- equal(path->schemas, cur->schemas))
- result = true;
- else
- result = false;
- list_free(cur->schemas);
- pfree(cur);
- return result;
+ recomputeNamespacePath();
+
+ /* We scan down the activeSearchPath to see if it matches the input. */
+ lc = list_head(activeSearchPath);
+
+ /* If path->addTemp, first item should be my temp namespace. */
+ if (path->addTemp)
+ {
+ if (lc && lfirst_oid(lc) == myTempNamespace)
+ lc = lnext(lc);
+ else
+ return false;
+ }
+ /* If path->addCatalog, next item should be pg_catalog. */
+ if (path->addCatalog)
+ {
+ if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
+ lc = lnext(lc);
+ else
+ return false;
+ }
+ /* We should now be looking at the activeCreationNamespace. */
+ if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
+ return false;
+ /* The remainder of activeSearchPath should match path->schemas. */
+ foreach(lcp, path->schemas)
+ {
+ if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
+ lc = lnext(lc);
+ else
+ return false;
+ }
+ if (lc)
+ return false;
+ return true;
}
/*