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
1 changed files with 21 additions and 16 deletions

View File

@ -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 "