]> granicus.if.org Git - postgresql/commitdiff
Fix incorrect logic for excluding range constructor functions in pg_dump.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 23 Sep 2016 17:49:27 +0000 (13:49 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 23 Sep 2016 17:49:27 +0000 (13:49 -0400)
Faulty AND/OR nesting in the WHERE clause of getFuncs' SQL query led to
dumping range constructor functions if they are part of an extension
and we're in binary-upgrade mode.  Actually, we don't want to dump them
separately even then, since CREATE TYPE AS RANGE will create the range's
constructor functions regardless.  Per report from Andrew Dunstan.

It looks like this mistake was introduced by me, in commit b985d4877, in
perhaps-overzealous refactoring to reduce code duplication.  I'm suitably
embarrassed.

Report: <34854939-02d7-f591-5677-ce2994104599@dunslane.net>

src/bin/pg_dump/pg_dump.c

index 2451d0fc62677082ebcc2c998df0a2e910da2be4..ec690b091bbecee45ed6b72a5101776819efad10 100644 (file)
@@ -3831,19 +3831,22 @@ getFuncs(Archive *fout, int *numFuncs)
        selectSourceSchema(fout, "pg_catalog");
 
        /*
-        * 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.
+        * Find all interesting functions.  This is a bit complicated:
         *
-        * Also, in 9.2 and up, exclude functions that are internally dependent on
-        * something else, since presumably those will be created as a result of
-        * creating the something else.  This currently only acts to suppress
-        * constructor functions for range types.  Note that this is OK only
-        * because the constructors don't have any dependencies the range type
-        * doesn't have; otherwise we might not get creation ordering correct.
+        * 1. Always exclude aggregates; those are handled elsewhere.
+        *
+        * 2. Always exclude functions that are internally dependent on something
+        * else, since presumably those will be created as a result of creating
+        * the something else.  This currently acts only to suppress constructor
+        * functions for range types (so we only need it in 9.2 and up).  Note
+        * this is OK only because the constructors don't have any dependencies
+        * the range type doesn't have; otherwise we might not get creation
+        * ordering correct.
+        *
+        * 3. Otherwise, we normally exclude functions in pg_catalog.  However, if
+        * they're members of extensions and we are in binary-upgrade mode then
+        * include them, since we want to dump extension members individually in
+        * that mode.
         */
 
        if (fout->remoteVersion >= 70300)
@@ -3854,16 +3857,18 @@ getFuncs(Archive *fout, int *numFuncs)
                                                  "pronamespace, "
                                                  "(%s proowner) AS rolname "
                                                  "FROM pg_proc p "
-                                                 "WHERE NOT proisagg AND ("
-                                                 "pronamespace != "
-                                                 "(SELECT oid FROM pg_namespace "
-                                                 "WHERE nspname = 'pg_catalog')",
+                                                 "WHERE NOT proisagg",
                                                  username_subquery);
                if (fout->remoteVersion >= 90200)
                        appendPQExpBuffer(query,
                                                          "\n  AND NOT EXISTS (SELECT 1 FROM pg_depend "
                                                          "WHERE classid = 'pg_proc'::regclass AND "
                                                          "objid = p.oid AND deptype = 'i')");
+               appendPQExpBuffer(query,
+                                                 "\n  AND ("
+                                                 "\n  pronamespace != "
+                                                 "(SELECT oid FROM pg_namespace "
+                                                 "WHERE nspname = 'pg_catalog')");
                if (binary_upgrade && fout->remoteVersion >= 90100)
                        appendPQExpBuffer(query,
                                                          "\n  OR EXISTS(SELECT 1 FROM pg_depend WHERE "