]> granicus.if.org Git - postgresql/commitdiff
Improve performance of OverrideSearchPathMatchesCurrent().
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 28 Nov 2014 17:37:27 +0000 (12:37 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 28 Nov 2014 17:37:27 +0000 (12:37 -0500)
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.

src/backend/catalog/namespace.c

index 911f015f27ec933c4082660364d672170b86de8e..7a063329fe11fe20f75abe832695274e26d0530e 100644 (file)
@@ -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;
 }
 
 /*