]> granicus.if.org Git - postgresql/commitdiff
Fix corner case for binary upgrade: extension functions in pg_catalog.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 15 Feb 2011 23:09:41 +0000 (18:09 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 15 Feb 2011 23:10:22 +0000 (18:10 -0500)
Normally, pg_dump summarily excludes functions in pg_catalog from
consideration.  However, some extensions may create functions in pg_catalog
(adminpack already does that, and extensions for procedural languages will
likely do it too).  In binary-upgrade mode, we have to dump such functions,
or the extension will be incomplete after upgrading.  Per experimentation
with adminpack.

src/bin/pg_dump/pg_dump.c

index 0fd706c0fc73ed68c2db728f9b53d039ee751648..60609b6b3593a038afc09366ad05ef8e4c0bd3f5 100644 (file)
@@ -3462,7 +3462,10 @@ getAggregates(int *numAggs)
        /* Make sure we are in proper schema */
        selectSourceSchema("pg_catalog");
 
-       /* find all user-defined aggregates */
+       /*
+        * Find all user-defined aggregates.  See comment in getFuncs() for the
+        * rationale behind the filtering logic.
+        */
 
        if (g_fout->remoteVersion >= 80200)
        {
@@ -3471,11 +3474,20 @@ getAggregates(int *numAggs)
                                                  "pronargs, proargtypes, "
                                                  "(%s proowner) AS rolname, "
                                                  "proacl AS aggacl "
-                                                 "FROM pg_proc "
-                                                 "WHERE proisagg "
-                                                 "AND pronamespace != "
-                          "(SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog')",
+                                                 "FROM pg_proc p "
+                                                 "WHERE proisagg AND ("
+                                                 "pronamespace != "
+                                                 "(SELECT oid FROM pg_namespace "
+                                                 "WHERE nspname = 'pg_catalog')",
                                                  username_subquery);
+               if (binary_upgrade && g_fout->remoteVersion >= 90100)
+                       appendPQExpBuffer(query,
+                                                         " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
+                                                         "classid = 'pg_proc'::regclass AND "
+                                                         "objid = p.oid AND "
+                                                         "refclassid = 'pg_extension'::regclass AND "
+                                                         "deptype = 'e')");
+               appendPQExpBuffer(query, ")");
        }
        else if (g_fout->remoteVersion >= 70300)
        {
@@ -3608,7 +3620,14 @@ getFuncs(int *numFuncs)
        /* Make sure we are in proper schema */
        selectSourceSchema("pg_catalog");
 
-       /* find all user-defined funcs */
+       /*
+        * Find all user-defined functions.  Normally we can exclude functions
+        * in pg_catalog, which is worth doing since there are several thousand
+        * of 'em.  However, there are some extensions that create functions in
+        * pg_catalog.  In normal dumps we can still ignore those --- but in
+        * binary-upgrade mode, we must dump the member objects of the extension,
+        * so be sure to fetch any such functions.
+        */
 
        if (g_fout->remoteVersion >= 70300)
        {
@@ -3617,12 +3636,20 @@ getFuncs(int *numFuncs)
                                                  "pronargs, proargtypes, prorettype, proacl, "
                                                  "pronamespace, "
                                                  "(%s proowner) AS rolname "
-                                                 "FROM pg_proc "
-                                                 "WHERE NOT proisagg "
-                                                 "AND pronamespace != "
+                                                 "FROM pg_proc "
+                                                 "WHERE NOT proisagg AND ("
+                                                 "pronamespace != "
                                                  "(SELECT oid FROM pg_namespace "
                                                  "WHERE nspname = 'pg_catalog')",
                                                  username_subquery);
+               if (binary_upgrade && g_fout->remoteVersion >= 90100)
+                       appendPQExpBuffer(query,
+                                                         " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
+                                                         "classid = 'pg_proc'::regclass AND "
+                                                         "objid = p.oid AND "
+                                                         "refclassid = 'pg_extension'::regclass AND "
+                                                         "deptype = 'e')");
+               appendPQExpBuffer(query, ")");
        }
        else if (g_fout->remoteVersion >= 70100)
        {
@@ -13319,6 +13346,8 @@ getExtensionMembership(ExtensionInfo extinfo[], int numExtensions)
                 */
                if (!binary_upgrade)
                        dobj->dump = false;
+               else
+                       dobj->dump = refdobj->dump;
        }
 
        PQclear(res);