Attached is a proposed patch that refactors getTables() along the
same lines as some previous work (eg 047329624, ed2c7f65b, daa9fe8a5)
to avoid having multiple partially-redundant copies of the SQL query.
This gets rid of nearly 300 lines of duplicative spaghetti code,
creates a uniform style for dealing with cross-version changes
(replacing at least three different methods currently being used
for that in this same stretch of code), and allows moving some
comments to be closer to the code they describe.
There's a lot I still want to change here, but this part seems like it
should be fairly uncontroversial. I've tested it against servers back
to 8.0 (which is what led me to trip over the bug fixed in 40dfac4fc).
Any objections to just pushing it?
regards, tom lane
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 6ec524f8e6..e35ff6e7fb 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -6274,65 +6274,152 @@ getTables(Archive *fout, int *numTables)
* We include system catalogs, so that we can work if a user table is
* defined to inherit from a system catalog (pretty weird, but...)
*
- * We ignore relations that are not ordinary tables, sequences, views,
- * materialized views, composite types, or foreign tables.
- *
- * Composite-type table entries won't be dumped as such, but we have to
- * make a DumpableObject for them so that we can track dependencies of the
- * composite type (pg_depend entries for columns of the composite type
- * link to the pg_class entry not the pg_type entry).
- *
* Note: in this phase we should collect only a minimal amount of
* information about each table, basically just enough to decide if it is
* interesting. We must fetch all tables in this phase because otherwise
* we cannot correctly identify inherited columns, owned sequences, etc.
- *
- * We purposefully ignore toast OIDs for partitioned tables; the reason is
- * that versions 10 and 11 have them, but 12 does not, so emitting them
- * causes the upgrade to fail.
*/
+ appendPQExpBuffer(query,
+ "SELECT c.tableoid, c.oid, c.relname, "
+ "c.relnamespace, c.relkind, "
+ "(%s c.relowner) AS rolname, "
+ "c.relchecks, "
+ "c.relhasindex, c.relhasrules, c.relpages, "
+ "d.refobjid AS owning_tab, "
+ "d.refobjsubid AS owning_col, "
+ "tsp.spcname AS reltablespace, ",
+ username_subquery);
+
+ if (fout->remoteVersion >= 80400)
+ appendPQExpBufferStr(query,
+ "c.relhastriggers, ");
+ else
+ appendPQExpBufferStr(query,
+ "(c.reltriggers <> 0) AS relhastriggers, ");
+
+ if (fout->remoteVersion >= 90500)
+ appendPQExpBufferStr(query,
+ "c.relrowsecurity, c.relforcerowsecurity, ");
+ else
+ appendPQExpBufferStr(query,
+ "false AS relrowsecurity, "
+ "false AS relforcerowsecurity, ");
+
+ if (fout->remoteVersion >= 12)
+ appendPQExpBufferStr(query,
+ "false AS relhasoids, ");
+ else
+ appendPQExpBufferStr(query,
+ "c.relhasoids, ");
+
+ if (fout->remoteVersion >= 80200)
+ appendPQExpBufferStr(query,
+ "c.relfrozenxid, tc.relfrozenxid AS tfrozenxid, ");
+ else
+ appendPQExpBufferStr(query,
+ "0 AS relfrozenxid, 0 AS tfrozenxid, ");
+
+ if (fout->remoteVersion >= 90300)
+ appendPQExpBufferStr(query,
+ "c.relminmxid, tc.relminmxid AS tminmxid, ");
+ else
+ appendPQExpBufferStr(query,
+ "0 AS relminmxid, 0 AS tminmxid, ");
+
+ if (fout->remoteVersion >= 80200)
+ appendPQExpBufferStr(query,
+ "tc.oid AS toid, ");
+ else
+ appendPQExpBufferStr(query,
+ "0 AS toid, ");
+
+ if (fout->remoteVersion >= 90100)
+ appendPQExpBufferStr(query,
+ "c.relpersistence, ");
+ else
+ appendPQExpBufferStr(query,
+ "'p' AS relpersistence, ");
+
+ if (fout->remoteVersion >= 90300)
+ appendPQExpBufferStr(query,
+ "c.relispopulated, ");
+ else
+ appendPQExpBufferStr(query,
+ "'t' as relispopulated, ");
+
+ if (fout->remoteVersion >= 90400)
+ appendPQExpBufferStr(query,
+ "c.relreplident, ");
+ else
+ appendPQExpBufferStr(query,
+ "'d' AS relreplident, ");
+
+ if (fout->remoteVersion >= 90100)
+ appendPQExpBufferStr(query,
+ "CASE WHEN c.relkind = " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN "
+ "(SELECT ftserver FROM pg_catalog.pg_foreign_table WHERE ftrelid = c.oid) "
+ "ELSE 0 END AS foreignserver, ");
+ else
+ appendPQExpBufferStr(query,
+ "0 AS foreignserver, ");
+
+ if (fout->remoteVersion >= 90300)
+ appendPQExpBufferStr(query,
+ "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, ");
+ else if (fout->remoteVersion >= 80200)
+ appendPQExpBufferStr(query,
+