diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2014-11-28 12:37:27 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2014-11-28 12:37:27 -0500 |
commit | 96d66bcfc60d9bcb7db767f23d33abf4d8bc7021 (patch) | |
tree | a707fb3a8fc6bf29ba20aecaaf9f71d9f21d3faa | |
parent | e384ed6cdec691e0f7c9a077d0fb2a357763c335 (diff) | |
download | postgresql-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.c | 50 |
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; } /* |