postgres.git / summary / log / commit / refs

commit    5daf1012a902bfc00b365360f35ea972a3b19e13
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Wed Apr 13 22:57:52 2016 +0000
First released in: 9.6.0, 9.1.22, 9.2.17, 9.3.13, 9.4.8, 9.5.3

    Fix pg_dump so pg_upgrade'ing an extension with simple opfamilies works.
    
    As reported by Michael Feld, pg_upgrade'ing an installation having
    extensions with operator families that contain just a single operator class
    failed to reproduce the extension membership of those operator families.
    This caused no immediate ill effects, but would create problems when later
    trying to do a plain dump and restore, because the seemingly-not-part-of-
    the-extension operator families would appear separately in the pg_dump
    output, and then would conflict with the families created by loading the
    extension.  This has been broken ever since extensions were introduced,
    and many of the standard contrib extensions are affected, so it's a bit
    astonishing nobody complained before.
    
    The cause of the problem is a perhaps-ill-considered decision to omit
    such operator families from pg_dump's output on the grounds that the
    CREATE OPERATOR CLASS commands could recreate them, and having explicit
    CREATE OPERATOR FAMILY commands would impede loading the dump script into
    pre-8.3 servers.  Whatever the merits of that decision when 8.3 was being
    written, it looks like a poor tradeoff now.  We can fix the pg_upgrade
    problem simply by removing that code, so that the operator families are
    dumped explicitly (and then will be properly made to be part of their
    extensions).
    
    Although this fixes the behavior of future pg_upgrade runs, it does nothing
    to clean up existing installations that may have improperly-linked operator
    families.  Given the small number of complaints to date, maybe we don't
    need to worry about providing an automated solution for that; anyone who
    needs to clean it up can do so with manual "ALTER EXTENSION ADD OPERATOR
    FAMILY" commands, or even just ignore the duplicate-opfamily errors they
    get during a pg_restore.  In any case we need this fix.
    
    Back-patch to all supported branches.
    
    Discussion: <20228.1460575691@sss.pgh.pa.us>


src/bin/pg_dump/pg_dump.c | 47 +---------------------------------------------- 1 file changed, 1 insertion(+), 46 deletions(-) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 41ca186df91..28b9c37ea65 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -10860,9 +10860,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) appendPQExpBuffer(q, "FOR TYPE %s USING %s", opcintype, fmtId(amname)); - if (strlen(opcfamilyname) > 0 && - (strcmp(opcfamilyname, opcinfo->dobj.name) != 0 || - strcmp(opcfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0)) + if (strlen(opcfamilyname) > 0) { appendPQExpBufferStr(q, " FAMILY "); if (strcmp(opcfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0) @@ -11145,15 +11143,6 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo) if (!opfinfo->dobj.dump || dataOnly) return; - /* - * We want to dump the opfamily only if (1) it contains "loose" operators - * or functions, or (2) it contains an opclass with a different name or - * owner. Otherwise it's sufficient to let it be created during creation - * of the contained opclass, and not dumping it improves portability of - * the dump. Since we have to fetch the loose operators/funcs anyway, do - * that first. - */ - query = createPQExpBuffer(); q = createPQExpBuffer(); delq = createPQExpBuffer(); @@ -11236,40 +11225,6 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo) res_procs = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - if (PQntuples(res_ops) == 0 && PQntuples(res_procs) == 0) - { - /* No loose members, so check contained opclasses */ - resetPQExpBuffer(query); - - appendPQExpBuffer(query, "SELECT 1 " - "FROM pg_catalog.pg_opclass c, pg_catalog.pg_opfamily f, pg_catalog.pg_depend " - "WHERE f.oid = '%u'::pg_catalog.oid " - "AND refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass " - "AND refobjid = f.oid " - "AND classid = 'pg_catalog.pg_opclass'::pg_catalog.regclass " - "AND objid = c.oid " - "AND (opcname != opfname OR opcnamespace != opfnamespace OR opcowner != opfowner) " - "LIMIT 1", - opfinfo->dobj.catId.oid); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) == 0) - { - /* no need to dump it, so bail out */ - PQclear(res); - PQclear(res_ops); - PQclear(res_procs); - destroyPQExpBuffer(query); - destroyPQExpBuffer(q); - destroyPQExpBuffer(delq); - destroyPQExpBuffer(labelq); - return; - } - - PQclear(res); - } - /* Get additional fields from the pg_opfamily row */ resetPQExpBuffer(query); [parent: 112e5d2a8b32]