Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7e02476

Browse files
committed
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 b985d48, in perhaps-overzealous refactoring to reduce code duplication. I'm suitably embarrassed. Report: <34854939-02d7-f591-5677-ce2994104599@dunslane.net>
1 parent a20435f commit 7e02476

File tree

1 file changed

+30
-23
lines changed

1 file changed

+30
-23
lines changed

src/bin/pg_dump/pg_dump.c

+30-23
Original file line numberDiff line numberDiff line change
@@ -4952,20 +4952,23 @@ getFuncs(Archive *fout, int *numFuncs)
49524952
selectSourceSchema(fout, "pg_catalog");
49534953

49544954
/*
4955-
* Find all interesting functions. We include functions in pg_catalog, if
4956-
* they have an ACL different from what we set at initdb time (which is
4957-
* saved in pg_init_privs for us to perform this check). There may also
4958-
* be functions which are members of extensions which we must dump if we
4959-
* are in binary upgrade mode (we'll mark those functions as to-be-dumped
4960-
* when we check if the extension is to-be-dumped and we're in binary
4961-
* upgrade mode).
4955+
* Find all interesting functions. This is a bit complicated:
49624956
*
4963-
* Also, in 9.2 and up, exclude functions that are internally dependent on
4964-
* something else, since presumably those will be created as a result of
4965-
* creating the something else. This currently only acts to suppress
4966-
* constructor functions for range types. Note that this is OK only
4967-
* because the constructors don't have any dependencies the range type
4968-
* doesn't have; otherwise we might not get creation ordering correct.
4957+
* 1. Always exclude aggregates; those are handled elsewhere.
4958+
*
4959+
* 2. Always exclude functions that are internally dependent on something
4960+
* else, since presumably those will be created as a result of creating
4961+
* the something else. This currently acts only to suppress constructor
4962+
* functions for range types (so we only need it in 9.2 and up). Note
4963+
* this is OK only because the constructors don't have any dependencies
4964+
* the range type doesn't have; otherwise we might not get creation
4965+
* ordering correct.
4966+
*
4967+
* 3. Otherwise, we normally exclude functions in pg_catalog. However, if
4968+
* they're members of extensions and we are in binary-upgrade mode then
4969+
* include them, since we want to dump extension members individually in
4970+
* that mode. Also, in 9.6 and up, include functions in pg_catalog if
4971+
* they have an ACL different from what's shown in pg_init_privs.
49694972
*/
49704973
if (fout->remoteVersion >= 90600)
49714974
{
@@ -4992,14 +4995,14 @@ getFuncs(Archive *fout, int *numFuncs)
49924995
"(p.oid = pip.objoid "
49934996
"AND pip.classoid = 'pg_proc'::regclass "
49944997
"AND pip.objsubid = 0) "
4995-
"WHERE NOT proisagg "
4996-
"AND NOT EXISTS (SELECT 1 FROM pg_depend "
4998+
"WHERE NOT proisagg"
4999+
"\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
49975000
"WHERE classid = 'pg_proc'::regclass AND "
4998-
"objid = p.oid AND deptype = 'i') AND ("
4999-
"pronamespace != "
5001+
"objid = p.oid AND deptype = 'i')"
5002+
"\n AND ("
5003+
"\n pronamespace != "
50005004
"(SELECT oid FROM pg_namespace "
5001-
"WHERE nspname = 'pg_catalog') OR "
5002-
"p.proacl IS DISTINCT FROM pip.initprivs",
5005+
"WHERE nspname = 'pg_catalog')",
50035006
acl_subquery->data,
50045007
racl_subquery->data,
50055008
initacl_subquery->data,
@@ -5012,6 +5015,8 @@ getFuncs(Archive *fout, int *numFuncs)
50125015
"objid = p.oid AND "
50135016
"refclassid = 'pg_extension'::regclass AND "
50145017
"deptype = 'e')");
5018+
appendPQExpBufferStr(query,
5019+
"\n OR p.proacl IS DISTINCT FROM pip.initprivs");
50155020
appendPQExpBufferChar(query, ')');
50165021

50175022
destroyPQExpBuffer(acl_subquery);
@@ -5029,16 +5034,18 @@ getFuncs(Archive *fout, int *numFuncs)
50295034
"pronamespace, "
50305035
"(%s proowner) AS rolname "
50315036
"FROM pg_proc p "
5032-
"WHERE NOT proisagg AND ("
5033-
"pronamespace != "
5034-
"(SELECT oid FROM pg_namespace "
5035-
"WHERE nspname = 'pg_catalog')",
5037+
"WHERE NOT proisagg",
50365038
username_subquery);
50375039
if (fout->remoteVersion >= 90200)
50385040
appendPQExpBufferStr(query,
50395041
"\n AND NOT EXISTS (SELECT 1 FROM pg_depend "
50405042
"WHERE classid = 'pg_proc'::regclass AND "
50415043
"objid = p.oid AND deptype = 'i')");
5044+
appendPQExpBufferStr(query,
5045+
"\n AND ("
5046+
"\n pronamespace != "
5047+
"(SELECT oid FROM pg_namespace "
5048+
"WHERE nspname = 'pg_catalog')");
50425049
if (dopt->binary_upgrade && fout->remoteVersion >= 90100)
50435050
appendPQExpBufferStr(query,
50445051
"\n OR EXISTS(SELECT 1 FROM pg_depend WHERE "

0 commit comments

Comments
 (0)