X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=src%2Fbin%2Fpg_dump%2Fpg_dump.c;h=c2bb6161b214811d38af43f480e5bb517d4db0c1;hb=f0fedfe82c8adea78354652d67c027a1a8fbce88;hp=01c63b133483c0d6a6bbd66490631bc997da9b36;hpb=5b6d08cd2992922b667564a49f19580f11676050;p=postgresql diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 01c63b1334..c2bb6161b2 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -4,7 +4,7 @@ * pg_dump is a utility for dumping out a postgres database * into a script file. * - * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, 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 @@ -63,10 +63,6 @@ #include "dumputils.h" #include "parallel.h" -extern char *optarg; -extern int optind, - opterr; - typedef struct { @@ -90,11 +86,11 @@ bool g_verbose; /* User wants verbose narration of our * activities. */ /* various user-settable parameters */ -bool schemaOnly; -bool dataOnly; -int dumpSections; /* bitmask of chosen sections */ -bool aclsSkip; -const char *lockWaitTimeout; +static bool schemaOnly; +static bool dataOnly; +static int dumpSections; /* bitmask of chosen sections */ +static bool aclsSkip; +static const char *lockWaitTimeout; /* subquery used to convert user ID (eg, datdba) to user name */ static const char *username_subquery; @@ -136,6 +132,7 @@ static int binary_upgrade = 0; static int disable_dollar_quoting = 0; static int dump_inserts = 0; static int column_inserts = 0; +static int if_exists = 0; static int no_security_labels = 0; static int no_synchronized_snapshots = 0; static int no_unlogged_table_data = 0; @@ -238,9 +235,9 @@ static char *format_function_arguments_old(Archive *fout, char **argnames); static char *format_function_signature(Archive *fout, FuncInfo *finfo, bool honor_quotes); -static const char *convertRegProcReference(Archive *fout, +static char *convertRegProcReference(Archive *fout, const char *proc); -static const char *convertOperatorReference(Archive *fout, const char *opr); +static char *convertOperatorReference(Archive *fout, const char *opr); static const char *convertTSFunction(Archive *fout, Oid funcOid); static Oid findLastBuiltinOid_V71(Archive *fout, const char *); static Oid findLastBuiltinOid_V70(Archive *fout); @@ -349,6 +346,7 @@ main(int argc, char **argv) {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1}, {"disable-triggers", no_argument, &disable_triggers, 1}, {"exclude-table-data", required_argument, NULL, 4}, + {"if-exists", no_argument, &if_exists, 1}, {"inserts", no_argument, &dump_inserts, 1}, {"lock-wait-timeout", required_argument, NULL, 2}, {"no-tablespaces", no_argument, &outputNoTablespaces, 1}, @@ -402,7 +400,7 @@ main(int argc, char **argv) } } - while ((c = getopt_long(argc, argv, "abcCd:E:f:F:h:ij:K:n:N:oOp:RsS:t:T:U:vwWxZ:", + while ((c = getopt_long(argc, argv, "abcCd:E:f:F:h:ij:n:N:oOp:RsS:t:T:U:vwWxZ:", long_options, &optindex)) != -1) { switch (c) @@ -565,10 +563,16 @@ main(int argc, char **argv) dump_inserts = 1; if (dataOnly && schemaOnly) - exit_horribly(NULL, "options -s/--schema-only and -a/--data-only cannot be used together\n"); + { + write_msg(NULL, "options -s/--schema-only and -a/--data-only cannot be used together\n"); + exit_nicely(1); + } if (dataOnly && outputClean) - exit_horribly(NULL, "options -c/--clean and -a/--data-only cannot be used together\n"); + { + write_msg(NULL, "options -c/--clean and -a/--data-only cannot be used together\n"); + exit_nicely(1); + } if (dump_inserts && oids) { @@ -577,6 +581,9 @@ main(int argc, char **argv) exit_nicely(1); } + if (if_exists && !outputClean) + exit_horribly(NULL, "option --if-exists requires -c/--clean option\n"); + /* Identify archive format to emit */ archiveFormat = parseArchiveFormat(format, &archiveMode); @@ -809,6 +816,7 @@ main(int argc, char **argv) ropt->dropSchema = outputClean; ropt->dataOnly = dataOnly; ropt->schemaOnly = schemaOnly; + ropt->if_exists = if_exists; ropt->dumpSections = dumpSections; ropt->aclsSkip = aclsSkip; ropt->superuser = outputSuperuser; @@ -890,6 +898,7 @@ help(const char *progname) printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n")); printf(_(" --disable-triggers disable triggers during data-only restore\n")); printf(_(" --exclude-table-data=TABLE do NOT dump data for the named table(s)\n")); + printf(_(" --if-exists use IF EXISTS when dropping objects\n")); printf(_(" --inserts dump data as INSERT commands, rather than COPY\n")); printf(_(" --no-security-labels do not dump security label assignments\n")); printf(_(" --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n")); @@ -1033,7 +1042,7 @@ setup_connection(Archive *AH, const char *dumpencoding, char *use_role) { PQExpBuffer query = createPQExpBuffer(); - appendPQExpBuffer(query, "SET TRANSACTION SNAPSHOT "); + appendPQExpBufferStr(query, "SET TRANSACTION SNAPSHOT "); appendStringLiteralConn(query, AH->sync_snapshot_id, conn); ExecuteSqlStatement(AH, query->data); destroyPQExpBuffer(query); @@ -1127,7 +1136,7 @@ expand_schema_name_patterns(Archive *fout, for (cell = patterns->head; cell; cell = cell->next) { if (cell != patterns->head) - appendPQExpBuffer(query, "UNION ALL\n"); + appendPQExpBufferStr(query, "UNION ALL\n"); appendPQExpBuffer(query, "SELECT oid FROM pg_catalog.pg_namespace n\n"); processSQLNamePattern(GetConnection(fout), query, cell->val, false, @@ -1171,7 +1180,7 @@ expand_table_name_patterns(Archive *fout, for (cell = patterns->head; cell; cell = cell->next) { if (cell != patterns->head) - appendPQExpBuffer(query, "UNION ALL\n"); + appendPQExpBufferStr(query, "UNION ALL\n"); appendPQExpBuffer(query, "SELECT c.oid" "\nFROM pg_catalog.pg_class c" @@ -1550,6 +1559,7 @@ dumpTableData_insert(Archive *fout, void *dcontext) TableInfo *tbinfo = tdinfo->tdtable; const char *classname = tbinfo->dobj.name; PQExpBuffer q = createPQExpBuffer(); + PQExpBuffer insertStmt = NULL; PGresult *res; int tuple; int nfields; @@ -1591,34 +1601,57 @@ dumpTableData_insert(Archive *fout, void *dcontext) nfields = PQnfields(res); for (tuple = 0; tuple < PQntuples(res); tuple++) { - archprintf(fout, "INSERT INTO %s ", fmtId(classname)); - if (nfields == 0) + /* + * First time through, we build as much of the INSERT statement as + * possible in "insertStmt", which we can then just print for each + * line. If the table happens to have zero columns then this will + * be a complete statement, otherwise it will end in "VALUES(" and + * be ready to have the row's column values appended. + */ + if (insertStmt == NULL) { + insertStmt = createPQExpBuffer(); + appendPQExpBuffer(insertStmt, "INSERT INTO %s ", + fmtId(classname)); + /* corner case for zero-column table */ - archprintf(fout, "DEFAULT VALUES;\n"); - continue; - } - if (column_inserts) - { - resetPQExpBuffer(q); - appendPQExpBuffer(q, "("); - for (field = 0; field < nfields; field++) + if (nfields == 0) + { + appendPQExpBufferStr(insertStmt, "DEFAULT VALUES;\n"); + } + else { - if (field > 0) - appendPQExpBuffer(q, ", "); - appendPQExpBufferStr(q, fmtId(PQfname(res, field))); + /* append the list of column names if required */ + if (column_inserts) + { + appendPQExpBufferStr(insertStmt, "("); + for (field = 0; field < nfields; field++) + { + if (field > 0) + appendPQExpBufferStr(insertStmt, ", "); + appendPQExpBufferStr(insertStmt, + fmtId(PQfname(res, field))); + } + appendPQExpBufferStr(insertStmt, ") "); + } + + appendPQExpBufferStr(insertStmt, "VALUES ("); } - appendPQExpBuffer(q, ") "); - archputs(q->data, fout); } - archprintf(fout, "VALUES ("); + + archputs(insertStmt->data, fout); + + /* if it is zero-column table then we're done */ + if (nfields == 0) + continue; + for (field = 0; field < nfields; field++) { if (field > 0) - archprintf(fout, ", "); + archputs(", ", fout); if (PQgetisnull(res, tuple, field)) { - archprintf(fout, "NULL"); + archputs("NULL", fout); continue; } @@ -1647,7 +1680,7 @@ dumpTableData_insert(Archive *fout, void *dcontext) const char *s = PQgetvalue(res, tuple, field); if (strspn(s, "0123456789 +-eE.") == strlen(s)) - archprintf(fout, "%s", s); + archputs(s, fout); else archprintf(fout, "'%s'", s); } @@ -1661,9 +1694,9 @@ dumpTableData_insert(Archive *fout, void *dcontext) case BOOLOID: if (strcmp(PQgetvalue(res, tuple, field), "t") == 0) - archprintf(fout, "true"); + archputs("true", fout); else - archprintf(fout, "false"); + archputs("false", fout); break; default: @@ -1676,7 +1709,7 @@ dumpTableData_insert(Archive *fout, void *dcontext) break; } } - archprintf(fout, ");\n"); + archputs(");\n", fout); } if (PQntuples(res) <= 0) @@ -1687,11 +1720,14 @@ dumpTableData_insert(Archive *fout, void *dcontext) PQclear(res); } - archprintf(fout, "\n\n"); + archputs("\n\n", fout); ExecuteSqlStatement(fout, "CLOSE _pg_dump_cursor"); destroyPQExpBuffer(q); + if (insertStmt != NULL) + destroyPQExpBuffer(insertStmt); + return 1; } @@ -1893,32 +1929,32 @@ buildMatViewRefreshDependencies(Archive *fout) query = createPQExpBuffer(); - appendPQExpBuffer(query, "with recursive w as " + appendPQExpBufferStr(query, "WITH RECURSIVE w AS " "( " - "select d1.objid, d2.refobjid, c2.relkind as refrelkind " - "from pg_depend d1 " - "join pg_class c1 on c1.oid = d1.objid " - "and c1.relkind = 'm' " - "join pg_rewrite r1 on r1.ev_class = d1.objid " - "join pg_depend d2 on d2.classid = 'pg_rewrite'::regclass " - "and d2.objid = r1.oid " - "and d2.refobjid <> d1.objid " - "join pg_class c2 on c2.oid = d2.refobjid " - "and c2.relkind in ('m','v') " - "where d1.classid = 'pg_class'::regclass " - "union " - "select w.objid, d3.refobjid, c3.relkind " - "from w " - "join pg_rewrite r3 on r3.ev_class = w.refobjid " - "join pg_depend d3 on d3.classid = 'pg_rewrite'::regclass " - "and d3.objid = r3.oid " - "and d3.refobjid <> w.refobjid " - "join pg_class c3 on c3.oid = d3.refobjid " - "and c3.relkind in ('m','v') " + "SELECT d1.objid, d2.refobjid, c2.relkind AS refrelkind " + "FROM pg_depend d1 " + "JOIN pg_class c1 ON c1.oid = d1.objid " + "AND c1.relkind = 'm' " + "JOIN pg_rewrite r1 ON r1.ev_class = d1.objid " + "JOIN pg_depend d2 ON d2.classid = 'pg_rewrite'::regclass " + "AND d2.objid = r1.oid " + "AND d2.refobjid <> d1.objid " + "JOIN pg_class c2 ON c2.oid = d2.refobjid " + "AND c2.relkind IN ('m','v') " + "WHERE d1.classid = 'pg_class'::regclass " + "UNION " + "SELECT w.objid, d3.refobjid, c3.relkind " + "FROM w " + "JOIN pg_rewrite r3 ON r3.ev_class = w.refobjid " + "JOIN pg_depend d3 ON d3.classid = 'pg_rewrite'::regclass " + "AND d3.objid = r3.oid " + "AND d3.refobjid <> w.refobjid " + "JOIN pg_class c3 ON c3.oid = d3.refobjid " + "AND c3.relkind IN ('m','v') " ") " - "select 'pg_class'::regclass::oid as classid, objid, refobjid " - "from w " - "where refrelkind = 'm'"); + "SELECT 'pg_class'::regclass::oid AS classid, objid, refobjid " + "FROM w " + "WHERE refrelkind = 'm'"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -2233,33 +2269,33 @@ dumpDatabase(Archive *fout) fmtId(datname)); if (strlen(encoding) > 0) { - appendPQExpBuffer(creaQry, " ENCODING = "); + appendPQExpBufferStr(creaQry, " ENCODING = "); appendStringLiteralAH(creaQry, encoding, fout); } if (strlen(collate) > 0) { - appendPQExpBuffer(creaQry, " LC_COLLATE = "); + appendPQExpBufferStr(creaQry, " LC_COLLATE = "); appendStringLiteralAH(creaQry, collate, fout); } if (strlen(ctype) > 0) { - appendPQExpBuffer(creaQry, " LC_CTYPE = "); + appendPQExpBufferStr(creaQry, " LC_CTYPE = "); appendStringLiteralAH(creaQry, ctype, fout); } if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0) appendPQExpBuffer(creaQry, " TABLESPACE = %s", fmtId(tablespace)); - appendPQExpBuffer(creaQry, ";\n"); + appendPQExpBufferStr(creaQry, ";\n"); if (binary_upgrade) { - appendPQExpBuffer(creaQry, "\n-- For binary upgrade, set datfrozenxid.\n"); + appendPQExpBufferStr(creaQry, "\n-- For binary upgrade, set datfrozenxid.\n"); appendPQExpBuffer(creaQry, "UPDATE pg_catalog.pg_database\n" "SET datfrozenxid = '%u'\n" "WHERE datname = ", frozenxid); appendStringLiteralAH(creaQry, datname, fout); - appendPQExpBuffer(creaQry, ";\n"); + appendPQExpBufferStr(creaQry, ";\n"); } @@ -2309,7 +2345,7 @@ dumpDatabase(Archive *fout) i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid"); - appendPQExpBuffer(loOutQry, "\n-- For binary upgrade, set pg_largeobject.relfrozenxid\n"); + appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, set pg_largeobject.relfrozenxid\n"); appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n" "SET relfrozenxid = '%u'\n" "WHERE oid = %u;\n", @@ -2341,7 +2377,7 @@ dumpDatabase(Archive *fout) i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid"); - appendPQExpBuffer(loOutQry, "\n-- For binary upgrade, set pg_largeobject_metadata.relfrozenxid\n"); + appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, set pg_largeobject_metadata.relfrozenxid\n"); appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n" "SET relfrozenxid = '%u'\n" "WHERE oid = %u;\n", @@ -2380,7 +2416,7 @@ dumpDatabase(Archive *fout) */ appendPQExpBuffer(dbQry, "COMMENT ON DATABASE %s IS ", fmtId(datname)); appendStringLiteralAH(dbQry, comment, fout); - appendPQExpBuffer(dbQry, ";\n"); + appendPQExpBufferStr(dbQry, ";\n"); ArchiveEntry(fout, dbCatId, createDumpId(), datname, NULL, NULL, dba, false, "COMMENT", SECTION_NONE, @@ -2433,9 +2469,9 @@ dumpEncoding(Archive *AH) if (g_verbose) write_msg(NULL, "saving encoding = %s\n", encname); - appendPQExpBuffer(qry, "SET client_encoding = "); + appendPQExpBufferStr(qry, "SET client_encoding = "); appendStringLiteralAH(qry, encname, AH); - appendPQExpBuffer(qry, ";\n"); + appendPQExpBufferStr(qry, ";\n"); ArchiveEntry(AH, nilCatalogId, createDumpId(), "ENCODING", NULL, NULL, "", @@ -2503,13 +2539,13 @@ getBlobs(Archive *fout) " FROM pg_largeobject_metadata", username_subquery); else if (fout->remoteVersion >= 70100) - appendPQExpBuffer(blobQry, - "SELECT DISTINCT loid, NULL::oid, NULL::oid" - " FROM pg_largeobject"); + appendPQExpBufferStr(blobQry, + "SELECT DISTINCT loid, NULL::oid, NULL::oid" + " FROM pg_largeobject"); else - appendPQExpBuffer(blobQry, - "SELECT oid, NULL::oid, NULL::oid" - " FROM pg_class WHERE relkind = 'l'"); + appendPQExpBufferStr(blobQry, + "SELECT oid, NULL::oid, NULL::oid" + " FROM pg_class WHERE relkind = 'l'"); res = ExecuteSqlQuery(fout, blobQry->data, PGRES_TUPLES_OK); @@ -2696,7 +2732,7 @@ binary_upgrade_set_type_oids_by_type_oid(Archive *fout, PGresult *upgrade_res; Oid pg_type_array_oid; - appendPQExpBuffer(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n"); + appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n"); appendPQExpBuffer(upgrade_buffer, "SELECT binary_upgrade.set_next_pg_type_oid('%u'::pg_catalog.oid);\n\n", pg_type_oid); @@ -2714,7 +2750,7 @@ binary_upgrade_set_type_oids_by_type_oid(Archive *fout, if (OidIsValid(pg_type_array_oid)) { - appendPQExpBuffer(upgrade_buffer, + appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type array oid\n"); appendPQExpBuffer(upgrade_buffer, "SELECT binary_upgrade.set_next_array_pg_type_oid('%u'::pg_catalog.oid);\n\n", @@ -2757,7 +2793,7 @@ binary_upgrade_set_type_oids_by_rel_oid(Archive *fout, Oid pg_type_toast_oid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "trel"))); - appendPQExpBuffer(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type toast oid\n"); + appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type toast oid\n"); appendPQExpBuffer(upgrade_buffer, "SELECT binary_upgrade.set_next_toast_pg_type_oid('%u'::pg_catalog.oid);\n\n", pg_type_toast_oid); @@ -2793,8 +2829,8 @@ binary_upgrade_set_pg_class_oids(Archive *fout, pg_class_reltoastrelid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "reltoastrelid"))); pg_index_indexrelid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "indexrelid"))); - appendPQExpBuffer(upgrade_buffer, - "\n-- For binary upgrade, must preserve pg_class oids\n"); + appendPQExpBufferStr(upgrade_buffer, + "\n-- For binary upgrade, must preserve pg_class oids\n"); if (!is_index) { @@ -2828,7 +2864,7 @@ binary_upgrade_set_pg_class_oids(Archive *fout, "SELECT binary_upgrade.set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n", pg_class_oid); - appendPQExpBuffer(upgrade_buffer, "\n"); + appendPQExpBufferChar(upgrade_buffer, '\n'); PQclear(upgrade_res); destroyPQExpBuffer(upgrade_query); @@ -2865,7 +2901,7 @@ binary_upgrade_extension_member(PQExpBuffer upgrade_buffer, if (extobj == NULL) exit_horribly(NULL, "could not find parent extension for %s\n", objlabel); - appendPQExpBuffer(upgrade_buffer, + appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, handle extension membership the hard way\n"); appendPQExpBuffer(upgrade_buffer, "ALTER EXTENSION %s ADD %s;\n", fmtId(extobj->name), @@ -3052,10 +3088,10 @@ getExtensions(Archive *fout, int *numExtensions) /* Make sure we are in proper schema */ selectSourceSchema(fout, "pg_catalog"); - appendPQExpBuffer(query, "SELECT x.tableoid, x.oid, " - "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition " - "FROM pg_extension x " - "JOIN pg_namespace n ON n.oid = x.extnamespace"); + appendPQExpBufferStr(query, "SELECT x.tableoid, x.oid, " + "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition " + "FROM pg_extension x " + "JOIN pg_namespace n ON n.oid = x.extnamespace"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -3575,7 +3611,7 @@ getConversions(Archive *fout, int *numConversions) PGresult *res; int ntups; int i; - PQExpBuffer query = createPQExpBuffer(); + PQExpBuffer query; ConvInfo *convinfo; int i_tableoid; int i_oid; @@ -3590,6 +3626,8 @@ getConversions(Archive *fout, int *numConversions) return NULL; } + query = createPQExpBuffer(); + /* * find all conversions, including builtin conversions; we filter out * system-defined conversions at dump-out time. @@ -3680,19 +3718,19 @@ getOpclasses(Archive *fout, int *numOpclasses) } else if (fout->remoteVersion >= 70100) { - appendPQExpBuffer(query, "SELECT tableoid, oid, opcname, " - "0::oid AS opcnamespace, " - "''::name AS rolname " - "FROM pg_opclass"); + appendPQExpBufferStr(query, "SELECT tableoid, oid, opcname, " + "0::oid AS opcnamespace, " + "''::name AS rolname " + "FROM pg_opclass"); } else { - appendPQExpBuffer(query, "SELECT " - "(SELECT oid FROM pg_class WHERE relname = 'pg_opclass') AS tableoid, " - "oid, opcname, " - "0::oid AS opcnamespace, " - "''::name AS rolname " - "FROM pg_opclass"); + appendPQExpBufferStr(query, "SELECT " + "(SELECT oid FROM pg_class WHERE relname = 'pg_opclass') AS tableoid, " + "oid, opcname, " + "0::oid AS opcnamespace, " + "''::name AS rolname " + "FROM pg_opclass"); } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -3875,13 +3913,13 @@ getAggregates(Archive *fout, int *numAggs) "WHERE nspname = 'pg_catalog')", username_subquery); if (binary_upgrade && fout->remoteVersion >= 90100) - appendPQExpBuffer(query, - " OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBuffer(query, ")"); + appendPQExpBufferStr(query, + " OR EXISTS(SELECT 1 FROM pg_depend WHERE " + "classid = 'pg_proc'::regclass AND " + "objid = p.oid AND " + "refclassid = 'pg_extension'::regclass AND " + "deptype = 'e')"); + appendPQExpBufferChar(query, ')'); } else if (fout->remoteVersion >= 80200) { @@ -4067,18 +4105,18 @@ getFuncs(Archive *fout, int *numFuncs) "WHERE nspname = 'pg_catalog')", username_subquery); if (fout->remoteVersion >= 90200) - appendPQExpBuffer(query, - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')"); + appendPQExpBufferStr(query, + "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " + "WHERE classid = 'pg_proc'::regclass AND " + "objid = p.oid AND deptype = 'i')"); if (binary_upgrade && fout->remoteVersion >= 90100) - appendPQExpBuffer(query, - "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " - "classid = 'pg_proc'::regclass AND " - "objid = p.oid AND " - "refclassid = 'pg_extension'::regclass AND " - "deptype = 'e')"); - appendPQExpBuffer(query, ")"); + appendPQExpBufferStr(query, + "\n OR EXISTS(SELECT 1 FROM pg_depend WHERE " + "classid = 'pg_proc'::regclass AND " + "objid = p.oid AND " + "refclassid = 'pg_extension'::regclass AND " + "deptype = 'e')"); + appendPQExpBufferChar(query, ')'); } else if (fout->remoteVersion >= 70300) { @@ -4221,6 +4259,7 @@ getTables(Archive *fout, int *numTables) int i_toastfrozenxid; int i_relpersistence; int i_relispopulated; + int i_relreplident; int i_owning_tab; int i_owning_col; int i_reltablespace; @@ -4253,7 +4292,46 @@ getTables(Archive *fout, int *numTables) * we cannot correctly identify inherited columns, owned sequences, etc. */ - if (fout->remoteVersion >= 90300) + if (fout->remoteVersion >= 90400) + { + /* + * Left join to pick up dependency info linking sequences to their + * owning column, if any (note this dependency is AUTO as of 8.2) + */ + appendPQExpBuffer(query, + "SELECT c.tableoid, c.oid, c.relname, " + "c.relacl, c.relkind, c.relnamespace, " + "(%s c.relowner) AS rolname, " + "c.relchecks, c.relhastriggers, " + "c.relhasindex, c.relhasrules, c.relhasoids, " + "c.relfrozenxid, tc.oid AS toid, " + "tc.relfrozenxid AS tfrozenxid, " + "c.relpersistence, c.relispopulated, " + "c.relreplident, c.relpages, " + "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, " + "d.refobjid AS owning_tab, " + "d.refobjsubid AS owning_col, " + "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, " + "array_to_string(array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded'), ', ') AS reloptions, " + "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " + "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, " + "array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_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 = 'a') " + "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid) " + "WHERE c.relkind in ('%c', '%c', '%c', '%c', '%c', '%c') " + "ORDER BY c.oid", + username_subquery, + RELKIND_SEQUENCE, + RELKIND_RELATION, RELKIND_SEQUENCE, + RELKIND_VIEW, RELKIND_COMPOSITE_TYPE, + RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE); + } + else if (fout->remoteVersion >= 90300) { /* * Left join to pick up dependency info linking sequences to their @@ -4268,7 +4346,7 @@ getTables(Archive *fout, int *numTables) "c.relfrozenxid, tc.oid AS toid, " "tc.relfrozenxid AS tfrozenxid, " "c.relpersistence, c.relispopulated, " - "c.relpages, " + "'d' AS relreplident, c.relpages, " "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, " "d.refobjid AS owning_tab, " "d.refobjsubid AS owning_col, " @@ -4307,7 +4385,7 @@ getTables(Archive *fout, int *numTables) "c.relfrozenxid, tc.oid AS toid, " "tc.relfrozenxid AS tfrozenxid, " "c.relpersistence, 't' as relispopulated, " - "c.relpages, " + "'d' AS relreplident, c.relpages, " "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, " "d.refobjid AS owning_tab, " "d.refobjsubid AS owning_col, " @@ -4344,7 +4422,7 @@ getTables(Archive *fout, int *numTables) "c.relfrozenxid, tc.oid AS toid, " "tc.relfrozenxid AS tfrozenxid, " "'p' AS relpersistence, 't' as relispopulated, " - "c.relpages, " + "'d' AS relreplident, c.relpages, " "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, " "d.refobjid AS owning_tab, " "d.refobjsubid AS owning_col, " @@ -4380,7 +4458,7 @@ getTables(Archive *fout, int *numTables) "c.relfrozenxid, tc.oid AS toid, " "tc.relfrozenxid AS tfrozenxid, " "'p' AS relpersistence, 't' as relispopulated, " - "c.relpages, " + "'d' AS relreplident, c.relpages, " "NULL AS reloftype, " "d.refobjid AS owning_tab, " "d.refobjsubid AS owning_col, " @@ -4416,7 +4494,7 @@ getTables(Archive *fout, int *numTables) "c.relfrozenxid, tc.oid AS toid, " "tc.relfrozenxid AS tfrozenxid, " "'p' AS relpersistence, 't' as relispopulated, " - "c.relpages, " + "'d' AS relreplident, c.relpages, " "NULL AS reloftype, " "d.refobjid AS owning_tab, " "d.refobjsubid AS owning_col, " @@ -4453,7 +4531,7 @@ getTables(Archive *fout, int *numTables) "0 AS toid, " "0 AS tfrozenxid, " "'p' AS relpersistence, 't' as relispopulated, " - "relpages, " + "'d' AS relreplident, relpages, " "NULL AS reloftype, " "d.refobjid AS owning_tab, " "d.refobjsubid AS owning_col, " @@ -4489,7 +4567,7 @@ getTables(Archive *fout, int *numTables) "0 AS toid, " "0 AS tfrozenxid, " "'p' AS relpersistence, 't' as relispopulated, " - "relpages, " + "'d' AS relreplident, relpages, " "NULL AS reloftype, " "d.refobjid AS owning_tab, " "d.refobjsubid AS owning_col, " @@ -4521,7 +4599,7 @@ getTables(Archive *fout, int *numTables) "0 AS toid, " "0 AS tfrozenxid, " "'p' AS relpersistence, 't' as relispopulated, " - "relpages, " + "'d' AS relreplident, relpages, " "NULL AS reloftype, " "NULL::oid AS owning_tab, " "NULL::int4 AS owning_col, " @@ -4548,7 +4626,7 @@ getTables(Archive *fout, int *numTables) "0 AS toid, " "0 AS tfrozenxid, " "'p' AS relpersistence, 't' as relispopulated, " - "relpages, " + "'d' AS relreplident, relpages, " "NULL AS reloftype, " "NULL::oid AS owning_tab, " "NULL::int4 AS owning_col, " @@ -4585,7 +4663,7 @@ getTables(Archive *fout, int *numTables) "0 AS toid, " "0 AS tfrozenxid, " "'p' AS relpersistence, 't' as relispopulated, " - "0 AS relpages, " + "'d' AS relreplident, 0 AS relpages, " "NULL AS reloftype, " "NULL::oid AS owning_tab, " "NULL::int4 AS owning_col, " @@ -4634,6 +4712,7 @@ getTables(Archive *fout, int *numTables) i_toastfrozenxid = PQfnumber(res, "tfrozenxid"); i_relpersistence = PQfnumber(res, "relpersistence"); i_relispopulated = PQfnumber(res, "relispopulated"); + i_relreplident = PQfnumber(res, "relreplident"); i_relpages = PQfnumber(res, "relpages"); i_owning_tab = PQfnumber(res, "owning_tab"); i_owning_col = PQfnumber(res, "owning_col"); @@ -4653,7 +4732,7 @@ getTables(Archive *fout, int *numTables) * applied to other things too. */ resetPQExpBuffer(query); - appendPQExpBuffer(query, "SET statement_timeout = "); + appendPQExpBufferStr(query, "SET statement_timeout = "); appendStringLiteralConn(query, lockWaitTimeout, GetConnection(fout)); ExecuteSqlStatement(fout, query->data); } @@ -4678,6 +4757,7 @@ getTables(Archive *fout, int *numTables) tblinfo[i].hastriggers = (strcmp(PQgetvalue(res, i, i_relhastriggers), "t") == 0); tblinfo[i].hasoids = (strcmp(PQgetvalue(res, i, i_relhasoids), "t") == 0); tblinfo[i].relispopulated = (strcmp(PQgetvalue(res, i, i_relispopulated), "t") == 0); + tblinfo[i].relreplident = *(PQgetvalue(res, i, i_relreplident)); tblinfo[i].relpages = atoi(PQgetvalue(res, i, i_relpages)); tblinfo[i].frozenxid = atooid(PQgetvalue(res, i, i_relfrozenxid)); tblinfo[i].toast_oid = atooid(PQgetvalue(res, i, i_toastoid)); @@ -4716,6 +4796,8 @@ getTables(Archive *fout, int *numTables) selectDumpableTable(&tblinfo[i]); tblinfo[i].interesting = tblinfo[i].dobj.dump; + tblinfo[i].postponed_def = false; /* might get set during sort */ + /* * Read-lock target tables to make sure they aren't DROPPED or altered * in schema before we get around to dumping them. @@ -4814,7 +4896,7 @@ getInherits(Archive *fout, int *numInherits) /* find all the inheritance information */ - appendPQExpBuffer(query, "SELECT inhrelid, inhparent FROM pg_inherits"); + appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -4863,6 +4945,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) i_indnkeys, i_indkey, i_indisclustered, + i_indisreplident, i_contype, i_conname, i_condeferrable, @@ -4909,7 +4992,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) * is not. */ resetPQExpBuffer(query); - if (fout->remoteVersion >= 90000) + if (fout->remoteVersion >= 90400) { /* * the test on indisready is necessary in 9.2, and harmless in @@ -4921,7 +5004,38 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, " "t.relnatts AS indnkeys, " "i.indkey, i.indisclustered, " - "t.relpages, " + "i.indisreplident, t.relpages, " + "c.contype, c.conname, " + "c.condeferrable, c.condeferred, " + "c.tableoid AS contableoid, " + "c.oid AS conoid, " + "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, " + "(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_constraint c " + "ON (i.indrelid = c.conrelid AND " + "i.indexrelid = c.conindid AND " + "c.contype IN ('p','u','x')) " + "WHERE i.indrelid = '%u'::pg_catalog.oid " + "AND i.indisvalid AND i.indisready " + "ORDER BY indexname", + tbinfo->dobj.catId.oid); + } + else if (fout->remoteVersion >= 90000) + { + /* + * the test on indisready is necessary in 9.2, and harmless in + * earlier/later versions + */ + 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, " + "false AS indisreplident, t.relpages, " "c.contype, c.conname, " "c.condeferrable, c.condeferred, " "c.tableoid AS contableoid, " @@ -4948,7 +5062,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, " "t.relnatts AS indnkeys, " "i.indkey, i.indisclustered, " - "t.relpages, " + "false AS indisreplident, t.relpages, " "c.contype, c.conname, " "c.condeferrable, c.condeferred, " "c.tableoid AS contableoid, " @@ -4978,7 +5092,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, " "t.relnatts AS indnkeys, " "i.indkey, i.indisclustered, " - "t.relpages, " + "false AS indisreplident, t.relpages, " "c.contype, c.conname, " "c.condeferrable, c.condeferred, " "c.tableoid AS contableoid, " @@ -5007,7 +5121,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, " "t.relnatts AS indnkeys, " "i.indkey, i.indisclustered, " - "t.relpages, " + "false AS indisreplident, t.relpages, " "c.contype, c.conname, " "c.condeferrable, c.condeferred, " "c.tableoid AS contableoid, " @@ -5036,7 +5150,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "pg_get_indexdef(i.indexrelid) AS indexdef, " "t.relnatts AS indnkeys, " "i.indkey, false AS indisclustered, " - "t.relpages, " + "false AS indisreplident, t.relpages, " "CASE WHEN i.indisprimary THEN 'p'::char " "ELSE '0'::char END AS contype, " "t.relname AS conname, " @@ -5063,7 +5177,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "pg_get_indexdef(i.indexrelid) AS indexdef, " "t.relnatts AS indnkeys, " "i.indkey, false AS indisclustered, " - "t.relpages, " + "false AS indisreplident, t.relpages, " "CASE WHEN i.indisprimary THEN 'p'::char " "ELSE '0'::char END AS contype, " "t.relname AS conname, " @@ -5092,6 +5206,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) i_indnkeys = PQfnumber(res, "indnkeys"); i_indkey = PQfnumber(res, "indkey"); i_indisclustered = PQfnumber(res, "indisclustered"); + i_indisreplident = PQfnumber(res, "indisreplident"); i_relpages = PQfnumber(res, "relpages"); i_contype = PQfnumber(res, "contype"); i_conname = PQfnumber(res, "conname"); @@ -5135,6 +5250,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) parseOidArray(PQgetvalue(res, j, i_indkey), indxinfo[j].indkeys, INDEX_MAX_KEYS); indxinfo[j].indisclustered = (PQgetvalue(res, j, i_indisclustered)[0] == 't'); + indxinfo[j].indisreplident = (PQgetvalue(res, j, i_indisreplident)[0] == 't'); indxinfo[j].relpages = atoi(PQgetvalue(res, j, i_relpages)); contype = *(PQgetvalue(res, j, i_contype)); @@ -5414,31 +5530,31 @@ getRules(Archive *fout, int *numRules) if (fout->remoteVersion >= 80300) { - appendPQExpBuffer(query, "SELECT " - "tableoid, oid, rulename, " - "ev_class AS ruletable, ev_type, is_instead, " - "ev_enabled " - "FROM pg_rewrite " - "ORDER BY oid"); + appendPQExpBufferStr(query, "SELECT " + "tableoid, oid, rulename, " + "ev_class AS ruletable, ev_type, is_instead, " + "ev_enabled " + "FROM pg_rewrite " + "ORDER BY oid"); } else if (fout->remoteVersion >= 70100) { - appendPQExpBuffer(query, "SELECT " - "tableoid, oid, rulename, " - "ev_class AS ruletable, ev_type, is_instead, " - "'O'::char AS ev_enabled " - "FROM pg_rewrite " - "ORDER BY oid"); + appendPQExpBufferStr(query, "SELECT " + "tableoid, oid, rulename, " + "ev_class AS ruletable, ev_type, is_instead, " + "'O'::char AS ev_enabled " + "FROM pg_rewrite " + "ORDER BY oid"); } else { - appendPQExpBuffer(query, "SELECT " - "(SELECT oid FROM pg_class WHERE relname = 'pg_rewrite') AS tableoid, " - "oid, rulename, " - "ev_class AS ruletable, ev_type, is_instead, " - "'O'::char AS ev_enabled " - "FROM pg_rewrite " - "ORDER BY oid"); + appendPQExpBufferStr(query, "SELECT " + "(SELECT oid FROM pg_class WHERE relname = 'pg_rewrite') AS tableoid, " + "oid, rulename, " + "ev_class AS ruletable, ev_type, is_instead, " + "'O'::char AS ev_enabled " + "FROM pg_rewrite " + "ORDER BY oid"); } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -5907,17 +6023,17 @@ getProcLangs(Archive *fout, int *numProcLangs) else if (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"); + appendPQExpBufferStr(query, "SELECT tableoid, oid, * FROM pg_language " + "WHERE lanispl " + "ORDER BY oid"); } else { - appendPQExpBuffer(query, "SELECT " - "(SELECT oid FROM pg_class WHERE relname = 'pg_language') AS tableoid, " - "oid, * FROM pg_language " - "WHERE lanispl " - "ORDER BY oid"); + appendPQExpBufferStr(query, "SELECT " + "(SELECT oid FROM pg_class WHERE relname = 'pg_language') AS tableoid, " + "oid, * FROM pg_language " + "WHERE lanispl " + "ORDER BY oid"); } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6015,29 +6131,29 @@ getCasts(Archive *fout, int *numCasts) if (fout->remoteVersion >= 80400) { - appendPQExpBuffer(query, "SELECT tableoid, oid, " - "castsource, casttarget, castfunc, castcontext, " - "castmethod " - "FROM pg_cast ORDER BY 3,4"); + appendPQExpBufferStr(query, "SELECT tableoid, oid, " + "castsource, casttarget, castfunc, castcontext, " + "castmethod " + "FROM pg_cast ORDER BY 3,4"); } else if (fout->remoteVersion >= 70300) { - appendPQExpBuffer(query, "SELECT tableoid, oid, " - "castsource, casttarget, castfunc, castcontext, " + appendPQExpBufferStr(query, "SELECT tableoid, oid, " + "castsource, casttarget, castfunc, castcontext, " "CASE WHEN castfunc = 0 THEN 'b' ELSE 'f' END AS castmethod " - "FROM pg_cast ORDER BY 3,4"); + "FROM pg_cast ORDER BY 3,4"); } else { - appendPQExpBuffer(query, "SELECT 0 AS tableoid, p.oid, " - "t1.oid AS castsource, t2.oid AS casttarget, " - "p.oid AS castfunc, 'e' AS castcontext, " - "'f' AS castmethod " - "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 " - "ORDER BY 3,4"); + appendPQExpBufferStr(query, "SELECT 0 AS tableoid, p.oid, " + "t1.oid AS castsource, t2.oid AS casttarget, " + "p.oid AS castfunc, 'e' AS castcontext, " + "'f' AS castmethod " + "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 " + "ORDER BY 3,4"); } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6737,10 +6853,10 @@ getTSParsers(Archive *fout, int *numTSParsers) /* Make sure we are in proper schema */ selectSourceSchema(fout, "pg_catalog"); - appendPQExpBuffer(query, "SELECT tableoid, oid, prsname, prsnamespace, " - "prsstart::oid, prstoken::oid, " - "prsend::oid, prsheadline::oid, prslextype::oid " - "FROM pg_ts_parser"); + appendPQExpBufferStr(query, "SELECT tableoid, oid, prsname, prsnamespace, " + "prsstart::oid, prstoken::oid, " + "prsend::oid, prsheadline::oid, prslextype::oid " + "FROM pg_ts_parser"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6906,9 +7022,9 @@ getTSTemplates(Archive *fout, int *numTSTemplates) /* Make sure we are in proper schema */ selectSourceSchema(fout, "pg_catalog"); - appendPQExpBuffer(query, "SELECT tableoid, oid, tmplname, " - "tmplnamespace, tmplinit::oid, tmpllexize::oid " - "FROM pg_ts_template"); + appendPQExpBufferStr(query, "SELECT tableoid, oid, tmplname, " + "tmplnamespace, tmplinit::oid, tmpllexize::oid " + "FROM pg_ts_template"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7040,7 +7156,7 @@ getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers) PGresult *res; int ntups; int i; - PQExpBuffer query = createPQExpBuffer(); + PQExpBuffer query; FdwInfo *fdwinfo; int i_tableoid; int i_oid; @@ -7058,6 +7174,8 @@ getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers) return NULL; } + query = createPQExpBuffer(); + /* Make sure we are in proper schema */ selectSourceSchema(fout, "pg_catalog"); @@ -7146,7 +7264,7 @@ getForeignServers(Archive *fout, int *numForeignServers) PGresult *res; int ntups; int i; - PQExpBuffer query = createPQExpBuffer(); + PQExpBuffer query; ForeignServerInfo *srvinfo; int i_tableoid; int i_oid; @@ -7165,6 +7283,8 @@ getForeignServers(Archive *fout, int *numForeignServers) return NULL; } + query = createPQExpBuffer(); + /* Make sure we are in proper schema */ selectSourceSchema(fout, "pg_catalog"); @@ -7368,7 +7488,7 @@ dumpComment(Archive *fout, const char *target, appendPQExpBuffer(query, "COMMENT ON %s IS ", target); appendStringLiteralAH(query, comments->descr, fout); - appendPQExpBuffer(query, ";\n"); + appendPQExpBufferStr(query, ";\n"); /* * We mark comments as SECTION_NONE because they really belong in the @@ -7432,7 +7552,7 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo, resetPQExpBuffer(query); appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data); appendStringLiteralAH(query, descr, fout); - appendPQExpBuffer(query, ";\n"); + appendPQExpBufferStr(query, ";\n"); ArchiveEntry(fout, nilCatalogId, createDumpId(), target->data, @@ -7448,13 +7568,12 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo, resetPQExpBuffer(target); appendPQExpBuffer(target, "COLUMN %s.", fmtId(tbinfo->dobj.name)); - appendPQExpBuffer(target, "%s", - fmtId(tbinfo->attnames[objsubid - 1])); + appendPQExpBufferStr(target, fmtId(tbinfo->attnames[objsubid - 1])); resetPQExpBuffer(query); appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data); appendStringLiteralAH(query, descr, fout); - appendPQExpBuffer(query, ";\n"); + appendPQExpBufferStr(query, ";\n"); ArchiveEntry(fout, nilCatalogId, createDumpId(), target->data, @@ -7595,22 +7714,22 @@ collectComments(Archive *fout, CommentItem **items) if (fout->remoteVersion >= 70300) { - appendPQExpBuffer(query, "SELECT description, classoid, objoid, objsubid " - "FROM pg_catalog.pg_description " - "ORDER BY classoid, objoid, objsubid"); + appendPQExpBufferStr(query, "SELECT description, classoid, objoid, objsubid " + "FROM pg_catalog.pg_description " + "ORDER BY classoid, objoid, objsubid"); } else if (fout->remoteVersion >= 70200) { - appendPQExpBuffer(query, "SELECT description, classoid, objoid, objsubid " - "FROM pg_description " - "ORDER BY classoid, objoid, objsubid"); + appendPQExpBufferStr(query, "SELECT description, classoid, objoid, objsubid " + "FROM pg_description " + "ORDER BY classoid, objoid, objsubid"); } else { /* Note: this will fail to find attribute comments in pre-7.2... */ - appendPQExpBuffer(query, "SELECT description, 0 AS classoid, objoid, 0 AS objsubid " - "FROM pg_description " - "ORDER BY objoid"); + appendPQExpBufferStr(query, "SELECT description, 0 AS classoid, objoid, 0 AS objsubid " + "FROM pg_description " + "ORDER BY objoid"); } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7873,7 +7992,7 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo) int i; int n; - appendPQExpBuffer(q, "-- For binary upgrade, create an empty extension and insert objects into it\n"); + appendPQExpBufferStr(q, "-- For binary upgrade, create an empty extension and insert objects into it\n"); /* * We unconditionally create the extension, so we must drop it if it @@ -7884,15 +8003,15 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo) */ appendPQExpBuffer(q, "DROP EXTENSION IF EXISTS %s;\n", qextname); - appendPQExpBuffer(q, + appendPQExpBufferStr(q, "SELECT binary_upgrade.create_empty_extension("); appendStringLiteralAH(q, extinfo->dobj.name, fout); - appendPQExpBuffer(q, ", "); + appendPQExpBufferStr(q, ", "); appendStringLiteralAH(q, extinfo->namespace, fout); - appendPQExpBuffer(q, ", "); + appendPQExpBufferStr(q, ", "); appendPQExpBuffer(q, "%s, ", extinfo->relocatable ? "true" : "false"); appendStringLiteralAH(q, extinfo->extversion, fout); - appendPQExpBuffer(q, ", "); + appendPQExpBufferStr(q, ", "); /* * Note that we're pushing extconfig (an OID array) back into @@ -7902,14 +8021,14 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo) if (strlen(extinfo->extconfig) > 2) appendStringLiteralAH(q, extinfo->extconfig, fout); else - appendPQExpBuffer(q, "NULL"); - appendPQExpBuffer(q, ", "); + appendPQExpBufferStr(q, "NULL"); + appendPQExpBufferStr(q, ", "); if (strlen(extinfo->extcondition) > 2) appendStringLiteralAH(q, extinfo->extcondition, fout); else - appendPQExpBuffer(q, "NULL"); - appendPQExpBuffer(q, ", "); - appendPQExpBuffer(q, "ARRAY["); + appendPQExpBufferStr(q, "NULL"); + appendPQExpBufferStr(q, ", "); + appendPQExpBufferStr(q, "ARRAY["); n = 0; for (i = 0; i < extinfo->dobj.nDeps; i++) { @@ -7919,12 +8038,12 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo) if (extobj && extobj->objType == DO_EXTENSION) { if (n++ > 0) - appendPQExpBuffer(q, ","); + appendPQExpBufferChar(q, ','); appendStringLiteralAH(q, extobj->name, fout); } } - appendPQExpBuffer(q, "]::pg_catalog.text[]"); - appendPQExpBuffer(q, ");\n"); + appendPQExpBufferStr(q, "]::pg_catalog.text[]"); + appendPQExpBufferStr(q, ");\n"); } appendPQExpBuffer(labelq, "EXTENSION %s", qextname); @@ -8044,13 +8163,13 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo) { label = PQgetvalue(res, i, PQfnumber(res, "enumlabel")); if (i > 0) - appendPQExpBuffer(q, ","); - appendPQExpBuffer(q, "\n "); + appendPQExpBufferChar(q, ','); + appendPQExpBufferStr(q, "\n "); appendStringLiteralAH(q, label, fout); } } - appendPQExpBuffer(q, "\n);\n"); + appendPQExpBufferStr(q, "\n);\n"); if (binary_upgrade) { @@ -8061,7 +8180,7 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo) label = PQgetvalue(res, i, PQfnumber(res, "enumlabel")); if (i == 0) - appendPQExpBuffer(q, "\n-- For binary upgrade, must preserve pg_enum oids\n"); + appendPQExpBufferStr(q, "\n-- For binary upgrade, must preserve pg_enum oids\n"); appendPQExpBuffer(q, "SELECT binary_upgrade.set_next_pg_enum_oid('%u'::pg_catalog.oid);\n", enum_oid); @@ -8070,7 +8189,7 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo) appendPQExpBuffer(q, "%s ADD VALUE ", qtypname); appendStringLiteralAH(q, label, fout); - appendPQExpBuffer(q, ";\n\n"); + appendPQExpBufferStr(q, ";\n\n"); } } @@ -8179,7 +8298,7 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo) /* always schema-qualify, don't try to be smart */ appendPQExpBuffer(q, ",\n subtype_opclass = %s.", fmtId(nspname)); - appendPQExpBuffer(q, "%s", fmtId(opcname)); + appendPQExpBufferStr(q, fmtId(opcname)); } collationOid = atooid(PQgetvalue(res, 0, PQfnumber(res, "collation"))); @@ -8192,8 +8311,7 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo) /* always schema-qualify, don't try to be smart */ appendPQExpBuffer(q, ",\n collation = %s.", fmtId(coll->dobj.namespace->dobj.name)); - appendPQExpBuffer(q, "%s", - fmtId(coll->dobj.name)); + appendPQExpBufferStr(q, fmtId(coll->dobj.name)); } } @@ -8205,7 +8323,7 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo) if (strcmp(procname, "-") != 0) appendPQExpBuffer(q, ",\n subtype_diff = %s", procname); - appendPQExpBuffer(q, "\n);\n"); + appendPQExpBufferStr(q, "\n);\n"); appendPQExpBuffer(labelq, "TYPE %s", qtypname); @@ -8537,11 +8655,11 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo) } if (strcmp(typcollatable, "t") == 0) - appendPQExpBuffer(q, ",\n COLLATABLE = true"); + appendPQExpBufferStr(q, ",\n COLLATABLE = true"); if (typdefault != NULL) { - appendPQExpBuffer(q, ",\n DEFAULT = "); + appendPQExpBufferStr(q, ",\n DEFAULT = "); if (typdefault_is_literal) appendStringLiteralAH(q, typdefault, fout); else @@ -8561,41 +8679,41 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo) if (strcmp(typcategory, "U") != 0) { - appendPQExpBuffer(q, ",\n CATEGORY = "); + appendPQExpBufferStr(q, ",\n CATEGORY = "); appendStringLiteralAH(q, typcategory, fout); } if (strcmp(typispreferred, "t") == 0) - appendPQExpBuffer(q, ",\n PREFERRED = true"); + appendPQExpBufferStr(q, ",\n PREFERRED = true"); if (typdelim && strcmp(typdelim, ",") != 0) { - appendPQExpBuffer(q, ",\n DELIMITER = "); + appendPQExpBufferStr(q, ",\n DELIMITER = "); appendStringLiteralAH(q, typdelim, fout); } if (strcmp(typalign, "c") == 0) - appendPQExpBuffer(q, ",\n ALIGNMENT = char"); + appendPQExpBufferStr(q, ",\n ALIGNMENT = char"); else if (strcmp(typalign, "s") == 0) - appendPQExpBuffer(q, ",\n ALIGNMENT = int2"); + appendPQExpBufferStr(q, ",\n ALIGNMENT = int2"); else if (strcmp(typalign, "i") == 0) - appendPQExpBuffer(q, ",\n ALIGNMENT = int4"); + appendPQExpBufferStr(q, ",\n ALIGNMENT = int4"); else if (strcmp(typalign, "d") == 0) - appendPQExpBuffer(q, ",\n ALIGNMENT = double"); + appendPQExpBufferStr(q, ",\n ALIGNMENT = double"); if (strcmp(typstorage, "p") == 0) - appendPQExpBuffer(q, ",\n STORAGE = plain"); + appendPQExpBufferStr(q, ",\n STORAGE = plain"); else if (strcmp(typstorage, "e") == 0) - appendPQExpBuffer(q, ",\n STORAGE = external"); + appendPQExpBufferStr(q, ",\n STORAGE = external"); else if (strcmp(typstorage, "x") == 0) - appendPQExpBuffer(q, ",\n STORAGE = extended"); + appendPQExpBufferStr(q, ",\n STORAGE = extended"); else if (strcmp(typstorage, "m") == 0) - appendPQExpBuffer(q, ",\n STORAGE = main"); + appendPQExpBufferStr(q, ",\n STORAGE = main"); if (strcmp(typbyval, "t") == 0) - appendPQExpBuffer(q, ",\n PASSEDBYVALUE"); + appendPQExpBufferStr(q, ",\n PASSEDBYVALUE"); - appendPQExpBuffer(q, "\n);\n"); + appendPQExpBufferStr(q, "\n);\n"); appendPQExpBuffer(labelq, "TYPE %s", qtypname); @@ -8719,17 +8837,16 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo) /* always schema-qualify, don't try to be smart */ appendPQExpBuffer(q, " COLLATE %s.", fmtId(coll->dobj.namespace->dobj.name)); - appendPQExpBuffer(q, "%s", - fmtId(coll->dobj.name)); + appendPQExpBufferStr(q, fmtId(coll->dobj.name)); } } if (typnotnull[0] == 't') - appendPQExpBuffer(q, " NOT NULL"); + appendPQExpBufferStr(q, " NOT NULL"); if (typdefault != NULL) { - appendPQExpBuffer(q, " DEFAULT "); + appendPQExpBufferStr(q, " DEFAULT "); if (typdefault_is_literal) appendStringLiteralAH(q, typdefault, fout); else @@ -8750,7 +8867,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo) fmtId(domcheck->dobj.name), domcheck->condef); } - appendPQExpBuffer(q, ";\n"); + appendPQExpBufferStr(q, ";\n"); /* * DROP must be fully qualified in case same name appears in pg_catalog @@ -8913,8 +9030,8 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo) /* Format properly if not first attr */ if (actual_atts++ > 0) - appendPQExpBuffer(q, ","); - appendPQExpBuffer(q, "\n\t"); + appendPQExpBufferChar(q, ','); + appendPQExpBufferStr(q, "\n\t"); if (!attisdropped) { @@ -8931,8 +9048,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo) /* always schema-qualify, don't try to be smart */ appendPQExpBuffer(q, " COLLATE %s.", fmtId(coll->dobj.namespace->dobj.name)); - appendPQExpBuffer(q, "%s", - fmtId(coll->dobj.name)); + appendPQExpBufferStr(q, fmtId(coll->dobj.name)); } } } @@ -8947,16 +9063,16 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo) appendPQExpBuffer(q, "%s INTEGER /* dummy */", fmtId(attname)); /* stash separately for insertion after the CREATE TYPE */ - appendPQExpBuffer(dropped, + appendPQExpBufferStr(dropped, "\n-- For binary upgrade, recreate dropped column.\n"); appendPQExpBuffer(dropped, "UPDATE pg_catalog.pg_attribute\n" "SET attlen = %s, " "attalign = '%s', attbyval = false\n" "WHERE attname = ", attlen, attalign); appendStringLiteralAH(dropped, attname, fout); - appendPQExpBuffer(dropped, "\n AND attrelid = "); + appendPQExpBufferStr(dropped, "\n AND attrelid = "); appendStringLiteralAH(dropped, qtypname, fout); - appendPQExpBuffer(dropped, "::pg_catalog.regclass;\n"); + appendPQExpBufferStr(dropped, "::pg_catalog.regclass;\n"); appendPQExpBuffer(dropped, "ALTER TYPE %s ", qtypname); @@ -8964,7 +9080,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo) fmtId(attname)); } } - appendPQExpBuffer(q, "\n);\n"); + appendPQExpBufferStr(q, "\n);\n"); appendPQExpBufferStr(q, dropped->data); /* @@ -9097,13 +9213,12 @@ dumpCompositeTypeColComments(Archive *fout, TypeInfo *tyinfo) resetPQExpBuffer(target); appendPQExpBuffer(target, "COLUMN %s.", fmtId(tyinfo->dobj.name)); - appendPQExpBuffer(target, "%s", - fmtId(attname)); + appendPQExpBufferStr(target, fmtId(attname)); resetPQExpBuffer(query); appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data); appendStringLiteralAH(query, descr, fout); - appendPQExpBuffer(query, ";\n"); + appendPQExpBufferStr(query, ";\n"); ArchiveEntry(fout, nilCatalogId, createDumpId(), target->data, @@ -9293,23 +9408,21 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang) fmtId(funcInfo->dobj.name)); if (OidIsValid(plang->laninline)) { - appendPQExpBuffer(defqry, " INLINE "); + appendPQExpBufferStr(defqry, " INLINE "); /* Cope with possibility that inline is in different schema */ if (inlineInfo->dobj.namespace != funcInfo->dobj.namespace) appendPQExpBuffer(defqry, "%s.", fmtId(inlineInfo->dobj.namespace->dobj.name)); - appendPQExpBuffer(defqry, "%s", - fmtId(inlineInfo->dobj.name)); + appendPQExpBufferStr(defqry, fmtId(inlineInfo->dobj.name)); } if (OidIsValid(plang->lanvalidator)) { - appendPQExpBuffer(defqry, " VALIDATOR "); + appendPQExpBufferStr(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)); + appendPQExpBufferStr(defqry, fmtId(validatorInfo->dobj.name)); } } else @@ -9326,7 +9439,7 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang) appendPQExpBuffer(defqry, "CREATE OR REPLACE PROCEDURAL LANGUAGE %s", qlanname); } - appendPQExpBuffer(defqry, ";\n"); + appendPQExpBufferStr(defqry, ";\n"); appendPQExpBuffer(labelq, "LANGUAGE %s", qlanname); @@ -9375,9 +9488,9 @@ format_function_arguments(FuncInfo *finfo, char *funcargs, bool is_agg) PQExpBufferData fn; initPQExpBuffer(&fn); - appendPQExpBuffer(&fn, "%s", fmtId(finfo->dobj.name)); + appendPQExpBufferStr(&fn, fmtId(finfo->dobj.name)); if (is_agg && finfo->nargs == 0) - appendPQExpBuffer(&fn, "(*)"); + appendPQExpBufferStr(&fn, "(*)"); else appendPQExpBuffer(&fn, "(%s)", funcargs); return fn.data; @@ -9450,7 +9563,7 @@ format_function_arguments_old(Archive *fout, typname); free(typname); } - appendPQExpBuffer(&fn, ")"); + appendPQExpBufferChar(&fn, ')'); return fn.data; } @@ -9479,15 +9592,15 @@ format_function_signature(Archive *fout, FuncInfo *finfo, bool honor_quotes) { char *typname; + if (j > 0) + appendPQExpBufferStr(&fn, ", "); + typname = getFormattedTypeName(fout, finfo->argtypes[j], zeroAsOpaque); - - appendPQExpBuffer(&fn, "%s%s", - (j > 0) ? ", " : "", - typname); + appendPQExpBufferStr(&fn, typname); free(typname); } - appendPQExpBuffer(&fn, ")"); + appendPQExpBufferChar(&fn, ')'); return fn.data; } @@ -9506,7 +9619,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) PQExpBuffer asPart; PGresult *res; char *funcsig; /* identity signature */ - char *funcfullsig; /* full signature */ + char *funcfullsig = NULL; /* full signature */ char *funcsig_tag; char *proretset; char *prosrc; @@ -9719,11 +9832,11 @@ dumpFunc(Archive *fout, FuncInfo *finfo) */ if (probin[0] != '\0' && strcmp(probin, "-") != 0) { - appendPQExpBuffer(asPart, "AS "); + appendPQExpBufferStr(asPart, "AS "); appendStringLiteralAH(asPart, probin, fout); if (strcmp(prosrc, "-") != 0) { - appendPQExpBuffer(asPart, ", "); + appendPQExpBufferStr(asPart, ", "); /* * where we have bin, use dollar quoting if allowed and src @@ -9740,7 +9853,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) { if (strcmp(prosrc, "-") != 0) { - appendPQExpBuffer(asPart, "AS "); + appendPQExpBufferStr(asPart, "AS "); /* with no bin, dollar quote src unconditionally if allowed */ if (disable_dollar_quoting) appendStringLiteralAH(asPart, prosrc, fout); @@ -9814,13 +9927,10 @@ dumpFunc(Archive *fout, FuncInfo *finfo) funcsig = format_function_arguments(finfo, funciargs, false); } else - { /* pre-8.4, do it ourselves */ funcsig = format_function_arguments_old(fout, finfo, nallargs, allargtypes, argmodes, argnames); - funcfullsig = funcsig; - } funcsig_tag = format_function_signature(fout, finfo, false); @@ -9831,7 +9941,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo) fmtId(finfo->dobj.namespace->dobj.name), funcsig); - appendPQExpBuffer(q, "CREATE FUNCTION %s ", funcfullsig); + appendPQExpBuffer(q, "CREATE FUNCTION %s ", funcfullsig ? funcfullsig : + funcsig); if (funcresult) appendPQExpBuffer(q, "RETURNS %s", funcresult); else @@ -9847,27 +9958,27 @@ dumpFunc(Archive *fout, FuncInfo *finfo) appendPQExpBuffer(q, "\n LANGUAGE %s", fmtId(lanname)); if (proiswindow[0] == 't') - appendPQExpBuffer(q, " WINDOW"); + appendPQExpBufferStr(q, " WINDOW"); if (provolatile[0] != PROVOLATILE_VOLATILE) { if (provolatile[0] == PROVOLATILE_IMMUTABLE) - appendPQExpBuffer(q, " IMMUTABLE"); + appendPQExpBufferStr(q, " IMMUTABLE"); else if (provolatile[0] == PROVOLATILE_STABLE) - appendPQExpBuffer(q, " STABLE"); + appendPQExpBufferStr(q, " STABLE"); else if (provolatile[0] != PROVOLATILE_VOLATILE) exit_horribly(NULL, "unrecognized provolatile value for function \"%s\"\n", finfo->dobj.name); } if (proisstrict[0] == 't') - appendPQExpBuffer(q, " STRICT"); + appendPQExpBufferStr(q, " STRICT"); if (prosecdef[0] == 't') - appendPQExpBuffer(q, " SECURITY DEFINER"); + appendPQExpBufferStr(q, " SECURITY DEFINER"); if (proleakproof[0] == 't') - appendPQExpBuffer(q, " LEAKPROOF"); + appendPQExpBufferStr(q, " LEAKPROOF"); /* * COST and ROWS are emitted only if present and not default, so as not to @@ -9911,7 +10022,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) */ if (pg_strcasecmp(configitem, "DateStyle") == 0 || pg_strcasecmp(configitem, "search_path") == 0) - appendPQExpBuffer(q, "%s", pos); + appendPQExpBufferStr(q, pos); else appendStringLiteralAH(q, pos, fout); } @@ -9954,6 +10065,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo) destroyPQExpBuffer(labelq); destroyPQExpBuffer(asPart); free(funcsig); + if (funcfullsig) + free(funcfullsig); free(funcsig_tag); if (allargtypes) free(allargtypes); @@ -10056,10 +10169,10 @@ dumpCast(Archive *fout, CastInfo *cast) switch (cast->castmethod) { case COERCION_METHOD_BINARY: - appendPQExpBuffer(defqry, "WITHOUT FUNCTION"); + appendPQExpBufferStr(defqry, "WITHOUT FUNCTION"); break; case COERCION_METHOD_INOUT: - appendPQExpBuffer(defqry, "WITH INOUT"); + appendPQExpBufferStr(defqry, "WITH INOUT"); break; case COERCION_METHOD_FUNCTION: if (funcInfo) @@ -10083,10 +10196,10 @@ dumpCast(Archive *fout, CastInfo *cast) } if (cast->castcontext == 'a') - appendPQExpBuffer(defqry, " AS ASSIGNMENT"); + appendPQExpBufferStr(defqry, " AS ASSIGNMENT"); else if (cast->castcontext == 'i') - appendPQExpBuffer(defqry, " AS IMPLICIT"); - appendPQExpBuffer(defqry, ";\n"); + appendPQExpBufferStr(defqry, " AS IMPLICIT"); + appendPQExpBufferStr(defqry, ";\n"); appendPQExpBuffer(labelq, "CAST (%s AS %s)", getFormattedTypeName(fout, cast->castsource, zeroAsNone), @@ -10148,6 +10261,8 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) char *oprjoin; char *oprcanmerge; char *oprcanhash; + char *oprregproc; + char *oprref; /* Skip if not to be dumped */ if (!oprinfo->dobj.dump || dataOnly) @@ -10254,8 +10369,12 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) oprcanmerge = PQgetvalue(res, 0, i_oprcanmerge); oprcanhash = PQgetvalue(res, 0, i_oprcanhash); - appendPQExpBuffer(details, " PROCEDURE = %s", - convertRegProcReference(fout, oprcode)); + oprregproc = convertRegProcReference(fout, oprcode); + if (oprregproc) + { + appendPQExpBuffer(details, " PROCEDURE = %s", oprregproc); + free(oprregproc); + } appendPQExpBuffer(oprid, "%s (", oprinfo->dobj.name); @@ -10272,10 +10391,10 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) else name = fmtId(oprleft); appendPQExpBuffer(details, ",\n LEFTARG = %s", name); - appendPQExpBuffer(oprid, "%s", name); + appendPQExpBufferStr(oprid, name); } else - appendPQExpBuffer(oprid, "NONE"); + appendPQExpBufferStr(oprid, "NONE"); if (strcmp(oprkind, "l") == 0 || strcmp(oprkind, "b") == 0) @@ -10288,29 +10407,41 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) appendPQExpBuffer(oprid, ", %s)", name); } else - appendPQExpBuffer(oprid, ", NONE)"); + appendPQExpBufferStr(oprid, ", NONE)"); - name = convertOperatorReference(fout, oprcom); - if (name) - appendPQExpBuffer(details, ",\n COMMUTATOR = %s", name); + oprref = convertOperatorReference(fout, oprcom); + if (oprref) + { + appendPQExpBuffer(details, ",\n COMMUTATOR = %s", oprref); + free(oprref); + } - name = convertOperatorReference(fout, oprnegate); - if (name) - appendPQExpBuffer(details, ",\n NEGATOR = %s", name); + oprref = convertOperatorReference(fout, oprnegate); + if (oprref) + { + appendPQExpBuffer(details, ",\n NEGATOR = %s", oprref); + free(oprref); + } if (strcmp(oprcanmerge, "t") == 0) - appendPQExpBuffer(details, ",\n MERGES"); + appendPQExpBufferStr(details, ",\n MERGES"); if (strcmp(oprcanhash, "t") == 0) - appendPQExpBuffer(details, ",\n HASHES"); + appendPQExpBufferStr(details, ",\n HASHES"); - name = convertRegProcReference(fout, oprrest); - if (name) - appendPQExpBuffer(details, ",\n RESTRICT = %s", name); + oprregproc = convertRegProcReference(fout, oprrest); + if (oprregproc) + { + appendPQExpBuffer(details, ",\n RESTRICT = %s", oprregproc); + free(oprregproc); + } - name = convertRegProcReference(fout, oprjoin); - if (name) - appendPQExpBuffer(details, ",\n JOIN = %s", name); + oprregproc = convertRegProcReference(fout, oprjoin); + if (oprregproc) + { + appendPQExpBuffer(details, ",\n JOIN = %s", oprregproc); + free(oprregproc); + } /* * DROP must be fully qualified in case same name appears in pg_catalog @@ -10355,12 +10486,13 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) /* * Convert a function reference obtained from pg_operator * - * Returns what to print, or NULL if function references is InvalidOid + * Returns allocated string of what to print, or NULL if function references + * is InvalidOid. Returned string is expected to be free'd by the caller. * * In 7.3 the input is a REGPROCEDURE display; we have to strip the * argument-types part. In prior versions, the input is a REGPROC display. */ -static const char * +static char * convertRegProcReference(Archive *fout, const char *proc) { /* In all cases "-" means a null reference */ @@ -10390,20 +10522,21 @@ convertRegProcReference(Archive *fout, const char *proc) } /* REGPROC before 7.3 does not quote its result */ - return fmtId(proc); + return pg_strdup(fmtId(proc)); } /* * Convert an operator cross-reference obtained from pg_operator * - * Returns what to print, or NULL to print nothing + * Returns an allocated string of what to print, or NULL to print nothing. + * Caller is responsible for free'ing result string. * * In 7.3 and up the input is a REGOPERATOR display; we have to strip the * argument-types part, and add OPERATOR() decoration if the name is * schema-qualified. In older versions, the input is just a numeric OID, * which we search our operator list for. */ -static const char * +static char * convertOperatorReference(Archive *fout, const char *opr) { OprInfo *oprInfo; @@ -10439,7 +10572,7 @@ convertOperatorReference(Archive *fout, const char *opr) /* If not schema-qualified, don't need to add OPERATOR() */ if (!sawdot) return name; - pg_asprintf(&oname, "OPERATOR(%s)", name); + oname = psprintf("OPERATOR(%s)", name); free(name); return oname; } @@ -10451,7 +10584,7 @@ convertOperatorReference(Archive *fout, const char *opr) opr); return NULL; } - return oprInfo->dobj.name; + return pg_strdup(oprInfo->dobj.name); } /* @@ -10611,7 +10744,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) appendPQExpBuffer(q, "CREATE OPERATOR CLASS %s\n ", fmtId(opcinfo->dobj.name)); if (strcmp(opcdefault, "t") == 0) - appendPQExpBuffer(q, "DEFAULT "); + appendPQExpBufferStr(q, "DEFAULT "); appendPQExpBuffer(q, "FOR TYPE %s USING %s", opcintype, fmtId(amname)); @@ -10619,12 +10752,12 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) (strcmp(opcfamilyname, opcinfo->dobj.name) != 0 || strcmp(opcfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0)) { - appendPQExpBuffer(q, " FAMILY "); + appendPQExpBufferStr(q, " FAMILY "); if (strcmp(opcfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0) appendPQExpBuffer(q, "%s.", fmtId(opcfamilynsp)); appendPQExpBuffer(q, "%s", fmtId(opcfamilyname)); } - appendPQExpBuffer(q, " AS\n "); + appendPQExpBufferStr(q, " AS\n "); needComma = false; @@ -10731,21 +10864,21 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) sortfamilynsp = PQgetvalue(res, i, i_sortfamilynsp); if (needComma) - appendPQExpBuffer(q, " ,\n "); + appendPQExpBufferStr(q, " ,\n "); appendPQExpBuffer(q, "OPERATOR %s %s", amopstrategy, amopopr); if (strlen(sortfamily) > 0) { - appendPQExpBuffer(q, " FOR ORDER BY "); + appendPQExpBufferStr(q, " FOR ORDER BY "); if (strcmp(sortfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0) appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp)); - appendPQExpBuffer(q, "%s", fmtId(sortfamily)); + appendPQExpBufferStr(q, fmtId(sortfamily)); } if (strcmp(amopreqcheck, "t") == 0) - appendPQExpBuffer(q, " RECHECK"); + appendPQExpBufferStr(q, " RECHECK"); needComma = true; } @@ -10809,7 +10942,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) amprocrighttype = PQgetvalue(res, i, i_amprocrighttype); if (needComma) - appendPQExpBuffer(q, " ,\n "); + appendPQExpBufferStr(q, " ,\n "); appendPQExpBuffer(q, "FUNCTION %s", amprocnum); @@ -10823,7 +10956,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) PQclear(res); - appendPQExpBuffer(q, ";\n"); + appendPQExpBufferStr(q, ";\n"); appendPQExpBuffer(labelq, "OPERATOR CLASS %s", fmtId(opcinfo->dobj.name)); @@ -11089,21 +11222,21 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo) sortfamilynsp = PQgetvalue(res_ops, i, i_sortfamilynsp); if (needComma) - appendPQExpBuffer(q, " ,\n "); + appendPQExpBufferStr(q, " ,\n "); appendPQExpBuffer(q, "OPERATOR %s %s", amopstrategy, amopopr); if (strlen(sortfamily) > 0) { - appendPQExpBuffer(q, " FOR ORDER BY "); + appendPQExpBufferStr(q, " FOR ORDER BY "); if (strcmp(sortfamilynsp, opfinfo->dobj.namespace->dobj.name) != 0) appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp)); - appendPQExpBuffer(q, "%s", fmtId(sortfamily)); + appendPQExpBufferStr(q, fmtId(sortfamily)); } if (strcmp(amopreqcheck, "t") == 0) - appendPQExpBuffer(q, " RECHECK"); + appendPQExpBufferStr(q, " RECHECK"); needComma = true; } @@ -11126,7 +11259,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo) amprocrighttype = PQgetvalue(res_procs, i, i_amprocrighttype); if (needComma) - appendPQExpBuffer(q, " ,\n "); + appendPQExpBufferStr(q, " ,\n "); appendPQExpBuffer(q, "FUNCTION %s (%s, %s) %s", amprocnum, amproclefttype, amprocrighttype, @@ -11135,7 +11268,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo) needComma = true; } - appendPQExpBuffer(q, ";\n"); + appendPQExpBufferStr(q, ";\n"); } appendPQExpBuffer(labelq, "OPERATOR FAMILY %s", @@ -11226,9 +11359,9 @@ dumpCollation(Archive *fout, CollInfo *collinfo) appendPQExpBuffer(q, "CREATE COLLATION %s (lc_collate = ", fmtId(collinfo->dobj.name)); appendStringLiteralAH(q, collcollate, fout); - appendPQExpBuffer(q, ", lc_ctype = "); + appendPQExpBufferStr(q, ", lc_ctype = "); appendStringLiteralAH(q, collctype, fout); - appendPQExpBuffer(q, ");\n"); + appendPQExpBufferStr(q, ");\n"); appendPQExpBuffer(labelq, "COLLATION %s", fmtId(collinfo->dobj.name)); @@ -11324,7 +11457,7 @@ dumpConversion(Archive *fout, ConvInfo *convinfo) (condefault) ? "DEFAULT " : "", fmtId(convinfo->dobj.name)); appendStringLiteralAH(q, conforencoding, fout); - appendPQExpBuffer(q, " TO "); + appendPQExpBufferStr(q, " TO "); appendStringLiteralAH(q, contoencoding, fout); /* regproc is automatically quoted in 7.3 and above */ appendPQExpBuffer(q, " FROM %s;\n", conproc); @@ -11371,16 +11504,15 @@ format_aggregate_signature(AggInfo *agginfo, Archive *fout, bool honor_quotes) initPQExpBuffer(&buf); if (honor_quotes) - appendPQExpBuffer(&buf, "%s", - fmtId(agginfo->aggfn.dobj.name)); + appendPQExpBufferStr(&buf, fmtId(agginfo->aggfn.dobj.name)); else - appendPQExpBuffer(&buf, "%s", agginfo->aggfn.dobj.name); + appendPQExpBufferStr(&buf, agginfo->aggfn.dobj.name); if (agginfo->aggfn.nargs == 0) appendPQExpBuffer(&buf, "(*)"); else { - appendPQExpBuffer(&buf, "("); + appendPQExpBufferChar(&buf, '('); for (j = 0; j < agginfo->aggfn.nargs; j++) { char *typname; @@ -11393,7 +11525,7 @@ format_aggregate_signature(AggInfo *agginfo, Archive *fout, bool honor_quotes) typname); free(typname); } - appendPQExpBuffer(&buf, ")"); + appendPQExpBufferChar(&buf, ')'); } return buf.data; } @@ -11411,20 +11543,41 @@ dumpAgg(Archive *fout, AggInfo *agginfo) PQExpBuffer labelq; PQExpBuffer details; char *aggsig; /* identity signature */ - char *aggfullsig; /* full signature */ + char *aggfullsig = NULL; /* full signature */ char *aggsig_tag; PGresult *res; int i_aggtransfn; int i_aggfinalfn; + int i_aggmtransfn; + int i_aggminvtransfn; + int i_aggmfinalfn; + int i_aggfinalextra; + int i_aggmfinalextra; int i_aggsortop; + int i_hypothetical; int i_aggtranstype; + int i_aggtransspace; + int i_aggmtranstype; + int i_aggmtransspace; int i_agginitval; + int i_aggminitval; int i_convertok; const char *aggtransfn; const char *aggfinalfn; + const char *aggmtransfn; + const char *aggminvtransfn; + const char *aggmfinalfn; + bool aggfinalextra; + bool aggmfinalextra; const char *aggsortop; + char *aggsortconvop; + bool hypothetical; const char *aggtranstype; + const char *aggtransspace; + const char *aggmtranstype; + const char *aggmtransspace; const char *agginitval; + const char *aggminitval; bool convertok; /* Skip if not to be dumped */ @@ -11441,13 +11594,37 @@ dumpAgg(Archive *fout, AggInfo *agginfo) selectSourceSchema(fout, agginfo->aggfn.dobj.namespace->dobj.name); /* Get aggregate-specific details */ - if (fout->remoteVersion >= 80400) + if (fout->remoteVersion >= 90400) { appendPQExpBuffer(query, "SELECT aggtransfn, " "aggfinalfn, aggtranstype::pg_catalog.regtype, " + "aggmtransfn, aggminvtransfn, aggmfinalfn, " + "aggmtranstype::pg_catalog.regtype, " + "aggfinalextra, aggmfinalextra, " "aggsortop::pg_catalog.regoperator, " - "agginitval, " - "'t'::boolean AS convertok, " + "(aggkind = 'h') AS hypothetical, " + "aggtransspace, agginitval, " + "aggmtransspace, aggminitval, " + "true AS convertok, " + "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs, " + "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs " + "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p " + "WHERE a.aggfnoid = p.oid " + "AND p.oid = '%u'::pg_catalog.oid", + agginfo->aggfn.dobj.catId.oid); + } + else if (fout->remoteVersion >= 80400) + { + appendPQExpBuffer(query, "SELECT aggtransfn, " + "aggfinalfn, aggtranstype::pg_catalog.regtype, " + "'-' AS aggmtransfn, '-' AS aggminvtransfn, " + "'-' AS aggmfinalfn, 0 AS aggmtranstype, " + "false AS aggfinalextra, false AS aggmfinalextra, " + "aggsortop::pg_catalog.regoperator, " + "false AS hypothetical, " + "0 AS aggtransspace, agginitval, " + "0 AS aggmtransspace, NULL AS aggminitval, " + "true AS convertok, " "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs, " "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs " "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p " @@ -11459,9 +11636,14 @@ dumpAgg(Archive *fout, AggInfo *agginfo) { appendPQExpBuffer(query, "SELECT aggtransfn, " "aggfinalfn, aggtranstype::pg_catalog.regtype, " + "'-' AS aggmtransfn, '-' AS aggminvtransfn, " + "'-' AS aggmfinalfn, 0 AS aggmtranstype, " + "false AS aggfinalextra, false AS aggmfinalextra, " "aggsortop::pg_catalog.regoperator, " - "agginitval, " - "'t'::boolean AS convertok " + "false AS hypothetical, " + "0 AS aggtransspace, agginitval, " + "0 AS aggmtransspace, NULL AS aggminitval, " + "true AS convertok " "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p " "WHERE a.aggfnoid = p.oid " "AND p.oid = '%u'::pg_catalog.oid", @@ -11471,9 +11653,14 @@ dumpAgg(Archive *fout, AggInfo *agginfo) { appendPQExpBuffer(query, "SELECT aggtransfn, " "aggfinalfn, aggtranstype::pg_catalog.regtype, " + "'-' AS aggmtransfn, '-' AS aggminvtransfn, " + "'-' AS aggmfinalfn, 0 AS aggmtranstype, " + "false AS aggfinalextra, false AS aggmfinalextra, " "0 AS aggsortop, " - "agginitval, " - "'t'::boolean AS convertok " + "false AS hypothetical, " + "0 AS aggtransspace, agginitval, " + "0 AS aggmtransspace, NULL AS aggminitval, " + "true AS convertok " "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p " "WHERE a.aggfnoid = p.oid " "AND p.oid = '%u'::pg_catalog.oid", @@ -11483,9 +11670,14 @@ dumpAgg(Archive *fout, AggInfo *agginfo) { appendPQExpBuffer(query, "SELECT aggtransfn, aggfinalfn, " "format_type(aggtranstype, NULL) AS aggtranstype, " + "'-' AS aggmtransfn, '-' AS aggminvtransfn, " + "'-' AS aggmfinalfn, 0 AS aggmtranstype, " + "false AS aggfinalextra, false AS aggmfinalextra, " "0 AS aggsortop, " - "agginitval, " - "'t'::boolean AS convertok " + "false AS hypothetical, " + "0 AS aggtransspace, agginitval, " + "0 AS aggmtransspace, NULL AS aggminitval, " + "true AS convertok " "FROM pg_aggregate " "WHERE oid = '%u'::oid", agginfo->aggfn.dobj.catId.oid); @@ -11495,8 +11687,13 @@ dumpAgg(Archive *fout, AggInfo *agginfo) appendPQExpBuffer(query, "SELECT aggtransfn1 AS aggtransfn, " "aggfinalfn, " "(SELECT typname FROM pg_type WHERE oid = aggtranstype1) AS aggtranstype, " + "'-' AS aggmtransfn, '-' AS aggminvtransfn, " + "'-' AS aggmfinalfn, 0 AS aggmtranstype, " + "false AS aggfinalextra, false AS aggmfinalextra, " "0 AS aggsortop, " - "agginitval1 AS agginitval, " + "false AS hypothetical, " + "0 AS aggtransspace, agginitval1 AS agginitval, " + "0 AS aggmtransspace, NULL AS aggminitval, " "(aggtransfn2 = 0 and aggtranstype2 = 0 and agginitval2 is null) AS convertok " "FROM pg_aggregate " "WHERE oid = '%u'::oid", @@ -11507,16 +11704,36 @@ dumpAgg(Archive *fout, AggInfo *agginfo) i_aggtransfn = PQfnumber(res, "aggtransfn"); i_aggfinalfn = PQfnumber(res, "aggfinalfn"); + i_aggmtransfn = PQfnumber(res, "aggmtransfn"); + i_aggminvtransfn = PQfnumber(res, "aggminvtransfn"); + i_aggmfinalfn = PQfnumber(res, "aggmfinalfn"); + i_aggfinalextra = PQfnumber(res, "aggfinalextra"); + i_aggmfinalextra = PQfnumber(res, "aggmfinalextra"); i_aggsortop = PQfnumber(res, "aggsortop"); + i_hypothetical = PQfnumber(res, "hypothetical"); i_aggtranstype = PQfnumber(res, "aggtranstype"); + i_aggtransspace = PQfnumber(res, "aggtransspace"); + i_aggmtranstype = PQfnumber(res, "aggmtranstype"); + i_aggmtransspace = PQfnumber(res, "aggmtransspace"); i_agginitval = PQfnumber(res, "agginitval"); + i_aggminitval = PQfnumber(res, "aggminitval"); i_convertok = PQfnumber(res, "convertok"); aggtransfn = PQgetvalue(res, 0, i_aggtransfn); aggfinalfn = PQgetvalue(res, 0, i_aggfinalfn); + aggmtransfn = PQgetvalue(res, 0, i_aggmtransfn); + aggminvtransfn = PQgetvalue(res, 0, i_aggminvtransfn); + aggmfinalfn = PQgetvalue(res, 0, i_aggmfinalfn); + aggfinalextra = (PQgetvalue(res, 0, i_aggfinalextra)[0] == 't'); + aggmfinalextra = (PQgetvalue(res, 0, i_aggmfinalextra)[0] == 't'); aggsortop = PQgetvalue(res, 0, i_aggsortop); + hypothetical = (PQgetvalue(res, 0, i_hypothetical)[0] == 't'); aggtranstype = PQgetvalue(res, 0, i_aggtranstype); + aggtransspace = PQgetvalue(res, 0, i_aggtransspace); + aggmtranstype = PQgetvalue(res, 0, i_aggmtranstype); + aggmtransspace = PQgetvalue(res, 0, i_aggmtransspace); agginitval = PQgetvalue(res, 0, i_agginitval); + aggminitval = PQgetvalue(res, 0, i_aggminitval); convertok = (PQgetvalue(res, 0, i_convertok)[0] == 't'); if (fout->remoteVersion >= 80400) @@ -11531,11 +11748,8 @@ dumpAgg(Archive *fout, AggInfo *agginfo) aggsig = format_function_arguments(&agginfo->aggfn, funciargs, true); } else - { /* pre-8.4, do it ourselves */ aggsig = format_aggregate_signature(agginfo, fout, true); - aggfullsig = aggsig; - } aggsig_tag = format_aggregate_signature(agginfo, fout, false); @@ -11543,6 +11757,12 @@ dumpAgg(Archive *fout, AggInfo *agginfo) { write_msg(NULL, "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n", aggsig); + + if (aggfullsig) + free(aggfullsig); + + free(aggsig); + return; } @@ -11569,9 +11789,15 @@ dumpAgg(Archive *fout, AggInfo *agginfo) fmtId(aggtranstype)); } + if (strcmp(aggtransspace, "0") != 0) + { + appendPQExpBuffer(details, ",\n SSPACE = %s", + aggtransspace); + } + if (!PQgetisnull(res, 0, i_agginitval)) { - appendPQExpBuffer(details, ",\n INITCOND = "); + appendPQExpBufferStr(details, ",\n INITCOND = "); appendStringLiteralAH(details, agginitval, fout); } @@ -11579,15 +11805,49 @@ dumpAgg(Archive *fout, AggInfo *agginfo) { appendPQExpBuffer(details, ",\n FINALFUNC = %s", aggfinalfn); + if (aggfinalextra) + appendPQExpBufferStr(details, ",\n FINALFUNC_EXTRA"); + } + + if (strcmp(aggmtransfn, "-") != 0) + { + appendPQExpBuffer(details, ",\n MSFUNC = %s,\n MINVFUNC = %s,\n MSTYPE = %s", + aggmtransfn, + aggminvtransfn, + aggmtranstype); } - aggsortop = convertOperatorReference(fout, aggsortop); - if (aggsortop) + if (strcmp(aggmtransspace, "0") != 0) + { + appendPQExpBuffer(details, ",\n MSSPACE = %s", + aggmtransspace); + } + + if (!PQgetisnull(res, 0, i_aggminitval)) + { + appendPQExpBufferStr(details, ",\n MINITCOND = "); + appendStringLiteralAH(details, aggminitval, fout); + } + + if (strcmp(aggmfinalfn, "-") != 0) + { + appendPQExpBuffer(details, ",\n MFINALFUNC = %s", + aggmfinalfn); + if (aggmfinalextra) + appendPQExpBufferStr(details, ",\n MFINALFUNC_EXTRA"); + } + + aggsortconvop = convertOperatorReference(fout, aggsortop); + if (aggsortconvop) { appendPQExpBuffer(details, ",\n SORTOP = %s", - aggsortop); + aggsortconvop); + free(aggsortconvop); } + if (hypothetical) + appendPQExpBufferStr(details, ",\n HYPOTHETICAL"); + /* * DROP must be fully qualified in case same name appears in pg_catalog */ @@ -11596,7 +11856,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo) aggsig); appendPQExpBuffer(q, "CREATE AGGREGATE %s (\n%s\n);\n", - aggfullsig, details->data); + aggfullsig ? aggfullsig : aggsig, details->data); appendPQExpBuffer(labelq, "AGGREGATE %s", aggsig); @@ -11624,7 +11884,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo) /* * 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. + * syntax for zero-argument aggregates and ordered-set aggregates. */ free(aggsig); free(aggsig_tag); @@ -11639,6 +11899,8 @@ dumpAgg(Archive *fout, AggInfo *agginfo) agginfo->aggfn.rolname, agginfo->aggfn.proacl); free(aggsig); + if (aggfullsig) + free(aggfullsig); free(aggsig_tag); PQclear(res); @@ -11761,10 +12023,10 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo) appendPQExpBuffer(q, "CREATE TEXT SEARCH DICTIONARY %s (\n", fmtId(dictinfo->dobj.name)); - appendPQExpBuffer(q, " TEMPLATE = "); + appendPQExpBufferStr(q, " TEMPLATE = "); if (strcmp(nspname, dictinfo->dobj.namespace->dobj.name) != 0) appendPQExpBuffer(q, "%s.", fmtId(nspname)); - appendPQExpBuffer(q, "%s", fmtId(tmplname)); + appendPQExpBufferStr(q, fmtId(tmplname)); PQclear(res); @@ -11772,7 +12034,7 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo) if (dictinfo->dictinitoption) appendPQExpBuffer(q, ",\n %s", dictinfo->dictinitoption); - appendPQExpBuffer(q, " );\n"); + appendPQExpBufferStr(q, " );\n"); /* * DROP must be fully qualified in case same name appears in pg_catalog @@ -11918,7 +12180,7 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo) appendPQExpBuffer(q, "CREATE TEXT SEARCH CONFIGURATION %s (\n", fmtId(cfginfo->dobj.name)); - appendPQExpBuffer(q, " PARSER = "); + appendPQExpBufferStr(q, " PARSER = "); if (strcmp(nspname, cfginfo->dobj.namespace->dobj.name) != 0) appendPQExpBuffer(q, "%s.", fmtId(nspname)); appendPQExpBuffer(q, "%s );\n", fmtId(prsname)); @@ -11952,7 +12214,7 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo) { /* starting a new token type, so start a new command */ if (i > 0) - appendPQExpBuffer(q, ";\n"); + appendPQExpBufferStr(q, ";\n"); appendPQExpBuffer(q, "\nALTER TEXT SEARCH CONFIGURATION %s\n", fmtId(cfginfo->dobj.name)); /* tokenname needs quoting, dictname does NOT */ @@ -11964,7 +12226,7 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo) } if (ntups > 0) - appendPQExpBuffer(q, ";\n"); + appendPQExpBufferStr(q, ";\n"); PQclear(res); @@ -12045,7 +12307,7 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo) if (strlen(fdwinfo->fdwoptions) > 0) appendPQExpBuffer(q, " OPTIONS (\n %s\n)", fdwinfo->fdwoptions); - appendPQExpBuffer(q, ";\n"); + appendPQExpBufferStr(q, ";\n"); appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n", qfdwname); @@ -12123,22 +12385,22 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo) appendPQExpBuffer(q, "CREATE SERVER %s", qsrvname); if (srvinfo->srvtype && strlen(srvinfo->srvtype) > 0) { - appendPQExpBuffer(q, " TYPE "); + appendPQExpBufferStr(q, " TYPE "); appendStringLiteralAH(q, srvinfo->srvtype, fout); } if (srvinfo->srvversion && strlen(srvinfo->srvversion) > 0) { - appendPQExpBuffer(q, " VERSION "); + appendPQExpBufferStr(q, " VERSION "); appendStringLiteralAH(q, srvinfo->srvversion, fout); } - appendPQExpBuffer(q, " FOREIGN DATA WRAPPER "); - appendPQExpBuffer(q, "%s", fmtId(fdwname)); + appendPQExpBufferStr(q, " FOREIGN DATA WRAPPER "); + appendPQExpBufferStr(q, fmtId(fdwname)); if (srvinfo->srvoptions && strlen(srvinfo->srvoptions) > 0) appendPQExpBuffer(q, " OPTIONS (\n %s\n)", srvinfo->srvoptions); - appendPQExpBuffer(q, ";\n"); + appendPQExpBufferStr(q, ";\n"); appendPQExpBuffer(delq, "DROP SERVER %s;\n", qsrvname); @@ -12255,7 +12517,7 @@ dumpUserMappings(Archive *fout, if (umoptions && strlen(umoptions) > 0) appendPQExpBuffer(q, " OPTIONS (\n %s\n)", umoptions); - appendPQExpBuffer(q, ";\n"); + appendPQExpBufferStr(q, ";\n"); resetPQExpBuffer(delq); appendPQExpBuffer(delq, "DROP USER MAPPING FOR %s", fmtId(usename)); @@ -12280,6 +12542,7 @@ dumpUserMappings(Archive *fout, destroyPQExpBuffer(query); destroyPQExpBuffer(delq); + destroyPQExpBuffer(tag); destroyPQExpBuffer(q); } @@ -12464,7 +12727,7 @@ dumpSecLabel(Archive *fout, const char *target, "SECURITY LABEL FOR %s ON %s IS ", fmtId(labels[i].provider), target); appendStringLiteralAH(query, labels[i].label, fout); - appendPQExpBuffer(query, ";\n"); + appendPQExpBufferStr(query, ";\n"); } if (query->len > 0) @@ -12538,7 +12801,7 @@ dumpTableSecLabel(Archive *fout, TableInfo *tbinfo, const char *reltypename) appendPQExpBuffer(query, "SECURITY LABEL FOR %s ON %s IS ", fmtId(provider), target->data); appendStringLiteralAH(query, label, fout); - appendPQExpBuffer(query, ";\n"); + appendPQExpBufferStr(query, ";\n"); } if (query->len > 0) { @@ -12668,10 +12931,10 @@ collectSecLabels(Archive *fout, SecLabelItem **items) query = createPQExpBuffer(); - appendPQExpBuffer(query, - "SELECT label, provider, classoid, objoid, objsubid " - "FROM pg_catalog.pg_seclabel " - "ORDER BY classoid, objoid, objsubid"); + appendPQExpBufferStr(query, + "SELECT label, provider, classoid, objoid, objsubid " + "FROM pg_catalog.pg_seclabel " + "ORDER BY classoid, objoid, objsubid"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -12753,7 +13016,7 @@ dumpTable(Archive *fout, TableInfo *tbinfo) char *acltag; attnamecopy = pg_strdup(fmtId(attname)); - pg_asprintf(&acltag, "%s.%s", tbinfo->dobj.name, attname); + acltag = psprintf("%s.%s", tbinfo->dobj.name, attname); /* Column's GRANT type is always TABLE */ dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId, "TABLE", namecopy, attnamecopy, acltag, @@ -12794,8 +13057,8 @@ createViewAsClause(Archive *fout, TableInfo *tbinfo) } else { - appendPQExpBuffer(query, "SELECT definition AS viewdef " - "FROM pg_views WHERE viewname = "); + appendPQExpBufferStr(query, "SELECT definition AS viewdef " + "FROM pg_views WHERE viewname = "); appendStringLiteralAH(query, tbinfo->dobj.name, fout); } @@ -12883,7 +13146,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) if (tbinfo->checkoption != NULL) appendPQExpBuffer(q, "\n WITH %s CHECK OPTION", tbinfo->checkoption); - appendPQExpBuffer(q, ";\n"); + appendPQExpBufferStr(q, ";\n"); appendPQExpBuffer(labelq, "VIEW %s", fmtId(tbinfo->dobj.name)); @@ -13002,15 +13265,14 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) /* Format properly if not first attr */ if (actual_atts == 0) - appendPQExpBuffer(q, " ("); + appendPQExpBufferStr(q, " ("); else - appendPQExpBuffer(q, ","); - appendPQExpBuffer(q, "\n "); + appendPQExpBufferStr(q, ","); + appendPQExpBufferStr(q, "\n "); actual_atts++; /* Attribute name */ - appendPQExpBuffer(q, "%s", - fmtId(tbinfo->attnames[j])); + appendPQExpBufferStr(q, fmtId(tbinfo->attnames[j])); if (tbinfo->attisdropped[j]) { @@ -13020,7 +13282,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) * valid type name; insert INTEGER as a stopgap. We'll * clean things up later. */ - appendPQExpBuffer(q, " INTEGER /* dummy */"); + appendPQExpBufferStr(q, " INTEGER /* dummy */"); /* Skip all the rest, too */ continue; } @@ -13028,7 +13290,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) /* Attribute type */ if (tbinfo->reloftype && !binary_upgrade) { - appendPQExpBuffer(q, " WITH OPTIONS"); + appendPQExpBufferStr(q, " WITH OPTIONS"); } else if (fout->remoteVersion >= 70100) { @@ -13054,8 +13316,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) /* always schema-qualify, don't try to be smart */ appendPQExpBuffer(q, " COLLATE %s.", fmtId(coll->dobj.namespace->dobj.name)); - appendPQExpBuffer(q, "%s", - fmtId(coll->dobj.name)); + appendPQExpBufferStr(q, fmtId(coll->dobj.name)); } } @@ -13064,7 +13325,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) tbinfo->attrdefs[j]->adef_expr); if (has_notnull) - appendPQExpBuffer(q, " NOT NULL"); + appendPQExpBufferStr(q, " NOT NULL"); } } @@ -13079,44 +13340,43 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) continue; if (actual_atts == 0) - appendPQExpBuffer(q, " (\n "); + appendPQExpBufferStr(q, " (\n "); else - appendPQExpBuffer(q, ",\n "); + appendPQExpBufferStr(q, ",\n "); appendPQExpBuffer(q, "CONSTRAINT %s ", fmtId(constr->dobj.name)); - appendPQExpBuffer(q, "%s", constr->condef); + appendPQExpBufferStr(q, constr->condef); actual_atts++; } if (actual_atts) - appendPQExpBuffer(q, "\n)"); + appendPQExpBufferStr(q, "\n)"); else if (!(tbinfo->reloftype && !binary_upgrade)) { /* * We must have a parenthesized attribute list, even though * empty, when not using the OF TYPE syntax. */ - appendPQExpBuffer(q, " (\n)"); + appendPQExpBufferStr(q, " (\n)"); } if (numParents > 0 && !binary_upgrade) { - appendPQExpBuffer(q, "\nINHERITS ("); + appendPQExpBufferStr(q, "\nINHERITS ("); for (k = 0; k < numParents; k++) { TableInfo *parentRel = parents[k]; if (k > 0) - appendPQExpBuffer(q, ", "); + appendPQExpBufferStr(q, ", "); if (parentRel->dobj.namespace != tbinfo->dobj.namespace) appendPQExpBuffer(q, "%s.", fmtId(parentRel->dobj.namespace->dobj.name)); - appendPQExpBuffer(q, "%s", - fmtId(parentRel->dobj.name)); + appendPQExpBufferStr(q, fmtId(parentRel->dobj.name)); } - appendPQExpBuffer(q, ")"); + appendPQExpBufferChar(q, ')'); } if (tbinfo->relkind == RELKIND_FOREIGN_TABLE) @@ -13128,18 +13388,18 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) { bool addcomma = false; - appendPQExpBuffer(q, "\nWITH ("); + appendPQExpBufferStr(q, "\nWITH ("); if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0) { addcomma = true; - appendPQExpBuffer(q, "%s", tbinfo->reloptions); + appendPQExpBufferStr(q, tbinfo->reloptions); } if (tbinfo->toast_reloptions && strlen(tbinfo->toast_reloptions) > 0) { appendPQExpBuffer(q, "%s%s", addcomma ? ", " : "", tbinfo->toast_reloptions); } - appendPQExpBuffer(q, ")"); + appendPQExpBufferChar(q, ')'); } /* Dump generic options if any */ @@ -13160,7 +13420,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) destroyPQExpBuffer(result); } else - appendPQExpBuffer(q, ";\n"); + appendPQExpBufferStr(q, ";\n"); /* * To create binary-compatible heap files, we have to ensure the same @@ -13182,7 +13442,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) { if (tbinfo->attisdropped[j]) { - appendPQExpBuffer(q, "\n-- For binary upgrade, recreate dropped column.\n"); + appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate dropped column.\n"); appendPQExpBuffer(q, "UPDATE pg_catalog.pg_attribute\n" "SET attlen = %d, " "attalign = '%c', attbyval = false\n" @@ -13190,9 +13450,9 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) tbinfo->attlen[j], tbinfo->attalign[j]); appendStringLiteralAH(q, tbinfo->attnames[j], fout); - appendPQExpBuffer(q, "\n AND attrelid = "); + appendPQExpBufferStr(q, "\n AND attrelid = "); appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout); - appendPQExpBuffer(q, "::pg_catalog.regclass;\n"); + appendPQExpBufferStr(q, "::pg_catalog.regclass;\n"); if (tbinfo->relkind == RELKIND_RELATION) appendPQExpBuffer(q, "ALTER TABLE ONLY %s ", @@ -13207,14 +13467,14 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) else if (!tbinfo->attislocal[j]) { Assert(tbinfo->relkind != RELKIND_FOREIGN_TABLE); - appendPQExpBuffer(q, "\n-- For binary upgrade, recreate inherited column.\n"); - appendPQExpBuffer(q, "UPDATE pg_catalog.pg_attribute\n" + appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate inherited column.\n"); + appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_attribute\n" "SET attislocal = false\n" "WHERE attname = "); appendStringLiteralAH(q, tbinfo->attnames[j], fout); - appendPQExpBuffer(q, "\n AND attrelid = "); + appendPQExpBufferStr(q, "\n AND attrelid = "); appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout); - appendPQExpBuffer(q, "::pg_catalog.regclass;\n"); + appendPQExpBufferStr(q, "::pg_catalog.regclass;\n"); } } @@ -13225,24 +13485,24 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) if (constr->separate || constr->conislocal) continue; - appendPQExpBuffer(q, "\n-- For binary upgrade, set up inherited constraint.\n"); + appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraint.\n"); appendPQExpBuffer(q, "ALTER TABLE ONLY %s ", fmtId(tbinfo->dobj.name)); appendPQExpBuffer(q, " ADD CONSTRAINT %s ", fmtId(constr->dobj.name)); appendPQExpBuffer(q, "%s;\n", constr->condef); - appendPQExpBuffer(q, "UPDATE pg_catalog.pg_constraint\n" + appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_constraint\n" "SET conislocal = false\n" "WHERE contype = 'c' AND conname = "); appendStringLiteralAH(q, constr->dobj.name, fout); - appendPQExpBuffer(q, "\n AND conrelid = "); + appendPQExpBufferStr(q, "\n AND conrelid = "); appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout); - appendPQExpBuffer(q, "::pg_catalog.regclass;\n"); + appendPQExpBufferStr(q, "::pg_catalog.regclass;\n"); } if (numParents > 0) { - appendPQExpBuffer(q, "\n-- For binary upgrade, set up inheritance this way.\n"); + appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance this way.\n"); for (k = 0; k < numParents; k++) { TableInfo *parentRel = parents[k]; @@ -13259,24 +13519,24 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) if (tbinfo->reloftype) { - appendPQExpBuffer(q, "\n-- For binary upgrade, set up typed tables this way.\n"); + appendPQExpBufferStr(q, "\n-- For binary upgrade, set up typed tables this way.\n"); appendPQExpBuffer(q, "ALTER TABLE ONLY %s OF %s;\n", fmtId(tbinfo->dobj.name), tbinfo->reloftype); } - appendPQExpBuffer(q, "\n-- For binary upgrade, set heap's relfrozenxid\n"); + appendPQExpBufferStr(q, "\n-- For binary upgrade, set heap's relfrozenxid\n"); appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n" "SET relfrozenxid = '%u'\n" "WHERE oid = ", tbinfo->frozenxid); appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout); - appendPQExpBuffer(q, "::pg_catalog.regclass;\n"); + appendPQExpBufferStr(q, "::pg_catalog.regclass;\n"); if (tbinfo->toast_oid) { /* We preserve the toast oids, so we can use it during restore */ - appendPQExpBuffer(q, "\n-- For binary upgrade, set toast's relfrozenxid\n"); + appendPQExpBufferStr(q, "\n-- For binary upgrade, set toast's relfrozenxid\n"); appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n" "SET relfrozenxid = '%u'\n" "WHERE oid = '%u';\n", @@ -13293,12 +13553,12 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) if (binary_upgrade && tbinfo->relkind == RELKIND_MATVIEW && tbinfo->relispopulated) { - appendPQExpBuffer(q, "\n-- For binary upgrade, mark materialized view as populated\n"); - appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n" + appendPQExpBufferStr(q, "\n-- For binary upgrade, mark materialized view as populated\n"); + appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_class\n" "SET relispopulated = 't'\n" "WHERE oid = "); appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout); - appendPQExpBuffer(q, "::pg_catalog.regclass;\n"); + appendPQExpBufferStr(q, "::pg_catalog.regclass;\n"); } /* @@ -13408,6 +13668,28 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) } } + /* + * dump properties we only have ALTER TABLE syntax for + */ + if ((tbinfo->relkind == RELKIND_RELATION || tbinfo->relkind == RELKIND_MATVIEW) && + tbinfo->relreplident != REPLICA_IDENTITY_DEFAULT) + { + if (tbinfo->relreplident == REPLICA_IDENTITY_INDEX) + { + /* nothing to do, will be set when the index is dumped */ + } + else if (tbinfo->relreplident == REPLICA_IDENTITY_NOTHING) + { + appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY NOTHING;\n", + fmtId(tbinfo->dobj.name)); + } + else if (tbinfo->relreplident == REPLICA_IDENTITY_FULL) + { + appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY FULL;\n", + fmtId(tbinfo->dobj.name)); + } + } + if (binary_upgrade) binary_upgrade_extension_member(q, &tbinfo->dobj, labelq->data); @@ -13417,7 +13699,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) (tbinfo->relkind == RELKIND_VIEW) ? NULL : tbinfo->reltablespace, tbinfo->rolname, (strcmp(reltypename, "TABLE") == 0) ? tbinfo->hasoids : false, - reltypename, SECTION_PRE_DATA, + reltypename, + tbinfo->postponed_def ? SECTION_POST_DATA : SECTION_PRE_DATA, q->data, delq->data, NULL, NULL, 0, NULL, NULL); @@ -13579,6 +13862,15 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo) fmtId(indxinfo->dobj.name)); } + /* If the index defines identity, we need to record that. */ + if (indxinfo->indisreplident) + { + appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING", + fmtId(tbinfo->dobj.name)); + appendPQExpBuffer(q, " INDEX %s;\n", + fmtId(indxinfo->dobj.name)); + } + /* * DROP must be fully qualified in case same name appears in * pg_catalog @@ -13676,19 +13968,19 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo) fmtId(attname)); } - appendPQExpBuffer(q, ")"); + appendPQExpBufferChar(q, ')'); if (indxinfo->options && strlen(indxinfo->options) > 0) appendPQExpBuffer(q, " WITH (%s)", indxinfo->options); if (coninfo->condeferrable) { - appendPQExpBuffer(q, " DEFERRABLE"); + appendPQExpBufferStr(q, " DEFERRABLE"); if (coninfo->condeferred) - appendPQExpBuffer(q, " INITIALLY DEFERRED"); + appendPQExpBufferStr(q, " INITIALLY DEFERRED"); } - appendPQExpBuffer(q, ";\n"); + appendPQExpBufferStr(q, ";\n"); } /* If the index is clustered, we need to record that. */ @@ -13881,7 +14173,7 @@ findLastBuiltinOid_V71(Archive *fout, const char *dbname) PQExpBuffer query = createPQExpBuffer(); resetPQExpBuffer(query); - appendPQExpBuffer(query, "SELECT datlastsysoid from pg_database where datname = "); + appendPQExpBufferStr(query, "SELECT datlastsysoid from pg_database where datname = "); appendStringLiteralAH(query, dbname, fout); res = ExecuteSqlQueryForSingleRow(fout, query->data); @@ -14033,18 +14325,18 @@ dumpSequence(Archive *fout, TableInfo *tbinfo) if (minv) appendPQExpBuffer(query, " MINVALUE %s\n", minv); else - appendPQExpBuffer(query, " NO MINVALUE\n"); + appendPQExpBufferStr(query, " NO MINVALUE\n"); if (maxv) appendPQExpBuffer(query, " MAXVALUE %s\n", maxv); else - appendPQExpBuffer(query, " NO MAXVALUE\n"); + appendPQExpBufferStr(query, " NO MAXVALUE\n"); appendPQExpBuffer(query, " CACHE %s%s", cache, (cycled ? "\n CYCLE" : "")); - appendPQExpBuffer(query, ";\n"); + appendPQExpBufferStr(query, ";\n"); appendPQExpBuffer(labelq, "SEQUENCE %s", fmtId(tbinfo->dobj.name)); @@ -14152,7 +14444,7 @@ dumpSequenceData(Archive *fout, TableDataInfo *tdinfo) called = (strcmp(PQgetvalue(res, 0, 1), "t") == 0); resetPQExpBuffer(query); - appendPQExpBuffer(query, "SELECT pg_catalog.setval("); + appendPQExpBufferStr(query, "SELECT pg_catalog.setval("); appendStringLiteralAH(query, fmtId(tbinfo->dobj.name), fout); appendPQExpBuffer(query, ", %s, %s);\n", last, (called ? "true" : "false")); @@ -14172,6 +14464,10 @@ dumpSequenceData(Archive *fout, TableDataInfo *tdinfo) destroyPQExpBuffer(query); } +/* + * dumpTrigger + * write the declaration of one user-defined table trigger + */ static void dumpTrigger(Archive *fout, TriggerInfo *tginfo) { @@ -14184,6 +14480,10 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) const char *p; int findx; + /* + * we needn't check dobj.dump because TriggerInfo wouldn't have been + * created in the first place for non-dumpable triggers + */ if (dataOnly) return; @@ -14209,23 +14509,23 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) { if (tginfo->tgisconstraint) { - appendPQExpBuffer(query, "CREATE CONSTRAINT TRIGGER "); + appendPQExpBufferStr(query, "CREATE CONSTRAINT TRIGGER "); appendPQExpBufferStr(query, fmtId(tginfo->tgconstrname)); } else { - appendPQExpBuffer(query, "CREATE TRIGGER "); + appendPQExpBufferStr(query, "CREATE TRIGGER "); appendPQExpBufferStr(query, fmtId(tginfo->dobj.name)); } - appendPQExpBuffer(query, "\n "); + appendPQExpBufferStr(query, "\n "); /* Trigger type */ if (TRIGGER_FOR_BEFORE(tginfo->tgtype)) - appendPQExpBuffer(query, "BEFORE"); + appendPQExpBufferStr(query, "BEFORE"); else if (TRIGGER_FOR_AFTER(tginfo->tgtype)) - appendPQExpBuffer(query, "AFTER"); + appendPQExpBufferStr(query, "AFTER"); else if (TRIGGER_FOR_INSTEAD(tginfo->tgtype)) - appendPQExpBuffer(query, "INSTEAD OF"); + appendPQExpBufferStr(query, "INSTEAD OF"); else { write_msg(NULL, "unexpected tgtype value: %d\n", tginfo->tgtype); @@ -14235,31 +14535,31 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) findx = 0; if (TRIGGER_FOR_INSERT(tginfo->tgtype)) { - appendPQExpBuffer(query, " INSERT"); + appendPQExpBufferStr(query, " INSERT"); findx++; } if (TRIGGER_FOR_DELETE(tginfo->tgtype)) { if (findx > 0) - appendPQExpBuffer(query, " OR DELETE"); + appendPQExpBufferStr(query, " OR DELETE"); else - appendPQExpBuffer(query, " DELETE"); + appendPQExpBufferStr(query, " DELETE"); findx++; } if (TRIGGER_FOR_UPDATE(tginfo->tgtype)) { if (findx > 0) - appendPQExpBuffer(query, " OR UPDATE"); + appendPQExpBufferStr(query, " OR UPDATE"); else - appendPQExpBuffer(query, " UPDATE"); + appendPQExpBufferStr(query, " UPDATE"); findx++; } if (TRIGGER_FOR_TRUNCATE(tginfo->tgtype)) { if (findx > 0) - appendPQExpBuffer(query, " OR TRUNCATE"); + appendPQExpBufferStr(query, " OR TRUNCATE"); else - appendPQExpBuffer(query, " TRUNCATE"); + appendPQExpBufferStr(query, " TRUNCATE"); findx++; } appendPQExpBuffer(query, " ON %s\n", @@ -14278,18 +14578,18 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) fmtId(tginfo->tgconstrrelname)); } if (!tginfo->tgdeferrable) - appendPQExpBuffer(query, "NOT "); - appendPQExpBuffer(query, "DEFERRABLE INITIALLY "); + appendPQExpBufferStr(query, "NOT "); + appendPQExpBufferStr(query, "DEFERRABLE INITIALLY "); if (tginfo->tginitdeferred) - appendPQExpBuffer(query, "DEFERRED\n"); + appendPQExpBufferStr(query, "DEFERRED\n"); else - appendPQExpBuffer(query, "IMMEDIATE\n"); + appendPQExpBufferStr(query, "IMMEDIATE\n"); } if (TRIGGER_FOR_ROW(tginfo->tgtype)) - appendPQExpBuffer(query, " FOR EACH ROW\n "); + appendPQExpBufferStr(query, " FOR EACH ROW\n "); else - appendPQExpBuffer(query, " FOR EACH STATEMENT\n "); + appendPQExpBufferStr(query, " FOR EACH STATEMENT\n "); /* In 7.3, result of regproc is already quoted */ if (fout->remoteVersion >= 70300) @@ -14318,12 +14618,12 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) } if (findx > 0) - appendPQExpBuffer(query, ", "); + appendPQExpBufferStr(query, ", "); appendStringLiteralAH(query, p, fout); p += tlen + 1; } free(tgargs); - appendPQExpBuffer(query, ");\n"); + appendPQExpBufferStr(query, ");\n"); } if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O') @@ -14334,16 +14634,16 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) { case 'D': case 'f': - appendPQExpBuffer(query, "DISABLE"); + appendPQExpBufferStr(query, "DISABLE"); break; case 'A': - appendPQExpBuffer(query, "ENABLE ALWAYS"); + appendPQExpBufferStr(query, "ENABLE ALWAYS"); break; case 'R': - appendPQExpBuffer(query, "ENABLE REPLICA"); + appendPQExpBufferStr(query, "ENABLE REPLICA"); break; default: - appendPQExpBuffer(query, "ENABLE"); + appendPQExpBufferStr(query, "ENABLE"); break; } appendPQExpBuffer(query, " TRIGGER %s;\n", @@ -14374,18 +14674,26 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) destroyPQExpBuffer(labelq); } +/* + * dumpEventTrigger + * write the declaration of one user-defined event trigger + */ static void dumpEventTrigger(Archive *fout, EventTriggerInfo *evtinfo) { PQExpBuffer query; PQExpBuffer labelq; + /* Skip if not to be dumped */ + if (!evtinfo->dobj.dump || dataOnly) + return; + query = createPQExpBuffer(); labelq = createPQExpBuffer(); - appendPQExpBuffer(query, "CREATE EVENT TRIGGER "); + appendPQExpBufferStr(query, "CREATE EVENT TRIGGER "); appendPQExpBufferStr(query, fmtId(evtinfo->dobj.name)); - appendPQExpBuffer(query, " ON "); + appendPQExpBufferStr(query, " ON "); appendPQExpBufferStr(query, fmtId(evtinfo->evtevent)); appendPQExpBufferStr(query, " "); @@ -14396,9 +14704,9 @@ dumpEventTrigger(Archive *fout, EventTriggerInfo *evtinfo) appendPQExpBufferStr(query, ") "); } - appendPQExpBuffer(query, "\n EXECUTE PROCEDURE "); + appendPQExpBufferStr(query, "\n EXECUTE PROCEDURE "); appendPQExpBufferStr(query, evtinfo->evtfname); - appendPQExpBuffer(query, "();\n"); + appendPQExpBufferStr(query, "();\n"); if (evtinfo->evtenabled != 'O') { @@ -14407,19 +14715,19 @@ dumpEventTrigger(Archive *fout, EventTriggerInfo *evtinfo) switch (evtinfo->evtenabled) { case 'D': - appendPQExpBuffer(query, "DISABLE"); + appendPQExpBufferStr(query, "DISABLE"); break; case 'A': - appendPQExpBuffer(query, "ENABLE ALWAYS"); + appendPQExpBufferStr(query, "ENABLE ALWAYS"); break; case 'R': - appendPQExpBuffer(query, "ENABLE REPLICA"); + appendPQExpBufferStr(query, "ENABLE REPLICA"); break; default: - appendPQExpBuffer(query, "ENABLE"); + appendPQExpBufferStr(query, "ENABLE"); break; } - appendPQExpBuffer(query, ";\n"); + appendPQExpBufferStr(query, ";\n"); } appendPQExpBuffer(labelq, "EVENT TRIGGER %s ", fmtId(evtinfo->dobj.name)); @@ -14598,12 +14906,12 @@ getExtensionMembership(Archive *fout, ExtensionInfo extinfo[], query = createPQExpBuffer(); /* refclassid constraint is redundant but may speed the search */ - appendPQExpBuffer(query, "SELECT " - "classid, objid, refclassid, refobjid " - "FROM pg_depend " - "WHERE refclassid = 'pg_extension'::regclass " - "AND deptype = 'e' " - "ORDER BY 3,4"); + appendPQExpBufferStr(query, "SELECT " + "classid, objid, refclassid, refobjid " + "FROM pg_depend " + "WHERE refclassid = 'pg_extension'::regclass " + "AND deptype = 'e' " + "ORDER BY 3,4"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -14802,11 +15110,11 @@ getDependencies(Archive *fout) * PIN dependencies aren't interesting, and EXTENSION dependencies were * already processed by getExtensionMembership. */ - appendPQExpBuffer(query, "SELECT " - "classid, objid, refclassid, refobjid, deptype " - "FROM pg_depend " - "WHERE deptype != 'p' AND deptype != 'e' " - "ORDER BY 1,2"); + appendPQExpBufferStr(query, "SELECT " + "classid, objid, refclassid, refobjid, deptype " + "FROM pg_depend " + "WHERE deptype != 'p' AND deptype != 'e' " + "ORDER BY 1,2"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -15146,7 +15454,7 @@ selectSourceSchema(Archive *fout, const char *schemaName) appendPQExpBuffer(query, "SET search_path = %s", fmtId(schemaName)); if (strcmp(schemaName, "pg_catalog") != 0) - appendPQExpBuffer(query, ", pg_catalog"); + appendPQExpBufferStr(query, ", pg_catalog"); ExecuteSqlStatement(fout, query->data); @@ -15239,21 +15547,21 @@ myFormatType(const char *typname, int32 typmod) { int len = (typmod - VARHDRSZ); - appendPQExpBuffer(buf, "character"); + appendPQExpBufferStr(buf, "character"); if (len > 1) appendPQExpBuffer(buf, "(%d)", typmod - VARHDRSZ); } else if (strcmp(typname, "varchar") == 0) { - appendPQExpBuffer(buf, "character varying"); + appendPQExpBufferStr(buf, "character varying"); if (typmod != -1) appendPQExpBuffer(buf, "(%d)", typmod - VARHDRSZ); } else if (strcmp(typname, "numeric") == 0) { - appendPQExpBuffer(buf, "numeric"); + appendPQExpBufferStr(buf, "numeric"); if (typmod != -1) { int32 tmp_typmod; @@ -15273,13 +15581,13 @@ myFormatType(const char *typname, int32 typmod) * through with quotes. - thomas 1998-12-13 */ else if (strcmp(typname, "char") == 0) - appendPQExpBuffer(buf, "\"char\""); + appendPQExpBufferStr(buf, "\"char\""); else - appendPQExpBuffer(buf, "%s", fmtId(typname)); + appendPQExpBufferStr(buf, fmtId(typname)); /* Append array qualifier for array types */ if (isarray) - appendPQExpBuffer(buf, "[]"); + appendPQExpBufferStr(buf, "[]"); result = pg_strdup(buf->data); destroyPQExpBuffer(buf); @@ -15302,22 +15610,22 @@ fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer) bool needComma; int i; - appendPQExpBuffer(buffer, "("); + appendPQExpBufferChar(buffer, '('); needComma = false; for (i = 0; i < numatts; i++) { if (attisdropped[i]) continue; if (needComma) - appendPQExpBuffer(buffer, ", "); - appendPQExpBuffer(buffer, "%s", fmtId(attnames[i])); + appendPQExpBufferStr(buffer, ", "); + appendPQExpBufferStr(buffer, fmtId(attnames[i])); needComma = true; } if (!needComma) return ""; /* no undropped columns */ - appendPQExpBuffer(buffer, ")"); + appendPQExpBufferChar(buffer, ')'); return buffer->data; }