]> granicus.if.org Git - postgresql/blobdiff - src/bin/pg_dump/pg_dump.c
Fix all known problems with pg_dump's handling of serial sequences
[postgresql] / src / bin / pg_dump / pg_dump.c
index ce9a5b0d1605fd3e6b6db34bc653d83735dfd43e..78a653fb48c0e40cff40aa819d48e0f82deed8bd 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-2005, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2006, 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
@@ -12,7 +12,7 @@
  *     by PostgreSQL
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.402 2005/01/26 21:24:12 tgl Exp $
+ *       $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.447 2006/08/21 00:57:25 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -25,6 +25,7 @@
 #include "postgres.h"
 
 #include <unistd.h>
+
 #include <ctype.h>
 #ifdef ENABLE_NLS
 #include <locale.h>
@@ -32,7 +33,6 @@
 #ifdef HAVE_TERMIOS_H
 #include <termios.h>
 #endif
-#include <time.h>
 
 #ifndef HAVE_STRDUP
 #include "strdup.h"
 int                    optreset;
 #endif
 
-#include "access/attnum.h"
+
+
 #include "access/htup.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-fe.h"
 #include "libpq/libpq-fs.h"
+#include "mb/pg_wchar.h"
 
-#include "pg_dump.h"
-#include "pg_backup.h"
 #include "pg_backup_archiver.h"
 #include "dumputils.h"
 
-#define _(x) gettext((x))
-
 extern char *optarg;
 extern int     optind,
                        opterr;
@@ -90,11 +85,25 @@ bool                schemaOnly;
 bool           dataOnly;
 bool           aclsSkip;
 
+/* subquery used to convert user ID (eg, datdba) to user name */
+static const char *username_subquery;
+
 /* obsolete as of 7.3: */
 static Oid     g_last_builtin_oid; /* value of the last builtin oid */
 
-static char *selectTableName = NULL;   /* name of a single table to dump */
-static char *selectSchemaName = NULL;  /* name of a single schema to dump */
+/* select and exclude tables and schemas */
+typedef struct objnameArg
+{
+       struct objnameArg *next;
+       char *name;                     /* name of the relation */
+       bool is_include;        /* include/exclude? */
+} objnameArg;
+
+objnameArg *schemaList = NULL; /* List of schemas to include/exclude */
+objnameArg *tableList = NULL; /* List of tables to include/exclude */
+
+char *matchingSchemas = NULL; /* Final list of schemas to dump by oid */
+char *matchingTables = NULL; /* Final list of tables to dump by oid */
 
 char           g_opaque_type[10];      /* name for the opaque type */
 
@@ -127,6 +136,7 @@ static void dumpType(Archive *fout, TypeInfo *tinfo);
 static void dumpBaseType(Archive *fout, TypeInfo *tinfo);
 static void dumpDomain(Archive *fout, TypeInfo *tinfo);
 static void dumpCompositeType(Archive *fout, TypeInfo *tinfo);
+static void dumpShellType(Archive *fout, ShellTypeInfo *stinfo);
 static void dumpProcLang(Archive *fout, ProcLangInfo *plang);
 static void dumpFunc(Archive *fout, FuncInfo *finfo);
 static void dumpCast(Archive *fout, CastInfo *cast);
@@ -152,21 +162,25 @@ static void dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
 static void getDependencies(void);
 static void getDomainConstraints(TypeInfo *tinfo);
 static void getTableData(TableInfo *tblinfo, int numTables, bool oids);
-static char *format_function_signature(FuncInfo *finfo, char **argnames,
-                                                 bool honor_quotes);
+static char *format_function_arguments(FuncInfo *finfo, int nallargs,
+                                                 char **allargtypes,
+                                                 char **argmodes,
+                                                 char **argnames);
+static char *format_function_signature(FuncInfo *finfo, bool honor_quotes);
 static const char *convertRegProcReference(const char *proc);
 static const char *convertOperatorReference(const char *opr);
 static Oid     findLastBuiltinOid_V71(const char *);
 static Oid     findLastBuiltinOid_V70(void);
-static void setMaxOid(Archive *fout);
 static void selectSourceSchema(const char *schemaName);
 static char *getFormattedTypeName(Oid oid, OidOptions opts);
 static char *myFormatType(const char *typname, int32 typmod);
 static const char *fmtQualifiedId(const char *schema, const char *id);
+static bool hasBlobs(Archive *AH);
 static int     dumpBlobs(Archive *AH, void *arg);
+static int     dumpBlobComments(Archive *AH, void *arg);
 static void dumpDatabase(Archive *AH);
-static void dumpTimestamp(Archive *AH, char *msg);
 static void dumpEncoding(Archive *AH);
+static void dumpStdStrings(Archive *AH);
 static const char *getAttrName(int attrnum, TableInfo *tblInfo);
 static const char *fmtCopyColumnList(const TableInfo *ti);
 static void do_sql_command(PGconn *conn, const char *query);
@@ -177,6 +191,9 @@ static void check_sql_result(PGresult *res, PGconn *conn, const char *query,
 int
 main(int argc, char **argv)
 {
+       PQExpBuffer query = createPQExpBuffer();
+       PGresult   *res;
+       objnameArg *this_obj_name, *schemaList_tail = NULL, *tableList_tail = NULL;
        int                     c;
        const char *filename = NULL;
        const char *format = "p";
@@ -184,19 +201,22 @@ main(int argc, char **argv)
        const char *pghost = NULL;
        const char *pgport = NULL;
        const char *username = NULL;
+       const char *dumpencoding = NULL;
+       const char *std_strings;
        bool            oids = false;
        TableInfo  *tblinfo;
        int                     numTables;
        DumpableObject **dobjs;
        int                     numObjs;
        int                     i;
+       bool            switch_include_exclude;
        bool            force_password = false;
        int                     compressLevel = -1;
        bool            ignore_version = false;
        int                     plainText = 0;
        int                     outputClean = 0;
        int                     outputCreate = 0;
-       int                     outputBlobs = 0;
+       bool            outputBlobs = true;
        int                     outputNoOwner = 0;
        static int      use_setsessauth = 0;
        static int      disable_triggers = 0;
@@ -221,21 +241,24 @@ main(int argc, char **argv)
                {"no-owner", no_argument, NULL, 'O'},
                {"port", required_argument, NULL, 'p'},
                {"schema", required_argument, NULL, 'n'},
+               {"exclude-schema", required_argument, NULL, 'N'},
                {"schema-only", no_argument, NULL, 's'},
                {"superuser", required_argument, NULL, 'S'},
                {"table", required_argument, NULL, 't'},
+               {"exclude-table", required_argument, NULL, 'T'},
                {"password", no_argument, NULL, 'W'},
                {"username", required_argument, NULL, 'U'},
                {"verbose", no_argument, NULL, 'v'},
                {"no-privileges", no_argument, NULL, 'x'},
                {"no-acl", no_argument, NULL, 'x'},
                {"compress", required_argument, NULL, 'Z'},
+               {"encoding", required_argument, NULL, 'E'},
                {"help", no_argument, NULL, '?'},
                {"version", no_argument, NULL, 'V'},
 
                /*
-                * the following options don't have an equivalent short option
-                * letter, but are available as '-X long-name'
+                * the following options don't have an equivalent short option letter,
+                * but are available as '-X long-name'
                 */
                {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
                {"disable-triggers", no_argument, &disable_triggers, 1},
@@ -259,10 +282,7 @@ main(int argc, char **argv)
 
        /* Set default options based on progname */
        if (strcmp(progname, "pg_backup") == 0)
-       {
                format = "c";
-               outputBlobs = true;
-       }
 
        if (argc > 1)
        {
@@ -278,7 +298,7 @@ main(int argc, char **argv)
                }
        }
 
-       while ((c = getopt_long(argc, argv, "abcCdDf:F:h:in:oOp:RsS:t:uU:vWxX:Z:",
+       while ((c = getopt_long(argc, argv, "abcCdDE:f:F:h:in:N:oOp:RsS:t:T:uU:vWxX:Z:",
                                                        long_options, &optindex)) != -1)
        {
                switch (c)
@@ -288,11 +308,10 @@ main(int argc, char **argv)
                                break;
 
                        case 'b':                       /* Dump blobs */
-                               outputBlobs = true;
+                               /* this is now default, so just ignore the switch */
                                break;
 
-                       case 'c':                       /* clean (i.e., drop) schema prior to
-                                                                * create */
+                       case 'c':                       /* clean (i.e., drop) schema prior to create */
                                outputClean = 1;
                                break;
 
@@ -310,6 +329,10 @@ main(int argc, char **argv)
                                attrNames = true;
                                break;
 
+                       case 'E':                       /* Dump encoding */
+                               dumpencoding = optarg;
+                               break;
+
                        case 'f':
                                filename = optarg;
                                break;
@@ -326,8 +349,42 @@ main(int argc, char **argv)
                                ignore_version = true;
                                break;
 
-                       case 'n':                       /* Dump data for this schema only */
-                               selectSchemaName = strdup(optarg);
+                       case 'n':               /* Include schemas */
+                       case 'N':               /* Exclude schemas */
+                       case 't':               /* Include tables */
+                       case 'T':               /* Exclude tables */
+
+                               if (strlen(optarg) < 1)
+                               {
+                                       fprintf(stderr, _("%s: invalid -%c option\n"), progname, c);
+                                       exit(1);
+                               }
+
+                               {
+                                       /* Create a struct for this name */
+                                       objnameArg *new_obj_name = (objnameArg *)
+                                                                                               malloc(sizeof(objnameArg));
+
+                                       new_obj_name->next = NULL;
+                                       new_obj_name->name = strdup(optarg);
+                                       new_obj_name->is_include = islower(c) ? true : false;
+
+                                       /* add new entry to the proper list */
+                                       if (tolower(c) == 'n')
+                                       {
+                                               if (!schemaList_tail)
+                                                       schemaList_tail = schemaList = new_obj_name;
+                                               else
+                                                       schemaList_tail = schemaList_tail->next = new_obj_name;
+                                       }
+                                       else
+                                       {
+                                               if (!tableList_tail)
+                                                       tableList_tail = tableList = new_obj_name;
+                                               else
+                                                       tableList_tail = tableList_tail->next = new_obj_name;
+                                       }
+                               }
                                break;
 
                        case 'o':                       /* Dump oids */
@@ -348,17 +405,13 @@ main(int argc, char **argv)
 
                        case 's':                       /* dump schema only */
                                schemaOnly = true;
+                               outputBlobs = false;
                                break;
 
-                       case 'S':                       /* Username for superuser in plain text
-                                                                * output */
+                       case 'S':                       /* Username for superuser in plain text output */
                                outputSuperuser = strdup(optarg);
                                break;
 
-                       case 't':                       /* Dump data for this table only */
-                               selectTableName = strdup(optarg);
-                               break;
-
                        case 'u':
                                force_password = true;
                                username = simple_prompt("User name: ", 100, true);
@@ -381,11 +434,11 @@ main(int argc, char **argv)
                                break;
 
                                /*
-                                * Option letters were getting scarce, so I invented this
-                                * new scheme: '-X feature' turns on some feature. Compare
-                                * to the -f option in GCC.  You should also add an
-                                * equivalent GNU-style option --feature.  Features that
-                                * require arguments should use '-X feature=foo'.
+                                * Option letters were getting scarce, so I invented this new
+                                * scheme: '-X feature' turns on some feature. Compare to the
+                                * -f option in GCC.  You should also add an equivalent
+                                * GNU-style option --feature.  Features that require
+                                * arguments should use '-X feature=foo'.
                                 */
                        case 'X':
                                if (strcmp(optarg, "disable-dollar-quoting") == 0)
@@ -443,19 +496,8 @@ main(int argc, char **argv)
                exit(1);
        }
 
-       if (outputBlobs && selectTableName != NULL)
-       {
-               write_msg(NULL, "large-object output not supported for a single table\n");
-               write_msg(NULL, "use a full dump instead\n");
-               exit(1);
-       }
-
-       if (outputBlobs && selectSchemaName != NULL)
-       {
-               write_msg(NULL, "large-object output not supported for a single schema\n");
-               write_msg(NULL, "use a full dump instead\n");
-               exit(1);
-       }
+       if (matchingTables != NULL || matchingSchemas != NULL)
+               outputBlobs = false;
 
        if (dumpInserts == true && oids == true)
        {
@@ -464,13 +506,6 @@ main(int argc, char **argv)
                exit(1);
        }
 
-       if (outputBlobs == true && (format[0] == 'p' || format[0] == 'P'))
-       {
-               write_msg(NULL, "large-object output is not supported for plain-text dump files\n");
-               write_msg(NULL, "(Use a different output format.)\n");
-               exit(1);
-       }
-
        /* open the output file */
        switch (format[0])
        {
@@ -518,12 +553,35 @@ main(int argc, char **argv)
        }
 
        /*
-        * Open the database using the Archiver, so it knows about it. Errors
-        * mean death.
+        * 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);
 
+       /* Set the client encoding if requested */
+       if (dumpencoding)
+       {
+               if (PQsetClientEncoding(g_conn, dumpencoding) < 0)
+               {
+                       write_msg(NULL, "invalid client encoding \"%s\" specified\n",
+                                         dumpencoding);
+                       exit(1);
+               }
+       }
+
+       /*
+        * Get the active encoding and the standard_conforming_strings setting,
+        * so we know how to escape strings.
+        */
+       g_fout->encoding = PQclientEncoding(g_conn);
+
+       std_strings = PQparameterStatus(g_conn, "standard_conforming_strings");
+       g_fout->std_strings = (std_strings && strcmp(std_strings, "on") == 0);
+
+       /* Set the datestyle to ISO to ensure the dump's portability */
+       do_sql_command(g_conn, "SET DATESTYLE = ISO");
+
        /*
         * Start serializable transaction to dump consistent data.
         */
@@ -531,8 +589,13 @@ main(int argc, char **argv)
 
        do_sql_command(g_conn, "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
 
-       /* Set the datestyle to ISO to ensure the dump's portability */
-       do_sql_command(g_conn, "SET DATESTYLE = ISO");
+       /* Select the appropriate subquery to convert user IDs to names */
+       if (g_fout->remoteVersion >= 80100)
+               username_subquery = "SELECT rolname FROM pg_catalog.pg_roles WHERE oid =";
+       else if (g_fout->remoteVersion >= 70300)
+               username_subquery = "SELECT usename FROM pg_catalog.pg_user WHERE usesysid =";
+       else
+               username_subquery = "SELECT usename FROM pg_user WHERE usesysid =";
 
        /*
         * If supported, set extra_float_digits so that we can dump float data
@@ -552,18 +615,174 @@ main(int argc, char **argv)
                        write_msg(NULL, "last built-in OID is %u\n", g_last_builtin_oid);
        }
 
+
+       if (schemaList != NULL && g_fout->remoteVersion < 70300)
+       {
+               write_msg(NULL, "Postgres must be at least version 7.3 to use schema switches\n");
+               exit_nicely();
+       }
+
+       /* Check schema selection flags */
+       resetPQExpBuffer(query);
+       switch_include_exclude = true;
+
+       for (this_obj_name = schemaList; this_obj_name; this_obj_name = this_obj_name->next)
+       {
+               if (switch_include_exclude)
+               {
+                       /* Special case for when -N is the first argument */
+                       if (this_obj_name == schemaList && !this_obj_name->is_include)
+                               appendPQExpBuffer(query,
+                                       "SELECT oid FROM pg_catalog.pg_namespace "
+                                       "WHERE nspname NOT LIKE 'pg_%%' AND "
+                                       "      nspname != 'information_schema' EXCEPT\n");
+       
+                       appendPQExpBuffer(query, "SELECT oid FROM pg_catalog.pg_namespace WHERE");
+               }
+       
+               appendPQExpBuffer(query, "%s nspname %c ", switch_include_exclude ? "" : " OR",
+                                                       /* any meta-characters? */
+                                                       strpbrk(this_obj_name->name,"([{\\.?+") == NULL ? '=' : '~');
+               appendStringLiteralAH(query, this_obj_name->name, g_fout);
+       
+               if (this_obj_name->next && this_obj_name->next->is_include == this_obj_name->is_include)
+                       switch_include_exclude = false;
+               else
+               {
+                       switch_include_exclude = true;
+       
+                       /* Add the joiner if needed */
+                       if (this_obj_name->next)
+                               appendPQExpBuffer(query, "\n%s\n",
+                                                                 this_obj_name->next->is_include ? "UNION" : "EXCEPT");
+               }
+       }
+
+       /* Construct OID list of matching schemas */
+       if (schemaList)
+       {
+               int len;
+               
+               res = PQexec(g_conn, query->data);
+               check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+               if (PQntuples(res) == 0)
+               {
+                       write_msg(NULL, "No matching schemas were found\n");
+                       exit_nicely();
+               }
+
+               for (i = 0, len = strlen(" "); i < PQntuples(res); i++)
+                       len += strlen(PQgetvalue(res, i, 0)) + 1;
+
+               /*
+                *      Need to use comma separators so it can be used by IN.  zero
+                *      is a dummy placeholder.  Format is " oid oid oid ".
+                */
+               matchingSchemas = malloc(len + 1);
+               strcpy(matchingSchemas, " ");
+               for (i = 0; i < PQntuples(res); i++)
+               {
+                       strcat(matchingSchemas, PQgetvalue(res, i, 0));
+                       strcat(matchingSchemas, " ");
+               }
+       }
+
+       /* Check table selection flags */
+       resetPQExpBuffer(query);
+       switch_include_exclude = true;
+
+       for (this_obj_name = tableList; this_obj_name; this_obj_name = this_obj_name->next)
+       {
+               if (switch_include_exclude)
+               {
+                       /* Special case for when -T is the first argument */
+                       if (this_obj_name == tableList && !this_obj_name->is_include && !strlen(query->data))
+                               appendPQExpBuffer(query,
+                                       "SELECT pg_class.oid FROM pg_catalog.pg_class, pg_catalog.pg_namespace "
+                                       "WHERE relkind='r' AND "
+                                       "      relnamespace = pg_namespace.oid AND "
+                                       "      nspname NOT LIKE 'pg_%%' AND "
+                                       "      nspname != 'information_schema' EXCEPT\n");
+       
+                       appendPQExpBuffer(query, "SELECT oid FROM pg_catalog.pg_class WHERE relkind='r' AND (");
+               }
+       
+               appendPQExpBuffer(query, "%srelname %c ", switch_include_exclude ? "" : " OR ",
+                                                       /* any meta-characters? */
+                                                       strpbrk(this_obj_name->name,"([{\\.?+") == NULL ? '=' : '~');
+               appendStringLiteralAH(query, this_obj_name->name, g_fout);
+       
+               if (this_obj_name->next && this_obj_name->next->is_include == this_obj_name->is_include)
+                       switch_include_exclude = false;
+               else
+               {
+                       switch_include_exclude = true;
+                       appendPQExpBuffer(query, ")");
+               
+                       /* Add the joiner if needed */
+                       if (this_obj_name->next)
+                               appendPQExpBuffer(query, "\n%s\n", this_obj_name->next->is_include ?
+                                                                 "UNION" : "EXCEPT");
+               }
+       }
+
+       /* Construct OID list of matching tables */
+       if (tableList)
+       {
+               int len;
+               
+               /* Restrict by schema? */
+               if (matchingSchemas != NULL)
+               {
+                       char *matchingSchemas_commas = strdup(matchingSchemas), *p;
+
+                       /* Construct "IN" SQL string by adding commas, " oid, oid, oid " */
+                       for (p = matchingSchemas_commas; *p; p++)
+                       {
+                               /* No commas for first/last characters */
+                               if (*p == ' ' && p != matchingSchemas_commas && *(p+1))
+                                       *p = ',';
+                       }
+
+                       appendPQExpBuffer(query,
+                                                         "\nINTERSECT\nSELECT oid FROM pg_catalog.pg_class WHERE relkind='r' AND relnamespace IN (%s)\n",
+                                                         matchingSchemas_commas);
+               }
+
+               res = PQexec(g_conn, query->data);
+               check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+               if (PQntuples(res) == 0)
+               {
+                       write_msg(NULL, "No matching tables were found\n");
+                       exit_nicely();
+               }
+
+               for (i = 0, len = strlen(" "); i < PQntuples(res); i++)
+                       len += strlen(PQgetvalue(res, i, 0)) + 1;
+
+               matchingTables = malloc(len + 1);
+               strcpy(matchingTables, " ");
+               for (i = 0; i < PQntuples(res); i++)
+               {
+                       strcat(matchingTables, PQgetvalue(res, i, 0));
+                       strcat(matchingTables, " ");
+               }
+       }
+
+       destroyPQExpBuffer(query);
+
        /*
         * Now scan the database and create DumpableObject structs for all the
         * objects we intend to dump.
         */
-       tblinfo = getSchemaData(&numTables, schemaOnly, dataOnly);
+       tblinfo = getSchemaData(&numTables);
 
        if (!schemaOnly)
                getTableData(tblinfo, numTables, oids);
 
-       if (outputBlobs)
+       if (outputBlobs && hasBlobs(g_fout))
        {
-               /* This is just a placeholder to allow correct sorting of blobs */
+               /* Add placeholders to allow correct sorting of blobs */
                DumpableObject *blobobj;
 
                blobobj = (DumpableObject *) malloc(sizeof(DumpableObject));
@@ -571,6 +790,12 @@ main(int argc, char **argv)
                blobobj->catId = nilCatalogId;
                AssignDumpId(blobobj);
                blobobj->name = strdup("BLOBS");
+
+               blobobj = (DumpableObject *) malloc(sizeof(DumpableObject));
+               blobobj->objType = DO_BLOB_COMMENTS;
+               blobobj->catId = nilCatalogId;
+               AssignDumpId(blobobj);
+               blobobj->name = strdup("BLOB COMMENTS");
        }
 
        /*
@@ -583,10 +808,9 @@ main(int argc, char **argv)
         *
         * In 7.3 or later, we can rely on dependency information to help us
         * determine a safe order, so the initial sort is mostly for cosmetic
-        * purposes: we sort by name to ensure that logically identical
-        * schemas will dump identically.  Before 7.3 we don't have
-        * dependencies and we use OID ordering as an (unreliable) guide to
-        * creation order.
+        * purposes: we sort by name to ensure that logically identical schemas
+        * will dump identically.  Before 7.3 we don't have dependencies and we
+        * use OID ordering as an (unreliable) guide to creation order.
         */
        getDumpableObjects(&dobjs, &numObjs);
 
@@ -598,31 +822,22 @@ main(int argc, char **argv)
        sortDumpableObjects(dobjs, numObjs);
 
        /*
-        * Create archive TOC entries for all the objects to be dumped, in a
-        * safe order.
+        * Create archive TOC entries for all the objects to be dumped, in a safe
+        * order.
         */
 
-       if (g_fout->verbose)
-               dumpTimestamp(g_fout, "Started on");
-
-       /* First the special encoding entry. */
+       /* First the special ENCODING and STDSTRINGS entries. */
        dumpEncoding(g_fout);
+       dumpStdStrings(g_fout);
 
-       /* The database item is always second. */
-       if (!dataOnly)
+       /* The database item is always next, unless we don't want it at all */
+       if (!dataOnly && matchingTables == NULL && matchingSchemas == NULL)
                dumpDatabase(g_fout);
 
-       /* Max OID is next. */
-       if (oids == true)
-               setMaxOid(g_fout);
-
        /* Now the rearrangeable objects. */
        for (i = 0; i < numObjs; i++)
                dumpDumpableObject(g_fout, dobjs[i]);
 
-       if (g_fout->verbose)
-               dumpTimestamp(g_fout, "Completed on");
-
        /*
         * And finally we can do the actual output.
         */
@@ -637,14 +852,14 @@ main(int argc, char **argv)
                ropt->noOwner = outputNoOwner;
                ropt->disable_triggers = disable_triggers;
                ropt->use_setsessauth = use_setsessauth;
+               ropt->dataOnly = dataOnly;
 
                if (compressLevel == -1)
                        ropt->compression = 0;
                else
                        ropt->compression = compressLevel;
 
-               ropt->suppressDumpWarnings = true;              /* We've already shown
-                                                                                                * them */
+               ropt->suppressDumpWarnings = true;              /* We've already shown them */
 
                RestoreArchive(g_fout, ropt);
        }
@@ -675,28 +890,30 @@ help(const char *progname)
        printf(_("  --version                output version information, then exit\n"));
 
        printf(_("\nOptions controlling the output content:\n"));
-       printf(_("  -a, --data-only          dump only the data, not the schema\n"));
-       printf(_("  -b, --blobs              include large objects in dump\n"));
-       printf(_("  -c, --clean              clean (drop) schema prior to create\n"));
-       printf(_("  -C, --create             include commands to create database in dump\n"));
-       printf(_("  -d, --inserts            dump data as INSERT, rather than COPY, commands\n"));
-       printf(_("  -D, --column-inserts     dump data as INSERT commands with column names\n"));
-       printf(_("  -n, --schema=SCHEMA      dump the named schema only\n"));
-       printf(_("  -o, --oids               include OIDs in dump\n"));
-       printf(_("  -O, --no-owner           skip restoration of object ownership\n"
-                        "                           in plain text format\n"));
-       printf(_("  -s, --schema-only        dump only the schema, no data\n"));
-       printf(_("  -S, --superuser=NAME     specify the superuser user name to use in\n"
-                        "                           plain text format\n"));
-       printf(_("  -t, --table=TABLE        dump the named table only\n"));
-       printf(_("  -x, --no-privileges      do not dump privileges (grant/revoke)\n"));
+       printf(_("  -a, --data-only             dump only the data, not the schema\n"));
+       printf(_("  -c, --clean                 clean (drop) schema prior to create\n"));
+       printf(_("  -C, --create                include commands to create database in dump\n"));
+       printf(_("  -d, --inserts               dump data as INSERT, rather than COPY, commands\n"));
+       printf(_("  -D, --column-inserts        dump data as INSERT commands with column names\n"));
+       printf(_("  -E, --encoding=ENCODING     dump the data in encoding ENCODING\n"));
+       printf(_("  -n, --schema=SCHEMA         dump the named schema only\n"));
+       printf(_("  -N, --exclude-schema=SCHEMA do NOT dump the named schema\n"));
+       printf(_("  -o, --oids                  include OIDs in dump\n"));
+       printf(_("  -O, --no-owner              skip restoration of object ownership\n"
+                        "                              in plain text format\n"));
+       printf(_("  -s, --schema-only           dump only the schema, no data\n"));
+       printf(_("  -S, --superuser=NAME        specify the superuser user name to use in\n"
+                        "                              plain text format\n"));
+       printf(_("  -t, --table=TABLE           dump the named table only\n"));
+       printf(_("  -T, --exclude-table=TABLE   do NOT dump the named table\n"));
+       printf(_("  -x, --no-privileges         do not dump privileges (grant/revoke)\n"));
        printf(_("  -X disable-dollar-quoting, --disable-dollar-quoting\n"
-                        "                           disable dollar quoting, use SQL standard quoting\n"));
+                        "                              disable dollar quoting, use SQL standard quoting\n"));
        printf(_("  -X disable-triggers, --disable-triggers\n"
-                        "                           disable triggers during data-only restore\n"));
+                        "                              disable triggers during data-only restore\n"));
        printf(_("  -X use-set-session-authorization, --use-set-session-authorization\n"
-                        "                           use SESSION AUTHORIZATION commands instead of\n"
-                        "                           OWNER TO commands\n"));
+                        "                              use SESSION AUTHORIZATION commands instead of\n"
+                        "                              OWNER TO commands\n"));
 
        printf(_("\nConnection options:\n"));
        printf(_("  -h, --host=HOSTNAME      database server host or socket directory\n"));
@@ -726,24 +943,28 @@ static void
 selectDumpableNamespace(NamespaceInfo *nsinfo)
 {
        /*
-        * If a specific table is being dumped, do not dump any complete
-        * namespaces.  If a specific namespace is being dumped, dump just
-        * that namespace. Otherwise, dump all non-system namespaces.
+        * If specific tables are being dumped, do not dump any complete
+        * namespaces.  If specific namespaces are being dumped, dump just 
+        * those namespaces. Otherwise, dump all non-system namespaces.
         */
-       if (selectTableName != NULL)
-               nsinfo->dump = false;
-       else if (selectSchemaName != NULL)
+       nsinfo->dobj.dump = false;
+
+       if (matchingTables != NULL)
+               /* false */;
+       else if (matchingSchemas != NULL)
        {
-               if (strcmp(nsinfo->dobj.name, selectSchemaName) == 0)
-                       nsinfo->dump = true;
-               else
-                       nsinfo->dump = false;
+               char *search_oid = malloc(20);
+
+               sprintf(search_oid, " %d ", nsinfo->dobj.catId.oid);
+               if (strstr(matchingSchemas, search_oid) != NULL)
+                       nsinfo->dobj.dump = true;
+
+               free(search_oid);
        }
-       else if (strncmp(nsinfo->dobj.name, "pg_", 3) == 0 ||
-                        strcmp(nsinfo->dobj.name, "information_schema") == 0)
-               nsinfo->dump = false;
-       else
-               nsinfo->dump = true;
+       /* The server prevents users from creating pg_ schemas */
+       else if (strncmp(nsinfo->dobj.name, "pg_", 3) != 0 &&
+                        strcmp(nsinfo->dobj.name, "information_schema") != 0)
+               nsinfo->dobj.dump = true;
 }
 
 /*
@@ -755,31 +976,83 @@ selectDumpableTable(TableInfo *tbinfo)
 {
        /*
         * Always dump if dumping parent namespace; else, if a particular
-        * tablename has been specified, dump matching table name; else, do
-        * not dump.
+        * tablename has been specified, dump matching table name; else, do not
+        * dump.
         */
-       tbinfo->dump = false;
-       if (tbinfo->dobj.namespace->dump)
-               tbinfo->dump = true;
-       else if (selectTableName != NULL &&
-                        strcmp(tbinfo->dobj.name, selectTableName) == 0)
-       {
-               /* If both -s and -t specified, must match both to dump */
-               if (selectSchemaName == NULL)
-                       tbinfo->dump = true;
-               else if (strcmp(tbinfo->dobj.namespace->dobj.name, selectSchemaName) == 0)
-                       tbinfo->dump = true;
+       tbinfo->dobj.dump = false;
+
+       if (matchingTables == NULL)
+       {
+               if (tbinfo->dobj.namespace->dobj.dump)
+                       tbinfo->dobj.dump = true;
+       }
+       else
+       {
+               char *search_oid = malloc(20);
+
+               sprintf(search_oid, " %d ", tbinfo->dobj.catId.oid);
+               if (strstr(matchingTables, search_oid) != NULL)
+                       tbinfo->dobj.dump = true;
+
+               free(search_oid);
        }
 }
 
+/*
+ * selectDumpableType: policy-setting subroutine
+ *             Mark a type as to be dumped or not
+ */
+static void
+selectDumpableType(TypeInfo *tinfo)
+{
+       /* Dump only types in dumpable namespaces */
+       if (!tinfo->dobj.namespace->dobj.dump)
+               tinfo->dobj.dump = false;
+
+       /* skip complex types, except for standalone composite types */
+       /* (note: this test should now be unnecessary) */
+       else if (OidIsValid(tinfo->typrelid) &&
+                        tinfo->typrelkind != RELKIND_COMPOSITE_TYPE)
+               tinfo->dobj.dump = false;
+
+       /* skip undefined placeholder types */
+       else if (!tinfo->isDefined)
+               tinfo->dobj.dump = false;
+
+       /* skip all array types that start w/ underscore */
+       else if ((tinfo->dobj.name[0] == '_') &&
+                        OidIsValid(tinfo->typelem))
+               tinfo->dobj.dump = false;
+
+       else
+               tinfo->dobj.dump = true;
+}
+
+/*
+ * selectDumpableObject: policy-setting subroutine
+ *             Mark a generic dumpable object as to be dumped or not
+ *
+ * Use this only for object types without a special-case routine above.
+ */
+static void
+selectDumpableObject(DumpableObject *dobj)
+{
+       /*
+        * Default policy is to dump if parent namespace is dumpable,
+        * or always for non-namespace-associated items.
+        */
+       if (dobj->namespace)
+               dobj->dump = dobj->namespace->dobj.dump;
+       else
+               dobj->dump = true;
+}
+
 /*
  *     Dump a table's contents for loading using the COPY command
  *     - this routine is called by the Archiver when it wants the table
  *       to be dumped.
  */
 
-#define COPYBUFSIZ             8192
-
 static int
 dumpTableData_copy(Archive *fout, void *dcontext)
 {
@@ -791,8 +1064,7 @@ dumpTableData_copy(Archive *fout, void *dcontext)
        PQExpBuffer q = createPQExpBuffer();
        PGresult   *res;
        int                     ret;
-       bool            copydone;
-       char            copybuf[COPYBUFSIZ];
+       char       *copybuf;
        const char *column_list;
 
        if (g_verbose)
@@ -800,17 +1072,17 @@ dumpTableData_copy(Archive *fout, void *dcontext)
 
        /*
         * Make sure we are in proper schema.  We will qualify the table name
-        * below anyway (in case its name conflicts with a pg_catalog table);
-        * but this ensures reproducible results in case the table contains
-        * regproc, regclass, etc columns.
+        * below anyway (in case its name conflicts with a pg_catalog table); but
+        * this ensures reproducible results in case the table contains regproc,
+        * regclass, etc columns.
         */
        selectSourceSchema(tbinfo->dobj.namespace->dobj.name);
 
        /*
         * If possible, specify the column list explicitly so that we have no
-        * possibility of retrieving data in the wrong column order.  (The
-        * default column ordering of COPY will not be what we want in certain
-        * corner cases involving ADD COLUMN and inheritance.)
+        * possibility of retrieving data in the wrong column order.  (The default
+        * column ordering of COPY will not be what we want in certain corner
+        * cases involving ADD COLUMN and inheritance.)
         */
        if (g_fout->remoteVersion >= 70300)
                column_list = fmtCopyColumnList(tbinfo);
@@ -820,101 +1092,90 @@ dumpTableData_copy(Archive *fout, void *dcontext)
        if (oids && hasoids)
        {
                appendPQExpBuffer(q, "COPY %s %s WITH OIDS TO stdout;",
-                                               fmtQualifiedId(tbinfo->dobj.namespace->dobj.name,
-                                                                          classname),
+                                                 fmtQualifiedId(tbinfo->dobj.namespace->dobj.name,
+                                                                                classname),
                                                  column_list);
        }
        else
        {
                appendPQExpBuffer(q, "COPY %s %s TO stdout;",
-                                               fmtQualifiedId(tbinfo->dobj.namespace->dobj.name,
-                                                                          classname),
+                                                 fmtQualifiedId(tbinfo->dobj.namespace->dobj.name,
+                                                                                classname),
                                                  column_list);
        }
        res = PQexec(g_conn, q->data);
        check_sql_result(res, g_conn, q->data, PGRES_COPY_OUT);
+       PQclear(res);
 
-       copydone = false;
-
-       while (!copydone)
+       for (;;)
        {
-               ret = PQgetline(g_conn, copybuf, COPYBUFSIZ);
+               ret = PQgetCopyData(g_conn, &copybuf, 0);
 
-               if (copybuf[0] == '\\' &&
-                       copybuf[1] == '.' &&
-                       copybuf[2] == '\0')
-               {
-                       copydone = true;        /* don't print this... */
-               }
-               else
+               if (ret < 0)
+                       break;                          /* done or error */
+
+               if (copybuf)
                {
-                       archputs(copybuf, fout);
-                       switch (ret)
-                       {
-                               case EOF:
-                                       copydone = true;
-                                       /* FALLTHROUGH */
-                               case 0:
-                                       archputs("\n", fout);
-                                       break;
-                               case 1:
-                                       break;
-                       }
+                       WriteData(fout, copybuf, ret);
+                       PQfreemem(copybuf);
                }
 
                /*
                 * THROTTLE:
                 *
                 * There was considerable discussion in late July, 2000 regarding
-                * slowing down pg_dump when backing up large tables. Users with
-                * both slow & fast (muti-processor) machines experienced
-                * performance degradation when doing a backup.
+                * slowing down pg_dump when backing up large tables. Users with both
+                * slow & fast (multi-processor) machines experienced performance
+                * degradation when doing a backup.
                 *
                 * Initial attempts based on sleeping for a number of ms for each ms
-                * of work were deemed too complex, then a simple 'sleep in each
-                * loop' implementation was suggested. The latter failed because
-                * the loop was too tight. Finally, the following was implemented:
+                * of work were deemed too complex, then a simple 'sleep in each loop'
+                * implementation was suggested. The latter failed because the loop
+                * was too tight. Finally, the following was implemented:
                 *
                 * If throttle is non-zero, then See how long since the last sleep.
-                * Work out how long to sleep (based on ratio). If sleep is more
-                * than 100ms, then sleep reset timer EndIf EndIf
+                * Work out how long to sleep (based on ratio). If sleep is more than
+                * 100ms, then sleep reset timer EndIf EndIf
                 *
                 * where the throttle value was the number of ms to sleep per ms of
                 * work. The calculation was done in each loop.
                 *
                 * Most of the hard work is done in the backend, and this solution
-                * still did not work particularly well: on slow machines, the
-                * ratio was 50:1, and on medium paced machines, 1:1, and on fast
-                * multi-processor machines, it had little or no effect, for
-                * reasons that were unclear.
+                * still did not work particularly well: on slow machines, the ratio
+                * was 50:1, and on medium paced machines, 1:1, and on fast
+                * multi-processor machines, it had little or no effect, for reasons
+                * that were unclear.
                 *
                 * Further discussion ensued, and the proposal was dropped.
                 *
-                * For those people who want this feature, it can be implemented
-                * using gettimeofday in each loop, calculating the time since
-                * last sleep, multiplying that by the sleep ratio, then if the
-                * result is more than a preset 'minimum sleep time' (say 100ms),
-                * call the 'select' function to sleep for a subsecond period ie.
+                * For those people who want this feature, it can be implemented using
+                * gettimeofday in each loop, calculating the time since last sleep,
+                * multiplying that by the sleep ratio, then if the result is more
+                * than a preset 'minimum sleep time' (say 100ms), call the 'select'
+                * function to sleep for a subsecond period ie.
                 *
                 * select(0, NULL, NULL, NULL, &tvi);
                 *
-                * This will return after the interval specified in the structure
-                * tvi. Finally, call gettimeofday again to save the 'last sleep
-                * time'.
+                * This will return after the interval specified in the structure tvi.
+                * Finally, call gettimeofday again to save the 'last sleep time'.
                 */
        }
        archprintf(fout, "\\.\n\n\n");
 
-       ret = PQendcopy(g_conn);
-       if (ret != 0)
+       if (ret == -2)
        {
-               write_msg(NULL, "SQL command to dump the contents of table \"%s\" failed: PQendcopy() failed.\n", classname);
+               /* copy data transfer failed */
+               write_msg(NULL, "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.\n", classname);
                write_msg(NULL, "Error message from server: %s", PQerrorMessage(g_conn));
                write_msg(NULL, "The command was: %s\n", q->data);
                exit_nicely();
        }
 
+       /* Check command status and return to normal libpq state */
+       res = PQgetResult(g_conn);
+       check_sql_result(res, g_conn, q->data, PGRES_COMMAND_OK);
        PQclear(res);
+
        destroyPQExpBuffer(q);
        return 1;
 }
@@ -933,9 +1194,9 @@ dumpTableData_insert(Archive *fout, void *dcontext)
 
        /*
         * Make sure we are in proper schema.  We will qualify the table name
-        * below anyway (in case its name conflicts with a pg_catalog table);
-        * but this ensures reproducible results in case the table contains
-        * regproc, regclass, etc columns.
+        * below anyway (in case its name conflicts with a pg_catalog table); but
+        * this ensures reproducible results in case the table contains regproc,
+        * regclass, etc columns.
         */
        selectSourceSchema(tbinfo->dobj.namespace->dobj.name);
 
@@ -943,15 +1204,15 @@ dumpTableData_insert(Archive *fout, void *dcontext)
        {
                appendPQExpBuffer(q, "DECLARE _pg_dump_cursor CURSOR FOR "
                                                  "SELECT * FROM ONLY %s",
-                                               fmtQualifiedId(tbinfo->dobj.namespace->dobj.name,
-                                                                          classname));
+                                                 fmtQualifiedId(tbinfo->dobj.namespace->dobj.name,
+                                                                                classname));
        }
        else
        {
                appendPQExpBuffer(q, "DECLARE _pg_dump_cursor CURSOR FOR "
                                                  "SELECT * FROM %s",
-                                               fmtQualifiedId(tbinfo->dobj.namespace->dobj.name,
-                                                                          classname));
+                                                 fmtQualifiedId(tbinfo->dobj.namespace->dobj.name,
+                                                                                classname));
        }
 
        res = PQexec(g_conn, q->data);
@@ -982,7 +1243,7 @@ dumpTableData_insert(Archive *fout, void *dcontext)
                                {
                                        if (field > 0)
                                                appendPQExpBuffer(q, ", ");
-                                       appendPQExpBuffer(q, fmtId(PQfname(res, field)));
+                                       appendPQExpBufferStr(q, fmtId(PQfname(res, field)));
                                }
                                appendPQExpBuffer(q, ") ");
                                archputs(q->data, fout);
@@ -1010,16 +1271,15 @@ dumpTableData_insert(Archive *fout, void *dcontext)
                                        case NUMERICOID:
                                                {
                                                        /*
-                                                        * These types are printed without quotes
-                                                        * unless they contain values that aren't
-                                                        * accepted by the scanner unquoted (e.g.,
-                                                        * 'NaN').      Note that strtod() and friends
-                                                        * might accept NaN, so we can't use that to
-                                                        * test.
+                                                        * These types are printed without quotes unless
+                                                        * they contain values that aren't accepted by the
+                                                        * scanner unquoted (e.g., 'NaN').      Note that
+                                                        * strtod() and friends might accept NaN, so we
+                                                        * can't use that to test.
                                                         *
                                                         * In reality we only need to defend against
-                                                        * infinity and NaN, so we need not get too
-                                                        * crazy about pattern matching here.
+                                                        * infinity and NaN, so we need not get too crazy
+                                                        * about pattern matching here.
                                                         */
                                                        const char *s = PQgetvalue(res, tuple, field);
 
@@ -1046,7 +1306,9 @@ dumpTableData_insert(Archive *fout, void *dcontext)
                                        default:
                                                /* All other types are printed as string literals. */
                                                resetPQExpBuffer(q);
-                                               appendStringLiteral(q, PQgetvalue(res, tuple, field), false);
+                                               appendStringLiteralAH(q,
+                                                                                         PQgetvalue(res, tuple, field),
+                                                                                         fout);
                                                archputs(q->data, fout);
                                                break;
                                }
@@ -1089,7 +1351,7 @@ dumpTableData(Archive *fout, TableDataInfo *tdinfo)
                                                  fmtId(tbinfo->dobj.name));
                appendPQExpBuffer(copyBuf, "%s %sFROM stdin;\n",
                                                  fmtCopyColumnList(tbinfo),
-                                 (tdinfo->oids && tbinfo->hasoids) ? "WITH OIDS " : "");
+                                         (tdinfo->oids && tbinfo->hasoids) ? "WITH OIDS " : "");
                copyStmt = copyBuf->data;
        }
        else
@@ -1103,7 +1365,7 @@ dumpTableData(Archive *fout, TableDataInfo *tdinfo)
                                 tbinfo->dobj.name,
                                 tbinfo->dobj.namespace->dobj.name,
                                 NULL,
-                                tbinfo->usename, false,
+                                tbinfo->rolname, false,
                                 "TABLE DATA", "", "", copyStmt,
                                 tdinfo->dobj.dependencies, tdinfo->dobj.nDeps,
                                 dumpFn, tdinfo);
@@ -1129,7 +1391,7 @@ getTableData(TableInfo *tblinfo, int numTables, bool oids)
                if (tblinfo[i].relkind == RELKIND_SEQUENCE)
                        continue;
 
-               if (tblinfo[i].dump)
+               if (tblinfo[i].dobj.dump)
                {
                        TableDataInfo *tdinfo;
 
@@ -1138,8 +1400,8 @@ getTableData(TableInfo *tblinfo, int numTables, bool oids)
                        tdinfo->dobj.objType = DO_TABLE_DATA;
 
                        /*
-                        * Note: use tableoid 0 so that this object won't be mistaken
-                        * for something that pg_depend entries apply to.
+                        * Note: use tableoid 0 so that this object won't be mistaken for
+                        * something that pg_depend entries apply to.
                         */
                        tdinfo->dobj.catId.tableoid = 0;
                        tdinfo->dobj.catId.oid = tblinfo[i].dobj.catId.oid;
@@ -1187,37 +1449,53 @@ dumpDatabase(Archive *AH)
        selectSourceSchema("pg_catalog");
 
        /* Get the database owner and parameters from pg_database */
-       if (g_fout->remoteVersion >= 80000)
+       if (g_fout->remoteVersion >= 80200)
+       {
+               appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
+                                                 "(%s datdba) as dba, "
+                                                 "pg_encoding_to_char(encoding) as encoding, "
+                                                 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) as tablespace, "
+                                                 "shobj_description(oid, 'pg_database') as description "
+
+                                                 "FROM pg_database "
+                                                 "WHERE datname = ",
+                                                 username_subquery);
+               appendStringLiteralAH(dbQry, datname, AH);
+       }
+       else if (g_fout->remoteVersion >= 80000)
        {
                appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
-                "(SELECT usename FROM pg_user WHERE usesysid = datdba) as dba, "
+                                                 "(%s datdba) as dba, "
                                                  "pg_encoding_to_char(encoding) as encoding, "
                                                  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) as tablespace "
                                                  "FROM pg_database "
-                                                 "WHERE datname = ");
-               appendStringLiteral(dbQry, datname, true);
+                                                 "WHERE datname = ",
+                                                 username_subquery);
+               appendStringLiteralAH(dbQry, datname, AH);
        }
        else if (g_fout->remoteVersion >= 70100)
        {
                appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
-                "(SELECT usename FROM pg_user WHERE usesysid = datdba) as dba, "
+                                                 "(%s datdba) as dba, "
                                                  "pg_encoding_to_char(encoding) as encoding, "
                                                  "NULL as tablespace "
                                                  "FROM pg_database "
-                                                 "WHERE datname = ");
-               appendStringLiteral(dbQry, datname, true);
+                                                 "WHERE datname = ",
+                                                 username_subquery);
+               appendStringLiteralAH(dbQry, datname, AH);
        }
        else
        {
                appendPQExpBuffer(dbQry, "SELECT "
                                                  "(SELECT oid FROM pg_class WHERE relname = 'pg_database') AS tableoid, "
                                                  "oid, "
-                "(SELECT usename FROM pg_user WHERE usesysid = datdba) as dba, "
+                                                 "(%s datdba) as dba, "
                                                  "pg_encoding_to_char(encoding) as encoding, "
                                                  "NULL as tablespace "
                                                  "FROM pg_database "
-                                                 "WHERE datname = ");
-               appendStringLiteral(dbQry, datname, true);
+                                                 "WHERE datname = ",
+                                                 username_subquery);
+               appendStringLiteralAH(dbQry, datname, AH);
        }
 
        res = PQexec(g_conn, dbQry->data);
@@ -1256,7 +1534,7 @@ dumpDatabase(Archive *AH)
        if (strlen(encoding) > 0)
        {
                appendPQExpBuffer(creaQry, " ENCODING = ");
-               appendStringLiteral(creaQry, encoding, true);
+               appendStringLiteralAH(creaQry, encoding, AH);
        }
        if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0)
                appendPQExpBuffer(creaQry, " TABLESPACE = %s",
@@ -1273,7 +1551,7 @@ dumpDatabase(Archive *AH)
                                 dbDumpId,              /* dump ID */
                                 datname,               /* Name */
                                 NULL,                  /* Namespace */
-                                NULL,                  /* Tablespace */
+                                NULL,                  /* Tablespace */
                                 dba,                   /* Owner */
                                 false,                 /* with oids */
                                 "DATABASE",    /* Desc */
@@ -1286,10 +1564,28 @@ dumpDatabase(Archive *AH)
                                 NULL);                 /* Dumper Arg */
 
        /* Dump DB comment if any */
-       resetPQExpBuffer(dbQry);
-       appendPQExpBuffer(dbQry, "DATABASE %s", fmtId(datname));
-       dumpComment(AH, dbQry->data, NULL, "",
+       if (g_fout->remoteVersion >= 80200)
+       {
+               /* 8.2 keeps comments on shared objects in a shared table, so
+                * we cannot use the dumpComment used for other database objects.
+                */
+               char *comment = PQgetvalue(res, 0, PQfnumber(res, "description"));
+               if (comment && strlen(comment)) {
+                       resetPQExpBuffer(dbQry);
+                       appendPQExpBuffer(dbQry, "COMMENT ON DATABASE %s IS ", fmtId(datname));
+                       appendStringLiteralAH(dbQry, comment, AH);
+                       appendPQExpBuffer(dbQry, ";\n");
+
+                       ArchiveEntry(AH, dbCatId, createDumpId(), datname, NULL, NULL,
+                                                       dba, false, "COMMENT", dbQry->data, "", NULL,
+                                                       &dbDumpId, 1, NULL, NULL);
+               }
+       } else {
+               resetPQExpBuffer(dbQry);
+               appendPQExpBuffer(dbQry, "DATABASE %s", fmtId(datname));
+               dumpComment(AH, dbQry->data, NULL, "",
                                dbCatId, 0, dbDumpId);
+       }
 
        PQclear(res);
 
@@ -1300,96 +1596,100 @@ dumpDatabase(Archive *AH)
 
 
 /*
- * dumpTimestamp
+ * dumpEncoding: put the correct encoding into the archive
  */
 static void
-dumpTimestamp(Archive *AH, char *msg)
+dumpEncoding(Archive *AH)
 {
-       char            buf[256];
-       time_t          now = time(NULL);
+       const char *encname = pg_encoding_to_char(AH->encoding);
+       PQExpBuffer qry = createPQExpBuffer();
 
-       if (strftime(buf, 256, "%Y-%m-%d %H:%M:%S %Z", localtime(&now)) != 0)
-       {
-               PQExpBuffer qry = createPQExpBuffer();
+       if (g_verbose)
+               write_msg(NULL, "saving encoding = %s\n", encname);
 
-               appendPQExpBuffer(qry, "-- ");
-               appendPQExpBuffer(qry, msg);
-               appendPQExpBuffer(qry, " ");
-               appendPQExpBuffer(qry, buf);
-               appendPQExpBuffer(qry, "\n");
+       appendPQExpBuffer(qry, "SET client_encoding = ");
+       appendStringLiteralAH(qry, encname, AH);
+       appendPQExpBuffer(qry, ";\n");
 
-               ArchiveEntry(AH, nilCatalogId, createDumpId(),
-                                        "DUMP TIMESTAMP", NULL, NULL, "",
-                                        false, "DUMP TIMESTAMP", qry->data, "", NULL,
-                                        NULL, 0,
-                                        NULL, NULL);
-               destroyPQExpBuffer(qry);
-       }
+       ArchiveEntry(AH, nilCatalogId, createDumpId(),
+                                "ENCODING", NULL, NULL, "",
+                                false, "ENCODING", qry->data, "", NULL,
+                                NULL, 0,
+                                NULL, NULL);
+
+       destroyPQExpBuffer(qry);
 }
 
 
 /*
- * dumpEncoding: put the correct encoding into the archive
+ * dumpStdStrings: put the correct escape string behavior into the archive
  */
 static void
-dumpEncoding(Archive *AH)
+dumpStdStrings(Archive *AH)
 {
-       PQExpBuffer qry;
-       PGresult   *res;
-
-       /* Can't read the encoding from pre-7.3 servers (SHOW isn't a query) */
-       if (AH->remoteVersion < 70300)
-               return;
+       const char *stdstrings = AH->std_strings ? "on" : "off";
+       PQExpBuffer qry = createPQExpBuffer();
 
        if (g_verbose)
-               write_msg(NULL, "saving encoding\n");
+               write_msg(NULL, "saving standard_conforming_strings = %s\n",
+                                 stdstrings);
 
-       qry = createPQExpBuffer();
+       appendPQExpBuffer(qry, "SET standard_conforming_strings = '%s';\n",
+                                         stdstrings);
 
-       appendPQExpBuffer(qry, "SHOW client_encoding");
+       ArchiveEntry(AH, nilCatalogId, createDumpId(),
+                                "STDSTRINGS", NULL, NULL, "",
+                                false, "STDSTRINGS", qry->data, "", NULL,
+                                NULL, 0,
+                                NULL, NULL);
 
-       res = PQexec(g_conn, qry->data);
+       destroyPQExpBuffer(qry);
+}
 
-       check_sql_result(res, g_conn, qry->data, PGRES_TUPLES_OK);
 
-       resetPQExpBuffer(qry);
+/*
+ * hasBlobs:
+ *     Test whether database contains any large objects
+ */
+static bool
+hasBlobs(Archive *AH)
+{
+       bool            result;
+       const char *blobQry;
+       PGresult   *res;
 
-       appendPQExpBuffer(qry, "SET client_encoding = ");
-       appendStringLiteral(qry, PQgetvalue(res, 0, 0), true);
-       appendPQExpBuffer(qry, ";\n");
+       /* Make sure we are in proper schema */
+       selectSourceSchema("pg_catalog");
 
-       ArchiveEntry(AH, nilCatalogId, createDumpId(),
-                                "ENCODING", NULL, NULL, "",
-                                false, "ENCODING", qry->data, "", NULL,
-                                NULL, 0,
-                                NULL, NULL);
+       /* Check for BLOB OIDs */
+       if (AH->remoteVersion >= 70100)
+               blobQry = "SELECT loid FROM pg_largeobject LIMIT 1";
+       else
+               blobQry = "SELECT oid FROM pg_class WHERE relkind = 'l' LIMIT 1";
+
+       res = PQexec(g_conn, blobQry);
+       check_sql_result(res, g_conn, blobQry, PGRES_TUPLES_OK);
+
+       result = PQntuples(res) > 0;
 
        PQclear(res);
 
-       destroyPQExpBuffer(qry);
+       return result;
 }
 
-
 /*
  * dumpBlobs:
  *     dump all blobs
- *
  */
-
-#define loBufSize 16384
-#define loFetchSize 1000
-
 static int
 dumpBlobs(Archive *AH, void *arg)
 {
-       PQExpBuffer oidQry = createPQExpBuffer();
-       PQExpBuffer oidFetchQry = createPQExpBuffer();
+       const char *blobQry;
+       const char *blobFetchQry;
        PGresult   *res;
+       char            buf[LOBBUFSIZE];
        int                     i;
-       int                     loFd;
-       char            buf[loBufSize];
        int                     cnt;
-       Oid                     blobOid;
 
        if (g_verbose)
                write_msg(NULL, "saving large objects\n");
@@ -1397,29 +1697,32 @@ dumpBlobs(Archive *AH, void *arg)
        /* Make sure we are in proper schema */
        selectSourceSchema("pg_catalog");
 
-       /* Cursor to get all BLOB tables */
+       /* Cursor to get all BLOB OIDs */
        if (AH->remoteVersion >= 70100)
-               appendPQExpBuffer(oidQry, "DECLARE bloboid CURSOR FOR SELECT DISTINCT loid FROM pg_largeobject");
+               blobQry = "DECLARE bloboid CURSOR FOR SELECT DISTINCT loid FROM pg_largeobject";
        else
-               appendPQExpBuffer(oidQry, "DECLARE bloboid CURSOR FOR SELECT oid FROM pg_class WHERE relkind = 'l'");
+               blobQry = "DECLARE bloboid CURSOR FOR SELECT oid FROM pg_class WHERE relkind = 'l'";
 
-       res = PQexec(g_conn, oidQry->data);
-       check_sql_result(res, g_conn, oidQry->data, PGRES_COMMAND_OK);
+       res = PQexec(g_conn, blobQry);
+       check_sql_result(res, g_conn, blobQry, PGRES_COMMAND_OK);
 
-       /* Fetch for cursor */
-       appendPQExpBuffer(oidFetchQry, "FETCH %d IN bloboid", loFetchSize);
+       /* Command to fetch from cursor */
+       blobFetchQry = "FETCH 1000 IN bloboid";
 
        do
        {
-               /* Do a fetch */
                PQclear(res);
 
-               res = PQexec(g_conn, oidFetchQry->data);
-               check_sql_result(res, g_conn, oidFetchQry->data, PGRES_TUPLES_OK);
+               /* Do a fetch */
+               res = PQexec(g_conn, blobFetchQry);
+               check_sql_result(res, g_conn, blobFetchQry, PGRES_TUPLES_OK);
 
                /* Process the tuples, if any */
                for (i = 0; i < PQntuples(res); i++)
                {
+                       Oid                     blobOid;
+                       int                     loFd;
+
                        blobOid = atooid(PQgetvalue(res, i, 0));
                        /* Open the BLOB */
                        loFd = lo_open(g_conn, blobOid, INV_READ);
@@ -1435,7 +1738,7 @@ dumpBlobs(Archive *AH, void *arg)
                        /* Now read it in chunks, sending data to archive */
                        do
                        {
-                               cnt = lo_read(g_conn, loFd, buf, loBufSize);
+                               cnt = lo_read(g_conn, loFd, buf, LOBBUFSIZE);
                                if (cnt < 0)
                                {
                                        write_msg(NULL, "dumpBlobs(): error reading large object: %s",
@@ -1444,18 +1747,91 @@ dumpBlobs(Archive *AH, void *arg)
                                }
 
                                WriteData(AH, buf, cnt);
-
                        } while (cnt > 0);
 
                        lo_close(g_conn, loFd);
 
                        EndBlob(AH, blobOid);
+               }
+       } while (PQntuples(res) > 0);
+
+       PQclear(res);
 
+       return 1;
+}
+
+/*
+ * dumpBlobComments
+ *     dump all blob comments
+ *
+ * Since we don't provide any way to be selective about dumping blobs,
+ * there's no need to be selective about their comments either.  We put
+ * all the comments into one big TOC entry.
+ */
+static int
+dumpBlobComments(Archive *AH, void *arg)
+{
+       const char *blobQry;
+       const char *blobFetchQry;
+       PQExpBuffer commentcmd = createPQExpBuffer();
+       PGresult   *res;
+       int                     i;
+
+       if (g_verbose)
+               write_msg(NULL, "saving large object comments\n");
+
+       /* Make sure we are in proper schema */
+       selectSourceSchema("pg_catalog");
+
+       /* Cursor to get all BLOB comments */
+       if (AH->remoteVersion >= 70200)
+               blobQry = "DECLARE blobcmt CURSOR FOR SELECT loid, obj_description(loid, 'pg_largeobject') FROM (SELECT DISTINCT loid FROM pg_largeobject) ss";
+       else if (AH->remoteVersion >= 70100)
+               blobQry = "DECLARE blobcmt CURSOR FOR SELECT loid, obj_description(loid) FROM (SELECT DISTINCT loid FROM pg_largeobject) ss";
+       else
+               blobQry = "DECLARE blobcmt CURSOR FOR SELECT oid, (SELECT description FROM pg_description pd WHERE pd.objoid=pc.oid) FROM pg_class pc WHERE relkind = 'l'";
+
+       res = PQexec(g_conn, blobQry);
+       check_sql_result(res, g_conn, blobQry, PGRES_COMMAND_OK);
+
+       /* Command to fetch from cursor */
+       blobFetchQry = "FETCH 100 IN blobcmt";
+
+       do
+       {
+               PQclear(res);
+
+               /* Do a fetch */
+               res = PQexec(g_conn, blobFetchQry);
+               check_sql_result(res, g_conn, blobFetchQry, PGRES_TUPLES_OK);
+
+               /* Process the tuples, if any */
+               for (i = 0; i < PQntuples(res); i++)
+               {
+                       Oid                     blobOid;
+                       char       *comment;
+
+                       /* ignore blobs without comments */
+                       if (PQgetisnull(res, i, 1))
+                               continue;
+
+                       blobOid = atooid(PQgetvalue(res, i, 0));
+                       comment = PQgetvalue(res, i, 1);
+
+                       printfPQExpBuffer(commentcmd, "COMMENT ON LARGE OBJECT %u IS ",
+                                                         blobOid);
+                       appendStringLiteralAH(commentcmd, comment, AH);
+                       appendPQExpBuffer(commentcmd, ";\n");
+
+                       archputs(commentcmd->data, AH);
                }
        } while (PQntuples(res) > 0);
 
-       destroyPQExpBuffer(oidQry);
-       destroyPQExpBuffer(oidFetchQry);
+       PQclear(res);
+
+       archputs("\n", AH);
+
+       destroyPQExpBuffer(commentcmd);
 
        return 1;
 }
@@ -1478,12 +1854,12 @@ getNamespaces(int *numNamespaces)
        int                     i_tableoid;
        int                     i_oid;
        int                     i_nspname;
-       int                     i_usename;
+       int                     i_rolname;
        int                     i_nspacl;
 
        /*
-        * Before 7.3, there are no real namespaces; create two dummy entries,
-        * one for user stuff and one for system stuff.
+        * Before 7.3, there are no real namespaces; create two dummy entries, one
+        * for user stuff and one for system stuff.
         */
        if (g_fout->remoteVersion < 70300)
        {
@@ -1494,7 +1870,7 @@ getNamespaces(int *numNamespaces)
                nsinfo[0].dobj.catId.oid = 0;
                AssignDumpId(&nsinfo[0].dobj);
                nsinfo[0].dobj.name = strdup("public");
-               nsinfo[0].usename = strdup("");
+               nsinfo[0].rolname = strdup("");
                nsinfo[0].nspacl = strdup("");
 
                selectDumpableNamespace(&nsinfo[0]);
@@ -1504,7 +1880,7 @@ getNamespaces(int *numNamespaces)
                nsinfo[1].dobj.catId.oid = 1;
                AssignDumpId(&nsinfo[1].dobj);
                nsinfo[1].dobj.name = strdup("pg_catalog");
-               nsinfo[1].usename = strdup("");
+               nsinfo[1].rolname = strdup("");
                nsinfo[1].nspacl = strdup("");
 
                selectDumpableNamespace(&nsinfo[1]);
@@ -1521,12 +1897,13 @@ getNamespaces(int *numNamespaces)
        selectSourceSchema("pg_catalog");
 
        /*
-        * we fetch all namespaces including system ones, so that every object
-        * we read in can be linked to a containing namespace.
+        * we fetch all namespaces including system ones, so that every object we
+        * read in can be linked to a containing namespace.
         */
        appendPQExpBuffer(query, "SELECT tableoid, oid, nspname, "
-                                         "(select usename from pg_user where nspowner = usesysid) as usename, "
-                                         "nspacl FROM pg_namespace");
+                                         "(%s nspowner) as rolname, "
+                                         "nspacl FROM pg_namespace",
+                                         username_subquery);
 
        res = PQexec(g_conn, query->data);
        check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
@@ -1538,7 +1915,7 @@ getNamespaces(int *numNamespaces)
        i_tableoid = PQfnumber(res, "tableoid");
        i_oid = PQfnumber(res, "oid");
        i_nspname = PQfnumber(res, "nspname");
-       i_usename = PQfnumber(res, "usename");
+       i_rolname = PQfnumber(res, "rolname");
        i_nspacl = PQfnumber(res, "nspacl");
 
        for (i = 0; i < ntups; i++)
@@ -1548,36 +1925,17 @@ getNamespaces(int *numNamespaces)
                nsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                AssignDumpId(&nsinfo[i].dobj);
                nsinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_nspname));
-               nsinfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
+               nsinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
                nsinfo[i].nspacl = strdup(PQgetvalue(res, i, i_nspacl));
 
                /* Decide whether to dump this namespace */
                selectDumpableNamespace(&nsinfo[i]);
 
-               if (strlen(nsinfo[i].usename) == 0)
+               if (strlen(nsinfo[i].rolname) == 0)
                        write_msg(NULL, "WARNING: owner of schema \"%s\" appears to be invalid\n",
                                          nsinfo[i].dobj.name);
        }
 
-       /*
-        * If the user attempted to dump a specific namespace, check to ensure
-        * that the specified namespace actually exists.
-        */
-       if (selectSchemaName)
-       {
-               for (i = 0; i < ntups; i++)
-                       if (strcmp(nsinfo[i].dobj.name, selectSchemaName) == 0)
-                               break;
-
-               /* Didn't find a match */
-               if (i == ntups)
-               {
-                       write_msg(NULL, "specified schema \"%s\" does not exist\n",
-                                         selectSchemaName);
-                       exit_nicely();
-               }
-       }
-
        PQclear(res);
        destroyPQExpBuffer(query);
 
@@ -1643,11 +2001,12 @@ getTypes(int *numTypes)
        int                     i;
        PQExpBuffer query = createPQExpBuffer();
        TypeInfo   *tinfo;
+       ShellTypeInfo *stinfo;
        int                     i_tableoid;
        int                     i_oid;
        int                     i_typname;
        int                     i_typnamespace;
-       int                     i_usename;
+       int                     i_rolname;
        int                     i_typinput;
        int                     i_typoutput;
        int                     i_typelem;
@@ -1657,8 +2016,8 @@ getTypes(int *numTypes)
        int                     i_typisdefined;
 
        /*
-        * we include even the built-in types because those may be used as
-        * array elements by user-defined types
+        * we include even the built-in types because those may be used as array
+        * elements by user-defined types
         *
         * we filter out the built-in types when we dump out the types
         *
@@ -1672,39 +2031,42 @@ getTypes(int *numTypes)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, typname, "
                                                  "typnamespace, "
-                                                 "(select usename from pg_user where typowner = usesysid) as usename, "
+                                                 "(%s typowner) as rolname, "
                                                  "typinput::oid as typinput, "
-                                          "typoutput::oid as typoutput, typelem, typrelid, "
+                                                 "typoutput::oid as typoutput, typelem, typrelid, "
                                                  "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
                                                  "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END as typrelkind, "
                                                  "typtype, typisdefined "
-                                                 "FROM pg_type");
+                                                 "FROM pg_type",
+                                                 username_subquery);
        }
        else if (g_fout->remoteVersion >= 70100)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, typname, "
                                                  "0::oid as typnamespace, "
-                                                 "(select usename from pg_user where typowner = usesysid) as usename, "
+                                                 "(%s typowner) as rolname, "
                                                  "typinput::oid as typinput, "
-                                          "typoutput::oid as typoutput, typelem, typrelid, "
+                                                 "typoutput::oid as typoutput, typelem, typrelid, "
                                                  "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
                                                  "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END as typrelkind, "
                                                  "typtype, typisdefined "
-                                                 "FROM pg_type");
+                                                 "FROM pg_type",
+                                                 username_subquery);
        }
        else
        {
                appendPQExpBuffer(query, "SELECT "
-                                                 "(SELECT oid FROM pg_class WHERE relname = 'pg_type') AS tableoid, "
+                "(SELECT oid FROM pg_class WHERE relname = 'pg_type') AS tableoid, "
                                                  "oid, typname, "
                                                  "0::oid as typnamespace, "
-                                                 "(select usename from pg_user where typowner = usesysid) as usename, "
+                                                 "(%s typowner) as rolname, "
                                                  "typinput::oid as typinput, "
-                                          "typoutput::oid as typoutput, typelem, typrelid, "
+                                                 "typoutput::oid as typoutput, typelem, typrelid, "
                                                  "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
                                                  "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END as typrelkind, "
                                                  "typtype, typisdefined "
-                                                 "FROM pg_type");
+                                                 "FROM pg_type",
+                                                 username_subquery);
        }
 
        res = PQexec(g_conn, query->data);
@@ -1718,7 +2080,7 @@ getTypes(int *numTypes)
        i_oid = PQfnumber(res, "oid");
        i_typname = PQfnumber(res, "typname");
        i_typnamespace = PQfnumber(res, "typnamespace");
-       i_usename = PQfnumber(res, "usename");
+       i_rolname = PQfnumber(res, "rolname");
        i_typinput = PQfnumber(res, "typinput");
        i_typoutput = PQfnumber(res, "typoutput");
        i_typelem = PQfnumber(res, "typelem");
@@ -1729,9 +2091,6 @@ getTypes(int *numTypes)
 
        for (i = 0; i < ntups; i++)
        {
-               Oid                     typoutput;
-               FuncInfo   *funcInfo;
-
                tinfo[i].dobj.objType = DO_TYPE;
                tinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                tinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
@@ -1739,21 +2098,21 @@ getTypes(int *numTypes)
                tinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_typname));
                tinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_typnamespace)),
                                                                                                tinfo[i].dobj.catId.oid);
-               tinfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
-               tinfo[i].typinput = atooid(PQgetvalue(res, i, i_typinput));
-               typoutput = atooid(PQgetvalue(res, i, i_typoutput));
+               tinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
                tinfo[i].typelem = atooid(PQgetvalue(res, i, i_typelem));
                tinfo[i].typrelid = atooid(PQgetvalue(res, i, i_typrelid));
                tinfo[i].typrelkind = *PQgetvalue(res, i, i_typrelkind);
                tinfo[i].typtype = *PQgetvalue(res, i, i_typtype);
+               tinfo[i].shellType = NULL;
 
                /*
                 * If it's a table's rowtype, use special type code to facilitate
-                * sorting into the desired order.      (We don't want to consider it
-                * an ordinary type because that would bring the table up into the
+                * sorting into the desired order.      (We don't want to consider it an
+                * ordinary type because that would bring the table up into the
                 * datatype part of the dump order.)
                 */
-               if (OidIsValid(tinfo[i].typrelid) && tinfo[i].typrelkind != 'c')
+               if (OidIsValid(tinfo[i].typrelid) &&
+                       tinfo[i].typrelkind != RELKIND_COMPOSITE_TYPE)
                        tinfo[i].dobj.objType = DO_TABLE_TYPE;
 
                /*
@@ -1770,30 +2129,88 @@ getTypes(int *numTypes)
                else
                        tinfo[i].isDefined = false;
 
+               /* Decide whether we want to dump it */
+               selectDumpableType(&tinfo[i]);
+
                /*
                 * If it's a domain, fetch info about its constraints, if any
                 */
                tinfo[i].nDomChecks = 0;
                tinfo[i].domChecks = NULL;
-               if (tinfo[i].typtype == 'd')
+               if (tinfo[i].dobj.dump && tinfo[i].typtype == 'd')
                        getDomainConstraints(&(tinfo[i]));
 
                /*
-                * Make sure there are dependencies from the type to its input and
-                * output functions.  (We don't worry about typsend, typreceive,
-                * or typanalyze since those are only valid in 7.4 and later,
-                * wherein the standard dependency mechanism will pick them up.)
+                * If it's a base type, make a DumpableObject representing a shell
+                * definition of the type.  We will need to dump that ahead of the
+                * I/O functions for the type.
+                *
+                * Note: the shell type doesn't have a catId.  You might think it
+                * should copy the base type's catId, but then it might capture
+                * the pg_depend entries for the type, which we don't want.
                 */
-               funcInfo = findFuncByOid(tinfo[i].typinput);
-               if (funcInfo)
-                       addObjectDependency(&tinfo[i].dobj,
-                                                               funcInfo->dobj.dumpId);
-               funcInfo = findFuncByOid(typoutput);
-               if (funcInfo)
-                       addObjectDependency(&tinfo[i].dobj,
-                                                               funcInfo->dobj.dumpId);
-
-               if (strlen(tinfo[i].usename) == 0 && tinfo[i].isDefined)
+               if (tinfo[i].dobj.dump && tinfo[i].typtype == 'b')
+               {
+                       stinfo = (ShellTypeInfo *) malloc(sizeof(ShellTypeInfo));
+                       stinfo->dobj.objType = DO_SHELL_TYPE;
+                       stinfo->dobj.catId = nilCatalogId;
+                       AssignDumpId(&stinfo->dobj);
+                       stinfo->dobj.name = strdup(tinfo[i].dobj.name);
+                       stinfo->dobj.namespace = tinfo[i].dobj.namespace;
+                       stinfo->baseType = &(tinfo[i]);
+                       tinfo[i].shellType = stinfo;
+
+                       /*
+                        * Initially mark the shell type as not to be dumped.  We'll
+                        * only dump it if the I/O functions need to be dumped; this
+                        * is taken care of while sorting dependencies.
+                        */
+                       stinfo->dobj.dump = false;
+
+                       /*
+                        * However, if dumping from pre-7.3, there will be no dependency
+                        * info so we have to fake it here.  We only need to worry about
+                        * typinput and typoutput since the other functions only exist
+                        * post-7.3.
+                        */
+                       if (g_fout->remoteVersion < 70300)
+                       {
+                               Oid                     typinput;
+                               Oid                     typoutput;
+                               FuncInfo   *funcInfo;
+
+                               typinput = atooid(PQgetvalue(res, i, i_typinput));
+                               typoutput = atooid(PQgetvalue(res, i, i_typoutput));
+
+                               funcInfo = findFuncByOid(typinput);
+                               if (funcInfo && funcInfo->dobj.dump)
+                               {
+                                       /* base type depends on function */
+                                       addObjectDependency(&tinfo[i].dobj,
+                                                                               funcInfo->dobj.dumpId);
+                                       /* function depends on shell type */
+                                       addObjectDependency(&funcInfo->dobj,
+                                                                               stinfo->dobj.dumpId);
+                                       /* mark shell type as to be dumped */
+                                       stinfo->dobj.dump = true;
+                               }
+
+                               funcInfo = findFuncByOid(typoutput);
+                               if (funcInfo && funcInfo->dobj.dump)
+                               {
+                                       /* base type depends on function */
+                                       addObjectDependency(&tinfo[i].dobj,
+                                                                               funcInfo->dobj.dumpId);
+                                       /* function depends on shell type */
+                                       addObjectDependency(&funcInfo->dobj,
+                                                                               stinfo->dobj.dumpId);
+                                       /* mark shell type as to be dumped */
+                                       stinfo->dobj.dump = true;
+                               }
+                       }
+               }
+
+               if (strlen(tinfo[i].rolname) == 0 && tinfo[i].isDefined)
                        write_msg(NULL, "WARNING: owner of data type \"%s\" appears to be invalid\n",
                                          tinfo[i].dobj.name);
        }
@@ -1826,7 +2243,7 @@ getOperators(int *numOprs)
        int                     i_oid;
        int                     i_oprname;
        int                     i_oprnamespace;
-       int                     i_usename;
+       int                     i_rolname;
        int                     i_oprcode;
 
        /*
@@ -1841,17 +2258,19 @@ getOperators(int *numOprs)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, oprname, "
                                                  "oprnamespace, "
-                                                 "(select usename from pg_user where oprowner = usesysid) as usename, "
+                                                 "(%s oprowner) as rolname, "
                                                  "oprcode::oid as oprcode "
-                                                 "FROM pg_operator");
+                                                 "FROM pg_operator",
+                                                 username_subquery);
        }
        else if (g_fout->remoteVersion >= 70100)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, oprname, "
                                                  "0::oid as oprnamespace, "
-                                                 "(select usename from pg_user where oprowner = usesysid) as usename, "
+                                                 "(%s oprowner) as rolname, "
                                                  "oprcode::oid as oprcode "
-                                                 "FROM pg_operator");
+                                                 "FROM pg_operator",
+                                                 username_subquery);
        }
        else
        {
@@ -1859,9 +2278,10 @@ getOperators(int *numOprs)
                                                  "(SELECT oid FROM pg_class WHERE relname = 'pg_operator') AS tableoid, "
                                                  "oid, oprname, "
                                                  "0::oid as oprnamespace, "
-                                                 "(select usename from pg_user where oprowner = usesysid) as usename, "
+                                                 "(%s oprowner) as rolname, "
                                                  "oprcode::oid as oprcode "
-                                                 "FROM pg_operator");
+                                                 "FROM pg_operator",
+                                                 username_subquery);
        }
 
        res = PQexec(g_conn, query->data);
@@ -1876,7 +2296,7 @@ getOperators(int *numOprs)
        i_oid = PQfnumber(res, "oid");
        i_oprname = PQfnumber(res, "oprname");
        i_oprnamespace = PQfnumber(res, "oprnamespace");
-       i_usename = PQfnumber(res, "usename");
+       i_rolname = PQfnumber(res, "rolname");
        i_oprcode = PQfnumber(res, "oprcode");
 
        for (i = 0; i < ntups; i++)
@@ -1887,11 +2307,14 @@ getOperators(int *numOprs)
                AssignDumpId(&oprinfo[i].dobj);
                oprinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_oprname));
                oprinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)),
-                                                                                         oprinfo[i].dobj.catId.oid);
-               oprinfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
+                                                                                                 oprinfo[i].dobj.catId.oid);
+               oprinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
                oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
 
-               if (strlen(oprinfo[i].usename) == 0)
+               /* Decide whether we want to dump it */
+               selectDumpableObject(&(oprinfo[i].dobj));
+
+               if (strlen(oprinfo[i].rolname) == 0)
                        write_msg(NULL, "WARNING: owner of operator \"%s\" appears to be invalid\n",
                                          oprinfo[i].dobj.name);
        }
@@ -1922,7 +2345,7 @@ getConversions(int *numConversions)
        int                     i_oid;
        int                     i_conname;
        int                     i_connamespace;
-       int                     i_usename;
+       int                     i_rolname;
 
        /* Conversions didn't exist pre-7.3 */
        if (g_fout->remoteVersion < 70300)
@@ -1941,8 +2364,9 @@ getConversions(int *numConversions)
 
        appendPQExpBuffer(query, "SELECT tableoid, oid, conname, "
                                          "connamespace, "
-       "(select usename from pg_user where conowner = usesysid) as usename "
-                                         "FROM pg_conversion");
+                                         "(%s conowner) as rolname "
+                                         "FROM pg_conversion",
+                                         username_subquery);
 
        res = PQexec(g_conn, query->data);
        check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
@@ -1956,7 +2380,7 @@ getConversions(int *numConversions)
        i_oid = PQfnumber(res, "oid");
        i_conname = PQfnumber(res, "conname");
        i_connamespace = PQfnumber(res, "connamespace");
-       i_usename = PQfnumber(res, "usename");
+       i_rolname = PQfnumber(res, "rolname");
 
        for (i = 0; i < ntups; i++)
        {
@@ -1966,8 +2390,11 @@ getConversions(int *numConversions)
                AssignDumpId(&convinfo[i].dobj);
                convinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_conname));
                convinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_connamespace)),
-                                                                                        convinfo[i].dobj.catId.oid);
-               convinfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
+                                                                                                convinfo[i].dobj.catId.oid);
+               convinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
+
+               /* Decide whether we want to dump it */
+               selectDumpableObject(&(convinfo[i].dobj));
        }
 
        PQclear(res);
@@ -1996,7 +2423,7 @@ getOpclasses(int *numOpclasses)
        int                     i_oid;
        int                     i_opcname;
        int                     i_opcnamespace;
-       int                     i_usename;
+       int                     i_rolname;
 
        /*
         * find all opclasses, including builtin opclasses; we filter out
@@ -2010,14 +2437,15 @@ getOpclasses(int *numOpclasses)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, opcname, "
                                                  "opcnamespace, "
-                                                 "(select usename from pg_user where opcowner = usesysid) as usename "
-                                                 "FROM pg_opclass");
+                                                 "(%s opcowner) as rolname "
+                                                 "FROM pg_opclass",
+                                                 username_subquery);
        }
        else if (g_fout->remoteVersion >= 70100)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, opcname, "
                                                  "0::oid as opcnamespace, "
-                                                 "''::name as usename "
+                                                 "''::name as rolname "
                                                  "FROM pg_opclass");
        }
        else
@@ -2026,7 +2454,7 @@ getOpclasses(int *numOpclasses)
                                                  "(SELECT oid FROM pg_class WHERE relname = 'pg_opclass') AS tableoid, "
                                                  "oid, opcname, "
                                                  "0::oid as opcnamespace, "
-                                                 "''::name as usename "
+                                                 "''::name as rolname "
                                                  "FROM pg_opclass");
        }
 
@@ -2042,7 +2470,7 @@ getOpclasses(int *numOpclasses)
        i_oid = PQfnumber(res, "oid");
        i_opcname = PQfnumber(res, "opcname");
        i_opcnamespace = PQfnumber(res, "opcnamespace");
-       i_usename = PQfnumber(res, "usename");
+       i_rolname = PQfnumber(res, "rolname");
 
        for (i = 0; i < ntups; i++)
        {
@@ -2052,12 +2480,15 @@ getOpclasses(int *numOpclasses)
                AssignDumpId(&opcinfo[i].dobj);
                opcinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_opcname));
                opcinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_opcnamespace)),
-                                                                                         opcinfo[i].dobj.catId.oid);
-               opcinfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
+                                                                                                 opcinfo[i].dobj.catId.oid);
+               opcinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
+
+               /* Decide whether we want to dump it */
+               selectDumpableObject(&(opcinfo[i].dobj));
 
                if (g_fout->remoteVersion >= 70300)
                {
-                       if (strlen(opcinfo[i].usename) == 0)
+                       if (strlen(opcinfo[i].rolname) == 0)
                                write_msg(NULL, "WARNING: owner of operator class \"%s\" appears to be invalid\n",
                                                  opcinfo[i].dobj.name);
                }
@@ -2089,8 +2520,9 @@ getAggregates(int *numAggs)
        int                     i_oid;
        int                     i_aggname;
        int                     i_aggnamespace;
-       int                     i_aggbasetype;
-       int                     i_usename;
+       int                     i_pronargs;
+       int                     i_proargtypes;
+       int                     i_rolname;
        int                     i_aggacl;
 
        /* Make sure we are in proper schema */
@@ -2098,27 +2530,44 @@ getAggregates(int *numAggs)
 
        /* find all user-defined aggregates */
 
-       if (g_fout->remoteVersion >= 70300)
+       if (g_fout->remoteVersion >= 80200)
+       {
+               appendPQExpBuffer(query, "SELECT tableoid, oid, proname as aggname, "
+                                                 "pronamespace as aggnamespace, "
+                                                 "pronargs, proargtypes, "
+                                                 "(%s proowner) as rolname, "
+                                                 "proacl as aggacl "
+                                                 "FROM pg_proc "
+                                                 "WHERE proisagg "
+                                                 "AND pronamespace != "
+                          "(select oid from pg_namespace where nspname = 'pg_catalog')",
+                                                 username_subquery);
+       }
+       else if (g_fout->remoteVersion >= 70300)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, proname as aggname, "
                                                  "pronamespace as aggnamespace, "
-                                                 "proargtypes[0] as aggbasetype, "
-                                                 "(select usename from pg_user where proowner = usesysid) as usename, "
+                                                 "CASE WHEN proargtypes[0] = 'pg_catalog.\"any\"'::pg_catalog.regtype THEN 0 ELSE 1 END as pronargs, "
+                                                 "proargtypes, "
+                                                 "(%s proowner) as rolname, "
                                                  "proacl as aggacl "
                                                  "FROM pg_proc "
                                                  "WHERE proisagg "
                                                  "AND pronamespace != "
-                 "(select oid from pg_namespace where nspname = 'pg_catalog')");
+                          "(select oid from pg_namespace where nspname = 'pg_catalog')",
+                                                 username_subquery);
        }
        else if (g_fout->remoteVersion >= 70100)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, aggname, "
                                                  "0::oid as aggnamespace, "
-                                                 "aggbasetype, "
-                                                 "(select usename from pg_user where aggowner = usesysid) as usename, "
+                                                 "CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END as pronargs, "
+                                                 "aggbasetype as proargtypes, "
+                                                 "(%s aggowner) as rolname, "
                                                  "'{=X}' as aggacl "
                                                  "FROM pg_aggregate "
                                                  "where oid > '%u'::oid",
+                                                 username_subquery,
                                                  g_last_builtin_oid);
        }
        else
@@ -2127,11 +2576,13 @@ getAggregates(int *numAggs)
                                                  "(SELECT oid FROM pg_class WHERE relname = 'pg_aggregate') AS tableoid, "
                                                  "oid, aggname, "
                                                  "0::oid as aggnamespace, "
-                                                 "aggbasetype, "
-                                                 "(select usename from pg_user where aggowner = usesysid) as usename, "
+                                                 "CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END as pronargs, "
+                                                 "aggbasetype as proargtypes, "
+                                                 "(%s aggowner) as rolname, "
                                                  "'{=X}' as aggacl "
                                                  "FROM pg_aggregate "
                                                  "where oid > '%u'::oid",
+                                                 username_subquery,
                                                  g_last_builtin_oid);
        }
 
@@ -2147,8 +2598,9 @@ getAggregates(int *numAggs)
        i_oid = PQfnumber(res, "oid");
        i_aggname = PQfnumber(res, "aggname");
        i_aggnamespace = PQfnumber(res, "aggnamespace");
-       i_aggbasetype = PQfnumber(res, "aggbasetype");
-       i_usename = PQfnumber(res, "usename");
+       i_pronargs = PQfnumber(res, "pronargs");
+       i_proargtypes = PQfnumber(res, "proargtypes");
+       i_rolname = PQfnumber(res, "rolname");
        i_aggacl = PQfnumber(res, "aggacl");
 
        for (i = 0; i < ntups; i++)
@@ -2159,20 +2611,30 @@ getAggregates(int *numAggs)
                AssignDumpId(&agginfo[i].aggfn.dobj);
                agginfo[i].aggfn.dobj.name = strdup(PQgetvalue(res, i, i_aggname));
                agginfo[i].aggfn.dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_aggnamespace)),
-                                                                               agginfo[i].aggfn.dobj.catId.oid);
-               agginfo[i].aggfn.usename = strdup(PQgetvalue(res, i, i_usename));
-               if (strlen(agginfo[i].aggfn.usename) == 0)
+                                                                                       agginfo[i].aggfn.dobj.catId.oid);
+               agginfo[i].aggfn.rolname = strdup(PQgetvalue(res, i, i_rolname));
+               if (strlen(agginfo[i].aggfn.rolname) == 0)
                        write_msg(NULL, "WARNING: owner of aggregate function \"%s\" appears to be invalid\n",
                                          agginfo[i].aggfn.dobj.name);
-               agginfo[i].aggfn.lang = InvalidOid;             /* not currently
-                                                                                                * interesting */
-               agginfo[i].aggfn.nargs = 1;
-               agginfo[i].aggfn.argtypes = (Oid *) malloc(sizeof(Oid));
-               agginfo[i].aggfn.argtypes[0] = atooid(PQgetvalue(res, i, i_aggbasetype));
+               agginfo[i].aggfn.lang = InvalidOid;             /* not currently interesting */
                agginfo[i].aggfn.prorettype = InvalidOid;               /* not saved */
                agginfo[i].aggfn.proacl = strdup(PQgetvalue(res, i, i_aggacl));
-               agginfo[i].anybasetype = false; /* computed when it's dumped */
-               agginfo[i].fmtbasetype = NULL;  /* computed when it's dumped */
+               agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs));
+               if (agginfo[i].aggfn.nargs == 0)
+                       agginfo[i].aggfn.argtypes = NULL;
+               else
+               {
+                       agginfo[i].aggfn.argtypes = (Oid *) malloc(agginfo[i].aggfn.nargs * sizeof(Oid));
+                       if (g_fout->remoteVersion >= 70300)
+                               parseOidArray(PQgetvalue(res, i, i_proargtypes),
+                                                         agginfo[i].aggfn.argtypes,
+                                                         agginfo[i].aggfn.nargs);
+                       else                            /* it's just aggbasetype */
+                               agginfo[i].aggfn.argtypes[0] = atooid(PQgetvalue(res, i, i_proargtypes));
+               }
+
+               /* Decide whether we want to dump it */
+               selectDumpableObject(&(agginfo[i].aggfn.dobj));
        }
 
        PQclear(res);
@@ -2201,7 +2663,7 @@ getFuncs(int *numFuncs)
        int                     i_oid;
        int                     i_proname;
        int                     i_pronamespace;
-       int                     i_usename;
+       int                     i_rolname;
        int                     i_prolang;
        int                     i_pronargs;
        int                     i_proargtypes;
@@ -2219,11 +2681,13 @@ getFuncs(int *numFuncs)
                                                  "SELECT tableoid, oid, proname, prolang, "
                                                  "pronargs, proargtypes, prorettype, proacl, "
                                                  "pronamespace, "
-                                                 "(select usename from pg_user where proowner = usesysid) as usename "
+                                                 "(%s proowner) as rolname "
                                                  "FROM pg_proc "
                                                  "WHERE NOT proisagg "
                                                  "AND pronamespace != "
-                 "(select oid from pg_namespace where nspname = 'pg_catalog')");
+                                                 "(select oid from pg_namespace"
+                                                 " where nspname = 'pg_catalog')",
+                                                 username_subquery);
        }
        else if (g_fout->remoteVersion >= 70100)
        {
@@ -2232,23 +2696,26 @@ getFuncs(int *numFuncs)
                                                  "pronargs, proargtypes, prorettype, "
                                                  "'{=X}' as proacl, "
                                                  "0::oid as pronamespace, "
-                                                 "(select usename from pg_user where proowner = usesysid) as usename "
+                                                 "(%s proowner) as rolname "
                                                  "FROM pg_proc "
                                                  "where pg_proc.oid > '%u'::oid",
+                                                 username_subquery,
                                                  g_last_builtin_oid);
        }
        else
        {
                appendPQExpBuffer(query,
                                                  "SELECT "
-                                                 "(SELECT oid FROM pg_class WHERE relname = 'pg_proc') AS tableoid, "
+                                                 "(SELECT oid FROM pg_class "
+                                                 " WHERE relname = 'pg_proc') AS tableoid, "
                                                  "oid, proname, prolang, "
                                                  "pronargs, proargtypes, prorettype, "
                                                  "'{=X}' as proacl, "
                                                  "0::oid as pronamespace, "
-                                                 "(select usename from pg_user where proowner = usesysid) as usename "
+                                                 "(%s proowner) as rolname "
                                                  "FROM pg_proc "
                                                  "where pg_proc.oid > '%u'::oid",
+                                                 username_subquery,
                                                  g_last_builtin_oid);
        }
 
@@ -2265,7 +2732,7 @@ getFuncs(int *numFuncs)
        i_oid = PQfnumber(res, "oid");
        i_proname = PQfnumber(res, "proname");
        i_pronamespace = PQfnumber(res, "pronamespace");
-       i_usename = PQfnumber(res, "usename");
+       i_rolname = PQfnumber(res, "rolname");
        i_prolang = PQfnumber(res, "prolang");
        i_pronargs = PQfnumber(res, "pronargs");
        i_proargtypes = PQfnumber(res, "proargtypes");
@@ -2279,9 +2746,10 @@ getFuncs(int *numFuncs)
                finfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                AssignDumpId(&finfo[i].dobj);
                finfo[i].dobj.name = strdup(PQgetvalue(res, i, i_proname));
-               finfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_pronamespace)),
-                                                                                               finfo[i].dobj.catId.oid);
-               finfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
+               finfo[i].dobj.namespace =
+                       findNamespace(atooid(PQgetvalue(res, i, i_pronamespace)),
+                                                 finfo[i].dobj.catId.oid);
+               finfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
                finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
                finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype));
                finfo[i].proacl = strdup(PQgetvalue(res, i, i_proacl));
@@ -2295,8 +2763,12 @@ getFuncs(int *numFuncs)
                                                  finfo[i].argtypes, finfo[i].nargs);
                }
 
-               if (strlen(finfo[i].usename) == 0)
-                       write_msg(NULL, "WARNING: owner of function \"%s\" appears to be invalid\n",
+               /* Decide whether we want to dump it */
+               selectDumpableObject(&(finfo[i].dobj));
+
+               if (strlen(finfo[i].rolname) == 0)
+                       write_msg(NULL,
+                                "WARNING: owner of function \"%s\" appears to be invalid\n",
                                          finfo[i].dobj.name);
        }
 
@@ -2330,7 +2802,7 @@ getTables(int *numTables)
        int                     i_relnamespace;
        int                     i_relkind;
        int                     i_relacl;
-       int                     i_usename;
+       int                     i_rolname;
        int                     i_relchecks;
        int                     i_reltriggers;
        int                     i_relhasindex;
@@ -2339,6 +2811,7 @@ getTables(int *numTables)
        int                     i_owning_tab;
        int                     i_owning_col;
        int                     i_reltablespace;
+       int                     i_reloptions;
 
        /* Make sure we are in proper schema */
        selectSourceSchema("pg_catalog");
@@ -2352,41 +2825,71 @@ getTables(int *numTables)
         * We ignore tables that are not type 'r' (ordinary relation), 'S'
         * (sequence), 'v' (view), or 'c' (composite type).
         *
-        * Composite-type table entries won't be dumped as such, but we have
-        * to make a DumpableObject for them so that we can track dependencies
-        * of the composite type (pg_depend entries for columns of the composite
-        * type link to the pg_class entry not the pg_type entry).
+        * Composite-type table entries won't be dumped as such, but we have to
+        * make a DumpableObject for them so that we can track dependencies of the
+        * composite type (pg_depend entries for columns of the composite type
+        * link to the pg_class entry not the pg_type entry).
         *
         * Note: in this phase we should collect only a minimal amount of
-        * information about each table, basically just enough to decide if it
-        * is interesting.      We must fetch all tables in this phase because
-        * otherwise we cannot correctly identify inherited columns, serial
-        * columns, etc.
+        * information about each table, basically just enough to decide if it is
+        * interesting. We must fetch all tables in this phase because otherwise
+        * we cannot correctly identify inherited columns, owned sequences, etc.
         */
 
-       if (g_fout->remoteVersion >= 80000)
+       if (g_fout->remoteVersion >= 80200)
        {
                /*
                 * Left join to pick up dependency info linking sequences to their
-                * serial column, if any
+                * owning column, if any (note this dependency is AUTO as of 8.2)
                 */
                appendPQExpBuffer(query,
                                                  "SELECT c.tableoid, c.oid, relname, "
                                                  "relacl, relkind, relnamespace, "
-                                                 "(select usename from pg_user where relowner = usesysid) as usename, "
+                                                 "(%s relowner) as rolname, "
                                                  "relchecks, reltriggers, "
                                                  "relhasindex, relhasrules, relhasoids, "
                                                  "d.refobjid as owning_tab, "
                                                  "d.refobjsubid as owning_col, "
-                                                 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace "
+                                                 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
+                                                 "array_to_string(c.reloptions, ', ') as reloptions "
                                                  "from pg_class c "
                                                  "left join pg_depend d on "
                                                  "(c.relkind = '%c' and "
-                                               "d.classid = c.tableoid and d.objid = c.oid and "
+                                                 "d.classid = c.tableoid and d.objid = c.oid and "
                                                  "d.objsubid = 0 and "
-                                               "d.refclassid = c.tableoid and d.deptype = 'i') "
+                                                 "d.refclassid = c.tableoid and d.deptype = 'a') "
                                                  "where relkind in ('%c', '%c', '%c', '%c') "
                                                  "order by c.oid",
+                                                 username_subquery,
+                                                 RELKIND_SEQUENCE,
+                                                 RELKIND_RELATION, RELKIND_SEQUENCE,
+                                                 RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
+       }
+       else if (g_fout->remoteVersion >= 80000)
+       {
+               /*
+                * Left join to pick up dependency info linking sequences to their
+                * owning column, if any
+                */
+               appendPQExpBuffer(query,
+                                                 "SELECT c.tableoid, c.oid, relname, "
+                                                 "relacl, relkind, relnamespace, "
+                                                 "(%s relowner) as rolname, "
+                                                 "relchecks, reltriggers, "
+                                                 "relhasindex, relhasrules, relhasoids, "
+                                                 "d.refobjid as owning_tab, "
+                                                 "d.refobjsubid as owning_col, "
+                                                 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
+                                                 "NULL as reloptions "
+                                                 "from pg_class c "
+                                                 "left join pg_depend d on "
+                                                 "(c.relkind = '%c' and "
+                                                 "d.classid = c.tableoid and d.objid = c.oid and "
+                                                 "d.objsubid = 0 and "
+                                                 "d.refclassid = c.tableoid and d.deptype = 'i') "
+                                                 "where relkind in ('%c', '%c', '%c', '%c') "
+                                                 "order by c.oid",
+                                                 username_subquery,
                                                  RELKIND_SEQUENCE,
                                                  RELKIND_RELATION, RELKIND_SEQUENCE,
                                                  RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
@@ -2395,25 +2898,27 @@ getTables(int *numTables)
        {
                /*
                 * Left join to pick up dependency info linking sequences to their
-                * serial column, if any
+                * owning column, if any
                 */
                appendPQExpBuffer(query,
                                                  "SELECT c.tableoid, c.oid, relname, "
                                                  "relacl, relkind, relnamespace, "
-                                                 "(select usename from pg_user where relowner = usesysid) as usename, "
+                                                 "(%s relowner) as rolname, "
                                                  "relchecks, reltriggers, "
                                                  "relhasindex, relhasrules, relhasoids, "
                                                  "d.refobjid as owning_tab, "
                                                  "d.refobjsubid as owning_col, "
-                                                 "NULL as reltablespace "
+                                                 "NULL as reltablespace, "
+                                                 "NULL as reloptions "
                                                  "from pg_class c "
                                                  "left join pg_depend d on "
                                                  "(c.relkind = '%c' and "
-                                               "d.classid = c.tableoid and d.objid = c.oid and "
+                                                 "d.classid = c.tableoid and d.objid = c.oid and "
                                                  "d.objsubid = 0 and "
-                                               "d.refclassid = c.tableoid and d.deptype = 'i') "
+                                                 "d.refclassid = c.tableoid and d.deptype = 'i') "
                                                  "where relkind in ('%c', '%c', '%c', '%c') "
                                                  "order by c.oid",
+                                                 username_subquery,
                                                  RELKIND_SEQUENCE,
                                                  RELKIND_RELATION, RELKIND_SEQUENCE,
                                                  RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
@@ -2421,64 +2926,70 @@ getTables(int *numTables)
        else if (g_fout->remoteVersion >= 70200)
        {
                appendPQExpBuffer(query,
-                                          "SELECT tableoid, oid, relname, relacl, relkind, "
+                                                 "SELECT tableoid, oid, relname, relacl, relkind, "
                                                  "0::oid as relnamespace, "
-                                                 "(select usename from pg_user where relowner = usesysid) as usename, "
+                                                 "(%s relowner) as rolname, "
                                                  "relchecks, reltriggers, "
                                                  "relhasindex, relhasrules, relhasoids, "
                                                  "NULL::oid as owning_tab, "
                                                  "NULL::int4 as owning_col, "
-                                                 "NULL as reltablespace "
+                                                 "NULL as reltablespace, "
+                                                 "NULL as reloptions "
                                                  "from pg_class "
                                                  "where relkind in ('%c', '%c', '%c') "
                                                  "order by oid",
-                                          RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW);
+                                                 username_subquery,
+                                                 RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW);
        }
        else if (g_fout->remoteVersion >= 70100)
        {
                /* all tables have oids in 7.1 */
                appendPQExpBuffer(query,
-                                          "SELECT tableoid, oid, relname, relacl, relkind, "
+                                                 "SELECT tableoid, oid, relname, relacl, relkind, "
                                                  "0::oid as relnamespace, "
-                                                 "(select usename from pg_user where relowner = usesysid) as usename, "
+                                                 "(%s relowner) as rolname, "
                                                  "relchecks, reltriggers, "
                                                  "relhasindex, relhasrules, "
                                                  "'t'::bool as relhasoids, "
                                                  "NULL::oid as owning_tab, "
                                                  "NULL::int4 as owning_col, "
-                                                 "NULL as reltablespace "
+                                                 "NULL as reltablespace, "
+                                                 "NULL as reloptions "
                                                  "from pg_class "
                                                  "where relkind in ('%c', '%c', '%c') "
                                                  "order by oid",
-                                          RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW);
+                                                 username_subquery,
+                                                 RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW);
        }
        else
        {
                /*
-                * Before 7.1, view relkind was not set to 'v', so we must check
-                * if we have a view by looking for a rule in pg_rewrite.
+                * Before 7.1, view relkind was not set to 'v', so we must check if we
+                * have a view by looking for a rule in pg_rewrite.
                 */
                appendPQExpBuffer(query,
                                                  "SELECT "
-                                                 "(SELECT oid FROM pg_class WHERE relname = 'pg_class') AS tableoid, "
+               "(SELECT oid FROM pg_class WHERE relname = 'pg_class') AS tableoid, "
                                                  "oid, relname, relacl, "
                                                  "CASE WHEN relhasrules and relkind = 'r' "
-                                 "  and EXISTS(SELECT rulename FROM pg_rewrite r WHERE "
-                                 "             r.ev_class = c.oid AND r.ev_type = '1') "
+                                         "  and EXISTS(SELECT rulename FROM pg_rewrite r WHERE "
+                                         "             r.ev_class = c.oid AND r.ev_type = '1') "
                                                  "THEN '%c'::\"char\" "
                                                  "ELSE relkind END AS relkind,"
                                                  "0::oid as relnamespace, "
-                                                 "(select usename from pg_user where relowner = usesysid) as usename, "
+                                                 "(%s relowner) as rolname, "
                                                  "relchecks, reltriggers, "
                                                  "relhasindex, relhasrules, "
                                                  "'t'::bool as relhasoids, "
                                                  "NULL::oid as owning_tab, "
                                                  "NULL::int4 as owning_col, "
-                                                 "NULL as reltablespace "
+                                                 "NULL as reltablespace, "
+                                                 "NULL as reloptions "
                                                  "from pg_class c "
                                                  "where relkind in ('%c', '%c') "
                                                  "order by oid",
                                                  RELKIND_VIEW,
+                                                 username_subquery,
                                                  RELKIND_RELATION, RELKIND_SEQUENCE);
        }
 
@@ -2490,13 +3001,13 @@ getTables(int *numTables)
        *numTables = ntups;
 
        /*
-        * Extract data from result and lock dumpable tables.  We do the
-        * locking before anything else, to minimize the window wherein a
-        * table could disappear under us.
+        * Extract data from result and lock dumpable tables.  We do the locking
+        * before anything else, to minimize the window wherein a table could
+        * disappear under us.
         *
-        * Note that we have to save info about all tables here, even when
-        * dumping only one, because we don't yet know which tables might be
-        * inheritance ancestors of the target table.
+        * Note that we have to save info about all tables here, even when dumping
+        * only one, because we don't yet know which tables might be inheritance
+        * ancestors of the target table.
         */
        tblinfo = (TableInfo *) calloc(ntups, sizeof(TableInfo));
 
@@ -2506,7 +3017,7 @@ getTables(int *numTables)
        i_relnamespace = PQfnumber(res, "relnamespace");
        i_relacl = PQfnumber(res, "relacl");
        i_relkind = PQfnumber(res, "relkind");
-       i_usename = PQfnumber(res, "usename");
+       i_rolname = PQfnumber(res, "rolname");
        i_relchecks = PQfnumber(res, "relchecks");
        i_reltriggers = PQfnumber(res, "reltriggers");
        i_relhasindex = PQfnumber(res, "relhasindex");
@@ -2515,6 +3026,7 @@ getTables(int *numTables)
        i_owning_tab = PQfnumber(res, "owning_tab");
        i_owning_col = PQfnumber(res, "owning_col");
        i_reltablespace = PQfnumber(res, "reltablespace");
+       i_reloptions = PQfnumber(res, "reloptions");
 
        for (i = 0; i < ntups; i++)
        {
@@ -2524,8 +3036,8 @@ getTables(int *numTables)
                AssignDumpId(&tblinfo[i].dobj);
                tblinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_relname));
                tblinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_relnamespace)),
-                                                                                         tblinfo[i].dobj.catId.oid);
-               tblinfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
+                                                                                                 tblinfo[i].dobj.catId.oid);
+               tblinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
                tblinfo[i].relacl = strdup(PQgetvalue(res, i, i_relacl));
                tblinfo[i].relkind = *(PQgetvalue(res, i, i_relkind));
                tblinfo[i].hasindex = (strcmp(PQgetvalue(res, i, i_relhasindex), "t") == 0);
@@ -2544,71 +3056,77 @@ getTables(int *numTables)
                        tblinfo[i].owning_col = atoi(PQgetvalue(res, i, i_owning_col));
                }
                tblinfo[i].reltablespace = strdup(PQgetvalue(res, i, i_reltablespace));
+               tblinfo[i].reloptions = strdup(PQgetvalue(res, i, i_reloptions));
 
                /* other fields were zeroed above */
 
                /*
-                * Decide whether we want to dump this table.  Sequences owned by
-                * serial columns are never dumpable on their own; we will
-                * transpose their owning table's dump flag to them below.
+                * Decide whether we want to dump this table.
                 */
                if (tblinfo[i].relkind == RELKIND_COMPOSITE_TYPE)
-                       tblinfo[i].dump = false;
-               else if (OidIsValid(tblinfo[i].owning_tab))
-                       tblinfo[i].dump = false;
+                       tblinfo[i].dobj.dump = false;
                else
                        selectDumpableTable(&tblinfo[i]);
-               tblinfo[i].interesting = tblinfo[i].dump;
+               tblinfo[i].interesting = tblinfo[i].dobj.dump;
 
                /*
-                * Read-lock target tables to make sure they aren't DROPPED or
-                * altered in schema before we get around to dumping them.
+                * Read-lock target tables to make sure they aren't DROPPED or altered
+                * in schema before we get around to dumping them.
                 *
-                * Note that we don't explicitly lock parents of the target tables;
-                * we assume our lock on the child is enough to prevent schema
+                * Note that we don't explicitly lock parents of the target tables; we
+                * assume our lock on the child is enough to prevent schema
                 * alterations to parent tables.
                 *
                 * NOTE: it'd be kinda nice to lock views and sequences too, not only
                 * plain tables, but the backend doesn't presently allow that.
                 */
-               if (tblinfo[i].dump && tblinfo[i].relkind == RELKIND_RELATION)
+               if (tblinfo[i].dobj.dump && tblinfo[i].relkind == RELKIND_RELATION)
                {
                        resetPQExpBuffer(lockquery);
                        appendPQExpBuffer(lockquery,
                                                          "LOCK TABLE %s IN ACCESS SHARE MODE",
-                                        fmtQualifiedId(tblinfo[i].dobj.namespace->dobj.name,
-                                                                       tblinfo[i].dobj.name));
+                                                fmtQualifiedId(tblinfo[i].dobj.namespace->dobj.name,
+                                                                               tblinfo[i].dobj.name));
                        do_sql_command(g_conn, lockquery->data);
                }
 
                /* Emit notice if join for owner failed */
-               if (strlen(tblinfo[i].usename) == 0)
+               if (strlen(tblinfo[i].rolname) == 0)
                        write_msg(NULL, "WARNING: owner of table \"%s\" appears to be invalid\n",
                                          tblinfo[i].dobj.name);
        }
 
+       PQclear(res);
+
        /*
-        * If the user is attempting to dump a specific table, check to ensure
-        * that the specified table actually exists.  (This is a bit
-        * simplistic since we don't fully check the combination of -n and -t
-        * switches.)
+        * Force sequences that are "owned" by table columns to be dumped
+        * whenever their owning table is being dumped.
         */
-       if (selectTableName)
+       for (i = 0; i < ntups; i++)
        {
-               for (i = 0; i < ntups; i++)
-                       if (strcmp(tblinfo[i].dobj.name, selectTableName) == 0)
-                               break;
+               TableInfo  *seqinfo = &tblinfo[i];
+               int             j;
+
+               if (!OidIsValid(seqinfo->owning_tab))
+                       continue;                       /* not an owned sequence */
+               if (seqinfo->dobj.dump)
+                       continue;                       /* no need to search */
 
-               /* Didn't find a match */
-               if (i == ntups)
+               /* can't use findTableByOid yet, unfortunately */
+               for (j = 0; j < ntups; j++)
                {
-                       write_msg(NULL, "specified table \"%s\" does not exist\n",
-                                         selectTableName);
-                       exit_nicely();
+                       if (tblinfo[j].dobj.catId.oid == seqinfo->owning_tab)
+                       {
+                               if (tblinfo[j].dobj.dump)
+                               {
+                                       seqinfo->interesting = true;
+                                       seqinfo->dobj.dump = true;
+                               }
+                               break;
+                       }
                }
        }
 
-       PQclear(res);
        destroyPQExpBuffer(query);
        destroyPQExpBuffer(delqry);
        destroyPQExpBuffer(lockquery);
@@ -2694,7 +3212,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                i_conname,
                                i_contableoid,
                                i_conoid,
-                               i_tablespace;
+                               i_tablespace,
+                               i_options;
        int                     ntups;
 
        for (i = 0; i < numTables; i++)
@@ -2705,7 +3224,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
                if (tbinfo->relkind != RELKIND_RELATION || !tbinfo->hasindex)
                        continue;
 
-               if (!tbinfo->dump)
+               /* Ignore indexes of tables not to be dumped */
+               if (!tbinfo->dobj.dump)
                        continue;
 
                if (g_verbose)
@@ -2716,27 +3236,53 @@ getIndexes(TableInfo tblinfo[], int numTables)
                selectSourceSchema(tbinfo->dobj.namespace->dobj.name);
 
                /*
-                * The point of the messy-looking outer join is to find a
-                * constraint that is related by an internal dependency link to
-                * the index. If we find one, create a CONSTRAINT entry linked to
-                * the INDEX entry.  We assume an index won't have more than one
-                * internal dependency.
+                * The point of the messy-looking outer join is to find a constraint
+                * that is related by an internal dependency link to the index. If we
+                * find one, create a CONSTRAINT entry linked to the INDEX entry.  We
+                * assume an index won't have more than one internal dependency.
                 */
                resetPQExpBuffer(query);
-               if (g_fout->remoteVersion >= 80000)
+               if (g_fout->remoteVersion >= 80200)
+               {
+                       appendPQExpBuffer(query,
+                                                         "SELECT t.tableoid, t.oid, "
+                                                         "t.relname as indexname, "
+                                        "pg_catalog.pg_get_indexdef(i.indexrelid) as indexdef, "
+                                                         "t.relnatts as indnkeys, "
+                                                         "i.indkey, i.indisclustered, "
+                                                         "c.contype, c.conname, "
+                                                         "c.tableoid as contableoid, "
+                                                         "c.oid as conoid, "
+                                                         "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) as tablespace, "
+                                                         "array_to_string(t.reloptions, ', ') as options "
+                                                         "FROM pg_catalog.pg_index i "
+                                         "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
+                                                         "LEFT JOIN pg_catalog.pg_depend d "
+                                                         "ON (d.classid = t.tableoid "
+                                                         "AND d.objid = t.oid "
+                                                         "AND d.deptype = 'i') "
+                                                         "LEFT JOIN pg_catalog.pg_constraint c "
+                                                         "ON (d.refclassid = c.tableoid "
+                                                         "AND d.refobjid = c.oid) "
+                                                         "WHERE i.indrelid = '%u'::pg_catalog.oid "
+                                                         "ORDER BY indexname",
+                                                         tbinfo->dobj.catId.oid);
+               }
+               else if (g_fout->remoteVersion >= 80000)
                {
                        appendPQExpBuffer(query,
                                                          "SELECT t.tableoid, t.oid, "
                                                          "t.relname as indexname, "
-                                "pg_catalog.pg_get_indexdef(i.indexrelid) as indexdef, "
+                                        "pg_catalog.pg_get_indexdef(i.indexrelid) as indexdef, "
                                                          "t.relnatts as indnkeys, "
                                                          "i.indkey, i.indisclustered, "
                                                          "c.contype, c.conname, "
                                                          "c.tableoid as contableoid, "
                                                          "c.oid as conoid, "
-                                                         "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) as tablespace "
+                                                         "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) as tablespace, "
+                                                         "null as options "
                                                          "FROM pg_catalog.pg_index i "
-                                 "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
+                                         "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
                                                          "LEFT JOIN pg_catalog.pg_depend d "
                                                          "ON (d.classid = t.tableoid "
                                                          "AND d.objid = t.oid "
@@ -2753,15 +3299,16 @@ getIndexes(TableInfo tblinfo[], int numTables)
                        appendPQExpBuffer(query,
                                                          "SELECT t.tableoid, t.oid, "
                                                          "t.relname as indexname, "
-                                "pg_catalog.pg_get_indexdef(i.indexrelid) as indexdef, "
+                                        "pg_catalog.pg_get_indexdef(i.indexrelid) as indexdef, "
                                                          "t.relnatts as indnkeys, "
                                                          "i.indkey, i.indisclustered, "
                                                          "c.contype, c.conname, "
                                                          "c.tableoid as contableoid, "
                                                          "c.oid as conoid, "
-                                                         "NULL as tablespace "
+                                                         "NULL as tablespace, "
+                                                         "null as options "
                                                          "FROM pg_catalog.pg_index i "
-                                 "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
+                                         "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
                                                          "LEFT JOIN pg_catalog.pg_depend d "
                                                          "ON (d.classid = t.tableoid "
                                                          "AND d.objid = t.oid "
@@ -2778,7 +3325,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
                        appendPQExpBuffer(query,
                                                          "SELECT t.tableoid, t.oid, "
                                                          "t.relname as indexname, "
-                                                       "pg_get_indexdef(i.indexrelid) as indexdef, "
+                                                         "pg_get_indexdef(i.indexrelid) as indexdef, "
                                                          "t.relnatts as indnkeys, "
                                                          "i.indkey, false as indisclustered, "
                                                          "CASE WHEN i.indisprimary THEN 'p'::char "
@@ -2786,7 +3333,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                                          "t.relname as conname, "
                                                          "0::oid as contableoid, "
                                                          "t.oid as conoid, "
-                                                         "NULL as tablespace "
+                                                         "NULL as tablespace, "
+                                                         "null as options "
                                                          "FROM pg_index i, pg_class t "
                                                          "WHERE t.oid = i.indexrelid "
                                                          "AND i.indrelid = '%u'::oid "
@@ -2800,7 +3348,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                                          "(SELECT oid FROM pg_class WHERE relname = 'pg_class') AS tableoid, "
                                                          "t.oid, "
                                                          "t.relname as indexname, "
-                                                       "pg_get_indexdef(i.indexrelid) as indexdef, "
+                                                         "pg_get_indexdef(i.indexrelid) as indexdef, "
                                                          "t.relnatts as indnkeys, "
                                                          "i.indkey, false as indisclustered, "
                                                          "CASE WHEN i.indisprimary THEN 'p'::char "
@@ -2808,7 +3356,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                                          "t.relname as conname, "
                                                          "0::oid as contableoid, "
                                                          "t.oid as conoid, "
-                                                         "NULL as tablespace "
+                                                         "NULL as tablespace, "
+                                                         "null as options "
                                                          "FROM pg_index i, pg_class t "
                                                          "WHERE t.oid = i.indexrelid "
                                                          "AND i.indrelid = '%u'::oid "
@@ -2833,6 +3382,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
                i_contableoid = PQfnumber(res, "contableoid");
                i_conoid = PQfnumber(res, "conoid");
                i_tablespace = PQfnumber(res, "tablespace");
+               i_options = PQfnumber(res, "options");
 
                indxinfo = (IndxInfo *) malloc(ntups * sizeof(IndxInfo));
                constrinfo = (ConstraintInfo *) malloc(ntups * sizeof(ConstraintInfo));
@@ -2851,15 +3401,16 @@ getIndexes(TableInfo tblinfo[], int numTables)
                        indxinfo[j].indexdef = strdup(PQgetvalue(res, j, i_indexdef));
                        indxinfo[j].indnkeys = atoi(PQgetvalue(res, j, i_indnkeys));
                        indxinfo[j].tablespace = strdup(PQgetvalue(res, j, i_tablespace));
+                       indxinfo[j].options = strdup(PQgetvalue(res, j, i_options));
 
                        /*
                         * In pre-7.4 releases, indkeys may contain more entries than
                         * indnkeys says (since indnkeys will be 1 for a functional
-                        * index).      We don't actually care about this case since we
-                        * don't examine indkeys except for indexes associated with
-                        * PRIMARY and UNIQUE constraints, which are never functional
-                        * indexes. But we have to allocate enough space to keep
-                        * parseOidArray from complaining.
+                        * index).      We don't actually care about this case since we don't
+                        * examine indkeys except for indexes associated with PRIMARY and
+                        * UNIQUE constraints, which are never functional indexes. But we
+                        * have to allocate enough space to keep parseOidArray from
+                        * complaining.
                         */
                        indxinfo[j].indkeys = (Oid *) malloc(INDEX_MAX_KEYS * sizeof(Oid));
                        parseOidArray(PQgetvalue(res, j, i_indkey),
@@ -2942,7 +3493,7 @@ getConstraints(TableInfo tblinfo[], int numTables)
        {
                TableInfo  *tbinfo = &tblinfo[i];
 
-               if (tbinfo->ntrig == 0 || !tbinfo->dump)
+               if (tbinfo->ntrig == 0 || !tbinfo->dobj.dump)
                        continue;
 
                if (g_verbose)
@@ -2958,7 +3509,7 @@ getConstraints(TableInfo tblinfo[], int numTables)
                resetPQExpBuffer(query);
                appendPQExpBuffer(query,
                                                  "SELECT tableoid, oid, conname, "
-                                               "pg_catalog.pg_get_constraintdef(oid) as condef "
+                                                 "pg_catalog.pg_get_constraintdef(oid) as condef "
                                                  "FROM pg_catalog.pg_constraint "
                                                  "WHERE conrelid = '%u'::pg_catalog.oid "
                                                  "AND contype = 'f'",
@@ -3021,8 +3572,8 @@ getDomainConstraints(TypeInfo *tinfo)
                return;
 
        /*
-        * select appropriate schema to ensure names in constraint are
-        * properly qualified
+        * select appropriate schema to ensure names in constraint are properly
+        * qualified
         */
        selectSourceSchema(tinfo->dobj.namespace->dobj.name);
 
@@ -3030,7 +3581,7 @@ getDomainConstraints(TypeInfo *tinfo)
 
        if (g_fout->remoteVersion >= 70400)
                appendPQExpBuffer(query, "SELECT tableoid, oid, conname, "
-                                               "pg_catalog.pg_get_constraintdef(oid) AS consrc "
+                                                 "pg_catalog.pg_get_constraintdef(oid) AS consrc "
                                                  "FROM pg_catalog.pg_constraint "
                                                  "WHERE contypid = '%u'::pg_catalog.oid "
                                                  "ORDER BY conname",
@@ -3156,16 +3707,24 @@ getRules(int *numRules)
                ruleinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_rulename));
                ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
                ruleinfo[i].ruletable = findTableByOid(ruletableoid);
+               if (ruleinfo[i].ruletable == NULL)
+               {
+                       write_msg(NULL, "failed sanity check, parent table OID %u of pg_rewrite entry OID %u not found\n",
+                                         ruletableoid,
+                                         ruleinfo[i].dobj.catId.oid);
+                       exit_nicely();
+               }
                ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
+               ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
                ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
                ruleinfo[i].is_instead = *(PQgetvalue(res, i, i_is_instead)) == 't';
                if (ruleinfo[i].ruletable)
                {
                        /*
-                        * If the table is a view, force its ON SELECT rule to be
-                        * sorted before the view itself --- this ensures that any
-                        * dependencies for the rule affect the table's positioning.
-                        * Other rules are forced to appear after their table.
+                        * If the table is a view, force its ON SELECT rule to be sorted
+                        * before the view itself --- this ensures that any dependencies
+                        * for the rule affect the table's positioning. Other rules are
+                        * forced to appear after their table.
                         */
                        if (ruleinfo[i].ruletable->relkind == RELKIND_VIEW &&
                                ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
@@ -3219,6 +3778,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
                                i_tgconstrname,
                                i_tgconstrrelid,
                                i_tgconstrrelname,
+                               i_tgenabled,
                                i_tgdeferrable,
                                i_tginitdeferred;
        int                     ntups;
@@ -3227,7 +3787,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
        {
                TableInfo  *tbinfo = &tblinfo[i];
 
-               if (tbinfo->ntrig == 0 || !tbinfo->dump)
+               if (tbinfo->ntrig == 0 || !tbinfo->dobj.dump)
                        continue;
 
                if (g_verbose)
@@ -3235,8 +3795,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
                                          tbinfo->dobj.name);
 
                /*
-                * select table schema to ensure regproc name is qualified if
-                * needed
+                * select table schema to ensure regproc name is qualified if needed
                 */
                selectSourceSchema(tbinfo->dobj.namespace->dobj.name);
 
@@ -3244,16 +3803,15 @@ getTriggers(TableInfo tblinfo[], int numTables)
                if (g_fout->remoteVersion >= 70300)
                {
                        /*
-                        * We ignore triggers that are tied to a foreign-key
-                        * constraint
+                        * We ignore triggers that are tied to a foreign-key constraint
                         */
                        appendPQExpBuffer(query,
                                                          "SELECT tgname, "
                                                          "tgfoid::pg_catalog.regproc as tgfname, "
-                                                         "tgtype, tgnargs, tgargs, "
-                                                  "tgisconstraint, tgconstrname, tgdeferrable, "
-                                                "tgconstrrelid, tginitdeferred, tableoid, oid, "
-                                "tgconstrrelid::pg_catalog.regclass as tgconstrrelname "
+                                                         "tgtype, tgnargs, tgargs, tgenabled, "
+                                                         "tgisconstraint, tgconstrname, tgdeferrable, "
+                                                         "tgconstrrelid, tginitdeferred, tableoid, oid, "
+                                        "tgconstrrelid::pg_catalog.regclass as tgconstrrelname "
                                                          "from pg_catalog.pg_trigger t "
                                                          "where tgrelid = '%u'::pg_catalog.oid "
                                                          "and (not tgisconstraint "
@@ -3266,11 +3824,11 @@ getTriggers(TableInfo tblinfo[], int numTables)
                else if (g_fout->remoteVersion >= 70100)
                {
                        appendPQExpBuffer(query,
-                                                       "SELECT tgname, tgfoid::regproc as tgfname, "
-                                                         "tgtype, tgnargs, tgargs, "
-                                                  "tgisconstraint, tgconstrname, tgdeferrable, "
-                                                "tgconstrrelid, tginitdeferred, tableoid, oid, "
-                         "(select relname from pg_class where oid = tgconstrrelid) "
+                                                         "SELECT tgname, tgfoid::regproc as tgfname, "
+                                                         "tgtype, tgnargs, tgargs, tgenabled, "
+                                                         "tgisconstraint, tgconstrname, tgdeferrable, "
+                                                         "tgconstrrelid, tginitdeferred, tableoid, oid, "
+                                 "(select relname from pg_class where oid = tgconstrrelid) "
                                                          "             as tgconstrrelname "
                                                          "from pg_trigger "
                                                          "where tgrelid = '%u'::oid",
@@ -3279,14 +3837,14 @@ getTriggers(TableInfo tblinfo[], int numTables)
                else
                {
                        appendPQExpBuffer(query,
-                                                       "SELECT tgname, tgfoid::regproc as tgfname, "
-                                                         "tgtype, tgnargs, tgargs, "
-                                                  "tgisconstraint, tgconstrname, tgdeferrable, "
+                                                         "SELECT tgname, tgfoid::regproc as tgfname, "
+                                                         "tgtype, tgnargs, tgargs, tgenabled, "
+                                                         "tgisconstraint, tgconstrname, tgdeferrable, "
                                                          "tgconstrrelid, tginitdeferred, "
                                                          "(SELECT oid FROM pg_class WHERE relname = 'pg_trigger') AS tableoid, "
 
                                                          "oid, "
-                         "(select relname from pg_class where oid = tgconstrrelid) "
+                                 "(select relname from pg_class where oid = tgconstrrelid) "
                                                          "             as tgconstrrelname "
                                                          "from pg_trigger "
                                                          "where tgrelid = '%u'::oid",
@@ -3318,6 +3876,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
                i_tgconstrname = PQfnumber(res, "tgconstrname");
                i_tgconstrrelid = PQfnumber(res, "tgconstrrelid");
                i_tgconstrrelname = PQfnumber(res, "tgconstrrelname");
+               i_tgenabled = PQfnumber(res, "tgenabled");
                i_tgdeferrable = PQfnumber(res, "tgdeferrable");
                i_tginitdeferred = PQfnumber(res, "tginitdeferred");
 
@@ -3337,6 +3896,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
                        tginfo[j].tgnargs = atoi(PQgetvalue(res, j, i_tgnargs));
                        tginfo[j].tgargs = strdup(PQgetvalue(res, j, i_tgargs));
                        tginfo[j].tgisconstraint = *(PQgetvalue(res, j, i_tgisconstraint)) == 't';
+                       tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled)) == 't';
                        tginfo[j].tgdeferrable = *(PQgetvalue(res, j, i_tgdeferrable)) == 't';
                        tginfo[j].tginitdeferred = *(PQgetvalue(res, j, i_tginitdeferred)) == 't';
 
@@ -3394,14 +3954,36 @@ getProcLangs(int *numProcLangs)
        int                     i_lanname;
        int                     i_lanpltrusted;
        int                     i_lanplcallfoid;
-       int                     i_lanvalidator = -1;
-       int                     i_lanacl = -1;
+       int                     i_lanvalidator;
+       int                     i_lanacl;
+       int                     i_lanowner;
 
        /* Make sure we are in proper schema */
        selectSourceSchema("pg_catalog");
 
-       if (g_fout->remoteVersion >= 70100)
+       if (g_fout->remoteVersion >= 80100)
+       {
+               /* Languages are owned by the bootstrap superuser, OID 10 */
+               appendPQExpBuffer(query, "SELECT tableoid, oid, *, "
+                                                 "(%s '10') as lanowner "
+                                                 "FROM pg_language "
+                                                 "WHERE lanispl "
+                                                 "ORDER BY oid",
+                                                 username_subquery);
+       }
+       else if (g_fout->remoteVersion >= 70400)
+       {
+               /* Languages are owned by the bootstrap superuser, sysid 1 */
+               appendPQExpBuffer(query, "SELECT tableoid, oid, *, "
+                                                 "(%s '1') as lanowner "
+                                                 "FROM pg_language "
+                                                 "WHERE lanispl "
+                                                 "ORDER BY oid",
+                                                 username_subquery);
+       }
+       else if (g_fout->remoteVersion >= 70100)
        {
+               /* No clear notion of an owner at all before 7.4 ... */
                appendPQExpBuffer(query, "SELECT tableoid, oid, * FROM pg_language "
                                                  "WHERE lanispl "
                                                  "ORDER BY oid");
@@ -3429,11 +4011,10 @@ getProcLangs(int *numProcLangs)
        i_lanname = PQfnumber(res, "lanname");
        i_lanpltrusted = PQfnumber(res, "lanpltrusted");
        i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
-       if (g_fout->remoteVersion >= 70300)
-       {
-               i_lanvalidator = PQfnumber(res, "lanvalidator");
-               i_lanacl = PQfnumber(res, "lanacl");
-       }
+       /* these may fail and return -1: */
+       i_lanvalidator = PQfnumber(res, "lanvalidator");
+       i_lanacl = PQfnumber(res, "lanacl");
+       i_lanowner = PQfnumber(res, "lanowner");
 
        for (i = 0; i < ntups; i++)
        {
@@ -3445,24 +4026,28 @@ getProcLangs(int *numProcLangs)
                planginfo[i].dobj.name = strdup(PQgetvalue(res, i, i_lanname));
                planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't';
                planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
-               if (g_fout->remoteVersion >= 70300)
-               {
+               if (i_lanvalidator >= 0)
                        planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
-                       planginfo[i].lanacl = strdup(PQgetvalue(res, i, i_lanacl));
-               }
                else
-               {
-                       FuncInfo   *funcInfo;
-
                        planginfo[i].lanvalidator = InvalidOid;
+               if (i_lanacl >= 0)
+                       planginfo[i].lanacl = strdup(PQgetvalue(res, i, i_lanacl));
+               else
                        planginfo[i].lanacl = strdup("{=U}");
+               if (i_lanowner >= 0)
+                       planginfo[i].lanowner = strdup(PQgetvalue(res, i, i_lanowner));
+               else
+                       planginfo[i].lanowner = strdup("");
 
+               if (g_fout->remoteVersion < 70300)
+               {
                        /*
                         * We need to make a dependency to ensure the function will be
                         * dumped first.  (In 7.3 and later the regular dependency
                         * mechanism will handle this for us.)
                         */
-                       funcInfo = findFuncByOid(planginfo[i].lanplcallfoid);
+                       FuncInfo   *funcInfo = findFuncByOid(planginfo[i].lanplcallfoid);
+
                        if (funcInfo)
                                addObjectDependency(&planginfo[i].dobj,
                                                                        funcInfo->dobj.dumpId);
@@ -3514,7 +4099,7 @@ getCasts(int *numCasts)
                                                  "FROM pg_type t1, pg_type t2, pg_proc p "
                                                  "WHERE p.pronargs = 1 AND "
                                                  "p.proargtypes[0] = t1.oid AND "
-                                         "p.prorettype = t2.oid AND p.proname = t2.typname "
+                                                 "p.prorettype = t2.oid AND p.proname = t2.typname "
                                                  "ORDER BY 3,4");
        }
 
@@ -3550,9 +4135,9 @@ getCasts(int *numCasts)
                castinfo[i].castcontext = *(PQgetvalue(res, i, i_castcontext));
 
                /*
-                * Try to name cast as concatenation of typnames.  This is only
-                * used for purposes of sorting.  If we fail to find either type,
-                * the name will be an empty string.
+                * Try to name cast as concatenation of typnames.  This is only used
+                * for purposes of sorting.  If we fail to find either type, the name
+                * will be an empty string.
                 */
                initPQExpBuffer(&namebuf);
                sTypeInfo = findTypeByOid(castinfo[i].castsource);
@@ -3602,8 +4187,7 @@ void
 getTableAttrs(TableInfo *tblinfo, int numTables)
 {
        int                     i,
-                               j,
-                               k;
+                               j;
        PQExpBuffer q = createPQExpBuffer();
        int                     i_attnum;
        int                     i_attname;
@@ -3641,12 +4225,11 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                /* find all the user attributes and their types */
 
                /*
-                * we must read the attribute names in attribute number order!
-                * because we will use the attnum to index into the attnames array
-                * later.  We actually ask to order by "attrelid, attnum" because
-                * (at least up to 7.3) the planner is not smart enough to realize
-                * it needn't re-sort the output of an indexscan on
-                * pg_attribute_relid_attnum_index.
+                * we must read the attribute names in attribute number order! because
+                * we will use the attnum to index into the attnames array later.  We
+                * actually ask to order by "attrelid, attnum" because (at least up to
+                * 7.3) the planner is not smart enough to realize it needn't re-sort
+                * the output of an indexscan on pg_attribute_relid_attnum_index.
                 */
                if (g_verbose)
                        write_msg(NULL, "finding the columns and types of table \"%s\"\n",
@@ -3658,9 +4241,9 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                {
                        /* need left join here to not fail on dropped columns ... */
                        appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, a.attstattarget, a.attstorage, t.typstorage, "
-                         "a.attnotnull, a.atthasdef, a.attisdropped, a.attislocal, "
-                          "pg_catalog.format_type(t.oid,a.atttypmod) as atttypname "
-                                                         "from pg_catalog.pg_attribute a left join pg_catalog.pg_type t "
+                                 "a.attnotnull, a.atthasdef, a.attisdropped, a.attislocal, "
+                                  "pg_catalog.format_type(t.oid,a.atttypmod) as atttypname "
+                        "from pg_catalog.pg_attribute a left join pg_catalog.pg_type t "
                                                          "on a.atttypid = t.oid "
                                                          "where a.attrelid = '%u'::pg_catalog.oid "
                                                          "and a.attnum > 0::pg_catalog.int2 "
@@ -3670,13 +4253,13 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                else if (g_fout->remoteVersion >= 70100)
                {
                        /*
-                        * attstattarget doesn't exist in 7.1.  It does exist in 7.2,
-                        * but we don't dump it because we can't tell whether it's
-                        * been explicitly set or was just a default.
+                        * attstattarget doesn't exist in 7.1.  It does exist in 7.2, but
+                        * we don't dump it because we can't tell whether it's been
+                        * explicitly set or was just a default.
                         */
                        appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, -1 as attstattarget, a.attstorage, t.typstorage, "
                                                          "a.attnotnull, a.atthasdef, false as attisdropped, false as attislocal, "
-                                                 "format_type(t.oid,a.atttypmod) as atttypname "
+                                                         "format_type(t.oid,a.atttypmod) as atttypname "
                                                          "from pg_attribute a left join pg_type t "
                                                          "on a.atttypid = t.oid "
                                                          "where a.attrelid = '%u'::oid "
@@ -3723,7 +4306,6 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                tbinfo->typstorage = (char *) malloc(ntups * sizeof(char));
                tbinfo->attisdropped = (bool *) malloc(ntups * sizeof(bool));
                tbinfo->attislocal = (bool *) malloc(ntups * sizeof(bool));
-               tbinfo->attisserial = (bool *) malloc(ntups * sizeof(bool));
                tbinfo->notnull = (bool *) malloc(ntups * sizeof(bool));
                tbinfo->attrdefs = (AttrDefInfo **) malloc(ntups * sizeof(AttrDefInfo *));
                tbinfo->inhAttrs = (bool *) malloc(ntups * sizeof(bool));
@@ -3747,7 +4329,6 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                        tbinfo->typstorage[j] = *(PQgetvalue(res, j, i_typstorage));
                        tbinfo->attisdropped[j] = (PQgetvalue(res, j, i_attisdropped)[0] == 't');
                        tbinfo->attislocal[j] = (PQgetvalue(res, j, i_attislocal)[0] == 't');
-                       tbinfo->attisserial[j] = false;         /* fix below */
                        tbinfo->notnull[j] = (PQgetvalue(res, j, i_attnotnull)[0] == 't');
                        tbinfo->attrdefs[j] = NULL; /* fix below */
                        if (PQgetvalue(res, j, i_atthasdef)[0] == 't')
@@ -3776,7 +4357,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                        if (g_fout->remoteVersion >= 70300)
                        {
                                appendPQExpBuffer(q, "SELECT tableoid, oid, adnum, "
-                                          "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc "
+                                                  "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc "
                                                                  "FROM pg_catalog.pg_attrdef "
                                                                  "WHERE adrelid = '%u'::pg_catalog.oid",
                                                                  tbinfo->dobj.catId.oid);
@@ -3829,12 +4410,14 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                attrdefs[j].dobj.name = strdup(tbinfo->dobj.name);
                                attrdefs[j].dobj.namespace = tbinfo->dobj.namespace;
 
+                               attrdefs[j].dobj.dump = tbinfo->dobj.dump;
+
                                /*
-                                * Defaults on a VIEW must always be dumped as separate
-                                * ALTER TABLE commands.  Defaults on regular tables are
-                                * dumped as part of the CREATE TABLE if possible.      To
-                                * check if it's safe, we mark the default as needing to
-                                * appear before the CREATE.
+                                * Defaults on a VIEW must always be dumped as separate ALTER
+                                * TABLE commands.      Defaults on regular tables are dumped as
+                                * part of the CREATE TABLE if possible.  To check if it's
+                                * safe, we mark the default as needing to appear before the
+                                * CREATE.
                                 */
                                if (tbinfo->relkind == RELKIND_VIEW)
                                {
@@ -3877,7 +4460,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                        if (g_fout->remoteVersion >= 70400)
                        {
                                appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
-                                               "pg_catalog.pg_get_constraintdef(oid) AS consrc "
+                                                       "pg_catalog.pg_get_constraintdef(oid) AS consrc "
                                                                  "FROM pg_catalog.pg_constraint "
                                                                  "WHERE conrelid = '%u'::pg_catalog.oid "
                                                                  "   AND contype = 'c' "
@@ -3958,11 +4541,14 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                constrs[j].conindex = 0;
                                constrs[j].coninherited = false;
                                constrs[j].separate = false;
+
+                               constrs[j].dobj.dump = tbinfo->dobj.dump;
+
                                /*
-                                * Mark the constraint as needing to appear before the
-                                * table --- this is so that any other dependencies of
-                                * the constraint will be emitted before we try to create
-                                * the table.
+                                * Mark the constraint as needing to appear before the table
+                                * --- this is so that any other dependencies of the
+                                * constraint will be emitted before we try to create the
+                                * table.
                                 */
                                addObjectDependency(&tbinfo->dobj,
                                                                        constrs[j].dobj.dumpId);
@@ -3975,45 +4561,6 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                        }
                        PQclear(res);
                }
-
-               /*
-                * Check to see if any columns are serial columns.      Our first
-                * quick filter is that it must be integer or bigint with a
-                * default.  If so, we scan to see if we found a sequence linked
-                * to this column. If we did, mark the column and sequence
-                * appropriately.
-                */
-               for (j = 0; j < ntups; j++)
-               {
-                       /*
-                        * Note assumption that format_type will show these types as
-                        * exactly "integer" and "bigint" regardless of schema path.
-                        * This is correct in 7.3 but needs to be watched.
-                        */
-                       if (strcmp(tbinfo->atttypnames[j], "integer") != 0 &&
-                               strcmp(tbinfo->atttypnames[j], "bigint") != 0)
-                               continue;
-                       if (tbinfo->attrdefs[j] == NULL)
-                               continue;
-                       for (k = 0; k < numTables; k++)
-                       {
-                               TableInfo  *seqinfo = &tblinfo[k];
-
-                               if (OidIsValid(seqinfo->owning_tab) &&
-                                       seqinfo->owning_tab == tbinfo->dobj.catId.oid &&
-                                       seqinfo->owning_col == j + 1)
-                               {
-                                       /*
-                                        * Found a match.  Copy the table's interesting and
-                                        * dumpable flags to the sequence.
-                                        */
-                                       tbinfo->attisserial[j] = true;
-                                       seqinfo->interesting = tbinfo->interesting;
-                                       seqinfo->dump = tbinfo->dump;
-                                       break;
-                               }
-                       }
-               }
        }
 
        destroyPQExpBuffer(q);
@@ -4069,7 +4616,7 @@ dumpComment(Archive *fout, const char *target,
                PQExpBuffer query = createPQExpBuffer();
 
                appendPQExpBuffer(query, "COMMENT ON %s IS ", target);
-               appendStringLiteral(query, comments->descr, false);
+               appendStringLiteralAH(query, comments->descr, fout);
                appendPQExpBuffer(query, ";\n");
 
                ArchiveEntry(fout, nilCatalogId, createDumpId(),
@@ -4127,14 +4674,14 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
 
                        resetPQExpBuffer(query);
                        appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
-                       appendStringLiteral(query, descr, false);
+                       appendStringLiteralAH(query, descr, fout);
                        appendPQExpBuffer(query, ";\n");
 
                        ArchiveEntry(fout, nilCatalogId, createDumpId(),
                                                 target->data,
                                                 tbinfo->dobj.namespace->dobj.name,
                                                 NULL,
-                                                tbinfo->usename,
+                                                tbinfo->rolname,
                                                 false, "COMMENT", query->data, "", NULL,
                                                 &(tbinfo->dobj.dumpId), 1,
                                                 NULL, NULL);
@@ -4149,14 +4696,14 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
 
                        resetPQExpBuffer(query);
                        appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
-                       appendStringLiteral(query, descr, false);
+                       appendStringLiteralAH(query, descr, fout);
                        appendPQExpBuffer(query, ";\n");
 
                        ArchiveEntry(fout, nilCatalogId, createDumpId(),
                                                 target->data,
                                                 tbinfo->dobj.namespace->dobj.name,
                                                 NULL,
-                                                tbinfo->usename,
+                                                tbinfo->rolname,
                                                 false, "COMMENT", query->data, "", NULL,
                                                 &(tbinfo->dobj.dumpId), 1,
                                                 NULL, NULL);
@@ -4195,9 +4742,9 @@ findComments(Archive *fout, Oid classoid, Oid objoid,
                ncomments = collectComments(fout, &comments);
 
        /*
-        * Pre-7.2, pg_description does not contain classoid, so
-        * collectComments just stores a zero.  If there's a collision on
-        * object OID, well, you get duplicate comments.
+        * Pre-7.2, pg_description does not contain classoid, so collectComments
+        * just stores a zero.  If there's a collision on object OID, well, you
+        * get duplicate comments.
         */
        if (fout->remoteVersion < 70200)
                classoid = 0;
@@ -4231,8 +4778,8 @@ findComments(Archive *fout, Oid classoid, Oid objoid,
 
        /*
         * Now determine how many items match the object.  The search loop
-        * invariant still holds: only items between low and high inclusive
-        * could match.
+        * invariant still holds: only items between low and high inclusive could
+        * match.
         */
        nmatch = 1;
        while (middle > low)
@@ -4355,6 +4902,9 @@ dumpDumpableObject(Archive *fout, DumpableObject *dobj)
                case DO_TYPE:
                        dumpType(fout, (TypeInfo *) dobj);
                        break;
+               case DO_SHELL_TYPE:
+                       dumpShellType(fout, (ShellTypeInfo *) dobj);
+                       break;
                case DO_FUNC:
                        dumpFunc(fout, (FuncInfo *) dobj);
                        break;
@@ -4410,6 +4960,13 @@ dumpDumpableObject(Archive *fout, DumpableObject *dobj)
                                                 NULL, 0,
                                                 dumpBlobs, NULL);
                        break;
+               case DO_BLOB_COMMENTS:
+                       ArchiveEntry(fout, dobj->catId, dobj->dumpId,
+                                                dobj->name, NULL, NULL, "",
+                                                false, "BLOB COMMENTS", "", "", NULL,
+                                                NULL, 0,
+                                                dumpBlobComments, NULL);
+                       break;
        }
 }
 
@@ -4424,8 +4981,8 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
        PQExpBuffer delq;
        char       *qnspname;
 
-       /* skip if not to be dumped */
-       if (!nspinfo->dump || dataOnly)
+       /* Skip if not to be dumped */
+       if (!nspinfo->dobj.dump || dataOnly)
                return;
 
        /* don't dump dummy namespace from pre-7.3 source */
@@ -4443,8 +5000,8 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
 
        ArchiveEntry(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId,
                                 nspinfo->dobj.name,
-                                NULL, NULL, 
-                                nspinfo->usename,
+                                NULL, NULL,
+                                nspinfo->rolname,
                                 false, "SCHEMA", q->data, delq->data, NULL,
                                 nspinfo->dobj.dependencies, nspinfo->dobj.nDeps,
                                 NULL, NULL);
@@ -4453,12 +5010,12 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
        resetPQExpBuffer(q);
        appendPQExpBuffer(q, "SCHEMA %s", qnspname);
        dumpComment(fout, q->data,
-                               NULL, nspinfo->usename,
+                               NULL, nspinfo->rolname,
                                nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
 
        dumpACL(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId, "SCHEMA",
                        qnspname, nspinfo->dobj.name, NULL,
-                       nspinfo->usename, nspinfo->nspacl);
+                       nspinfo->rolname, nspinfo->nspacl);
 
        free(qnspname);
 
@@ -4473,22 +5030,8 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
 static void
 dumpType(Archive *fout, TypeInfo *tinfo)
 {
-       /* Dump only types in dumpable namespaces */
-       if (!tinfo->dobj.namespace->dump || dataOnly)
-               return;
-
-       /* skip complex types, except for standalone composite types */
-       /* (note: this test should now be unnecessary) */
-       if (OidIsValid(tinfo->typrelid) && tinfo->typrelkind != 'c')
-               return;
-
-       /* skip undefined placeholder types */
-       if (!tinfo->isDefined)
-               return;
-
-       /* skip all array types that start w/ underscore */
-       if ((tinfo->dobj.name[0] == '_') &&
-               OidIsValid(tinfo->typelem))
+       /* Skip if not to be dumped */
+       if (!tinfo->dobj.dump || dataOnly)
                return;
 
        /* Dump out in proper style */
@@ -4524,10 +5067,11 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
        Oid                     typsendoid;
        Oid                     typanalyzeoid;
        char       *typdelim;
-       char       *typdefault;
        char       *typbyval;
        char       *typalign;
        char       *typstorage;
+       char       *typdefault;
+       bool            typdefault_is_literal = false;
 
        /* Set proper schema search path so regproc references list correctly */
        selectSourceSchema(tinfo->dobj.namespace->dobj.name);
@@ -4543,8 +5087,8 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
                                                  "typreceive::pg_catalog.oid as typreceiveoid, "
                                                  "typsend::pg_catalog.oid as typsendoid, "
                                                  "typanalyze::pg_catalog.oid as typanalyzeoid, "
-                                                 "typdelim, typdefault, typbyval, typalign, "
-                                                 "typstorage "
+                                                 "typdelim, typbyval, typalign, typstorage, "
+                                                 "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
                                                  "FROM pg_catalog.pg_type "
                                                  "WHERE oid = '%u'::pg_catalog.oid",
                                                  tinfo->dobj.catId.oid);
@@ -4559,8 +5103,8 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
                                                  "typreceive::pg_catalog.oid as typreceiveoid, "
                                                  "typsend::pg_catalog.oid as typsendoid, "
                                                  "0 as typanalyzeoid, "
-                                                 "typdelim, typdefault, typbyval, typalign, "
-                                                 "typstorage "
+                                                 "typdelim, typbyval, typalign, typstorage, "
+                                                 "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
                                                  "FROM pg_catalog.pg_type "
                                                  "WHERE oid = '%u'::pg_catalog.oid",
                                                  tinfo->dobj.catId.oid);
@@ -4575,17 +5119,37 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
                                                  "typoutput::pg_catalog.oid as typoutputoid, "
                                                  "0 as typreceiveoid, 0 as typsendoid, "
                                                  "0 as typanalyzeoid, "
-                                                 "typdelim, typdefault, typbyval, typalign, "
-                                                 "typstorage "
-                                                 "FROM pg_catalog.pg_type "
-                                                 "WHERE oid = '%u'::pg_catalog.oid",
+                                                 "typdelim, typbyval, typalign, typstorage, "
+                                                 "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
+                                                 "FROM pg_catalog.pg_type "
+                                                 "WHERE oid = '%u'::pg_catalog.oid",
+                                                 tinfo->dobj.catId.oid);
+       }
+       else if (fout->remoteVersion >= 70200)
+       {
+               /*
+                * Note: although pre-7.3 catalogs contain typreceive and typsend,
+                * ignore them because they are not right.
+                */
+               appendPQExpBuffer(query, "SELECT typlen, "
+                                                 "typinput, typoutput, "
+                                                 "'-' as typreceive, '-' as typsend, "
+                                                 "'-' as typanalyze, "
+                                                 "typinput::oid as typinputoid, "
+                                                 "typoutput::oid as typoutputoid, "
+                                                 "0 as typreceiveoid, 0 as typsendoid, "
+                                                 "0 as typanalyzeoid, "
+                                                 "typdelim, typbyval, typalign, typstorage, "
+                                                 "NULL as typdefaultbin, typdefault "
+                                                 "FROM pg_type "
+                                                 "WHERE oid = '%u'::oid",
                                                  tinfo->dobj.catId.oid);
        }
        else if (fout->remoteVersion >= 70100)
        {
                /*
-                * Note: although pre-7.3 catalogs contain typreceive and typsend,
-                * ignore them because they are not right.
+                * Ignore pre-7.2 typdefault; the field exists but has an unusable
+                * representation.
                 */
                appendPQExpBuffer(query, "SELECT typlen, "
                                                  "typinput, typoutput, "
@@ -4595,8 +5159,8 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
                                                  "typoutput::oid as typoutputoid, "
                                                  "0 as typreceiveoid, 0 as typsendoid, "
                                                  "0 as typanalyzeoid, "
-                                                 "typdelim, typdefault, typbyval, typalign, "
-                                                 "typstorage "
+                                                 "typdelim, typbyval, typalign, typstorage, "
+                                                 "NULL as typdefaultbin, NULL as typdefault "
                                                  "FROM pg_type "
                                                  "WHERE oid = '%u'::oid",
                                                  tinfo->dobj.catId.oid);
@@ -4611,8 +5175,9 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
                                                  "typoutput::oid as typoutputoid, "
                                                  "0 as typreceiveoid, 0 as typsendoid, "
                                                  "0 as typanalyzeoid, "
-                                                 "typdelim, typdefault, typbyval, typalign, "
-                                                 "'p'::char as typstorage "
+                                                 "typdelim, typbyval, typalign, "
+                                                 "'p'::char as typstorage, "
+                                                 "NULL as typdefaultbin, NULL as typdefault "
                                                  "FROM pg_type "
                                                  "WHERE oid = '%u'::oid",
                                                  tinfo->dobj.catId.oid);
@@ -4642,17 +5207,24 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
        typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid")));
        typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid")));
        typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim"));
-       if (PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
-               typdefault = NULL;
-       else
-               typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
        typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval"));
        typalign = PQgetvalue(res, 0, PQfnumber(res, "typalign"));
        typstorage = PQgetvalue(res, 0, PQfnumber(res, "typstorage"));
+       if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
+               typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
+       else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
+       {
+               typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
+               typdefault_is_literal = true;           /* it needs quotes */
+       }
+       else
+               typdefault = NULL;
 
        /*
-        * DROP must be fully qualified in case same name appears in
-        * pg_catalog
+        * DROP must be fully qualified in case same name appears in pg_catalog.
+        * The reason we include CASCADE is that the circular dependency between
+        * the type and its I/O functions makes it impossible to drop the type
+        * any other way.
         */
        appendPQExpBuffer(delq, "DROP TYPE %s.",
                                          fmtId(tinfo->dobj.namespace->dobj.name));
@@ -4689,7 +5261,10 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
        if (typdefault != NULL)
        {
                appendPQExpBuffer(q, ",\n    DEFAULT = ");
-               appendStringLiteral(q, typdefault, true);
+               if (typdefault_is_literal)
+                       appendStringLiteralAH(q, typdefault, fout);
+               else
+                       appendPQExpBufferStr(q, typdefault);
        }
 
        if (tinfo->isArray)
@@ -4706,7 +5281,7 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
        if (typdelim && strcmp(typdelim, ",") != 0)
        {
                appendPQExpBuffer(q, ",\n    DELIMITER = ");
-               appendStringLiteral(q, typdelim, true);
+               appendStringLiteralAH(q, typdelim, fout);
        }
 
        if (strcmp(typalign, "c") == 0)
@@ -4736,7 +5311,7 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
                                 tinfo->dobj.name,
                                 tinfo->dobj.namespace->dobj.name,
                                 NULL,
-                                tinfo->usename, false,
+                                tinfo->rolname, false,
                                 "TYPE", q->data, delq->data, NULL,
                                 tinfo->dobj.dependencies, tinfo->dobj.nDeps,
                                 NULL, NULL);
@@ -4746,7 +5321,7 @@ dumpBaseType(Archive *fout, TypeInfo *tinfo)
 
        appendPQExpBuffer(q, "TYPE %s", fmtId(tinfo->dobj.name));
        dumpComment(fout, q->data,
-                               tinfo->dobj.namespace->dobj.name, tinfo->usename,
+                               tinfo->dobj.namespace->dobj.name, tinfo->rolname,
                                tinfo->dobj.catId, 0, tinfo->dobj.dumpId);
 
        PQclear(res);
@@ -4771,6 +5346,7 @@ dumpDomain(Archive *fout, TypeInfo *tinfo)
        char       *typnotnull;
        char       *typdefn;
        char       *typdefault;
+       bool            typdefault_is_literal = false;
 
        /* Set proper schema search path so type references list correctly */
        selectSourceSchema(tinfo->dobj.namespace->dobj.name);
@@ -4778,8 +5354,8 @@ dumpDomain(Archive *fout, TypeInfo *tinfo)
        /* Fetch domain specific details */
        /* We assume here that remoteVersion must be at least 70300 */
        appendPQExpBuffer(query, "SELECT typnotnull, "
-                       "pg_catalog.format_type(typbasetype, typtypmod) as typdefn, "
-                                         "typdefault "
+                               "pg_catalog.format_type(typbasetype, typtypmod) as typdefn, "
+                                         "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) as typdefaultbin, typdefault "
                                          "FROM pg_catalog.pg_type "
                                          "WHERE oid = '%u'::pg_catalog.oid",
                                          tinfo->dobj.catId.oid);
@@ -4798,10 +5374,15 @@ dumpDomain(Archive *fout, TypeInfo *tinfo)
 
        typnotnull = PQgetvalue(res, 0, PQfnumber(res, "typnotnull"));
        typdefn = PQgetvalue(res, 0, PQfnumber(res, "typdefn"));
-       if (PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
-               typdefault = NULL;
-       else
+       if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
+               typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
+       else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
+       {
                typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
+               typdefault_is_literal = true;           /* it needs quotes */
+       }
+       else
+               typdefault = NULL;
 
        appendPQExpBuffer(q,
                                          "CREATE DOMAIN %s AS %s",
@@ -4811,8 +5392,14 @@ dumpDomain(Archive *fout, TypeInfo *tinfo)
        if (typnotnull[0] == 't')
                appendPQExpBuffer(q, " NOT NULL");
 
-       if (typdefault)
-               appendPQExpBuffer(q, " DEFAULT %s", typdefault);
+       if (typdefault != NULL)
+       {
+               appendPQExpBuffer(q, " DEFAULT ");
+               if (typdefault_is_literal)
+                       appendStringLiteralAH(q, typdefault, fout);
+               else
+                       appendPQExpBufferStr(q, typdefault);
+       }
 
        PQclear(res);
 
@@ -4825,14 +5412,13 @@ dumpDomain(Archive *fout, TypeInfo *tinfo)
 
                if (!domcheck->separate)
                        appendPQExpBuffer(q, "\n\tCONSTRAINT %s %s",
-                                                  fmtId(domcheck->dobj.name), domcheck->condef);
+                                                         fmtId(domcheck->dobj.name), domcheck->condef);
        }
 
        appendPQExpBuffer(q, ";\n");
 
        /*
-        * DROP must be fully qualified in case same name appears in
-        * pg_catalog
+        * DROP must be fully qualified in case same name appears in pg_catalog
         */
        appendPQExpBuffer(delq, "DROP DOMAIN %s.",
                                          fmtId(tinfo->dobj.namespace->dobj.name));
@@ -4843,7 +5429,7 @@ dumpDomain(Archive *fout, TypeInfo *tinfo)
                                 tinfo->dobj.name,
                                 tinfo->dobj.namespace->dobj.name,
                                 NULL,
-                                tinfo->usename, false,
+                                tinfo->rolname, false,
                                 "DOMAIN", q->data, delq->data, NULL,
                                 tinfo->dobj.dependencies, tinfo->dobj.nDeps,
                                 NULL, NULL);
@@ -4853,7 +5439,7 @@ dumpDomain(Archive *fout, TypeInfo *tinfo)
 
        appendPQExpBuffer(q, "DOMAIN %s", fmtId(tinfo->dobj.name));
        dumpComment(fout, q->data,
-                               tinfo->dobj.namespace->dobj.name, tinfo->usename,
+                               tinfo->dobj.namespace->dobj.name, tinfo->rolname,
                                tinfo->dobj.catId, 0, tinfo->dobj.dumpId);
 
        destroyPQExpBuffer(q);
@@ -4885,8 +5471,8 @@ dumpCompositeType(Archive *fout, TypeInfo *tinfo)
        /* We assume here that remoteVersion must be at least 70300 */
 
        appendPQExpBuffer(query, "SELECT a.attname, "
-                "pg_catalog.format_type(a.atttypid, a.atttypmod) as atttypdefn "
-                                 "FROM pg_catalog.pg_type t, pg_catalog.pg_attribute a "
+                        "pg_catalog.format_type(a.atttypid, a.atttypmod) as atttypdefn "
+                                         "FROM pg_catalog.pg_type t, pg_catalog.pg_attribute a "
                                          "WHERE t.oid = '%u'::pg_catalog.oid "
                                          "AND a.attrelid = t.typrelid "
                                          "AND NOT a.attisdropped "
@@ -4925,8 +5511,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tinfo)
        appendPQExpBuffer(q, "\n);\n");
 
        /*
-        * DROP must be fully qualified in case same name appears in
-        * pg_catalog
+        * DROP must be fully qualified in case same name appears in pg_catalog
         */
        appendPQExpBuffer(delq, "DROP TYPE %s.",
                                          fmtId(tinfo->dobj.namespace->dobj.name));
@@ -4937,7 +5522,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tinfo)
                                 tinfo->dobj.name,
                                 tinfo->dobj.namespace->dobj.name,
                                 NULL,
-                                tinfo->usename, false,
+                                tinfo->rolname, false,
                                 "TYPE", q->data, delq->data, NULL,
                                 tinfo->dobj.dependencies, tinfo->dobj.nDeps,
                                 NULL, NULL);
@@ -4948,7 +5533,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tinfo)
 
        appendPQExpBuffer(q, "TYPE %s", fmtId(tinfo->dobj.name));
        dumpComment(fout, q->data,
-                               tinfo->dobj.namespace->dobj.name, tinfo->usename,
+                               tinfo->dobj.namespace->dobj.name, tinfo->rolname,
                                tinfo->dobj.catId, 0, tinfo->dobj.dumpId);
 
        PQclear(res);
@@ -4957,6 +5542,70 @@ dumpCompositeType(Archive *fout, TypeInfo *tinfo)
        destroyPQExpBuffer(query);
 }
 
+/*
+ * dumpShellType
+ *       writes out to fout the queries to create a shell type
+ *
+ * We dump a shell definition in advance of the I/O functions for the type.
+ */
+static void
+dumpShellType(Archive *fout, ShellTypeInfo *stinfo)
+{
+       PQExpBuffer q;
+
+       /* Skip if not to be dumped */
+       if (!stinfo->dobj.dump || dataOnly)
+               return;
+
+       q = createPQExpBuffer();
+
+       /*
+        * Note the lack of a DROP command for the shell type; any required DROP
+        * is driven off the base type entry, instead.  This interacts with
+        * _printTocEntry()'s use of the presence of a DROP command to decide
+        * whether an entry needs an ALTER OWNER command.  We don't want to
+        * alter the shell type's owner immediately on creation; that should
+        * happen only after it's filled in, otherwise the backend complains.
+        */
+
+       appendPQExpBuffer(q, "CREATE TYPE %s;\n",
+                                         fmtId(stinfo->dobj.name));
+
+       ArchiveEntry(fout, stinfo->dobj.catId, stinfo->dobj.dumpId,
+                                stinfo->dobj.name,
+                                stinfo->dobj.namespace->dobj.name,
+                                NULL,
+                                stinfo->baseType->rolname, false,
+                                "SHELL TYPE", q->data, "", NULL,
+                                stinfo->dobj.dependencies, stinfo->dobj.nDeps,
+                                NULL, NULL);
+
+       destroyPQExpBuffer(q);
+}
+
+/*
+ * Determine whether we want to dump definitions for procedural languages.
+ * Since the languages themselves don't have schemas, we can't rely on
+ * the normal schema-based selection mechanism.  We choose to dump them
+ * whenever neither --schema nor --table was given.  (Before 8.1, we used
+ * the dump flag of the PL's call handler function, but in 8.1 this will
+ * probably always be false since call handlers are created in pg_catalog.)
+ *
+ * For some backwards compatibility with the older behavior, we forcibly
+ * dump a PL if its handler function (and validator if any) are in a
+ * dumpable namespace. That case is not checked here.
+ */
+static bool
+shouldDumpProcLangs(void)
+{
+       if (matchingTables != NULL || matchingSchemas != NULL)
+               return false;
+       /* And they're schema not data */
+       if (dataOnly)
+               return false;
+       return true;
+}
+
 /*
  * dumpProcLang
  *               writes out to fout the queries to recreate a user-defined
@@ -4967,7 +5616,9 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
 {
        PQExpBuffer defqry;
        PQExpBuffer delqry;
+       bool            useParams;
        char       *qlanname;
+       char       *lanschema;
        FuncInfo   *funcInfo;
        FuncInfo   *validatorInfo = NULL;
 
@@ -4975,60 +5626,76 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
                return;
 
        /*
-        * Current theory is to dump PLs iff their underlying functions will
-        * be dumped (are in a dumpable namespace, or have a non-system OID in
-        * pre-7.3 databases).  Actually, we treat the PL itself as being in
-        * the underlying function's namespace, though it isn't really.  This
-        * avoids searchpath problems for the HANDLER clause.
-        *
-        * If the underlying function is in the pg_catalog namespace, we won't
-        * have loaded it into finfo[] at all; therefore, treat failure to
-        * find it in finfo[] as indicating we shouldn't dump it, not as an
-        * error condition.  Ditto for the validator.
+        * Try to find the support function(s).  It is not an error if we don't
+        * find them --- if the functions are in the pg_catalog schema, as is
+        * standard in 8.1 and up, then we won't have loaded them. (In this case
+        * we will emit a parameterless CREATE LANGUAGE command, which will
+        * require PL template knowledge in the backend to reload.)
         */
 
        funcInfo = findFuncByOid(plang->lanplcallfoid);
-       if (funcInfo == NULL)
-               return;
-
-       if (!funcInfo->dobj.namespace->dump)
-               return;
+       if (funcInfo != NULL && !funcInfo->dobj.dump)
+               funcInfo = NULL;                /* treat not-dumped same as not-found */
 
        if (OidIsValid(plang->lanvalidator))
        {
                validatorInfo = findFuncByOid(plang->lanvalidator);
-               if (validatorInfo == NULL)
-                       return;
+               if (validatorInfo != NULL && !validatorInfo->dobj.dump)
+                       validatorInfo = NULL;
        }
 
+       /*
+        * If the functions are dumpable then emit a traditional CREATE LANGUAGE
+        * with parameters.  Otherwise, dump only if shouldDumpProcLangs() says to
+        * dump it.
+        */
+       useParams = (funcInfo != NULL &&
+                                (validatorInfo != NULL || !OidIsValid(plang->lanvalidator)));
+
+       if (!useParams && !shouldDumpProcLangs())
+               return;
+
        defqry = createPQExpBuffer();
        delqry = createPQExpBuffer();
 
        qlanname = strdup(fmtId(plang->dobj.name));
 
+       /*
+        * If dumping a HANDLER clause, treat the language as being in the handler
+        * function's schema; this avoids cluttering the HANDLER clause. Otherwise
+        * it doesn't really have a schema.
+        */
+       if (useParams)
+               lanschema = funcInfo->dobj.namespace->dobj.name;
+       else
+               lanschema = NULL;
+
        appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s;\n",
                                          qlanname);
 
        appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE %s",
-                                         plang->lanpltrusted ? "TRUSTED " : "",
+                                         (useParams && plang->lanpltrusted) ? "TRUSTED " : "",
                                          qlanname);
-       appendPQExpBuffer(defqry, " HANDLER %s",
-                                         fmtId(funcInfo->dobj.name));
-       if (OidIsValid(plang->lanvalidator))
+       if (useParams)
        {
-               appendPQExpBuffer(defqry, " VALIDATOR ");
-               /* Cope with possibility that validator is in different schema */
-               if (validatorInfo->dobj.namespace != funcInfo->dobj.namespace)
-                       appendPQExpBuffer(defqry, "%s.",
-                                               fmtId(validatorInfo->dobj.namespace->dobj.name));
-               appendPQExpBuffer(defqry, "%s",
-                                                 fmtId(validatorInfo->dobj.name));
+               appendPQExpBuffer(defqry, " HANDLER %s",
+                                                 fmtId(funcInfo->dobj.name));
+               if (OidIsValid(plang->lanvalidator))
+               {
+                       appendPQExpBuffer(defqry, " VALIDATOR ");
+                       /* Cope with possibility that validator is in different schema */
+                       if (validatorInfo->dobj.namespace != funcInfo->dobj.namespace)
+                               appendPQExpBuffer(defqry, "%s.",
+                                                       fmtId(validatorInfo->dobj.namespace->dobj.name));
+                       appendPQExpBuffer(defqry, "%s",
+                                                         fmtId(validatorInfo->dobj.name));
+               }
        }
        appendPQExpBuffer(defqry, ";\n");
 
        ArchiveEntry(fout, plang->dobj.catId, plang->dobj.dumpId,
                                 plang->dobj.name,
-                                funcInfo->dobj.namespace->dobj.name, NULL, "",
+                                lanschema, NULL, plang->lanowner,
                                 false, "PROCEDURAL LANGUAGE",
                                 defqry->data, delqry->data, NULL,
                                 plang->dobj.dependencies, plang->dobj.nDeps,
@@ -5036,7 +5703,6 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
 
        /* Dump Proc Lang Comments */
        resetPQExpBuffer(defqry);
-
        appendPQExpBuffer(defqry, "LANGUAGE %s", qlanname);
        dumpComment(fout, defqry->data,
                                NULL, "",
@@ -5045,8 +5711,8 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
        if (plang->lanpltrusted)
                dumpACL(fout, plang->dobj.catId, plang->dobj.dumpId, "LANGUAGE",
                                qlanname, plang->dobj.name,
-                               funcInfo->dobj.namespace->dobj.name,
-                               NULL, plang->lanacl);
+                               lanschema,
+                               plang->lanowner, plang->lanacl);
 
        free(qlanname);
 
@@ -5055,38 +5721,63 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
 }
 
 /*
- * format_function_signature: generate function name and argument list
+ * format_function_arguments: generate function name and argument list
  *
  * The argument type names are qualified if needed.  The function name
  * is never qualified.
  *
- * argnames may be NULL if no names are available.
+ * Any or all of allargtypes, argmodes, argnames may be NULL.
  */
 static char *
-format_function_signature(FuncInfo *finfo, char **argnames,
-                                                 bool honor_quotes)
+format_function_arguments(FuncInfo *finfo, int nallargs,
+                                                 char **allargtypes,
+                                                 char **argmodes,
+                                                 char **argnames)
 {
        PQExpBufferData fn;
        int                     j;
 
        initPQExpBuffer(&fn);
-       if (honor_quotes)
-               appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
-       else
-               appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
-       for (j = 0; j < finfo->nargs; j++)
+       appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
+       for (j = 0; j < nallargs; j++)
        {
+               Oid                     typid;
                char       *typname;
-               char       *argname;
+               const char *argmode;
+               const char *argname;
 
-               typname = getFormattedTypeName(finfo->argtypes[j], zeroAsOpaque);
+               typid = allargtypes ? atooid(allargtypes[j]) : finfo->argtypes[j];
+               typname = getFormattedTypeName(typid, zeroAsOpaque);
+
+               if (argmodes)
+               {
+                       switch (argmodes[j][0])
+                       {
+                               case 'i':
+                                       argmode = "";
+                                       break;
+                               case 'o':
+                                       argmode = "OUT ";
+                                       break;
+                               case 'b':
+                                       argmode = "INOUT ";
+                                       break;
+                               default:
+                                       write_msg(NULL, "WARNING: bogus value in proargmodes array\n");
+                                       argmode = "";
+                                       break;
+                       }
+               }
+               else
+                       argmode = "";
 
                argname = argnames ? argnames[j] : (char *) NULL;
                if (argname && argname[0] == '\0')
                        argname = NULL;
 
-               appendPQExpBuffer(&fn, "%s%s%s%s",
+               appendPQExpBuffer(&fn, "%s%s%s%s%s",
                                                  (j > 0) ? ", " : "",
+                                                 argmode,
                                                  argname ? fmtId(argname) : "",
                                                  argname ? " " : "",
                                                  typname);
@@ -5096,6 +5787,42 @@ format_function_signature(FuncInfo *finfo, char **argnames,
        return fn.data;
 }
 
+/*
+ * format_function_signature: generate function name and argument list
+ *
+ * This is like format_function_arguments except that only a minimal
+ * list of input argument types is generated; this is sufficient to
+ * reference the function, but not to define it.
+ *
+ * If honor_quotes is false then the function name is never quoted.
+ * This is appropriate for use in TOC tags, but not in SQL commands.
+ */
+static char *
+format_function_signature(FuncInfo *finfo, bool honor_quotes)
+{
+       PQExpBufferData fn;
+       int                     j;
+
+       initPQExpBuffer(&fn);
+       if (honor_quotes)
+               appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
+       else
+               appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
+       for (j = 0; j < finfo->nargs; j++)
+       {
+               char       *typname;
+
+               typname = getFormattedTypeName(finfo->argtypes[j], zeroAsOpaque);
+
+               appendPQExpBuffer(&fn, "%s%s",
+                                                 (j > 0) ? ", " : "",
+                                                 typname);
+               free(typname);
+       }
+       appendPQExpBuffer(&fn, ")");
+       return fn.data;
+}
+
 
 /*
  * dumpFunc:
@@ -5115,16 +5842,21 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        char       *proretset;
        char       *prosrc;
        char       *probin;
+       char       *proallargtypes;
+       char       *proargmodes;
        char       *proargnames;
        char       *provolatile;
        char       *proisstrict;
        char       *prosecdef;
        char       *lanname;
        char       *rettypename;
-       char      **argnamearray = NULL;
+       int                     nallargs;
+       char      **allargtypes = NULL;
+       char      **argmodes = NULL;
+       char      **argnames = NULL;
 
-       /* Dump only funcs in dumpable namespaces */
-       if (!finfo->dobj.namespace->dump || dataOnly)
+       /* Skip if not to be dumped */
+       if (!finfo->dobj.dump || dataOnly)
                return;
 
        query = createPQExpBuffer();
@@ -5136,10 +5868,23 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        selectSourceSchema(finfo->dobj.namespace->dobj.name);
 
        /* Fetch function-specific details */
-       if (g_fout->remoteVersion >= 80000)
+       if (g_fout->remoteVersion >= 80100)
+       {
+               appendPQExpBuffer(query,
+                                                 "SELECT proretset, prosrc, probin, "
+                                                 "proallargtypes, proargmodes, proargnames, "
+                                                 "provolatile, proisstrict, prosecdef, "
+                                                 "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
+                                                 "FROM pg_catalog.pg_proc "
+                                                 "WHERE oid = '%u'::pg_catalog.oid",
+                                                 finfo->dobj.catId.oid);
+       }
+       else if (g_fout->remoteVersion >= 80000)
        {
                appendPQExpBuffer(query,
                                                  "SELECT proretset, prosrc, probin, "
+                                                 "null as proallargtypes, "
+                                                 "null as proargmodes, "
                                                  "proargnames, "
                                                  "provolatile, proisstrict, prosecdef, "
                                                  "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
@@ -5151,7 +5896,9 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        {
                appendPQExpBuffer(query,
                                                  "SELECT proretset, prosrc, probin, "
-                                                 "null::text as proargnames, "
+                                                 "null as proallargtypes, "
+                                                 "null as proargmodes, "
+                                                 "null as proargnames, "
                                                  "provolatile, proisstrict, prosecdef, "
                                                  "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
                                                  "FROM pg_catalog.pg_proc "
@@ -5162,11 +5909,13 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        {
                appendPQExpBuffer(query,
                                                  "SELECT proretset, prosrc, probin, "
-                                                 "null::text as proargnames, "
-                "case when proiscachable then 'i' else 'v' end as provolatile, "
+                                                 "null as proallargtypes, "
+                                                 "null as proargmodes, "
+                                                 "null as proargnames, "
+                        "case when proiscachable then 'i' else 'v' end as provolatile, "
                                                  "proisstrict, "
                                                  "'f'::boolean as prosecdef, "
-                                                 "(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
+                 "(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
                                                  "FROM pg_proc "
                                                  "WHERE oid = '%u'::oid",
                                                  finfo->dobj.catId.oid);
@@ -5175,11 +5924,13 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        {
                appendPQExpBuffer(query,
                                                  "SELECT proretset, prosrc, probin, "
-                                                 "null::text as proargnames, "
-                "case when proiscachable then 'i' else 'v' end as provolatile, "
+                                                 "null as proallargtypes, "
+                                                 "null as proargmodes, "
+                                                 "null as proargnames, "
+                        "case when proiscachable then 'i' else 'v' end as provolatile, "
                                                  "'f'::boolean as proisstrict, "
                                                  "'f'::boolean as prosecdef, "
-                                                 "(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
+                 "(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
                                                  "FROM pg_proc "
                                                  "WHERE oid = '%u'::oid",
                                                  finfo->dobj.catId.oid);
@@ -5200,6 +5951,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        proretset = PQgetvalue(res, 0, PQfnumber(res, "proretset"));
        prosrc = PQgetvalue(res, 0, PQfnumber(res, "prosrc"));
        probin = PQgetvalue(res, 0, PQfnumber(res, "probin"));
+       proallargtypes = PQgetvalue(res, 0, PQfnumber(res, "proallargtypes"));
+       proargmodes = PQgetvalue(res, 0, PQfnumber(res, "proargmodes"));
        proargnames = PQgetvalue(res, 0, PQfnumber(res, "proargnames"));
        provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
        proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
@@ -5213,7 +5966,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        if (strcmp(probin, "-") != 0)
        {
                appendPQExpBuffer(asPart, "AS ");
-               appendStringLiteral(asPart, probin, true);
+               appendStringLiteralAH(asPart, probin, fout);
                if (strcmp(prosrc, "-") != 0)
                {
                        appendPQExpBuffer(asPart, ", ");
@@ -5222,10 +5975,11 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                         * where we have bin, use dollar quoting if allowed and src
                         * contains quote or backslash; else use regular quoting.
                         */
-                       if (disable_dollar_quoting)
-                               appendStringLiteral(asPart, prosrc, false);
+                       if (disable_dollar_quoting ||
+                               (strchr(prosrc, '\'') == NULL && strchr(prosrc, '\\') == NULL))
+                               appendStringLiteralAH(asPart, prosrc, fout);
                        else
-                               appendStringLiteralDQOpt(asPart, prosrc, false, NULL);
+                               appendStringLiteralDQ(asPart, prosrc, NULL);
                }
        }
        else
@@ -5235,32 +5989,64 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                        appendPQExpBuffer(asPart, "AS ");
                        /* with no bin, dollar quote src unconditionally if allowed */
                        if (disable_dollar_quoting)
-                               appendStringLiteral(asPart, prosrc, false);
+                               appendStringLiteralAH(asPart, prosrc, fout);
                        else
                                appendStringLiteralDQ(asPart, prosrc, NULL);
                }
        }
 
+       nallargs = finfo->nargs;        /* unless we learn different from allargs */
+
+       if (proallargtypes && *proallargtypes)
+       {
+               int                     nitems = 0;
+
+               if (!parsePGArray(proallargtypes, &allargtypes, &nitems) ||
+                       nitems < finfo->nargs)
+               {
+                       write_msg(NULL, "WARNING: could not parse proallargtypes array\n");
+                       if (allargtypes)
+                               free(allargtypes);
+                       allargtypes = NULL;
+               }
+               else
+                       nallargs = nitems;
+       }
+
+       if (proargmodes && *proargmodes)
+       {
+               int                     nitems = 0;
+
+               if (!parsePGArray(proargmodes, &argmodes, &nitems) ||
+                       nitems != nallargs)
+               {
+                       write_msg(NULL, "WARNING: could not parse proargmodes array\n");
+                       if (argmodes)
+                               free(argmodes);
+                       argmodes = NULL;
+               }
+       }
+
        if (proargnames && *proargnames)
        {
                int                     nitems = 0;
 
-               if (!parsePGArray(proargnames, &argnamearray, &nitems) ||
-                       nitems != finfo->nargs)
+               if (!parsePGArray(proargnames, &argnames, &nitems) ||
+                       nitems != nallargs)
                {
                        write_msg(NULL, "WARNING: could not parse proargnames array\n");
-                       if (argnamearray)
-                               free(argnamearray);
-                       argnamearray = NULL;
+                       if (argnames)
+                               free(argnames);
+                       argnames = NULL;
                }
        }
 
-       funcsig = format_function_signature(finfo, argnamearray, true);
-       funcsig_tag = format_function_signature(finfo, NULL, false);
+       funcsig = format_function_arguments(finfo, nallargs, allargtypes,
+                                                                               argmodes, argnames);
+       funcsig_tag = format_function_signature(finfo, false);
 
        /*
-        * DROP must be fully qualified in case same name appears in
-        * pg_catalog
+        * DROP must be fully qualified in case same name appears in pg_catalog
         */
        appendPQExpBuffer(delqry, "DROP FUNCTION %s.%s;\n",
                                          fmtId(finfo->dobj.namespace->dobj.name),
@@ -5303,7 +6089,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                                 funcsig_tag,
                                 finfo->dobj.namespace->dobj.name,
                                 NULL,
-                                finfo->usename, false,
+                                finfo->rolname, false,
                                 "FUNCTION", q->data, delqry->data, NULL,
                                 finfo->dobj.dependencies, finfo->dobj.nDeps,
                                 NULL, NULL);
@@ -5312,13 +6098,13 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        resetPQExpBuffer(q);
        appendPQExpBuffer(q, "FUNCTION %s", funcsig);
        dumpComment(fout, q->data,
-                               finfo->dobj.namespace->dobj.name, finfo->usename,
+                               finfo->dobj.namespace->dobj.name, finfo->rolname,
                                finfo->dobj.catId, 0, finfo->dobj.dumpId);
 
        dumpACL(fout, finfo->dobj.catId, finfo->dobj.dumpId, "FUNCTION",
                        funcsig, funcsig_tag,
                        finfo->dobj.namespace->dobj.name,
-                       finfo->usename, finfo->proacl);
+                       finfo->rolname, finfo->proacl);
 
        PQclear(res);
 
@@ -5328,8 +6114,12 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        destroyPQExpBuffer(asPart);
        free(funcsig);
        free(funcsig_tag);
-       if (argnamearray)
-               free(argnamearray);
+       if (allargtypes)
+               free(allargtypes);
+       if (argmodes)
+               free(argmodes);
+       if (argnames)
+               free(argnames);
 }
 
 
@@ -5359,9 +6149,8 @@ dumpCast(Archive *fout, CastInfo *cast)
        /*
         * As per discussion we dump casts if one or more of the underlying
         * objects (the conversion function and the two data types) are not
-        * builtin AND if all of the non-builtin objects namespaces are
-        * included in the dump. Builtin meaning, the namespace name does not
-        * start with "pg_".
+        * builtin AND if all of the non-builtin objects are included in the dump.
+        * Builtin meaning, the namespace name does not start with "pg_".
         */
        sourceInfo = findTypeByOid(cast->castsource);
        targetInfo = findTypeByOid(cast->casttarget);
@@ -5373,32 +6162,31 @@ dumpCast(Archive *fout, CastInfo *cast)
         * Skip this cast if all objects are from pg_
         */
        if ((funcInfo == NULL ||
-                strncmp(funcInfo->dobj.namespace->dobj.name, "pg_", 3) == 0) &&
+               strncmp(funcInfo->dobj.namespace->dobj.name, "pg_", 3) == 0) &&
                strncmp(sourceInfo->dobj.namespace->dobj.name, "pg_", 3) == 0 &&
                strncmp(targetInfo->dobj.namespace->dobj.name, "pg_", 3) == 0)
                return;
 
        /*
-        * Skip cast if function isn't from pg_ and that namespace is not
-        * dumped.
+        * Skip cast if function isn't from pg_ and is not to be dumped.
         */
        if (funcInfo &&
                strncmp(funcInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
-               !funcInfo->dobj.namespace->dump)
+               !funcInfo->dobj.dump)
                return;
 
        /*
-        * Same for the Source type
+        * Same for the source type
         */
        if (strncmp(sourceInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
-               !sourceInfo->dobj.namespace->dump)
+               !sourceInfo->dobj.dump)
                return;
 
        /*
         * and the target type.
         */
        if (strncmp(targetInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
-               !targetInfo->dobj.namespace->dump)
+               !targetInfo->dobj.dump)
                return;
 
        /* Make sure we are in proper schema (needed for getFormattedTypeName) */
@@ -5421,13 +6209,13 @@ dumpCast(Archive *fout, CastInfo *cast)
        else
        {
                /*
-                * Always qualify the function name, in case it is not in
-                * pg_catalog schema (format_function_signature won't qualify it).
+                * Always qualify the function name, in case it is not in pg_catalog
+                * schema (format_function_signature won't qualify it).
                 */
                appendPQExpBuffer(defqry, "WITH FUNCTION %s.",
                                                  fmtId(funcInfo->dobj.namespace->dobj.name));
                appendPQExpBuffer(defqry, "%s",
-                                               format_function_signature(funcInfo, NULL, true));
+                                                 format_function_signature(funcInfo, true));
        }
 
        if (cast->castcontext == 'a')
@@ -5503,8 +6291,8 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
        char       *oprltcmpop;
        char       *oprgtcmpop;
 
-       /* Dump only operators in dumpable namespaces */
-       if (!oprinfo->dobj.namespace->dump || dataOnly)
+       /* Skip if not to be dumped */
+       if (!oprinfo->dobj.dump || dataOnly)
                return;
 
        /*
@@ -5546,9 +6334,9 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
        {
                appendPQExpBuffer(query, "SELECT oprkind, oprcode, "
                                                  "CASE WHEN oprleft = 0 THEN '-' "
-                                          "ELSE format_type(oprleft, NULL) END as oprleft, "
+                                                 "ELSE format_type(oprleft, NULL) END as oprleft, "
                                                  "CASE WHEN oprright = 0 THEN '-' "
-                                        "ELSE format_type(oprright, NULL) END as oprright, "
+                                                 "ELSE format_type(oprright, NULL) END as oprright, "
                                                  "oprcom, oprnegate, oprrest, oprjoin, "
                                                  "oprcanhash, oprlsortop, oprrsortop, "
                                                  "0 as oprltcmpop, 0 as oprgtcmpop "
@@ -5683,8 +6471,7 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
                appendPQExpBuffer(details, ",\n    GTCMP = %s", name);
 
        /*
-        * DROP must be fully qualified in case same name appears in
-        * pg_catalog
+        * DROP must be fully qualified in case same name appears in pg_catalog
         */
        appendPQExpBuffer(delq, "DROP OPERATOR %s.%s;\n",
                                          fmtId(oprinfo->dobj.namespace->dobj.name),
@@ -5695,9 +6482,9 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
 
        ArchiveEntry(fout, oprinfo->dobj.catId, oprinfo->dobj.dumpId,
                                 oprinfo->dobj.name,
-                                oprinfo->dobj.namespace->dobj.name, 
+                                oprinfo->dobj.namespace->dobj.name,
                                 NULL,
-                                oprinfo->usename,
+                                oprinfo->rolname,
                                 false, "OPERATOR", q->data, delq->data, NULL,
                                 oprinfo->dobj.dependencies, oprinfo->dobj.nDeps,
                                 NULL, NULL);
@@ -5706,7 +6493,7 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
        resetPQExpBuffer(q);
        appendPQExpBuffer(q, "OPERATOR %s", oprid->data);
        dumpComment(fout, q->data,
-                               oprinfo->dobj.namespace->dobj.name, oprinfo->usename,
+                               oprinfo->dobj.namespace->dobj.name, oprinfo->rolname,
                                oprinfo->dobj.catId, 0, oprinfo->dobj.dumpId);
 
        PQclear(res);
@@ -5764,9 +6551,10 @@ convertRegProcReference(const char *proc)
  *
  * Returns what to print, or NULL to print nothing
  *
- * In 7.3 the input is a REGOPERATOR display; we have to strip the
- * argument-types part.  In prior versions, the input is just a
- * numeric OID, which we search our operator list for.
+ * 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 *
 convertOperatorReference(const char *opr)
@@ -5780,23 +6568,34 @@ convertOperatorReference(const char *opr)
        if (g_fout->remoteVersion >= 70300)
        {
                char       *name;
-               char       *paren;
+               char       *oname;
+               char       *ptr;
                bool            inquote;
+               bool            sawdot;
 
                name = strdup(opr);
-               /* find non-double-quoted left paren */
+               /* find non-double-quoted left paren, and check for non-quoted dot */
                inquote = false;
-               for (paren = name; *paren; paren++)
+               sawdot = false;
+               for (ptr = name; *ptr; ptr++)
                {
-                       if (*paren == '(' && !inquote)
+                       if (*ptr == '"')
+                               inquote = !inquote;
+                       else if (*ptr == '.' && !inquote)
+                               sawdot = true;
+                       else if (*ptr == '(' && !inquote)
                        {
-                               *paren = '\0';
+                               *ptr = '\0';
                                break;
                        }
-                       if (*paren == '"')
-                               inquote = !inquote;
                }
-               return name;
+               /* If not schema-qualified, don't need to add OPERATOR() */
+               if (!sawdot)
+                       return name;
+               oname = malloc(strlen(name) + 11);
+               sprintf(oname, "OPERATOR(%s)", name);
+               free(name);
+               return oname;
        }
 
        oprInfo = findOprByOid(atooid(opr));
@@ -5842,8 +6641,8 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
        bool            needComma;
        int                     i;
 
-       /* Dump only opclasses in dumpable namespaces */
-       if (!opcinfo->dobj.namespace->dump || dataOnly)
+       /* Skip if not to be dumped */
+       if (!opcinfo->dobj.dump || dataOnly)
                return;
 
        /*
@@ -5865,7 +6664,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
        appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
                                          "opckeytype::pg_catalog.regtype, "
                                          "opcdefault, "
-       "(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);
@@ -5894,8 +6693,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
        amname = strdup(PQgetvalue(res, 0, i_amname));
 
        /*
-        * DROP must be fully qualified in case same name appears in
-        * pg_catalog
+        * DROP must be fully qualified in case same name appears in pg_catalog
         */
        appendPQExpBuffer(delq, "DROP OPERATOR CLASS %s",
                                          fmtId(opcinfo->dobj.namespace->dobj.name));
@@ -6004,9 +6802,9 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
 
        ArchiveEntry(fout, opcinfo->dobj.catId, opcinfo->dobj.dumpId,
                                 opcinfo->dobj.name,
-                                opcinfo->dobj.namespace->dobj.name, 
+                                opcinfo->dobj.namespace->dobj.name,
                                 NULL,
-                                opcinfo->usename,
+                                opcinfo->rolname,
                                 false, "OPERATOR CLASS", q->data, delq->data, NULL,
                                 opcinfo->dobj.dependencies, opcinfo->dobj.nDeps,
                                 NULL, NULL);
@@ -6018,7 +6816,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
        appendPQExpBuffer(q, " USING %s",
                                          fmtId(amname));
        dumpComment(fout, q->data,
-                               NULL, opcinfo->usename,
+                               NULL, opcinfo->rolname,
                                opcinfo->dobj.catId, 0, opcinfo->dobj.dumpId);
 
        free(amname);
@@ -6051,8 +6849,8 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
        const char *conproc;
        bool            condefault;
 
-       /* Dump only conversions in dumpable namespaces */
-       if (!convinfo->dobj.namespace->dump || dataOnly)
+       /* Skip if not to be dumped */
+       if (!convinfo->dobj.dump || dataOnly)
                return;
 
        query = createPQExpBuffer();
@@ -6065,8 +6863,8 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
 
        /* Get conversion-specific details */
        appendPQExpBuffer(query, "SELECT conname, "
-        "pg_catalog.pg_encoding_to_char(conforencoding) AS conforencoding, "
-          "pg_catalog.pg_encoding_to_char(contoencoding) AS contoencoding, "
+                "pg_catalog.pg_encoding_to_char(conforencoding) AS conforencoding, "
+                  "pg_catalog.pg_encoding_to_char(contoencoding) AS contoencoding, "
                                          "conproc, condefault "
                                          "FROM pg_catalog.pg_conversion c "
                                          "WHERE c.oid = '%u'::pg_catalog.oid",
@@ -6097,8 +6895,7 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
        condefault = (PQgetvalue(res, 0, i_condefault)[0] == 't');
 
        /*
-        * DROP must be fully qualified in case same name appears in
-        * pg_catalog
+        * DROP must be fully qualified in case same name appears in pg_catalog
         */
        appendPQExpBuffer(delq, "DROP CONVERSION %s",
                                          fmtId(convinfo->dobj.namespace->dobj.name));
@@ -6108,17 +6905,17 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
        appendPQExpBuffer(q, "CREATE %sCONVERSION %s FOR ",
                                          (condefault) ? "DEFAULT " : "",
                                          fmtId(convinfo->dobj.name));
-       appendStringLiteral(q, conforencoding, true);
+       appendStringLiteralAH(q, conforencoding, fout);
        appendPQExpBuffer(q, " TO ");
-       appendStringLiteral(q, contoencoding, true);
+       appendStringLiteralAH(q, contoencoding, fout);
        /* regproc is automatically quoted in 7.3 and above */
        appendPQExpBuffer(q, " FROM %s;\n", conproc);
 
        ArchiveEntry(fout, convinfo->dobj.catId, convinfo->dobj.dumpId,
                                 convinfo->dobj.name,
-                                convinfo->dobj.namespace->dobj.name, 
-                                NULL, 
-                                convinfo->usename,
+                                convinfo->dobj.namespace->dobj.name,
+                                NULL,
+                                convinfo->rolname,
                                 false, "CONVERSION", q->data, delq->data, NULL,
                                 convinfo->dobj.dependencies, convinfo->dobj.nDeps,
                                 NULL, NULL);
@@ -6127,7 +6924,7 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
        resetPQExpBuffer(q);
        appendPQExpBuffer(q, "CONVERSION %s", fmtId(convinfo->dobj.name));
        dumpComment(fout, q->data,
-                               convinfo->dobj.namespace->dobj.name, convinfo->usename,
+                               convinfo->dobj.namespace->dobj.name, convinfo->rolname,
                                convinfo->dobj.catId, 0, convinfo->dobj.dumpId);
 
        PQclear(res);
@@ -6148,6 +6945,7 @@ static char *
 format_aggregate_signature(AggInfo *agginfo, Archive *fout, bool honor_quotes)
 {
        PQExpBufferData buf;
+       int                     j;
 
        initPQExpBuffer(&buf);
        if (honor_quotes)
@@ -6156,23 +6954,24 @@ format_aggregate_signature(AggInfo *agginfo, Archive *fout, bool honor_quotes)
        else
                appendPQExpBuffer(&buf, "%s", agginfo->aggfn.dobj.name);
 
-       /* If using regtype or format_type, fmtbasetype is already quoted */
-       if (fout->remoteVersion >= 70100)
-       {
-               if (agginfo->anybasetype)
-                       appendPQExpBuffer(&buf, "(*)");
-               else
-                       appendPQExpBuffer(&buf, "(%s)", agginfo->fmtbasetype);
-       }
+       if (agginfo->aggfn.nargs == 0)
+               appendPQExpBuffer(&buf, "(*)");
        else
        {
-               if (agginfo->anybasetype)
-                       appendPQExpBuffer(&buf, "(*)");
-               else
-                       appendPQExpBuffer(&buf, "(%s)",
-                                                         fmtId(agginfo->fmtbasetype));
-       }
+               appendPQExpBuffer(&buf, "(");
+               for (j = 0; j < agginfo->aggfn.nargs; j++)
+               {
+                       char       *typname;
+
+                       typname = getFormattedTypeName(agginfo->aggfn.argtypes[j], zeroAsOpaque);
 
+                       appendPQExpBuffer(&buf, "%s%s",
+                                                         (j > 0) ? ", " : "",
+                                                         typname);
+                       free(typname);
+               }
+               appendPQExpBuffer(&buf, ")");
+       }
        return buf.data;
 }
 
@@ -6193,19 +6992,19 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        int                     ntups;
        int                     i_aggtransfn;
        int                     i_aggfinalfn;
+       int                     i_aggsortop;
        int                     i_aggtranstype;
        int                     i_agginitval;
-       int                     i_anybasetype;
-       int                     i_fmtbasetype;
        int                     i_convertok;
        const char *aggtransfn;
        const char *aggfinalfn;
+       const char *aggsortop;
        const char *aggtranstype;
        const char *agginitval;
        bool            convertok;
 
-       /* Dump only aggs in dumpable namespaces */
-       if (!agginfo->aggfn.dobj.namespace->dump || dataOnly)
+       /* Skip if not to be dumped */
+       if (!agginfo->aggfn.dobj.dump || dataOnly)
                return;
 
        query = createPQExpBuffer();
@@ -6217,15 +7016,26 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        selectSourceSchema(agginfo->aggfn.dobj.namespace->dobj.name);
 
        /* Get aggregate-specific details */
-       if (g_fout->remoteVersion >= 70300)
+       if (g_fout->remoteVersion >= 80100)
+       {
+               appendPQExpBuffer(query, "SELECT aggtransfn, "
+                                                 "aggfinalfn, aggtranstype::pg_catalog.regtype, "
+                                                 "aggsortop::pg_catalog.regoperator, "
+                                                 "agginitval, "
+                                                 "'t'::boolean 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",
+                                                 agginfo->aggfn.dobj.catId.oid);
+       }
+       else if (g_fout->remoteVersion >= 70300)
        {
                appendPQExpBuffer(query, "SELECT aggtransfn, "
                                                  "aggfinalfn, aggtranstype::pg_catalog.regtype, "
+                                                 "0 as aggsortop, "
                                                  "agginitval, "
-                                                 "proargtypes[0] = 'pg_catalog.\"any\"'::pg_catalog.regtype as anybasetype, "
-                                       "proargtypes[0]::pg_catalog.regtype as fmtbasetype, "
                                                  "'t'::boolean as convertok "
-                                 "from pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
+                                         "from pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
                                                  "where a.aggfnoid = p.oid "
                                                  "and p.oid = '%u'::pg_catalog.oid",
                                                  agginfo->aggfn.dobj.catId.oid);
@@ -6233,11 +7043,9 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        else if (g_fout->remoteVersion >= 70100)
        {
                appendPQExpBuffer(query, "SELECT aggtransfn, aggfinalfn, "
-                                         "format_type(aggtranstype, NULL) as aggtranstype, "
+                                                 "format_type(aggtranstype, NULL) as aggtranstype, "
+                                                 "0 as aggsortop, "
                                                  "agginitval, "
-                                                 "aggbasetype = 0 as anybasetype, "
-                                                 "CASE WHEN aggbasetype = 0 THEN '-' "
-                          "ELSE format_type(aggbasetype, NULL) END as fmtbasetype, "
                                                  "'t'::boolean as convertok "
                                                  "from pg_aggregate "
                                                  "where oid = '%u'::oid",
@@ -6248,9 +7056,8 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                appendPQExpBuffer(query, "SELECT aggtransfn1 as aggtransfn, "
                                                  "aggfinalfn, "
                                                  "(select typname from pg_type where oid = aggtranstype1) as aggtranstype, "
+                                                 "0 as aggsortop, "
                                                  "agginitval1 as agginitval, "
-                                                 "aggbasetype = 0 as anybasetype, "
-                                                 "(select typname from pg_type where oid = aggbasetype) as fmtbasetype, "
                                                  "(aggtransfn2 = 0 and aggtranstype2 = 0 and agginitval2 is null) as convertok "
                                                  "from pg_aggregate "
                                                  "where oid = '%u'::oid",
@@ -6271,20 +7078,16 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
 
        i_aggtransfn = PQfnumber(res, "aggtransfn");
        i_aggfinalfn = PQfnumber(res, "aggfinalfn");
+       i_aggsortop = PQfnumber(res, "aggsortop");
        i_aggtranstype = PQfnumber(res, "aggtranstype");
        i_agginitval = PQfnumber(res, "agginitval");
-       i_anybasetype = PQfnumber(res, "anybasetype");
-       i_fmtbasetype = PQfnumber(res, "fmtbasetype");
        i_convertok = PQfnumber(res, "convertok");
 
        aggtransfn = PQgetvalue(res, 0, i_aggtransfn);
        aggfinalfn = PQgetvalue(res, 0, i_aggfinalfn);
+       aggsortop = PQgetvalue(res, 0, i_aggsortop);
        aggtranstype = PQgetvalue(res, 0, i_aggtranstype);
        agginitval = PQgetvalue(res, 0, i_agginitval);
-       /* we save anybasetype for format_aggregate_signature */
-       agginfo->anybasetype = (PQgetvalue(res, 0, i_anybasetype)[0] == 't');
-       /* we save fmtbasetype for format_aggregate_signature */
-       agginfo->fmtbasetype = strdup(PQgetvalue(res, 0, i_fmtbasetype));
        convertok = (PQgetvalue(res, 0, i_convertok)[0] == 't');
 
        aggsig = format_aggregate_signature(agginfo, fout, true);
@@ -6300,27 +7103,20 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        if (g_fout->remoteVersion >= 70300)
        {
                /* If using 7.3's regproc or regtype, data is already quoted */
-               appendPQExpBuffer(details, "    BASETYPE = %s,\n    SFUNC = %s,\n    STYPE = %s",
-                                                 agginfo->anybasetype ? "'any'" :
-                                                 agginfo->fmtbasetype,
+               appendPQExpBuffer(details, "    SFUNC = %s,\n    STYPE = %s",
                                                  aggtransfn,
                                                  aggtranstype);
        }
        else if (g_fout->remoteVersion >= 70100)
        {
                /* format_type quotes, regproc does not */
-               appendPQExpBuffer(details, "    BASETYPE = %s,\n    SFUNC = %s,\n    STYPE = %s",
-                                                 agginfo->anybasetype ? "'any'" :
-                                                 agginfo->fmtbasetype,
+               appendPQExpBuffer(details, "    SFUNC = %s,\n    STYPE = %s",
                                                  fmtId(aggtransfn),
                                                  aggtranstype);
        }
        else
        {
                /* need quotes all around */
-               appendPQExpBuffer(details, "    BASETYPE = %s,\n",
-                                                 agginfo->anybasetype ? "'any'" :
-                                                 fmtId(agginfo->fmtbasetype));
                appendPQExpBuffer(details, "    SFUNC = %s,\n",
                                                  fmtId(aggtransfn));
                appendPQExpBuffer(details, "    STYPE = %s",
@@ -6330,7 +7126,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        if (!PQgetisnull(res, 0, i_agginitval))
        {
                appendPQExpBuffer(details, ",\n    INITCOND = ");
-               appendStringLiteral(details, agginitval, true);
+               appendStringLiteralAH(details, agginitval, fout);
        }
 
        if (strcmp(aggfinalfn, "-") != 0)
@@ -6339,23 +7135,28 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                                  aggfinalfn);
        }
 
+       aggsortop = convertOperatorReference(aggsortop);
+       if (aggsortop)
+       {
+               appendPQExpBuffer(details, ",\n    SORTOP = %s",
+                                                 aggsortop);
+       }
+
        /*
-        * DROP must be fully qualified in case same name appears in
-        * pg_catalog
+        * DROP must be fully qualified in case same name appears in pg_catalog
         */
        appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n",
                                          fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
                                          aggsig);
 
        appendPQExpBuffer(q, "CREATE AGGREGATE %s (\n%s\n);\n",
-                                         fmtId(agginfo->aggfn.dobj.name),
-                                         details->data);
+                                         aggsig, details->data);
 
        ArchiveEntry(fout, agginfo->aggfn.dobj.catId, agginfo->aggfn.dobj.dumpId,
                                 aggsig_tag,
                                 agginfo->aggfn.dobj.namespace->dobj.name,
                                 NULL,
-                                agginfo->aggfn.usename,
+                                agginfo->aggfn.rolname,
                                 false, "AGGREGATE", q->data, delq->data, NULL,
                                 agginfo->aggfn.dobj.dependencies, agginfo->aggfn.dobj.nDeps,
                                 NULL, NULL);
@@ -6364,25 +7165,25 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        resetPQExpBuffer(q);
        appendPQExpBuffer(q, "AGGREGATE %s", aggsig);
        dumpComment(fout, q->data,
-               agginfo->aggfn.dobj.namespace->dobj.name, agginfo->aggfn.usename,
+                       agginfo->aggfn.dobj.namespace->dobj.name, agginfo->aggfn.rolname,
                                agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
 
        /*
-        * Since there is no GRANT ON AGGREGATE syntax, we have to make the
-        * ACL command look like a function's GRANT; in particular this
-        * affects the syntax for aggregates on ANY.
+        * Since there is no GRANT ON AGGREGATE syntax, we have to make the ACL
+        * command look like a function's GRANT; in particular this affects the
+        * syntax for zero-argument aggregates.
         */
        free(aggsig);
        free(aggsig_tag);
 
-       aggsig = format_function_signature(&agginfo->aggfn, NULL, true);
-       aggsig_tag = format_function_signature(&agginfo->aggfn, NULL, false);
+       aggsig = format_function_signature(&agginfo->aggfn, true);
+       aggsig_tag = format_function_signature(&agginfo->aggfn, false);
 
        dumpACL(fout, agginfo->aggfn.dobj.catId, agginfo->aggfn.dobj.dumpId,
                        "FUNCTION",
                        aggsig, aggsig_tag,
                        agginfo->aggfn.dobj.namespace->dobj.name,
-                       agginfo->aggfn.usename, agginfo->aggfn.proacl);
+                       agginfo->aggfn.rolname, agginfo->aggfn.proacl);
 
        free(aggsig);
        free(aggsig_tag);
@@ -6401,7 +7202,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
  *
  * 'objCatId' is the catalog ID of the underlying object.
  * 'objDumpId' is the dump ID of the underlying object.
- * 'type' must be TABLE, FUNCTION, LANGUAGE, or SCHEMA.
+ * 'type' must be TABLE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, or TABLESPACE.
  * 'name' is the formatted name of the object. Must be quoted etc. already.
  * 'tag' is the tag for the archive entry (typ. unquoted name of object).
  * 'nspname' is the namespace the object is in (NULL if none).
@@ -6434,7 +7235,7 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
        if (sql->len > 0)
                ArchiveEntry(fout, nilCatalogId, createDumpId(),
                                         tag, nspname,
-                                        NULL, 
+                                        NULL,
                                         owner ? owner : "",
                                         false, "ACL", sql->data, "", NULL,
                                         &(objDumpId), 1,
@@ -6452,7 +7253,7 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
 {
        char       *namecopy;
 
-       if (tbinfo->dump)
+       if (tbinfo->dobj.dump)
        {
                if (tbinfo->relkind == RELKIND_SEQUENCE)
                        dumpSequence(fout, tbinfo);
@@ -6461,9 +7262,10 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
 
                /* Handle the ACL here */
                namecopy = strdup(fmtId(tbinfo->dobj.name));
-               dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId, "TABLE",
+               dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
+                               (tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE",
                                namecopy, tbinfo->dobj.name,
-                               tbinfo->dobj.namespace->dobj.name, tbinfo->usename,
+                               tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                                tbinfo->relacl);
                free(namecopy);
        }
@@ -6510,7 +7312,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                {
                        appendPQExpBuffer(query, "SELECT definition as viewdef "
                                                          " from pg_views where viewname = ");
-                       appendStringLiteral(query, tbinfo->dobj.name, true);
+                       appendStringLiteralAH(query, tbinfo->dobj.name, fout);
                        appendPQExpBuffer(query, ";");
                }
 
@@ -6586,16 +7388,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                /* Attribute type */
                                if (g_fout->remoteVersion >= 70100)
                                {
-                                       char       *typname = tbinfo->atttypnames[j];
-
-                                       if (tbinfo->attisserial[j])
-                                       {
-                                               if (strcmp(typname, "integer") == 0)
-                                                       typname = "serial";
-                                               else if (strcmp(typname, "bigint") == 0)
-                                                       typname = "bigserial";
-                                       }
-                                       appendPQExpBuffer(q, "%s", typname);
+                                       appendPQExpBuffer(q, "%s",
+                                                                         tbinfo->atttypnames[j]);
                                }
                                else
                                {
@@ -6606,24 +7400,17 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                }
 
                                /*
-                                * Default value --- suppress if inherited, serial, or to
-                                * be printed separately.
+                                * Default value --- suppress if inherited or to be
+                                * printed separately.
                                 */
                                if (tbinfo->attrdefs[j] != NULL &&
                                        !tbinfo->inhAttrDef[j] &&
-                                       !tbinfo->attisserial[j] &&
                                        !tbinfo->attrdefs[j]->separate)
                                        appendPQExpBuffer(q, " DEFAULT %s",
                                                                          tbinfo->attrdefs[j]->adef_expr);
 
                                /*
                                 * Not Null constraint --- suppress if inherited
-                                *
-                                * Note: we could suppress this for serial columns since
-                                * SERIAL implies NOT NULL.  We choose not to for forward
-                                * compatibility, since there has been some talk of making
-                                * SERIAL not imply NOT NULL, in which case the explicit
-                                * specification would be needed.
                                 */
                                if (tbinfo->notnull[j] && !tbinfo->inhNotNull[j])
                                        appendPQExpBuffer(q, " NOT NULL");
@@ -6665,22 +7452,25 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                        appendPQExpBuffer(q, ", ");
                                if (parentRel->dobj.namespace != tbinfo->dobj.namespace)
                                        appendPQExpBuffer(q, "%s.",
-                                                       fmtId(parentRel->dobj.namespace->dobj.name));
+                                                               fmtId(parentRel->dobj.namespace->dobj.name));
                                appendPQExpBuffer(q, "%s",
                                                                  fmtId(parentRel->dobj.name));
                        }
                        appendPQExpBuffer(q, ")");
                }
 
+               if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0)
+                       appendPQExpBuffer(q, "\nWITH (%s)", tbinfo->reloptions);
+
                appendPQExpBuffer(q, ";\n");
 
                /* Loop dumping statistics and storage statements */
                for (j = 0; j < tbinfo->numatts; j++)
                {
                        /*
-                        * Dump per-column statistics information. We only issue an
-                        * ALTER TABLE statement if the attstattarget entry for this
-                        * column is non-negative (i.e. it's not the default value)
+                        * Dump per-column statistics information. We only issue an ALTER
+                        * TABLE statement if the attstattarget entry for this column is
+                        * non-negative (i.e. it's not the default value)
                         */
                        if (tbinfo->attstattarget[j] >= 0 &&
                                !tbinfo->attisdropped[j])
@@ -6695,8 +7485,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 
                        /*
                         * Dump per-column storage information.  The statement is only
-                        * dumped if the storage has been changed from the type's
-                        * default.
+                        * dumped if the storage has been changed from the type's default.
                         */
                        if (!tbinfo->attisdropped[j] && tbinfo->attstorage[j] != tbinfo->typstorage[j])
                        {
@@ -6719,8 +7508,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                }
 
                                /*
-                                * Only dump the statement if it's a storage type we
-                                * recognize
+                                * Only dump the statement if it's a storage type we recognize
                                 */
                                if (storage != NULL)
                                {
@@ -6738,9 +7526,9 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
        ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
                                 tbinfo->dobj.name,
                                 tbinfo->dobj.namespace->dobj.name,
-                                (tbinfo->relkind == RELKIND_VIEW) ? NULL : tbinfo->reltablespace,
-                                tbinfo->usename,
-                                (strcmp(reltypename, "TABLE") == 0) ? tbinfo->hasoids : false,
+                       (tbinfo->relkind == RELKIND_VIEW) ? NULL : tbinfo->reltablespace,
+                                tbinfo->rolname,
+                          (strcmp(reltypename, "TABLE") == 0) ? tbinfo->hasoids : false,
                                 reltypename, q->data, delq->data, NULL,
                                 tbinfo->dobj.dependencies, tbinfo->dobj.nDeps,
                                 NULL, NULL);
@@ -6776,11 +7564,11 @@ dumpAttrDef(Archive *fout, AttrDefInfo *adinfo)
        PQExpBuffer delq;
 
        /* Only print it if "separate" mode is selected */
-       if (!tbinfo->dump || !adinfo->separate || dataOnly)
+       if (!tbinfo->dobj.dump || !adinfo->separate || dataOnly)
                return;
 
-       /* Don't print inherited or serial defaults, either */
-       if (tbinfo->inhAttrDef[adnum - 1] || tbinfo->attisserial[adnum - 1])
+       /* Don't print inherited defaults, either */
+       if (tbinfo->inhAttrDef[adnum - 1])
                return;
 
        q = createPQExpBuffer();
@@ -6793,8 +7581,7 @@ dumpAttrDef(Archive *fout, AttrDefInfo *adinfo)
                                          adinfo->adef_expr);
 
        /*
-        * DROP must be fully qualified in case same name appears in
-        * pg_catalog
+        * DROP must be fully qualified in case same name appears in pg_catalog
         */
        appendPQExpBuffer(delq, "ALTER TABLE %s.",
                                          fmtId(tbinfo->dobj.namespace->dobj.name));
@@ -6805,9 +7592,9 @@ dumpAttrDef(Archive *fout, AttrDefInfo *adinfo)
 
        ArchiveEntry(fout, adinfo->dobj.catId, adinfo->dobj.dumpId,
                                 tbinfo->attnames[adnum - 1],
-                                tbinfo->dobj.namespace->dobj.name, 
+                                tbinfo->dobj.namespace->dobj.name,
                                 NULL,
-                                tbinfo->usename,
+                                tbinfo->rolname,
                                 false, "DEFAULT", q->data, delq->data, NULL,
                                 adinfo->dobj.dependencies, adinfo->dobj.nDeps,
                                 NULL, NULL);
@@ -6869,9 +7656,9 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
        delq = createPQExpBuffer();
 
        /*
-        * If there's an associated constraint, don't dump the index per se,
-        * but do dump any comment for it.  (This is safe because dependency
-        * ordering will have ensured the constraint is emitted first.)
+        * If there's an associated constraint, don't dump the index per se, but
+        * do dump any comment for it.  (This is safe because dependency ordering
+        * will have ensured the constraint is emitted first.)
         */
        if (indxinfo->indexconstraint == 0)
        {
@@ -6900,7 +7687,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
                                         indxinfo->dobj.name,
                                         tbinfo->dobj.namespace->dobj.name,
                                         indxinfo->tablespace,
-                                        tbinfo->usename, false,
+                                        tbinfo->rolname, false,
                                         "INDEX", q->data, delq->data, NULL,
                                         indxinfo->dobj.dependencies, indxinfo->dobj.nDeps,
                                         NULL, NULL);
@@ -6912,7 +7699,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
                                          fmtId(indxinfo->dobj.name));
        dumpComment(fout, q->data,
                                tbinfo->dobj.namespace->dobj.name,
-                               tbinfo->usename,
+                               tbinfo->rolname,
                                indxinfo->dobj.catId, 0, indxinfo->dobj.dumpId);
 
        destroyPQExpBuffer(q);
@@ -6930,9 +7717,8 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
        PQExpBuffer q;
        PQExpBuffer delq;
 
-       if (dataOnly)
-               return;
-       if (tbinfo && !tbinfo->dump)
+       /* Skip if not to be dumped */
+       if (!coninfo->dobj.dump || dataOnly)
                return;
 
        q = createPQExpBuffer();
@@ -6957,7 +7743,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                                                  fmtId(tbinfo->dobj.name));
                appendPQExpBuffer(q, "    ADD CONSTRAINT %s %s (",
                                                  fmtId(coninfo->dobj.name),
-                                        coninfo->contype == 'p' ? "PRIMARY KEY" : "UNIQUE");
+                                                 coninfo->contype == 'p' ? "PRIMARY KEY" : "UNIQUE");
 
                for (k = 0; k < indxinfo->indnkeys; k++)
                {
@@ -6973,7 +7759,12 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                                                          fmtId(attname));
                }
 
-               appendPQExpBuffer(q, ");\n");
+               appendPQExpBuffer(q, ")");
+
+               if (indxinfo->options && strlen(indxinfo->options) > 0)
+                       appendPQExpBuffer(q, " WITH (%s)", indxinfo->options);
+
+               appendPQExpBuffer(q, ";\n");
 
                /* If the index is clustered, we need to record that. */
                if (indxinfo->indisclustered)
@@ -6999,7 +7790,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                                         coninfo->dobj.name,
                                         tbinfo->dobj.namespace->dobj.name,
                                         indxinfo->tablespace,
-                                        tbinfo->usename, false,
+                                        tbinfo->rolname, false,
                                         "CONSTRAINT", q->data, delq->data, NULL,
                                         coninfo->dobj.dependencies, coninfo->dobj.nDeps,
                                         NULL, NULL);
@@ -7007,8 +7798,8 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
        else if (coninfo->contype == 'f')
        {
                /*
-                * XXX Potentially wrap in a 'SET CONSTRAINTS OFF' block so that
-                * the current table data is not processed
+                * XXX Potentially wrap in a 'SET CONSTRAINTS OFF' block so that the
+                * current table data is not processed
                 */
                appendPQExpBuffer(q, "ALTER TABLE ONLY %s\n",
                                                  fmtId(tbinfo->dobj.name));
@@ -7031,7 +7822,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                                         coninfo->dobj.name,
                                         tbinfo->dobj.namespace->dobj.name,
                                         NULL,
-                                        tbinfo->usename, false,
+                                        tbinfo->rolname, false,
                                         "FK CONSTRAINT", q->data, delq->data, NULL,
                                         coninfo->dobj.dependencies, coninfo->dobj.nDeps,
                                         NULL, NULL);
@@ -7065,7 +7856,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                                                 coninfo->dobj.name,
                                                 tbinfo->dobj.namespace->dobj.name,
                                                 NULL,
-                                                tbinfo->usename, false,
+                                                tbinfo->rolname, false,
                                                 "CHECK CONSTRAINT", q->data, delq->data, NULL,
                                                 coninfo->dobj.dependencies, coninfo->dobj.nDeps,
                                                 NULL, NULL);
@@ -7076,8 +7867,8 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                /* CHECK constraint on a domain */
                TypeInfo   *tinfo = coninfo->condomain;
 
-               /* Ignore if not to be dumped separately, or if not dumping domain */
-               if (coninfo->separate && tinfo->dobj.namespace->dump)
+               /* Ignore if not to be dumped separately */
+               if (coninfo->separate)
                {
                        appendPQExpBuffer(q, "ALTER DOMAIN %s\n",
                                                          fmtId(tinfo->dobj.name));
@@ -7100,7 +7891,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                                                 coninfo->dobj.name,
                                                 tinfo->dobj.namespace->dobj.name,
                                                 NULL,
-                                                tinfo->usename, false,
+                                                tinfo->rolname, false,
                                                 "CHECK CONSTRAINT", q->data, delq->data, NULL,
                                                 coninfo->dobj.dependencies, coninfo->dobj.nDeps,
                                                 NULL, NULL);
@@ -7139,58 +7930,13 @@ dumpTableConstraintComment(Archive *fout, ConstraintInfo *coninfo)
                                          fmtId(tbinfo->dobj.name));
        dumpComment(fout, q->data,
                                tbinfo->dobj.namespace->dobj.name,
-                               tbinfo->usename,
+                               tbinfo->rolname,
                                coninfo->dobj.catId, 0,
-                               coninfo->separate ? coninfo->dobj.dumpId : tbinfo->dobj.dumpId);
+                        coninfo->separate ? coninfo->dobj.dumpId : tbinfo->dobj.dumpId);
 
        destroyPQExpBuffer(q);
 }
 
-/*
- * setMaxOid -
- * find the maximum oid and generate a COPY statement to set it
- */
-static void
-setMaxOid(Archive *fout)
-{
-       PGresult   *res;
-       Oid                     max_oid;
-       char            sql[1024];
-
-       if (fout->remoteVersion >= 70200)
-               do_sql_command(g_conn,
-                                          "CREATE TEMPORARY TABLE pgdump_oid (dummy integer) WITH OIDS");
-       else
-               do_sql_command(g_conn,
-                                          "CREATE TEMPORARY TABLE pgdump_oid (dummy integer)");
-       res = PQexec(g_conn, "INSERT INTO pgdump_oid VALUES (0)");
-       check_sql_result(res, g_conn, "INSERT INTO pgdump_oid VALUES (0)",
-                                        PGRES_COMMAND_OK);
-       max_oid = PQoidValue(res);
-       if (max_oid == 0)
-       {
-               write_msg(NULL, "inserted invalid OID\n");
-               exit_nicely();
-       }
-       PQclear(res);
-       do_sql_command(g_conn, "DROP TABLE pgdump_oid;");
-       if (g_verbose)
-               write_msg(NULL, "maximum system OID is %u\n", max_oid);
-       snprintf(sql, sizeof(sql),
-                        "CREATE TEMPORARY TABLE pgdump_oid (dummy integer) WITH OIDS;\n"
-                        "COPY pgdump_oid WITH OIDS FROM stdin;\n"
-                        "%u\t0\n"
-                        "\\.\n"
-                        "DROP TABLE pgdump_oid;\n",
-                        max_oid);
-
-       ArchiveEntry(fout, nilCatalogId, createDumpId(),
-                                "Max OID", NULL, NULL, "",
-                                false, "<Init>", sql, "", NULL,
-                                NULL, 0,
-                                NULL, NULL);
-}
-
 /*
  * findLastBuiltInOid -
  * find the last built in oid
@@ -7208,7 +7954,7 @@ findLastBuiltinOid_V71(const char *dbname)
 
        resetPQExpBuffer(query);
        appendPQExpBuffer(query, "SELECT datlastsysoid from pg_database where datname = ");
-       appendStringLiteral(query, dbname, true);
+       appendStringLiteralAH(query, dbname, g_fout);
 
        res = PQexec(g_conn, query->data);
        check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
@@ -7248,7 +7994,7 @@ findLastBuiltinOid_V70(void)
        res = PQexec(g_conn,
                                 "SELECT oid FROM pg_class WHERE relname = 'pg_indexes'");
        check_sql_result(res, g_conn,
-                                "SELECT oid FROM pg_class WHERE relname = 'pg_indexes'",
+                                        "SELECT oid FROM pg_class WHERE relname = 'pg_indexes'",
                                         PGRES_TUPLES_OK);
        ntups = PQntuples(res);
        if (ntups < 1)
@@ -7290,12 +8036,12 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
 
        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 "
+                                  "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 "
+                                       "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",
@@ -7335,15 +8081,14 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
        /*
         * The logic we use for restoring sequences is as follows:
         *
-        * Add a basic CREATE SEQUENCE statement (use last_val for start if
-        * called is false, else use min_val for start_val).  Skip this if the
-        * sequence came from a SERIAL column.
+        * 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 SET OWNED command for it.
         *
-        * Add a 'SETVAL(seq, last_val, iscalled)' at restore-time iff we load
-        * data.  We do this for serial sequences too.
+        * Add a 'SETVAL(seq, last_val, iscalled)' as part of a "data" dump.
         */
-
-       if (!dataOnly && !OidIsValid(tbinfo->owning_tab))
+       if (!dataOnly)
        {
                resetPQExpBuffer(delqry);
 
@@ -7384,39 +8129,63 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
 
                ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
                                         tbinfo->dobj.name,
-                                        tbinfo->dobj.namespace->dobj.name, 
+                                        tbinfo->dobj.namespace->dobj.name,
                                         NULL,
-                                        tbinfo->usename,
+                                        tbinfo->rolname,
                                         false, "SEQUENCE", query->data, delqry->data, NULL,
                                         tbinfo->dobj.dependencies, tbinfo->dobj.nDeps,
                                         NULL, NULL);
+
+               /*
+                * If the sequence is owned by a table column, emit the ALTER for it
+                * as a separate TOC entry immediately following the sequence's own
+                * entry.  It's OK to do this rather than using full sorting logic,
+                * because the dependency that tells us it's owned will have forced
+                * the table to be created first.  We can't just include the ALTER
+                * in the TOC entry because it will fail if we haven't reassigned
+                * the sequence owner to match the table's owner.
+                *
+                * We need not schema-qualify the table reference because both
+                * sequence and table must be in the same schema.
+                */
+               if (OidIsValid(tbinfo->owning_tab))
+               {
+                       TableInfo  *owning_tab = findTableByOid(tbinfo->owning_tab);
+
+                       if (owning_tab)
+                       {
+                               resetPQExpBuffer(query);
+                               appendPQExpBuffer(query, "ALTER SEQUENCE %s",
+                                                                 fmtId(tbinfo->dobj.name));
+                               appendPQExpBuffer(query, " OWNED BY %s",
+                                                                 fmtId(owning_tab->dobj.name));
+                               appendPQExpBuffer(query, ".%s;\n",
+                                                                 fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
+
+                               ArchiveEntry(fout, nilCatalogId, createDumpId(),
+                                                        tbinfo->dobj.name,
+                                                        tbinfo->dobj.namespace->dobj.name,
+                                                        NULL,
+                                                        tbinfo->rolname,
+                                                        false, "SEQUENCE OWNED BY", query->data, "", NULL,
+                                                        &(tbinfo->dobj.dumpId), 1,
+                                                        NULL, NULL);
+                       }
+               }
+
+               /* Dump Sequence Comments */
+               resetPQExpBuffer(query);
+               appendPQExpBuffer(query, "SEQUENCE %s", fmtId(tbinfo->dobj.name));
+               dumpComment(fout, query->data,
+                                       tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
+                                       tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
        }
 
        if (!schemaOnly)
        {
-               TableInfo  *owning_tab;
-
                resetPQExpBuffer(query);
                appendPQExpBuffer(query, "SELECT pg_catalog.setval(");
-
-               /*
-                * If this is a SERIAL sequence, then use the
-                * pg_get_serial_sequence function to avoid hard-coding the
-                * sequence name.  Note that this implicitly assumes that the
-                * sequence and its owning table are in the same schema, because
-                * we don't schema-qualify the reference.
-                */
-               if (OidIsValid(tbinfo->owning_tab) &&
-                       (owning_tab = findTableByOid(tbinfo->owning_tab)) != NULL)
-               {
-                       appendPQExpBuffer(query, "pg_catalog.pg_get_serial_sequence(");
-                       appendStringLiteral(query, fmtId(owning_tab->dobj.name), true);
-                       appendPQExpBuffer(query, ", ");
-                       appendStringLiteral(query, owning_tab->attnames[tbinfo->owning_col - 1], true);
-                       appendPQExpBuffer(query, ")");
-               }
-               else
-                       appendStringLiteral(query, fmtId(tbinfo->dobj.name), true);
+               appendStringLiteralAH(query, fmtId(tbinfo->dobj.name), fout);
                appendPQExpBuffer(query, ", %s, %s);\n",
                                                  last, (called ? "true" : "false"));
 
@@ -7424,22 +8193,12 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
                                         tbinfo->dobj.name,
                                         tbinfo->dobj.namespace->dobj.name,
                                         NULL,
-                                        tbinfo->usename,
+                                        tbinfo->rolname,
                                         false, "SEQUENCE SET", query->data, "", NULL,
                                         &(tbinfo->dobj.dumpId), 1,
                                         NULL, NULL);
        }
 
-       if (!dataOnly)
-       {
-               /* Dump Sequence Comments */
-               resetPQExpBuffer(query);
-               appendPQExpBuffer(query, "SEQUENCE %s", fmtId(tbinfo->dobj.name));
-               dumpComment(fout, query->data,
-                                       tbinfo->dobj.namespace->dobj.name, tbinfo->usename,
-                                       tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
-       }
-
        PQclear(res);
 
        destroyPQExpBuffer(query);
@@ -7462,8 +8221,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
        delqry = createPQExpBuffer();
 
        /*
-        * DROP must be fully qualified in case same name appears in
-        * pg_catalog
+        * DROP must be fully qualified in case same name appears in pg_catalog
         */
        appendPQExpBuffer(delqry, "DROP TRIGGER %s ",
                                          fmtId(tginfo->dobj.name));
@@ -7475,12 +8233,12 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
        if (tginfo->tgisconstraint)
        {
                appendPQExpBuffer(query, "CREATE CONSTRAINT TRIGGER ");
-               appendPQExpBuffer(query, fmtId(tginfo->tgconstrname));
+               appendPQExpBufferStr(query, fmtId(tginfo->tgconstrname));
        }
        else
        {
                appendPQExpBuffer(query, "CREATE TRIGGER ");
-               appendPQExpBuffer(query, fmtId(tginfo->dobj.name));
+               appendPQExpBufferStr(query, fmtId(tginfo->dobj.name));
        }
        appendPQExpBuffer(query, "\n    ");
 
@@ -7552,6 +8310,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
        {
                const char *s = p;
 
+               /* Set 'p' to end of arg string. marked by '\000' */
                for (;;)
                {
                        p = strchr(p, '\\');
@@ -7564,20 +8323,27 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
                                exit_nicely();
                        }
                        p++;
-                       if (*p == '\\')
+                       if (*p == '\\')         /* is it '\\'? */
                        {
                                p++;
                                continue;
                        }
-                       if (p[0] == '0' && p[1] == '0' && p[2] == '0')
+                       if (p[0] == '0' && p[1] == '0' && p[2] == '0')          /* is it '\000'? */
                                break;
                }
                p--;
+
                appendPQExpBufferChar(query, '\'');
                while (s < p)
                {
                        if (*s == '\'')
-                               appendPQExpBufferChar(query, '\\');
+                               appendPQExpBufferChar(query, '\'');
+                       /*
+                        *      bytea unconditionally doubles backslashes, so we suppress
+                        *      the doubling for standard_conforming_strings.
+                        */
+                       if (fout->std_strings && *s == '\\' && s[1] == '\\')
+                               s++;
                        appendPQExpBufferChar(query, *s++);
                }
                appendPQExpBufferChar(query, '\'');
@@ -7587,11 +8353,19 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
        }
        appendPQExpBuffer(query, ");\n");
 
+       if (!tginfo->tgenabled)
+       {
+               appendPQExpBuffer(query, "\nALTER TABLE %s ",
+                                                 fmtId(tbinfo->dobj.name));
+               appendPQExpBuffer(query, "DISABLE TRIGGER %s;\n",
+                                                 fmtId(tginfo->dobj.name));
+       }
+
        ArchiveEntry(fout, tginfo->dobj.catId, tginfo->dobj.dumpId,
                                 tginfo->dobj.name,
                                 tbinfo->dobj.namespace->dobj.name,
                                 NULL,
-                                tbinfo->usename, false,
+                                tbinfo->rolname, false,
                                 "TRIGGER", query->data, delqry->data, NULL,
                                 tginfo->dobj.dependencies, tginfo->dobj.nDeps,
                                 NULL, NULL);
@@ -7603,7 +8377,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
                                          fmtId(tbinfo->dobj.name));
 
        dumpComment(fout, query->data,
-                               tbinfo->dobj.namespace->dobj.name, tbinfo->usename,
+                               tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                                tginfo->dobj.catId, 0, tginfo->dobj.dumpId);
 
        destroyPQExpBuffer(query);
@@ -7623,10 +8397,8 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
        PQExpBuffer delcmd;
        PGresult   *res;
 
-       /*
-        * Ignore rules for not-to-be-dumped tables
-        */
-       if (tbinfo == NULL || !tbinfo->dump || dataOnly)
+       /* Skip if not to be dumped */
+       if (!rinfo->dobj.dump || dataOnly)
                return;
 
        /*
@@ -7672,8 +8444,7 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
        printfPQExpBuffer(cmd, "%s\n", PQgetvalue(res, 0, 0));
 
        /*
-        * DROP must be fully qualified in case same name appears in
-        * pg_catalog
+        * DROP must be fully qualified in case same name appears in pg_catalog
         */
        appendPQExpBuffer(delcmd, "DROP RULE %s ",
                                          fmtId(rinfo->dobj.name));
@@ -7686,7 +8457,7 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
                                 rinfo->dobj.name,
                                 tbinfo->dobj.namespace->dobj.name,
                                 NULL,
-                                tbinfo->usename, false,
+                                tbinfo->rolname, false,
                                 "RULE", cmd->data, delcmd->data, NULL,
                                 rinfo->dobj.dependencies, rinfo->dobj.nDeps,
                                 NULL, NULL);
@@ -7699,7 +8470,7 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
                                          fmtId(tbinfo->dobj.name));
        dumpComment(fout, query->data,
                                tbinfo->dobj.namespace->dobj.name,
-                               tbinfo->usename,
+                               tbinfo->rolname,
                                rinfo->dobj.catId, 0, rinfo->dobj.dumpId);
 
        PQclear(res);
@@ -7758,8 +8529,8 @@ getDependencies(void)
 
        /*
         * Since we ordered the SELECT by referencing ID, we can expect that
-        * multiple entries for the same object will appear together; this
-        * saves on searches.
+        * multiple entries for the same object will appear together; this saves
+        * on searches.
         */
        dobj = NULL;
 
@@ -7781,9 +8552,8 @@ getDependencies(void)
                        dobj = findObjectByCatalogId(objId);
 
                /*
-                * Failure to find objects mentioned in pg_depend is not
-                * unexpected, since for example we don't collect info about TOAST
-                * tables.
+                * Failure to find objects mentioned in pg_depend is not unexpected,
+                * since for example we don't collect info about TOAST tables.
                 */
                if (dobj == NULL)
                {
@@ -7807,16 +8577,17 @@ getDependencies(void)
 
                /*
                 * Ordinarily, table rowtypes have implicit dependencies on their
-                * tables.  However, for a composite type the implicit dependency
-                * goes the other way in pg_depend; which is the right thing for
-                * DROP but it doesn't produce the dependency ordering we need.
-                * So in that one case, we reverse the direction of the dependency.
+                * tables.      However, for a composite type the implicit dependency goes
+                * the other way in pg_depend; which is the right thing for DROP but
+                * it doesn't produce the dependency ordering we need. So in that one
+                * case, we reverse the direction of the dependency.
                 */
                if (deptype == 'i' &&
                        dobj->objType == DO_TABLE &&
                        refdobj->objType == DO_TYPE)
                        addObjectDependency(refdobj, dobj->dumpId);
-               else                                    /* normal case */
+               else
+                       /* normal case */
                        addObjectDependency(dobj, refdobj->dumpId);
        }
 
@@ -7995,8 +8766,8 @@ myFormatType(const char *typname, int32 typmod)
        }
 
        /*
-        * char is an internal single-byte data type; Let's make sure we force
-        * it through with quotes. - thomas 1998-12-13
+        * char is an internal single-byte data type; Let's make sure we force it
+        * through with quotes. - thomas 1998-12-13
         */
        else if (strcmp(typname, "char") == 0)
                appendPQExpBuffer(buf, "\"char\"");