]> granicus.if.org Git - postgresql/blobdiff - src/bin/pg_dump/pg_dump.c
Allow polymorphic aggregates to have non-polymorphic state data types.
[postgresql] / src / bin / pg_dump / pg_dump.c
index ebbb5b730c3c9a2bd087c6cae4a5b74b47be801a..c2bb6161b214811d38af43f480e5bb517d4db0c1 100644 (file)
 #include "dumputils.h"
 #include "parallel.h"
 
-extern char *optarg;
-extern int     optind,
-                       opterr;
-
 
 typedef struct
 {
@@ -136,6 +132,7 @@ static int  binary_upgrade = 0;
 static int     disable_dollar_quoting = 0;
 static int     dump_inserts = 0;
 static int     column_inserts = 0;
+static int     if_exists = 0;
 static int     no_security_labels = 0;
 static int     no_synchronized_snapshots = 0;
 static int     no_unlogged_table_data = 0;
@@ -238,9 +235,9 @@ static char *format_function_arguments_old(Archive *fout,
                                                          char **argnames);
 static char *format_function_signature(Archive *fout,
                                                  FuncInfo *finfo, bool honor_quotes);
-static const char *convertRegProcReference(Archive *fout,
+static char *convertRegProcReference(Archive *fout,
                                                const char *proc);
-static const char *convertOperatorReference(Archive *fout, const char *opr);
+static char *convertOperatorReference(Archive *fout, const char *opr);
 static const char *convertTSFunction(Archive *fout, Oid funcOid);
 static Oid     findLastBuiltinOid_V71(Archive *fout, const char *);
 static Oid     findLastBuiltinOid_V70(Archive *fout);
@@ -349,6 +346,7 @@ main(int argc, char **argv)
                {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
                {"disable-triggers", no_argument, &disable_triggers, 1},
                {"exclude-table-data", required_argument, NULL, 4},
+               {"if-exists", no_argument, &if_exists, 1},
                {"inserts", no_argument, &dump_inserts, 1},
                {"lock-wait-timeout", required_argument, NULL, 2},
                {"no-tablespaces", no_argument, &outputNoTablespaces, 1},
@@ -565,10 +563,16 @@ main(int argc, char **argv)
                dump_inserts = 1;
 
        if (dataOnly && schemaOnly)
-               exit_horribly(NULL, "options -s/--schema-only and -a/--data-only cannot be used together\n");
+       {
+               write_msg(NULL, "options -s/--schema-only and -a/--data-only cannot be used together\n");
+               exit_nicely(1);
+       }
 
        if (dataOnly && outputClean)
-               exit_horribly(NULL, "options -c/--clean and -a/--data-only cannot be used together\n");
+       {
+               write_msg(NULL, "options -c/--clean and -a/--data-only cannot be used together\n");
+               exit_nicely(1);
+       }
 
        if (dump_inserts && oids)
        {
@@ -577,6 +581,9 @@ main(int argc, char **argv)
                exit_nicely(1);
        }
 
+       if (if_exists && !outputClean)
+               exit_horribly(NULL, "option --if-exists requires -c/--clean option\n");
+
        /* Identify archive format to emit */
        archiveFormat = parseArchiveFormat(format, &archiveMode);
 
@@ -809,6 +816,7 @@ main(int argc, char **argv)
        ropt->dropSchema = outputClean;
        ropt->dataOnly = dataOnly;
        ropt->schemaOnly = schemaOnly;
+       ropt->if_exists = if_exists;
        ropt->dumpSections = dumpSections;
        ropt->aclsSkip = aclsSkip;
        ropt->superuser = outputSuperuser;
@@ -890,6 +898,7 @@ help(const char *progname)
        printf(_("  --disable-dollar-quoting     disable dollar quoting, use SQL standard quoting\n"));
        printf(_("  --disable-triggers           disable triggers during data-only restore\n"));
        printf(_("  --exclude-table-data=TABLE   do NOT dump data for the named table(s)\n"));
+       printf(_("  --if-exists                  use IF EXISTS when dropping objects\n"));
        printf(_("  --inserts                    dump data as INSERT commands, rather than COPY\n"));
        printf(_("  --no-security-labels         do not dump security label assignments\n"));
        printf(_("  --no-synchronized-snapshots  do not use synchronized snapshots in parallel jobs\n"));
@@ -4787,6 +4796,8 @@ getTables(Archive *fout, int *numTables)
                        selectDumpableTable(&tblinfo[i]);
                tblinfo[i].interesting = tblinfo[i].dobj.dump;
 
+               tblinfo[i].postponed_def = false; /* might get set during sort */
+
                /*
                 * Read-lock target tables to make sure they aren't DROPPED or altered
                 * in schema before we get around to dumping them.
@@ -7145,7 +7156,7 @@ getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
        PGresult   *res;
        int                     ntups;
        int                     i;
-       PQExpBuffer query = createPQExpBuffer();
+       PQExpBuffer query;
        FdwInfo    *fdwinfo;
        int                     i_tableoid;
        int                     i_oid;
@@ -7163,6 +7174,8 @@ getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
                return NULL;
        }
 
+       query = createPQExpBuffer();
+
        /* Make sure we are in proper schema */
        selectSourceSchema(fout, "pg_catalog");
 
@@ -7251,7 +7264,7 @@ getForeignServers(Archive *fout, int *numForeignServers)
        PGresult   *res;
        int                     ntups;
        int                     i;
-       PQExpBuffer query = createPQExpBuffer();
+       PQExpBuffer query;
        ForeignServerInfo *srvinfo;
        int                     i_tableoid;
        int                     i_oid;
@@ -7270,6 +7283,8 @@ getForeignServers(Archive *fout, int *numForeignServers)
                return NULL;
        }
 
+       query = createPQExpBuffer();
+
        /* Make sure we are in proper schema */
        selectSourceSchema(fout, "pg_catalog");
 
@@ -9604,7 +9619,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        PQExpBuffer asPart;
        PGresult   *res;
        char       *funcsig;            /* identity signature */
-       char       *funcfullsig;        /* full signature */
+       char       *funcfullsig = NULL; /* full signature */
        char       *funcsig_tag;
        char       *proretset;
        char       *prosrc;
@@ -9912,13 +9927,10 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                funcsig = format_function_arguments(finfo, funciargs, false);
        }
        else
-       {
                /* pre-8.4, do it ourselves */
                funcsig = format_function_arguments_old(fout,
                                                                                                finfo, nallargs, allargtypes,
                                                                                                argmodes, argnames);
-               funcfullsig = funcsig;
-       }
 
        funcsig_tag = format_function_signature(fout, finfo, false);
 
@@ -9929,7 +9941,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                                          fmtId(finfo->dobj.namespace->dobj.name),
                                          funcsig);
 
-       appendPQExpBuffer(q, "CREATE FUNCTION %s ", funcfullsig);
+       appendPQExpBuffer(q, "CREATE FUNCTION %s ", funcfullsig ? funcfullsig :
+                                         funcsig);
        if (funcresult)
                appendPQExpBuffer(q, "RETURNS %s", funcresult);
        else
@@ -10052,6 +10065,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        destroyPQExpBuffer(labelq);
        destroyPQExpBuffer(asPart);
        free(funcsig);
+       if (funcfullsig)
+               free(funcfullsig);
        free(funcsig_tag);
        if (allargtypes)
                free(allargtypes);
@@ -10246,6 +10261,8 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
        char       *oprjoin;
        char       *oprcanmerge;
        char       *oprcanhash;
+       char       *oprregproc;
+       char       *oprref;
 
        /* Skip if not to be dumped */
        if (!oprinfo->dobj.dump || dataOnly)
@@ -10352,8 +10369,12 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
        oprcanmerge = PQgetvalue(res, 0, i_oprcanmerge);
        oprcanhash = PQgetvalue(res, 0, i_oprcanhash);
 
-       appendPQExpBuffer(details, "    PROCEDURE = %s",
-                                         convertRegProcReference(fout, oprcode));
+       oprregproc = convertRegProcReference(fout, oprcode);
+       if (oprregproc)
+       {
+               appendPQExpBuffer(details, "    PROCEDURE = %s", oprregproc);
+               free(oprregproc);
+       }
 
        appendPQExpBuffer(oprid, "%s (",
                                          oprinfo->dobj.name);
@@ -10388,13 +10409,19 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
        else
                appendPQExpBufferStr(oprid, ", NONE)");
 
-       name = convertOperatorReference(fout, oprcom);
-       if (name)
-               appendPQExpBuffer(details, ",\n    COMMUTATOR = %s", name);
+       oprref = convertOperatorReference(fout, oprcom);
+       if (oprref)
+       {
+               appendPQExpBuffer(details, ",\n    COMMUTATOR = %s", oprref);
+               free(oprref);
+       }
 
-       name = convertOperatorReference(fout, oprnegate);
-       if (name)
-               appendPQExpBuffer(details, ",\n    NEGATOR = %s", name);
+       oprref = convertOperatorReference(fout, oprnegate);
+       if (oprref)
+       {
+               appendPQExpBuffer(details, ",\n    NEGATOR = %s", oprref);
+               free(oprref);
+       }
 
        if (strcmp(oprcanmerge, "t") == 0)
                appendPQExpBufferStr(details, ",\n    MERGES");
@@ -10402,13 +10429,19 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
        if (strcmp(oprcanhash, "t") == 0)
                appendPQExpBufferStr(details, ",\n    HASHES");
 
-       name = convertRegProcReference(fout, oprrest);
-       if (name)
-               appendPQExpBuffer(details, ",\n    RESTRICT = %s", name);
+       oprregproc = convertRegProcReference(fout, oprrest);
+       if (oprregproc)
+       {
+               appendPQExpBuffer(details, ",\n    RESTRICT = %s", oprregproc);
+               free(oprregproc);
+       }
 
-       name = convertRegProcReference(fout, oprjoin);
-       if (name)
-               appendPQExpBuffer(details, ",\n    JOIN = %s", name);
+       oprregproc = convertRegProcReference(fout, oprjoin);
+       if (oprregproc)
+       {
+               appendPQExpBuffer(details, ",\n    JOIN = %s", oprregproc);
+               free(oprregproc);
+       }
 
        /*
         * DROP must be fully qualified in case same name appears in pg_catalog
@@ -10453,12 +10486,13 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
 /*
  * Convert a function reference obtained from pg_operator
  *
- * Returns what to print, or NULL if function references is InvalidOid
+ * Returns allocated string of what to print, or NULL if function references
+ * is InvalidOid. Returned string is expected to be free'd by the caller.
  *
  * In 7.3 the input is a REGPROCEDURE display; we have to strip the
  * argument-types part.  In prior versions, the input is a REGPROC display.
  */
-static const char *
+static char *
 convertRegProcReference(Archive *fout, const char *proc)
 {
        /* In all cases "-" means a null reference */
@@ -10488,20 +10522,21 @@ convertRegProcReference(Archive *fout, const char *proc)
        }
 
        /* REGPROC before 7.3 does not quote its result */
-       return fmtId(proc);
+       return pg_strdup(fmtId(proc));
 }
 
 /*
  * Convert an operator cross-reference obtained from pg_operator
  *
- * Returns what to print, or NULL to print nothing
+ * Returns an allocated string of what to print, or NULL to print nothing.
+ * Caller is responsible for free'ing result string.
  *
  * In 7.3 and up the input is a REGOPERATOR display; we have to strip the
  * argument-types part, and add OPERATOR() decoration if the name is
  * schema-qualified.  In older versions, the input is just a numeric OID,
  * which we search our operator list for.
  */
-static const char *
+static char *
 convertOperatorReference(Archive *fout, const char *opr)
 {
        OprInfo    *oprInfo;
@@ -10549,7 +10584,7 @@ convertOperatorReference(Archive *fout, const char *opr)
                                  opr);
                return NULL;
        }
-       return oprInfo->dobj.name;
+       return pg_strdup(oprInfo->dobj.name);
 }
 
 /*
@@ -11508,24 +11543,41 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        PQExpBuffer labelq;
        PQExpBuffer details;
        char       *aggsig;                     /* identity signature */
-       char       *aggfullsig;         /* full signature */
+       char       *aggfullsig = NULL;          /* full signature */
        char       *aggsig_tag;
        PGresult   *res;
        int                     i_aggtransfn;
        int                     i_aggfinalfn;
+       int                     i_aggmtransfn;
+       int                     i_aggminvtransfn;
+       int                     i_aggmfinalfn;
+       int                     i_aggfinalextra;
+       int                     i_aggmfinalextra;
        int                     i_aggsortop;
        int                     i_hypothetical;
        int                     i_aggtranstype;
        int                     i_aggtransspace;
+       int                     i_aggmtranstype;
+       int                     i_aggmtransspace;
        int                     i_agginitval;
+       int                     i_aggminitval;
        int                     i_convertok;
        const char *aggtransfn;
        const char *aggfinalfn;
+       const char *aggmtransfn;
+       const char *aggminvtransfn;
+       const char *aggmfinalfn;
+       bool            aggfinalextra;
+       bool            aggmfinalextra;
        const char *aggsortop;
+       char       *aggsortconvop;
        bool            hypothetical;
        const char *aggtranstype;
        const char *aggtransspace;
+       const char *aggmtranstype;
+       const char *aggmtransspace;
        const char *agginitval;
+       const char *aggminitval;
        bool            convertok;
 
        /* Skip if not to be dumped */
@@ -11546,10 +11598,14 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        {
                appendPQExpBuffer(query, "SELECT aggtransfn, "
                                                  "aggfinalfn, aggtranstype::pg_catalog.regtype, "
+                                                 "aggmtransfn, aggminvtransfn, aggmfinalfn, "
+                                                 "aggmtranstype::pg_catalog.regtype, "
+                                                 "aggfinalextra, aggmfinalextra, "
                                                  "aggsortop::pg_catalog.regoperator, "
-                                                 "(aggkind = 'h') as hypothetical, "
+                                                 "(aggkind = 'h') AS hypothetical, "
                                                  "aggtransspace, agginitval, "
-                                                 "'t'::boolean AS convertok, "
+                                                 "aggmtransspace, aggminitval, "
+                                                 "true AS convertok, "
                                                  "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs, "
                                                  "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs "
                                          "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
@@ -11561,10 +11617,14 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        {
                appendPQExpBuffer(query, "SELECT aggtransfn, "
                                                  "aggfinalfn, aggtranstype::pg_catalog.regtype, "
+                                                 "'-' AS aggmtransfn, '-' AS aggminvtransfn, "
+                                                 "'-' AS aggmfinalfn, 0 AS aggmtranstype, "
+                                                 "false AS aggfinalextra, false AS aggmfinalextra, "
                                                  "aggsortop::pg_catalog.regoperator, "
-                                                 "false as hypothetical, "
+                                                 "false AS hypothetical, "
                                                  "0 AS aggtransspace, agginitval, "
-                                                 "'t'::boolean AS convertok, "
+                                                 "0 AS aggmtransspace, NULL AS aggminitval, "
+                                                 "true AS convertok, "
                                                  "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs, "
                                                  "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs "
                                          "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
@@ -11576,10 +11636,14 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        {
                appendPQExpBuffer(query, "SELECT aggtransfn, "
                                                  "aggfinalfn, aggtranstype::pg_catalog.regtype, "
+                                                 "'-' AS aggmtransfn, '-' AS aggminvtransfn, "
+                                                 "'-' AS aggmfinalfn, 0 AS aggmtranstype, "
+                                                 "false AS aggfinalextra, false AS aggmfinalextra, "
                                                  "aggsortop::pg_catalog.regoperator, "
-                                                 "false as hypothetical, "
+                                                 "false AS hypothetical, "
                                                  "0 AS aggtransspace, agginitval, "
-                                                 "'t'::boolean AS convertok "
+                                                 "0 AS aggmtransspace, NULL AS aggminitval, "
+                                                 "true AS convertok "
                                                  "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
                                                  "WHERE a.aggfnoid = p.oid "
                                                  "AND p.oid = '%u'::pg_catalog.oid",
@@ -11589,10 +11653,14 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        {
                appendPQExpBuffer(query, "SELECT aggtransfn, "
                                                  "aggfinalfn, aggtranstype::pg_catalog.regtype, "
+                                                 "'-' AS aggmtransfn, '-' AS aggminvtransfn, "
+                                                 "'-' AS aggmfinalfn, 0 AS aggmtranstype, "
+                                                 "false AS aggfinalextra, false AS aggmfinalextra, "
                                                  "0 AS aggsortop, "
-                                                 "'f'::boolean as hypothetical, "
+                                                 "false AS hypothetical, "
                                                  "0 AS aggtransspace, agginitval, "
-                                                 "'t'::boolean AS convertok "
+                                                 "0 AS aggmtransspace, NULL AS aggminitval, "
+                                                 "true AS convertok "
                                          "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
                                                  "WHERE a.aggfnoid = p.oid "
                                                  "AND p.oid = '%u'::pg_catalog.oid",
@@ -11602,10 +11670,14 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        {
                appendPQExpBuffer(query, "SELECT aggtransfn, aggfinalfn, "
                                                  "format_type(aggtranstype, NULL) AS aggtranstype, "
+                                                 "'-' AS aggmtransfn, '-' AS aggminvtransfn, "
+                                                 "'-' AS aggmfinalfn, 0 AS aggmtranstype, "
+                                                 "false AS aggfinalextra, false AS aggmfinalextra, "
                                                  "0 AS aggsortop, "
-                                                 "'f'::boolean as hypothetical, "
+                                                 "false AS hypothetical, "
                                                  "0 AS aggtransspace, agginitval, "
-                                                 "'t'::boolean AS convertok "
+                                                 "0 AS aggmtransspace, NULL AS aggminitval, "
+                                                 "true AS convertok "
                                                  "FROM pg_aggregate "
                                                  "WHERE oid = '%u'::oid",
                                                  agginfo->aggfn.dobj.catId.oid);
@@ -11615,9 +11687,13 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                appendPQExpBuffer(query, "SELECT aggtransfn1 AS aggtransfn, "
                                                  "aggfinalfn, "
                                                  "(SELECT typname FROM pg_type WHERE oid = aggtranstype1) AS aggtranstype, "
+                                                 "'-' AS aggmtransfn, '-' AS aggminvtransfn, "
+                                                 "'-' AS aggmfinalfn, 0 AS aggmtranstype, "
+                                                 "false AS aggfinalextra, false AS aggmfinalextra, "
                                                  "0 AS aggsortop, "
-                                                 "'f'::boolean as hypothetical, "
+                                                 "false AS hypothetical, "
                                                  "0 AS aggtransspace, agginitval1 AS agginitval, "
+                                                 "0 AS aggmtransspace, NULL AS aggminitval, "
                                                  "(aggtransfn2 = 0 and aggtranstype2 = 0 and agginitval2 is null) AS convertok "
                                                  "FROM pg_aggregate "
                                                  "WHERE oid = '%u'::oid",
@@ -11628,20 +11704,36 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
 
        i_aggtransfn = PQfnumber(res, "aggtransfn");
        i_aggfinalfn = PQfnumber(res, "aggfinalfn");
+       i_aggmtransfn = PQfnumber(res, "aggmtransfn");
+       i_aggminvtransfn = PQfnumber(res, "aggminvtransfn");
+       i_aggmfinalfn = PQfnumber(res, "aggmfinalfn");
+       i_aggfinalextra = PQfnumber(res, "aggfinalextra");
+       i_aggmfinalextra = PQfnumber(res, "aggmfinalextra");
        i_aggsortop = PQfnumber(res, "aggsortop");
        i_hypothetical = PQfnumber(res, "hypothetical");
        i_aggtranstype = PQfnumber(res, "aggtranstype");
        i_aggtransspace = PQfnumber(res, "aggtransspace");
+       i_aggmtranstype = PQfnumber(res, "aggmtranstype");
+       i_aggmtransspace = PQfnumber(res, "aggmtransspace");
        i_agginitval = PQfnumber(res, "agginitval");
+       i_aggminitval = PQfnumber(res, "aggminitval");
        i_convertok = PQfnumber(res, "convertok");
 
        aggtransfn = PQgetvalue(res, 0, i_aggtransfn);
        aggfinalfn = PQgetvalue(res, 0, i_aggfinalfn);
+       aggmtransfn = PQgetvalue(res, 0, i_aggmtransfn);
+       aggminvtransfn = PQgetvalue(res, 0, i_aggminvtransfn);
+       aggmfinalfn = PQgetvalue(res, 0, i_aggmfinalfn);
+       aggfinalextra = (PQgetvalue(res, 0, i_aggfinalextra)[0] == 't');
+       aggmfinalextra = (PQgetvalue(res, 0, i_aggmfinalextra)[0] == 't');
        aggsortop = PQgetvalue(res, 0, i_aggsortop);
        hypothetical = (PQgetvalue(res, 0, i_hypothetical)[0] == 't');
        aggtranstype = PQgetvalue(res, 0, i_aggtranstype);
        aggtransspace = PQgetvalue(res, 0, i_aggtransspace);
+       aggmtranstype = PQgetvalue(res, 0, i_aggmtranstype);
+       aggmtransspace = PQgetvalue(res, 0, i_aggmtransspace);
        agginitval = PQgetvalue(res, 0, i_agginitval);
+       aggminitval = PQgetvalue(res, 0, i_aggminitval);
        convertok = (PQgetvalue(res, 0, i_convertok)[0] == 't');
 
        if (fout->remoteVersion >= 80400)
@@ -11656,11 +11748,8 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                aggsig = format_function_arguments(&agginfo->aggfn, funciargs, true);
        }
        else
-       {
                /* pre-8.4, do it ourselves */
                aggsig = format_aggregate_signature(agginfo, fout, true);
-               aggfullsig = aggsig;
-       }
 
        aggsig_tag = format_aggregate_signature(agginfo, fout, false);
 
@@ -11668,6 +11757,12 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        {
                write_msg(NULL, "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n",
                                  aggsig);
+
+               if (aggfullsig)
+                       free(aggfullsig);
+
+               free(aggsig);
+
                return;
        }
 
@@ -11710,13 +11805,44 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        {
                appendPQExpBuffer(details, ",\n    FINALFUNC = %s",
                                                  aggfinalfn);
+               if (aggfinalextra)
+                       appendPQExpBufferStr(details, ",\n    FINALFUNC_EXTRA");
+       }
+
+       if (strcmp(aggmtransfn, "-") != 0)
+       {
+               appendPQExpBuffer(details, ",\n    MSFUNC = %s,\n    MINVFUNC = %s,\n    MSTYPE = %s",
+                                                 aggmtransfn,
+                                                 aggminvtransfn,
+                                                 aggmtranstype);
        }
 
-       aggsortop = convertOperatorReference(fout, aggsortop);
-       if (aggsortop)
+       if (strcmp(aggmtransspace, "0") != 0)
+       {
+               appendPQExpBuffer(details, ",\n    MSSPACE = %s",
+                                                 aggmtransspace);
+       }
+
+       if (!PQgetisnull(res, 0, i_aggminitval))
+       {
+               appendPQExpBufferStr(details, ",\n    MINITCOND = ");
+               appendStringLiteralAH(details, aggminitval, fout);
+       }
+
+       if (strcmp(aggmfinalfn, "-") != 0)
+       {
+               appendPQExpBuffer(details, ",\n    MFINALFUNC = %s",
+                                                 aggmfinalfn);
+               if (aggmfinalextra)
+                       appendPQExpBufferStr(details, ",\n    MFINALFUNC_EXTRA");
+       }
+
+       aggsortconvop = convertOperatorReference(fout, aggsortop);
+       if (aggsortconvop)
        {
                appendPQExpBuffer(details, ",\n    SORTOP = %s",
-                                                 aggsortop);
+                                                 aggsortconvop);
+               free(aggsortconvop);
        }
 
        if (hypothetical)
@@ -11730,7 +11856,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                          aggsig);
 
        appendPQExpBuffer(q, "CREATE AGGREGATE %s (\n%s\n);\n",
-                                         aggfullsig, details->data);
+                                         aggfullsig ? aggfullsig : aggsig, details->data);
 
        appendPQExpBuffer(labelq, "AGGREGATE %s", aggsig);
 
@@ -11773,6 +11899,8 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                        agginfo->aggfn.rolname, agginfo->aggfn.proacl);
 
        free(aggsig);
+       if (aggfullsig)
+               free(aggfullsig);
        free(aggsig_tag);
 
        PQclear(res);
@@ -12414,6 +12542,7 @@ dumpUserMappings(Archive *fout,
 
        destroyPQExpBuffer(query);
        destroyPQExpBuffer(delq);
+       destroyPQExpBuffer(tag);
        destroyPQExpBuffer(q);
 }
 
@@ -13570,7 +13699,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                        (tbinfo->relkind == RELKIND_VIEW) ? NULL : tbinfo->reltablespace,
                                 tbinfo->rolname,
                           (strcmp(reltypename, "TABLE") == 0) ? tbinfo->hasoids : false,
-                                reltypename, SECTION_PRE_DATA,
+                                reltypename,
+                                tbinfo->postponed_def ? SECTION_POST_DATA : SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
                                 NULL, 0,
                                 NULL, NULL);
@@ -13732,7 +13862,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
                                                          fmtId(indxinfo->dobj.name));
                }
 
-               /* If the index is clustered, we need to record that. */
+               /* If the index defines identity, we need to record that. */
                if (indxinfo->indisreplident)
                {
                        appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",