diff options
Diffstat (limited to 'src/bin/pg_dump/pg_dump.c')
-rw-r--r-- | src/bin/pg_dump/pg_dump.c | 73 |
1 files changed, 58 insertions, 15 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 08288e871a9..b0a0dc56072 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -975,8 +975,9 @@ expand_table_name_patterns(SimpleStringList *patterns, SimpleOidList *oids) "SELECT c.oid" "\nFROM pg_catalog.pg_class c" "\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace" - "\nWHERE c.relkind in ('%c', '%c', '%c')\n", - RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW); + "\nWHERE c.relkind in ('%c', '%c', '%c', '%c')\n", + RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW, + RELKIND_FOREIGN_TABLE); processSQLNamePattern(g_conn, query, cell->val, true, false, "n.nspname", "c.relname", NULL, "pg_catalog.pg_table_is_visible(c.oid)"); @@ -1476,6 +1477,9 @@ getTableData(TableInfo *tblinfo, int numTables, bool oids) /* Skip SEQUENCEs (handled elsewhere) */ if (tblinfo[i].relkind == RELKIND_SEQUENCE) continue; + /* Skip FOREIGN TABLEs (no data to dump) */ + if (tblinfo[i].relkind == RELKIND_FOREIGN_TABLE) + continue; /* Skip unlogged tables if so requested */ if (tblinfo[i].relpersistence == RELPERSISTENCE_UNLOGGED && no_unlogged_table_data) @@ -3513,12 +3517,13 @@ getTables(int *numTables) "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') " + "WHERE c.relkind in ('%c', '%c', '%c', '%c', '%c') " "ORDER BY c.oid", username_subquery, RELKIND_SEQUENCE, RELKIND_RELATION, RELKIND_SEQUENCE, - RELKIND_VIEW, RELKIND_COMPOSITE_TYPE); + RELKIND_VIEW, RELKIND_COMPOSITE_TYPE, + RELKIND_FOREIGN_TABLE); } else if (g_fout->remoteVersion >= 90000) { @@ -3871,7 +3876,7 @@ getTables(int *numTables) * assume our lock on the child is enough to prevent schema * alterations to parent tables. * - * NOTE: it'd be kinda nice to lock views and sequences too, not only + * NOTE: it'd be kinda nice to lock other relations too, not only * plain tables, but the backend doesn't presently allow that. */ if (tblinfo[i].dobj.dump && tblinfo[i].relkind == RELKIND_RELATION) @@ -10938,7 +10943,9 @@ dumpTable(Archive *fout, TableInfo *tbinfo) /* Handle the ACL here */ namecopy = strdup(fmtId(tbinfo->dobj.name)); dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId, - (tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE", + (tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : + (tbinfo->relkind == RELKIND_FOREIGN_TABLE) ? "FOREIGN TABLE" : + "TABLE", namecopy, NULL, tbinfo->dobj.name, tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->relacl); @@ -11007,6 +11014,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) int j, k; bool toast_set = false; + char *srvname; + char *ftoptions = NULL; /* Make sure we are in proper schema */ selectSourceSchema(tbinfo->dobj.namespace->dobj.name); @@ -11080,7 +11089,35 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) } else { - reltypename = "TABLE"; + if (tbinfo->relkind == RELKIND_FOREIGN_TABLE) + { + int i_srvname; + int i_ftoptions; + + reltypename = "FOREIGN TABLE"; + + /* retrieve name of foreign server and generic options */ + appendPQExpBuffer(query, + "SELECT fs.srvname, array_to_string(ARRAY(" + " SELECT option_name || ' ' || quote_literal(option_value)" + " FROM pg_options_to_table(ftoptions)), ', ') AS ftoptions " + "FROM pg_foreign_table ft JOIN pg_foreign_server fs " + " ON (fs.oid = ft.ftserver) " + "WHERE ft.ftrelid = %u", tbinfo->dobj.catId.oid); + res = PQexec(g_conn, query->data); + check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK); + i_srvname = PQfnumber(res, "srvname"); + i_ftoptions = PQfnumber(res, "ftoptions"); + srvname = strdup(PQgetvalue(res, 0, i_srvname)); + ftoptions = strdup(PQgetvalue(res, 0, i_ftoptions)); + PQclear(res); + } + else + { + reltypename = "TABLE"; + srvname = NULL; + ftoptions = NULL; + } numParents = tbinfo->numParents; parents = tbinfo->parents; @@ -11088,7 +11125,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) * DROP must be fully qualified in case same name appears in * pg_catalog */ - appendPQExpBuffer(delq, "DROP TABLE %s.", + appendPQExpBuffer(delq, "DROP %s %s.", reltypename, fmtId(tbinfo->dobj.namespace->dobj.name)); appendPQExpBuffer(delq, "%s;\n", fmtId(tbinfo->dobj.name)); @@ -11096,12 +11133,11 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) if (binary_upgrade) binary_upgrade_set_relfilenodes(q, tbinfo->dobj.catId.oid, false); - if (tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED) - appendPQExpBuffer(q, "CREATE UNLOGGED TABLE %s", - fmtId(tbinfo->dobj.name)); - else - appendPQExpBuffer(q, "CREATE TABLE %s", - fmtId(tbinfo->dobj.name)); + appendPQExpBuffer(q, "CREATE %s%s %s", + tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ? + "UNLOGGED " : "", + reltypename, + fmtId(tbinfo->dobj.name)); if (tbinfo->reloftype) appendPQExpBuffer(q, " OF %s", tbinfo->reloftype); actual_atts = 0; @@ -11235,6 +11271,9 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) appendPQExpBuffer(q, ")"); } + if (tbinfo->relkind == RELKIND_FOREIGN_TABLE) + appendPQExpBuffer(q, "\nSERVER %s", srvname); + if ((tbinfo->reloptions && strlen(tbinfo->reloptions) > 0) || (tbinfo->toast_reloptions && strlen(tbinfo->toast_reloptions) > 0)) { @@ -11254,6 +11293,10 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) appendPQExpBuffer(q, ")"); } + /* Dump generic options if any */ + if (ftoptions && ftoptions[0]) + appendPQExpBuffer(q, "\nOPTIONS (%s)", ftoptions); + appendPQExpBuffer(q, ";\n"); /* @@ -11268,7 +11311,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) * order. That also means we have to take care about setting * attislocal correctly, plus fix up any inherited CHECK constraints. */ - if (binary_upgrade) + if (binary_upgrade && tbinfo->relkind == RELKIND_RELATION) { for (j = 0; j < tbinfo->numatts; j++) { |