OSDN Git Service

Add a "provariadic" column to pg_proc to eliminate the remarkably expensive
[pg-rex/syncrep.git] / src / bin / pg_dump / pg_dump.c
index ba15398..c4602fd 100644 (file)
@@ -4,7 +4,7 @@
  *       pg_dump is a utility for dumping out a postgres database
  *       into a script file.
  *
- * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *     pg_dump will read the system catalogs in a database and dump out a
  *     by PostgreSQL
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.475 2007/11/08 10:37:54 petere Exp $
+ *       $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.495 2008/07/16 16:55:23 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
-/*
- * Although this is not a backend module, we must include postgres.h anyway
- * so that we can include a bunch of backend include files.  pg_dump has
- * never pretended to be very independent of the backend anyhow ...
- */
-#include "postgres.h"
+#include "postgres_fe.h"
 
 #include <unistd.h>
-
 #include <ctype.h>
 #ifdef ENABLE_NLS
 #include <locale.h>
 int                    optreset;
 #endif
 
-#include "access/htup.h"
+#include "access/attnum.h"
+#include "access/sysattr.h"
 #include "catalog/pg_class.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_trigger.h"
 #include "catalog/pg_type.h"
-#include "commands/sequence.h"
 #include "libpq/libpq-fs.h"
 
 #include "pg_backup_archiver.h"
@@ -90,15 +84,15 @@ static Oid  g_last_builtin_oid; /* value of the last builtin oid */
  * The string lists record the patterns given by command-line switches,
  * which we then convert to lists of OIDs of matching objects.
  */
-static SimpleStringList schema_include_patterns = { NULL, NULL };
-static SimpleOidList schema_include_oids = { NULL, NULL };
-static SimpleStringList schema_exclude_patterns = { NULL, NULL };
-static SimpleOidList schema_exclude_oids = { NULL, NULL };
+static SimpleStringList schema_include_patterns = {NULL, NULL};
+static SimpleOidList schema_include_oids = {NULL, NULL};
+static SimpleStringList schema_exclude_patterns = {NULL, NULL};
+static SimpleOidList schema_exclude_oids = {NULL, NULL};
 
-static SimpleStringList table_include_patterns = { NULL, NULL };
-static SimpleOidList table_include_oids = { NULL, NULL };
-static SimpleStringList table_exclude_patterns = { NULL, NULL };
-static SimpleOidList table_exclude_oids = { NULL, NULL };
+static SimpleStringList table_include_patterns = {NULL, NULL};
+static SimpleOidList table_include_oids = {NULL, NULL};
+static SimpleStringList table_exclude_patterns = {NULL, NULL};
+static SimpleOidList table_exclude_oids = {NULL, NULL};
 
 /* default, if no "inclusion" switches appear, is to dump everything */
 static bool include_everything = true;
@@ -121,11 +115,12 @@ static int        disable_dollar_quoting = 0;
 
 static void help(const char *progname);
 static void expand_schema_name_patterns(SimpleStringList *patterns,
-                                                                               SimpleOidList *oids);
+                                                       SimpleOidList *oids);
 static void expand_table_name_patterns(SimpleStringList *patterns,
-                                                                          SimpleOidList *oids);
+                                                  SimpleOidList *oids);
 static NamespaceInfo *findNamespace(Oid nsoid, Oid objoid);
 static void dumpTableData(Archive *fout, TableDataInfo *tdinfo);
+static void guessConstraintInheritance(TableInfo *tblinfo, int numTables);
 static void dumpComment(Archive *fout, const char *target,
                        const char *namespace, const char *owner,
                        CatalogId catalogId, int subid, DumpId dumpId);
@@ -217,18 +212,20 @@ main(int argc, char **argv)
        int                     i;
        bool            force_password = false;
        int                     compressLevel = -1;
-       bool            ignore_version = false;
        int                     plainText = 0;
        int                     outputClean = 0;
        int                     outputCreate = 0;
        bool            outputBlobs = false;
        int                     outputNoOwner = 0;
-       static int      use_setsessauth = 0;
-       static int      disable_triggers = 0;
        char       *outputSuperuser = NULL;
-
+       int                     my_version;
+       int                     optindex;
        RestoreOptions *ropt;
 
+       static int      disable_triggers = 0;
+       static int  outputNoTablespaces = 0;
+       static int      use_setsessauth = 0;
+
        static struct option long_options[] = {
                {"data-only", no_argument, NULL, 'a'},
                {"blobs", no_argument, NULL, 'b'},
@@ -266,11 +263,11 @@ main(int argc, char **argv)
                 */
                {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
                {"disable-triggers", no_argument, &disable_triggers, 1},
+               {"no-tablespaces", no_argument, &outputNoTablespaces, 1},
                {"use-set-session-authorization", no_argument, &use_setsessauth, 1},
 
                {NULL, 0, NULL, 0}
        };
-       int                     optindex;
 
        set_pglocale_pgservice(argv[0], "pg_dump");
 
@@ -302,7 +299,7 @@ main(int argc, char **argv)
                }
        }
 
-       while ((c = getopt_long(argc, argv, "abcCdDE:f:F:h:in:N:oOp:RsS:t:T:uU:vWxX:Z:",
+       while ((c = getopt_long(argc, argv, "abcCdDE:f:F:h:in:N:oOp:RsS:t:T:U:vWxX:Z:",
                                                        long_options, &optindex)) != -1)
        {
                switch (c)
@@ -349,8 +346,8 @@ main(int argc, char **argv)
                                pghost = optarg;
                                break;
 
-                       case 'i':                       /* ignore database version mismatch */
-                               ignore_version = true;
+                       case 'i':
+                               /* ignored, deprecated option */
                                break;
 
                        case 'n':                       /* include schema(s) */
@@ -395,11 +392,6 @@ main(int argc, char **argv)
                                simple_string_list_append(&table_exclude_patterns, optarg);
                                break;
 
-                       case 'u':
-                               force_password = true;
-                               username = simple_prompt("User name: ", 100, true);
-                               break;
-
                        case 'U':
                                username = optarg;
                                break;
@@ -422,6 +414,8 @@ main(int argc, char **argv)
                                        disable_dollar_quoting = 1;
                                else if (strcmp(optarg, "disable-triggers") == 0)
                                        disable_triggers = 1;
+                               else if (strcmp(optarg, "no-tablespaces") == 0)
+                                       outputNoTablespaces = 1;
                                else if (strcmp(optarg, "use-set-session-authorization") == 0)
                                        use_setsessauth = 1;
                                else
@@ -492,8 +486,8 @@ main(int argc, char **argv)
        else if (pg_strcasecmp(format, "f") == 0 || pg_strcasecmp(format, "file") == 0)
        {
                /*
-                *      Dump files into the current directory; for demonstration only, not
-                *      documented.
+                * Dump files into the current directory; for demonstration only, not
+                * documented.
                 */
                g_fout = CreateArchive(filename, archFiles, compressLevel, archModeWrite);
        }
@@ -519,20 +513,26 @@ main(int argc, char **argv)
        /* Let the archiver know how noisy to be */
        g_fout->verbose = g_verbose;
 
-       g_fout->minRemoteVersion = 70000;       /* we can handle back to 7.0 */
-       g_fout->maxRemoteVersion = parse_version(PG_VERSION);
-       if (g_fout->maxRemoteVersion < 0)
+       my_version = parse_version(PG_VERSION);
+       if (my_version < 0)
        {
                write_msg(NULL, "could not parse version string \"%s\"\n", PG_VERSION);
                exit(1);
        }
 
        /*
+        * We allow the server to be back to 7.0, and up to any minor release
+        * of our own major version.  (See also version check in pg_dumpall.c.)
+        */
+       g_fout->minRemoteVersion = 70000;
+       g_fout->maxRemoteVersion = (my_version / 100) * 100 + 99;
+
+       /*
         * Open the database using the Archiver, so it knows about it. Errors mean
         * death.
         */
        g_conn = ConnectDatabase(g_fout, dbname, pghost, pgport,
-                                                        username, force_password, ignore_version);
+                                                        username, force_password);
 
        /* Set the client encoding if requested */
        if (dumpencoding)
@@ -558,6 +558,26 @@ main(int argc, char **argv)
        do_sql_command(g_conn, "SET DATESTYLE = ISO");
 
        /*
+        * If supported, set extra_float_digits so that we can dump float data
+        * exactly (given correctly implemented float I/O code, anyway)
+        */
+       if (g_fout->remoteVersion >= 70400)
+               do_sql_command(g_conn, "SET extra_float_digits TO 2");
+
+       /*
+        * If synchronized scanning is supported, disable it, to prevent
+        * unpredictable changes in row ordering across a dump and reload.
+        */
+       if (g_fout->remoteVersion >= 80300)
+               do_sql_command(g_conn, "SET synchronize_seqscans TO off");
+
+       /*
+        * Disable timeouts if supported.
+        */
+       if (g_fout->remoteVersion >= 70300)
+               do_sql_command(g_conn, "SET statement_timeout = 0");
+         
+       /*
         * Start serializable transaction to dump consistent data.
         */
        do_sql_command(g_conn, "BEGIN");
@@ -572,13 +592,6 @@ main(int argc, char **argv)
        else
                username_subquery = "SELECT usename FROM pg_user WHERE usesysid =";
 
-       /*
-        * If supported, set extra_float_digits so that we can dump float data
-        * exactly (given correctly implemented float I/O code, anyway)
-        */
-       if (g_fout->remoteVersion >= 70400)
-               do_sql_command(g_conn, "SET extra_float_digits TO 2");
-
        /* Find the last built-in OID, if needed */
        if (g_fout->remoteVersion < 70300)
        {
@@ -633,6 +646,9 @@ main(int argc, char **argv)
         */
        tblinfo = getSchemaData(&numTables);
 
+       if (g_fout->remoteVersion < 80400)
+               guessConstraintInheritance(tblinfo, numTables);
+
        if (!schemaOnly)
                getTableData(tblinfo, numTables, oids);
 
@@ -706,6 +722,7 @@ main(int argc, char **argv)
                ropt->superuser = outputSuperuser;
                ropt->create = outputCreate;
                ropt->noOwner = outputNoOwner;
+               ropt->noTablespace = outputNoTablespaces;
                ropt->disable_triggers = disable_triggers;
                ropt->use_setsessauth = use_setsessauth;
                ropt->dataOnly = dataOnly;
@@ -738,8 +755,6 @@ help(const char *progname)
        printf(_("\nGeneral options:\n"));
        printf(_("  -f, --file=FILENAME      output file name\n"));
        printf(_("  -F, --format=c|t|p       output file format (custom, tar, plain text)\n"));
-       printf(_("  -i, --ignore-version     proceed even when server version mismatches\n"
-                        "                           pg_dump version\n"));
        printf(_("  -v, --verbose            verbose mode\n"));
        printf(_("  -Z, --compress=0-9       compression level for compressed formats\n"));
        printf(_("  --help                   show this help, then exit\n"));
@@ -766,9 +781,10 @@ help(const char *progname)
        printf(_("  -x, --no-privileges         do not dump privileges (grant/revoke)\n"));
        printf(_("  --disable-dollar-quoting    disable dollar quoting, use SQL standard quoting\n"));
        printf(_("  --disable-triggers          disable triggers during data-only restore\n"));
+       printf(_("  --no-tablespaces            do not dump tablespace assignments\n"));
        printf(_("  --use-set-session-authorization\n"
                         "                              use SESSION AUTHORIZATION commands instead of\n"
-                        "                              ALTER OWNER commands to set ownership\n"));
+       "                              ALTER OWNER commands to set ownership\n"));
 
        printf(_("\nConnection options:\n"));
        printf(_("  -h, --host=HOSTNAME      database server host or socket directory\n"));
@@ -870,7 +886,7 @@ expand_table_name_patterns(SimpleStringList *patterns, SimpleOidList *oids)
                appendPQExpBuffer(query,
                                                  "SELECT c.oid"
                                                  "\nFROM pg_catalog.pg_class c"
-                                                 "\n     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace"
+               "\n     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace"
                                                  "\nWHERE c.relkind in ('%c', '%c', '%c')\n",
                                                  RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW);
                processSQLNamePattern(g_conn, query, cell->val, true, false,
@@ -912,6 +928,7 @@ selectDumpableNamespace(NamespaceInfo *nsinfo)
                nsinfo->dobj.dump = false;
        else
                nsinfo->dobj.dump = true;
+
        /*
         * In any case, a namespace can be excluded by an exclusion switch
         */
@@ -929,14 +946,15 @@ static void
 selectDumpableTable(TableInfo *tbinfo)
 {
        /*
-        * If specific tables are being dumped, dump just those tables;
-        * else, dump according to the parent namespace's dump flag.
+        * If specific tables are being dumped, dump just those tables; else, dump
+        * according to the parent namespace's dump flag.
         */
        if (table_include_oids.head != NULL)
                tbinfo->dobj.dump = simple_oid_list_member(&table_include_oids,
                                                                                                   tbinfo->dobj.catId.oid);
        else
                tbinfo->dobj.dump = tbinfo->dobj.namespace->dobj.dump;
+
        /*
         * In any case, a table can be excluded by an exclusion switch
         */
@@ -1081,10 +1099,10 @@ dumpTableData_copy(Archive *fout, void *dcontext)
                 * was too tight. Finally, the following was implemented:
                 *
                 * If throttle is non-zero, then
-                *              See how long since the last sleep.
+                *              See how long since the last sleep.
                 *              Work out how long to sleep (based on ratio).
-                *              If sleep is more than 100ms, then 
-                *                      sleep 
+                *              If sleep is more than 100ms, then
+                *                      sleep
                 *                      reset timer
                 *              EndIf
                 * EndIf
@@ -1370,6 +1388,81 @@ getTableData(TableInfo *tblinfo, int numTables, bool oids)
 
 
 /*
+ * guessConstraintInheritance:
+ *     In pre-8.4 databases, we can't tell for certain which constraints
+ *     are inherited.  We assume a CHECK constraint is inherited if its name
+ *     matches the name of any constraint in the parent.  Originally this code
+ *     tried to compare the expression texts, but that can fail for various
+ *     reasons --- for example, if the parent and child tables are in different
+ *     schemas, reverse-listing of function calls may produce different text
+ *     (schema-qualified or not) depending on search path.
+ *
+ *     In 8.4 and up we can rely on the conislocal field to decide which
+ *     constraints must be dumped; much safer.
+ *
+ *     This function assumes all conislocal flags were initialized to TRUE.
+ *     It clears the flag on anything that seems to be inherited.
+ */
+static void
+guessConstraintInheritance(TableInfo *tblinfo, int numTables)
+{
+       int                     i,
+                               j,
+                               k;
+
+       for (i = 0; i < numTables; i++)
+       {
+               TableInfo  *tbinfo = &(tblinfo[i]);
+               int                     numParents;
+               TableInfo **parents;
+               TableInfo  *parent;
+
+               /* Sequences and views never have parents */
+               if (tbinfo->relkind == RELKIND_SEQUENCE ||
+                       tbinfo->relkind == RELKIND_VIEW)
+                       continue;
+
+               /* Don't bother computing anything for non-target tables, either */
+               if (!tbinfo->dobj.dump)
+                       continue;
+
+               numParents = tbinfo->numParents;
+               parents = tbinfo->parents;
+
+               if (numParents == 0)
+                       continue;                       /* nothing to see here, move along */
+
+               /* scan for inherited CHECK constraints */
+               for (j = 0; j < tbinfo->ncheck; j++)
+               {
+                       ConstraintInfo *constr;
+
+                       constr = &(tbinfo->checkexprs[j]);
+
+                       for (k = 0; k < numParents; k++)
+                       {
+                               int                     l;
+
+                               parent = parents[k];
+                               for (l = 0; l < parent->ncheck; l++)
+                               {
+                                       ConstraintInfo *pconstr = &(parent->checkexprs[l]);
+
+                                       if (strcmp(pconstr->dobj.name, constr->dobj.name) == 0)
+                                       {
+                                               constr->conislocal = false;
+                                               break;
+                                       }
+                               }
+                               if (!constr->conislocal)
+                                       break;
+                       }
+               }
+       }
+}
+
+
+/*
  * dumpDatabase:
  *     dump the database definition
  */
@@ -1528,6 +1621,7 @@ dumpDatabase(Archive *AH)
                if (comment && strlen(comment))
                {
                        resetPQExpBuffer(dbQry);
+                       /* Generates warning when loaded into a differently-named database.*/
                        appendPQExpBuffer(dbQry, "COMMENT ON DATABASE %s IS ", fmtId(datname));
                        appendStringLiteralAH(dbQry, comment, AH);
                        appendPQExpBuffer(dbQry, ";\n");
@@ -1984,10 +2078,10 @@ getTypes(int *numTypes)
         *
         * Note: as of 8.3 we can reliably detect whether a type is an
         * auto-generated array type by checking the element type's typarray.
-        * (Before that the test is capable of generating false positives.)
-        * We still check for name beginning with '_', though, so as to avoid
-        * the cost of the subselect probe for all standard types.  This would
-        * have to be revisited if the backend ever allows renaming of array types.
+        * (Before that the test is capable of generating false positives.) We
+        * still check for name beginning with '_', though, so as to avoid the
+        * cost of the subselect probe for all standard types.  This would have to
+        * be revisited if the backend ever allows renaming of array types.
         */
 
        /* Make sure we are in proper schema */
@@ -3507,7 +3601,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                constrinfo[j].contype = contype;
                                constrinfo[j].condef = NULL;
                                constrinfo[j].conindex = indxinfo[j].dobj.dumpId;
-                               constrinfo[j].coninherited = false;
+                               constrinfo[j].conislocal = true;
                                constrinfo[j].separate = true;
 
                                indxinfo[j].indexconstraint = constrinfo[j].dobj.dumpId;
@@ -3608,7 +3702,7 @@ getConstraints(TableInfo tblinfo[], int numTables)
                        constrinfo[j].contype = 'f';
                        constrinfo[j].condef = strdup(PQgetvalue(res, j, i_condef));
                        constrinfo[j].conindex = 0;
-                       constrinfo[j].coninherited = false;
+                       constrinfo[j].conislocal = true;
                        constrinfo[j].separate = true;
                }
 
@@ -3691,7 +3785,7 @@ getDomainConstraints(TypeInfo *tinfo)
                constrinfo[i].contype = 'c';
                constrinfo[i].condef = strdup(PQgetvalue(res, i, i_consrc));
                constrinfo[i].conindex = 0;
-               constrinfo[i].coninherited = false;
+               constrinfo[i].conislocal = true;
                constrinfo[i].separate = false;
 
                /*
@@ -4571,10 +4665,22 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                                  tbinfo->dobj.name);
 
                        resetPQExpBuffer(q);
-                       if (g_fout->remoteVersion >= 70400)
+                       if (g_fout->remoteVersion >= 80400)
                        {
                                appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
-                                                       "pg_catalog.pg_get_constraintdef(oid) AS consrc "
+                                                       "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
+                                                                 "conislocal "
+                                                                 "FROM pg_catalog.pg_constraint "
+                                                                 "WHERE conrelid = '%u'::pg_catalog.oid "
+                                                                 "   AND contype = 'c' "
+                                                                 "ORDER BY conname",
+                                                                 tbinfo->dobj.catId.oid);
+                       }
+                       else if (g_fout->remoteVersion >= 70400)
+                       {
+                               appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
+                                                       "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
+                                                                 "true as conislocal "
                                                                  "FROM pg_catalog.pg_constraint "
                                                                  "WHERE conrelid = '%u'::pg_catalog.oid "
                                                                  "   AND contype = 'c' "
@@ -4585,7 +4691,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                        {
                                /* no pg_get_constraintdef, must use consrc */
                                appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
-                                                                 "'CHECK (' || consrc || ')' AS consrc "
+                                                                 "'CHECK (' || consrc || ')' AS consrc, "
+                                                                 "true as conislocal "
                                                                  "FROM pg_catalog.pg_constraint "
                                                                  "WHERE conrelid = '%u'::pg_catalog.oid "
                                                                  "   AND contype = 'c' "
@@ -4597,7 +4704,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                /* 7.2 did not have OIDs in pg_relcheck */
                                appendPQExpBuffer(q, "SELECT tableoid, 0 as oid, "
                                                                  "rcname AS conname, "
-                                                                 "'CHECK (' || rcsrc || ')' AS consrc "
+                                                                 "'CHECK (' || rcsrc || ')' AS consrc, "
+                                                                 "true as conislocal "
                                                                  "FROM pg_relcheck "
                                                                  "WHERE rcrelid = '%u'::oid "
                                                                  "ORDER BY rcname",
@@ -4607,7 +4715,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                        {
                                appendPQExpBuffer(q, "SELECT tableoid, oid, "
                                                                  "rcname AS conname, "
-                                                                 "'CHECK (' || rcsrc || ')' AS consrc "
+                                                                 "'CHECK (' || rcsrc || ')' AS consrc, "
+                                                                 "true as conislocal "
                                                                  "FROM pg_relcheck "
                                                                  "WHERE rcrelid = '%u'::oid "
                                                                  "ORDER BY rcname",
@@ -4619,7 +4728,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                appendPQExpBuffer(q, "SELECT "
                                                                  "(SELECT oid FROM pg_class WHERE relname = 'pg_relcheck') AS tableoid, "
                                                                  "oid, rcname AS conname, "
-                                                                 "'CHECK (' || rcsrc || ')' AS consrc "
+                                                                 "'CHECK (' || rcsrc || ')' AS consrc, "
+                                                                 "true as conislocal "
                                                                  "FROM pg_relcheck "
                                                                  "WHERE rcrelid = '%u'::oid "
                                                                  "ORDER BY rcname",
@@ -4653,7 +4763,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                constrs[j].contype = 'c';
                                constrs[j].condef = strdup(PQgetvalue(res, j, 3));
                                constrs[j].conindex = 0;
-                               constrs[j].coninherited = false;
+                               constrs[j].conislocal = (PQgetvalue(res, j, 4)[0] == 't');
                                constrs[j].separate = false;
 
                                constrs[j].dobj.dump = tbinfo->dobj.dump;
@@ -4669,8 +4779,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
 
                                /*
                                 * If the constraint is inherited, this will be detected
-                                * later.  We also detect later if the constraint must be
-                                * split out from the table definition.
+                                * later (in pre-8.4 databases).  We also detect later if the
+                                * constraint must be split out from the table definition.
                                 */
                        }
                        PQclear(res);
@@ -4752,7 +4862,7 @@ getTSParsers(int *numTSParsers)
                AssignDumpId(&prsinfo[i].dobj);
                prsinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_prsname));
                prsinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_prsnamespace)),
-                                                                               prsinfo[i].dobj.catId.oid);
+                                                                                                 prsinfo[i].dobj.catId.oid);
                prsinfo[i].prsstart = atooid(PQgetvalue(res, i, i_prsstart));
                prsinfo[i].prstoken = atooid(PQgetvalue(res, i, i_prstoken));
                prsinfo[i].prsend = atooid(PQgetvalue(res, i, i_prsend));
@@ -4833,7 +4943,7 @@ getTSDictionaries(int *numTSDicts)
                AssignDumpId(&dictinfo[i].dobj);
                dictinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_dictname));
                dictinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_dictnamespace)),
-                                                                                                       dictinfo[i].dobj.catId.oid);
+                                                                                                dictinfo[i].dobj.catId.oid);
                dictinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
                dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
                if (PQgetisnull(res, i, i_dictinitoption))
@@ -4911,7 +5021,7 @@ getTSTemplates(int *numTSTemplates)
                AssignDumpId(&tmplinfo[i].dobj);
                tmplinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_tmplname));
                tmplinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_tmplnamespace)),
-                                                                                                       tmplinfo[i].dobj.catId.oid);
+                                                                                                tmplinfo[i].dobj.catId.oid);
                tmplinfo[i].tmplinit = atooid(PQgetvalue(res, i, i_tmplinit));
                tmplinfo[i].tmpllexize = atooid(PQgetvalue(res, i, i_tmpllexize));
 
@@ -4986,7 +5096,7 @@ getTSConfigurations(int *numTSConfigs)
                AssignDumpId(&cfginfo[i].dobj);
                cfginfo[i].dobj.name = strdup(PQgetvalue(res, i, i_cfgname));
                cfginfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)),
-                                                                                                       cfginfo[i].dobj.catId.oid);
+                                                                                                 cfginfo[i].dobj.catId.oid);
                cfginfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
                cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
 
@@ -5506,8 +5616,9 @@ dumpEnumType(Archive *fout, TypeInfo *tinfo)
        PQExpBuffer delq = createPQExpBuffer();
        PQExpBuffer query = createPQExpBuffer();
        PGresult   *res;
-       int num, i;
-       char *label;
+       int                     num,
+                               i;
+       char       *label;
 
        /* Set proper schema search path so regproc references list correctly */
        selectSourceSchema(tinfo->dobj.namespace->dobj.name);
@@ -5530,8 +5641,8 @@ dumpEnumType(Archive *fout, TypeInfo *tinfo)
 
        /*
         * DROP must be fully qualified in case same name appears in pg_catalog.
-        * CASCADE shouldn't be required here as for normal types since the
-        * I/O functions are generic and do not get dropped.
+        * CASCADE shouldn't be required here as for normal types since the I/O
+        * functions are generic and do not get dropped.
         */
        appendPQExpBuffer(delq, "DROP TYPE %s.",
                                          fmtId(tinfo->dobj.namespace->dobj.name));
@@ -5543,8 +5654,8 @@ dumpEnumType(Archive *fout, TypeInfo *tinfo)
        {
                label = PQgetvalue(res, i, 0);
                if (i > 0)
-                       appendPQExpBuffer(q, ",\n"); 
-               appendPQExpBuffer(q, "    "); 
+                       appendPQExpBuffer(q, ",\n");
+               appendPQExpBuffer(q, "    ");
                appendStringLiteralAH(q, label, fout);
        }
        appendPQExpBuffer(q, "\n);\n");
@@ -6324,15 +6435,18 @@ format_function_arguments(FuncInfo *finfo, int nallargs,
                {
                        switch (argmodes[j][0])
                        {
-                               case 'i':
+                               case PROARGMODE_IN:
                                        argmode = "";
                                        break;
-                               case 'o':
+                               case PROARGMODE_OUT:
                                        argmode = "OUT ";
                                        break;
-                               case 'b':
+                               case PROARGMODE_INOUT:
                                        argmode = "INOUT ";
                                        break;
+                               case PROARGMODE_VARIADIC:
+                                       argmode = "VARIADIC ";
+                                       break;
                                default:
                                        write_msg(NULL, "WARNING: bogus value in proargmodes array\n");
                                        argmode = "";
@@ -6557,10 +6671,12 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));
 
        /*
-        * See backend/commands/define.c for details of how the 'AS' clause is
-        * used.
+        * See backend/commands/functioncmds.c for details of how the 'AS' clause
+        * is used.  In 8.4 and up, an unused probin is NULL (here ""); previous
+        * versions would set it to "-".  There are no known cases in which prosrc
+        * is unused, so the tests below for "-" are probably useless.
         */
-       if (strcmp(probin, "-") != 0)
+       if (probin[0] != '\0' && strcmp(probin, "-") != 0)
        {
                appendPQExpBuffer(asPart, "AS ");
                appendStringLiteralAH(asPart, probin, fout);
@@ -6664,14 +6780,12 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        rettypename = getFormattedTypeName(finfo->prorettype, zeroAsOpaque);
 
        appendPQExpBuffer(q, "CREATE FUNCTION %s ", funcsig);
-       appendPQExpBuffer(q, "RETURNS %s%s\n    %s\n    LANGUAGE %s",
+       appendPQExpBuffer(q, "RETURNS %s%s",
                                          (proretset[0] == 't') ? "SETOF " : "",
-                                         rettypename,
-                                         asPart->data,
-                                         fmtId(lanname));
-
+                                         rettypename);
        free(rettypename);
 
+       appendPQExpBuffer(q, "\n    LANGUAGE %s", fmtId(lanname));
        if (provolatile[0] != PROVOLATILE_VOLATILE)
        {
                if (provolatile[0] == PROVOLATILE_IMMUTABLE)
@@ -6694,7 +6808,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
 
        /*
         * COST and ROWS are emitted only if present and not default, so as not to
-        * break backwards-compatibility of the dump without need.  Keep this code
+        * break backwards-compatibility of the dump without need.      Keep this code
         * in sync with the defaults in functioncmds.c.
         */
        if (strcmp(procost, "0") != 0)
@@ -6729,7 +6843,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                appendPQExpBuffer(q, "\n    SET %s TO ", fmtId(configitem));
 
                /*
-                * Some GUC variable names are 'LIST' type and hence must not be quoted.
+                * Some GUC variable names are 'LIST' type and hence must not be
+                * quoted.
                 */
                if (pg_strcasecmp(configitem, "DateStyle") == 0
                        || pg_strcasecmp(configitem, "search_path") == 0)
@@ -6738,7 +6853,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                        appendStringLiteralAH(q, pos, fout);
        }
 
-       appendPQExpBuffer(q, ";\n");
+       appendPQExpBuffer(q, "\n    %s;\n", asPart->data);
 
        ArchiveEntry(fout, finfo->dobj.catId, finfo->dobj.dumpId,
                                 funcsig_tag,
@@ -7355,8 +7470,8 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
                                                  "nspname AS opcfamilynsp, "
                                                  "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcmethod) AS amname "
                                                  "FROM pg_catalog.pg_opclass c "
-                                                 "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = opcfamily "
-                                                 "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
+                                  "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = opcfamily "
+                          "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
                                                  "WHERE c.oid = '%u'::pg_catalog.oid",
                                                  opcinfo->dobj.catId.oid);
        }
@@ -7367,7 +7482,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
                                                  "opcdefault, "
                                                  "NULL AS opcfamily, "
                                                  "NULL AS opcfamilynsp, "
-                                                 "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcamid) AS amname "
+               "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcamid) AS amname "
                                                  "FROM pg_catalog.pg_opclass "
                                                  "WHERE oid = '%u'::pg_catalog.oid",
                                                  opcinfo->dobj.catId.oid);
@@ -7445,18 +7560,38 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
         */
        resetPQExpBuffer(query);
 
-       if (g_fout->remoteVersion >= 80300)
+       if (g_fout->remoteVersion >= 80400)
+       {
+               /*
+                * Print only those opfamily members that are tied to the opclass by
+                * pg_depend entries.
+                *
+                * XXX RECHECK is gone as of 8.4, but we'll still print it if dumping
+                * an older server's table in which it is used.  Would it be better
+                * to silently ignore it?
+                */
+               appendPQExpBuffer(query, "SELECT amopstrategy, false as amopreqcheck, "
+                                                 "amopopr::pg_catalog.regoperator "
+                                                 "FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
+                  "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
+                                                 "AND refobjid = '%u'::pg_catalog.oid "
+                                  "AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
+                                                 "AND objid = ao.oid "
+                                                 "ORDER BY amopstrategy",
+                                                 opcinfo->dobj.catId.oid);
+       }
+       else if (g_fout->remoteVersion >= 80300)
        {
                /*
-                * Print only those opfamily members that are tied to the opclass
-                * by pg_depend entries.
+                * Print only those opfamily members that are tied to the opclass by
+                * pg_depend entries.
                 */
                appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
                                                  "amopopr::pg_catalog.regoperator "
                                                  "FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
-                                                 "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
+                  "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
                                                  "AND refobjid = '%u'::pg_catalog.oid "
-                                                 "AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
+                                  "AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
                                                  "AND objid = ao.oid "
                                                  "ORDER BY amopstrategy",
                                                  opcinfo->dobj.catId.oid);
@@ -7507,15 +7642,15 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
        if (g_fout->remoteVersion >= 80300)
        {
                /*
-                * Print only those opfamily members that are tied to the opclass
-                * by pg_depend entries.
+                * Print only those opfamily members that are tied to the opclass by
+                * pg_depend entries.
                 */
                appendPQExpBuffer(query, "SELECT amprocnum, "
                                                  "amproc::pg_catalog.regprocedure "
-                                                 "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
-                                                 "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
+                                               "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
+                  "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
                                                  "AND refobjid = '%u'::pg_catalog.oid "
-                                                 "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
+                                "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
                                                  "AND objid = ap.oid "
                                                  "ORDER BY amprocnum",
                                                  opcinfo->dobj.catId.oid);
@@ -7623,8 +7758,8 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
         * 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.
+        * the dump.  Since we have to fetch the loose operators/funcs anyway, do
+        * that first.
         */
 
        query = createPQExpBuffer();
@@ -7635,18 +7770,38 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
        selectSourceSchema(opfinfo->dobj.namespace->dobj.name);
 
        /*
-        * Fetch only those opfamily members that are tied directly to the opfamily
-        * by pg_depend entries.
+        * Fetch only those opfamily members that are tied directly to the
+        * opfamily by pg_depend entries.
         */
-       appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
+       if (g_fout->remoteVersion >= 80400)
+       {
+               /*
+                * XXX RECHECK is gone as of 8.4, but we'll still print it if dumping
+                * an older server's table in which it is used.  Would it be better
+                * to silently ignore it?
+                */
+               appendPQExpBuffer(query, "SELECT amopstrategy, false as amopreqcheck, "
+                                         "amopopr::pg_catalog.regoperator "
+                                         "FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
+                 "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
+                                         "AND refobjid = '%u'::pg_catalog.oid "
+                                  "AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
+                                         "AND objid = ao.oid "
+                                         "ORDER BY amopstrategy",
+                                         opfinfo->dobj.catId.oid);
+       }
+       else
+       {
+               appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
                                          "amopopr::pg_catalog.regoperator "
                                          "FROM pg_catalog.pg_amop ao, pg_catalog.pg_depend "
-                                         "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
+                 "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
                                          "AND refobjid = '%u'::pg_catalog.oid "
-                                         "AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
+                                  "AND classid = 'pg_catalog.pg_amop'::pg_catalog.regclass "
                                          "AND objid = ao.oid "
                                          "ORDER BY amopstrategy",
                                          opfinfo->dobj.catId.oid);
+       }
 
        res_ops = PQexec(g_conn, query->data);
        check_sql_result(res_ops, g_conn, query->data, PGRES_TUPLES_OK);
@@ -7658,9 +7813,9 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
                                          "amproclefttype::pg_catalog.regtype, "
                                          "amprocrighttype::pg_catalog.regtype "
                                          "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
-                                         "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
+                 "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
                                          "AND refobjid = '%u'::pg_catalog.oid "
-                                         "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
+                                "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
                                          "AND objid = ap.oid "
                                          "ORDER BY amprocnum",
                                          opfinfo->dobj.catId.oid);
@@ -7676,9 +7831,9 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
                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 refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
                                                  "AND refobjid = f.oid "
-                                                 "AND classid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
+                               "AND classid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
                                                  "AND objid = c.oid "
                                                  "AND (opcname != opfname OR opcnamespace != opfnamespace OR opcowner != opfowner) "
                                                  "LIMIT 1",
@@ -7706,7 +7861,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
        resetPQExpBuffer(query);
 
        appendPQExpBuffer(query, "SELECT "
-                                         "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opfmethod) AS amname "
+        "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opfmethod) AS amname "
                                          "FROM pg_catalog.pg_opfamily "
                                          "WHERE oid = '%u'::pg_catalog.oid",
                                          opfinfo->dobj.catId.oid);
@@ -8215,7 +8370,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
  *       write out a single text search parser
  */
 static void
-dumpTSParser(Archive *fout, TSParserInfo * prsinfo)
+dumpTSParser(Archive *fout, TSParserInfo *prsinfo)
 {
        PQExpBuffer q;
        PQExpBuffer delq;
@@ -8279,7 +8434,7 @@ dumpTSParser(Archive *fout, TSParserInfo * prsinfo)
  *       write out a single text search dictionary
  */
 static void
-dumpTSDictionary(Archive *fout, TSDictInfo * dictinfo)
+dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
 {
        PQExpBuffer q;
        PQExpBuffer delq;
@@ -8369,7 +8524,7 @@ dumpTSDictionary(Archive *fout, TSDictInfo * dictinfo)
  *       write out a single text search template
  */
 static void
-dumpTSTemplate(Archive *fout, TSTemplateInfo * tmplinfo)
+dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo)
 {
        PQExpBuffer q;
        PQExpBuffer delq;
@@ -8427,7 +8582,7 @@ dumpTSTemplate(Archive *fout, TSTemplateInfo * tmplinfo)
  *       write out a single text search configuration
  */
 static void
-dumpTSConfig(Archive *fout, TSConfigInfo * cfginfo)
+dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
 {
        PQExpBuffer q;
        PQExpBuffer delq;
@@ -8499,11 +8654,11 @@ dumpTSConfig(Archive *fout, TSConfigInfo * cfginfo)
 
        for (i = 0; i < ntups; i++)
        {
-               char   *tokenname = PQgetvalue(res, i, i_tokenname);
-               char   *dictname = PQgetvalue(res, i, i_dictname);
+               char       *tokenname = PQgetvalue(res, i, i_tokenname);
+               char       *dictname = PQgetvalue(res, i, i_dictname);
 
                if (i == 0 ||
-                       strcmp(tokenname, PQgetvalue(res, i-1, i_tokenname)) != 0)
+                       strcmp(tokenname, PQgetvalue(res, i - 1, i_tokenname)) != 0)
                {
                        /* starting a new token type, so start a new command */
                        if (i > 0)
@@ -8536,7 +8691,7 @@ dumpTSConfig(Archive *fout, TSConfigInfo * cfginfo)
                                 cfginfo->dobj.namespace->dobj.name,
                                 NULL,
                                 cfginfo->rolname,
-                                false, "TEXT SEARCH CONFIGURATION", q->data, delq->data, NULL,
+                          false, "TEXT SEARCH CONFIGURATION", q->data, delq->data, NULL,
                                 cfginfo->dobj.dependencies, cfginfo->dobj.nDeps,
                                 NULL, NULL);
 
@@ -8783,7 +8938,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                {
                        ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
 
-                       if (constr->coninherited || constr->separate)
+                       if (constr->separate || !constr->conislocal)
                                continue;
 
                        if (actual_atts > 0)
@@ -8898,7 +9053,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
        {
                ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
 
-               if (constr->coninherited || constr->separate)
+               if (constr->separate || !constr->conislocal)
                        continue;
 
                dumpTableConstraintComment(fout, constr);
@@ -9373,7 +9528,8 @@ static void
 dumpSequence(Archive *fout, TableInfo *tbinfo)
 {
        PGresult   *res;
-       char       *last,
+       char       *startv,
+                          *last,
                           *incby,
                           *maxv = NULL,
                           *minv = NULL,
@@ -9391,19 +9547,40 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
        snprintf(bufm, sizeof(bufm), INT64_FORMAT, SEQ_MINVALUE);
        snprintf(bufx, sizeof(bufx), INT64_FORMAT, SEQ_MAXVALUE);
 
-       appendPQExpBuffer(query,
-                                         "SELECT sequence_name, last_value, increment_by, "
-                                  "CASE WHEN increment_by > 0 AND max_value = %s THEN NULL "
-                                  "     WHEN increment_by < 0 AND max_value = -1 THEN NULL "
-                                         "     ELSE max_value "
-                                         "END AS max_value, "
-                                       "CASE WHEN increment_by > 0 AND min_value = 1 THEN NULL "
-                                  "     WHEN increment_by < 0 AND min_value = %s THEN NULL "
-                                         "     ELSE min_value "
-                                         "END AS min_value, "
-                                         "cache_value, is_cycled, is_called from %s",
-                                         bufx, bufm,
-                                         fmtId(tbinfo->dobj.name));
+       if (g_fout->remoteVersion >= 80400)
+       {
+               appendPQExpBuffer(query,
+                                 "SELECT sequence_name, "
+                                 "start_value, last_value, increment_by, "
+                                 "CASE WHEN increment_by > 0 AND max_value = %s THEN NULL "
+                                 "     WHEN increment_by < 0 AND max_value = -1 THEN NULL "
+                                 "     ELSE max_value "
+                                 "END AS max_value, "
+                                 "CASE WHEN increment_by > 0 AND min_value = 1 THEN NULL "
+                                 "     WHEN increment_by < 0 AND min_value = %s THEN NULL "
+                                 "     ELSE min_value "
+                                 "END AS min_value, "
+                                 "cache_value, is_cycled, is_called from %s",
+                                 bufx, bufm,
+                                 fmtId(tbinfo->dobj.name));
+       }
+       else
+       {
+               appendPQExpBuffer(query,
+                                 "SELECT sequence_name, "
+                                 "0 as start_value, last_value, increment_by, "
+                                 "CASE WHEN increment_by > 0 AND max_value = %s THEN NULL "
+                                 "     WHEN increment_by < 0 AND max_value = -1 THEN NULL "
+                                 "     ELSE max_value "
+                                 "END AS max_value, "
+                                 "CASE WHEN increment_by > 0 AND min_value = 1 THEN NULL "
+                                 "     WHEN increment_by < 0 AND min_value = %s THEN NULL "
+                                 "     ELSE min_value "
+                                 "END AS min_value, "
+                                 "cache_value, is_cycled, is_called from %s",
+                                 bufx, bufm,
+                                 fmtId(tbinfo->dobj.name));
+       }
 
        res = PQexec(g_conn, query->data);
        check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
@@ -9425,23 +9602,24 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
        }
 #endif
 
-       last = PQgetvalue(res, 0, 1);
-       incby = PQgetvalue(res, 0, 2);
-       if (!PQgetisnull(res, 0, 3))
-               maxv = PQgetvalue(res, 0, 3);
+       startv = PQgetvalue(res, 0, 1);
+       last = PQgetvalue(res, 0, 2);
+       incby = PQgetvalue(res, 0, 3);
        if (!PQgetisnull(res, 0, 4))
-               minv = PQgetvalue(res, 0, 4);
-       cache = PQgetvalue(res, 0, 5);
-       cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);
-       called = (strcmp(PQgetvalue(res, 0, 7), "t") == 0);
+               maxv = PQgetvalue(res, 0, 4);
+       if (!PQgetisnull(res, 0, 5))
+               minv = PQgetvalue(res, 0, 5);
+       cache = PQgetvalue(res, 0, 6);
+       cycled = (strcmp(PQgetvalue(res, 0, 7), "t") == 0);
+       called = (strcmp(PQgetvalue(res, 0, 8), "t") == 0);
 
        /*
         * The logic we use for restoring sequences is as follows:
         *
         * Add a CREATE SEQUENCE statement as part of a "schema" dump (use
         * last_val for start if called is false, else use min_val for start_val).
-        * Also, if the sequence is owned by a column, add an ALTER SEQUENCE
-        * OWNED BY command for it.
+        * Also, if the sequence is owned by a column, add an ALTER SEQUENCE OWNED
+        * BY command for it.
         *
         * Add a 'SETVAL(seq, last_val, iscalled)' as part of a "data" dump.
         */
@@ -9463,8 +9641,18 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
                                                  "CREATE SEQUENCE %s\n",
                                                  fmtId(tbinfo->dobj.name));
 
-               if (!called)
-                       appendPQExpBuffer(query, "    START WITH %s\n", last);
+               if (g_fout->remoteVersion >= 80400)
+                       appendPQExpBuffer(query, "    START WITH %s\n", startv);
+               else
+               {
+                       /*
+                        * Versions before 8.4 did not remember the true start value.  If
+                        * is_called is false then the sequence has never been incremented
+                        * so we can use last_val.  Otherwise punt and let it default.
+                        */
+                       if (!called)
+                               appendPQExpBuffer(query, "    START WITH %s\n", last);
+               }
 
                appendPQExpBuffer(query, "    INCREMENT BY %s\n", incby);
 
@@ -9625,6 +9813,13 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
                else
                        appendPQExpBuffer(query, " UPDATE");
        }
+       if (TRIGGER_FOR_TRUNCATE(tginfo->tgtype))
+       {
+               if (findx > 0)
+                       appendPQExpBuffer(query, " OR TRUNCATE");
+               else
+                       appendPQExpBuffer(query, " TRUNCATE");
+       }
        appendPQExpBuffer(query, " ON %s\n",
                                          fmtId(tbinfo->dobj.name));
 
@@ -9818,28 +10013,28 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
        printfPQExpBuffer(cmd, "%s\n", PQgetvalue(res, 0, 0));
 
        /*
-        * Add the command to alter the rules replication firing semantics
-        * if it differs from the default.
+        * Add the command to alter the rules replication firing semantics if it
+        * differs from the default.
         */
        if (rinfo->ev_enabled != 'O')
        {
                appendPQExpBuffer(cmd, "ALTER TABLE %s.",
-                                       fmtId(tbinfo->dobj.namespace->dobj.name));
+                                                 fmtId(tbinfo->dobj.namespace->dobj.name));
                appendPQExpBuffer(cmd, "%s ",
-                                       fmtId(tbinfo->dobj.name));
+                                                 fmtId(tbinfo->dobj.name));
                switch (rinfo->ev_enabled)
                {
                        case 'A':
                                appendPQExpBuffer(cmd, "ENABLE ALWAYS RULE %s;\n",
-                                                       fmtId(rinfo->dobj.name));
+                                                                 fmtId(rinfo->dobj.name));
                                break;
                        case 'R':
                                appendPQExpBuffer(cmd, "ENABLE REPLICA RULE %s;\n",
-                                                       fmtId(rinfo->dobj.name));
+                                                                 fmtId(rinfo->dobj.name));
                                break;
                        case 'D':
                                appendPQExpBuffer(cmd, "DISABLE RULE %s;\n",
-                                                       fmtId(rinfo->dobj.name));
+                                                                 fmtId(rinfo->dobj.name));
                                break;
                }
        }