From 96e16d73918f57ba8dd45d7708092d6220263bfc Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 23 Sep 2016 13:49:26 -0400 Subject: [PATCH] Fix incorrect logic for excluding range constructor functions in pg_dump. 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 | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index df6d2e7346..03531405e0 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -4481,19 +4481,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) @@ -4504,16 +4507,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) appendPQExpBufferStr(query, "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " "WHERE classid = 'pg_proc'::regclass AND " "objid = p.oid AND deptype = 'i')"); + appendPQExpBufferStr(query, + "\n AND (" + "\n pronamespace != " + "(SELECT oid FROM pg_namespace " + "WHERE nspname = 'pg_catalog')"); if (dopt->binary_upgrade && fout->remoteVersion >= 90100) appendPQExpBufferStr(query, "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "