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>
This commit is contained in:
Tom Lane 2016-09-23 13:49:26 -04:00
parent eda5e90829
commit 96e16d7391

View File

@ -4481,19 +4481,22 @@ getFuncs(Archive *fout, int *numFuncs)
selectSourceSchema(fout, "pg_catalog"); selectSourceSchema(fout, "pg_catalog");
/* /*
* Find all user-defined functions. Normally we can exclude functions in * Find all interesting functions. This is a bit complicated:
* 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.
* *
* Also, in 9.2 and up, exclude functions that are internally dependent on * 1. Always exclude aggregates; those are handled elsewhere.
* something else, since presumably those will be created as a result of *
* creating the something else. This currently only acts to suppress * 2. Always exclude functions that are internally dependent on something
* constructor functions for range types. Note that this is OK only * else, since presumably those will be created as a result of creating
* because the constructors don't have any dependencies the range type * the something else. This currently acts only to suppress constructor
* doesn't have; otherwise we might not get creation ordering correct. * 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) if (fout->remoteVersion >= 70300)
@ -4504,16 +4507,18 @@ getFuncs(Archive *fout, int *numFuncs)
"pronamespace, " "pronamespace, "
"(%s proowner) AS rolname " "(%s proowner) AS rolname "
"FROM pg_proc p " "FROM pg_proc p "
"WHERE NOT proisagg AND (" "WHERE NOT proisagg",
"pronamespace != "
"(SELECT oid FROM pg_namespace "
"WHERE nspname = 'pg_catalog')",
username_subquery); username_subquery);
if (fout->remoteVersion >= 90200) if (fout->remoteVersion >= 90200)
appendPQExpBufferStr(query, appendPQExpBufferStr(query,
"\n AND NOT EXISTS (SELECT 1 FROM pg_depend " "\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
"WHERE classid = 'pg_proc'::regclass AND " "WHERE classid = 'pg_proc'::regclass AND "
"objid = p.oid AND deptype = 'i')"); "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) if (dopt->binary_upgrade && fout->remoteVersion >= 90100)
appendPQExpBufferStr(query, appendPQExpBufferStr(query,
"\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "