From b21edbb59a6a5abb6cefdd2e0a84dfec06010300 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Wed, 8 Apr 2026 10:40:38 -0500 Subject: [PATCH v1 1/1] remove pg_dump, pg_dumpall, and pg_upgrade support for pre-10 servers --- doc/src/sgml/ref/pg_dump.sgml | 14 +- doc/src/sgml/ref/pgupgrade.sgml | 2 +- src/bin/pg_dump/pg_dump.c | 792 ++++++++--------------------- src/bin/pg_dump/pg_dumpall.c | 4 +- src/bin/pg_upgrade/check.c | 175 +------ src/bin/pg_upgrade/controldata.c | 97 +--- src/bin/pg_upgrade/exec.c | 20 +- src/bin/pg_upgrade/file.c | 164 ------ src/bin/pg_upgrade/pg_upgrade.c | 92 +--- src/bin/pg_upgrade/pg_upgrade.h | 30 -- src/bin/pg_upgrade/relfilenumber.c | 87 ++-- src/bin/pg_upgrade/server.c | 4 +- src/bin/pg_upgrade/version.c | 127 ----- src/bin/psql/command.c | 48 +- src/bin/psql/describe.c | 703 +++++++++---------------- src/bin/psql/tab-complete.in.c | 46 +- 16 files changed, 569 insertions(+), 1836 deletions(-) diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index ae1bc14d2f2..64a3447e445 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -407,18 +407,6 @@ PostgreSQL documentation and there is no way to continue with the dump, so pg_dump has no choice but to abort the dump. - - To perform a parallel dump, the database server needs to support - synchronized snapshots, a feature that was introduced in - PostgreSQL 9.2 for primary servers and 10 - for standbys. With this feature, database clients can ensure they see - the same data set even though they use different connections. - pg_dump -j uses multiple database connections; it - connects to the database once with the leader process and once again - for each worker job. Without the synchronized snapshot feature, the - different worker jobs wouldn't be guaranteed to see the same data in - each connection, which could lead to an inconsistent backup. - @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; PostgreSQL server versions newer than pg_dump's version. pg_dump can also dump from PostgreSQL servers older than its own version. - (Currently, servers back to version 9.2 are supported.) + (Currently, servers back to version 10 are supported.) However, pg_dump cannot dump from PostgreSQL servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump. diff --git a/doc/src/sgml/ref/pgupgrade.sgml b/doc/src/sgml/ref/pgupgrade.sgml index 38ca09b423c..c4ed75211db 100644 --- a/doc/src/sgml/ref/pgupgrade.sgml +++ b/doc/src/sgml/ref/pgupgrade.sgml @@ -67,7 +67,7 @@ PostgreSQL documentation - pg_upgrade supports upgrades from 9.2.X and later to the current + pg_upgrade supports upgrades from 10.X and later to the current major release of PostgreSQL, including snapshot and beta releases. diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index d34240073bb..70174715d2d 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -977,10 +977,10 @@ main(int argc, char **argv) /* - * We allow the server to be back to 9.2, and up to any minor release of + * We allow the server to be back to 10, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = numWorkers; @@ -1491,10 +1491,8 @@ setup_connection(Archive *AH, const char *dumpencoding, * Disable timeouts if supported. */ ExecuteSqlStatement(AH, "SET statement_timeout = 0"); - if (AH->remoteVersion >= 90300) - ExecuteSqlStatement(AH, "SET lock_timeout = 0"); - if (AH->remoteVersion >= 90600) - ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); + ExecuteSqlStatement(AH, "SET lock_timeout = 0"); + ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0"); if (AH->remoteVersion >= 170000) ExecuteSqlStatement(AH, "SET transaction_timeout = 0"); @@ -1507,13 +1505,10 @@ setup_connection(Archive *AH, const char *dumpencoding, /* * Adjust row-security mode, if supported. */ - if (AH->remoteVersion >= 90500) - { - if (dopt->enable_row_security) - ExecuteSqlStatement(AH, "SET row_security = on"); - else - ExecuteSqlStatement(AH, "SET row_security = off"); - } + if (dopt->enable_row_security) + ExecuteSqlStatement(AH, "SET row_security = on"); + else + ExecuteSqlStatement(AH, "SET row_security = off"); /* * For security reasons, we restrict the expansion of non-system views and @@ -1568,11 +1563,7 @@ setup_connection(Archive *AH, const char *dumpencoding, destroyPQExpBuffer(query); } else if (AH->numWorkers > 1) - { - if (AH->isStandby && AH->remoteVersion < 100000) - pg_fatal("parallel dumps from standby servers are not supported by this server version"); AH->sync_snapshot_id = get_synchronized_snapshot(AH); - } } /* Set up connection for a parallel worker process */ @@ -1942,12 +1933,9 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) addObjectDependency(dobj, ext->dobj.dumpId); /* - * In 9.6 and above, mark the member object to have any non-initial ACLs - * dumped. (Any initial ACLs will be removed later, using data from - * pg_init_privs, so that we'll dump only the delta from the extension's - * initial setup.) - * - * Prior to 9.6, we do not include any extension member components. + * Mark the member object to have any non-initial ACLs dumped. (Any + * initial ACLs will be removed later, using data from pg_init_privs, so + * that we'll dump only the delta from the extension's initial setup.) * * In binary upgrades, we still dump all components of the members * individually, since the idea is to exactly reproduce the database @@ -1964,12 +1952,7 @@ checkExtensionMembership(DumpableObject *dobj, Archive *fout) if (fout->dopt->binary_upgrade) dobj->dump = ext->dobj.dump; else - { - if (fout->remoteVersion < 90600) - dobj->dump = DUMP_COMPONENT_NONE; - else - dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); - } + dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL); return true; } @@ -2000,8 +1983,7 @@ selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout) simple_oid_list_member(&schema_include_oids, nsinfo->dobj.catId.oid) ? DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; - else if (fout->remoteVersion >= 90600 && - strcmp(nsinfo->dobj.name, "pg_catalog") == 0) + else if (strcmp(nsinfo->dobj.name, "pg_catalog") == 0) { /* * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if @@ -2213,8 +2195,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) else { if (plang->dobj.catId.oid <= g_last_builtin_oid) - plang->dobj.dump = fout->remoteVersion < 90600 ? - DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; + plang->dobj.dump = DUMP_COMPONENT_ACL; else plang->dobj.dump = DUMP_COMPONENT_ALL; } @@ -2231,13 +2212,6 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) static void selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) { - /* see getAccessMethods() comment about v9.6. */ - if (fout->remoteVersion < 90600) - { - method->dobj.dump = DUMP_COMPONENT_NONE; - return; - } - if (checkExtensionMembership(&method->dobj, fout)) return; /* extension membership overrides all else */ @@ -3123,10 +3097,6 @@ buildMatViewRefreshDependencies(Archive *fout) i_objid, i_refobjid; - /* No Mat Views before 9.3. */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "WITH RECURSIVE w AS " @@ -3324,11 +3294,7 @@ dumpDatabase(Archive *fout) "pg_encoding_to_char(encoding) AS encoding, " "datcollate, datctype, datfrozenxid, " "datacl, acldefault('d', datdba) AS acldefault, " - "datistemplate, datconnlimit, "); - if (fout->remoteVersion >= 90300) - appendPQExpBufferStr(dbQry, "datminmxid, "); - else - appendPQExpBufferStr(dbQry, "0 AS datminmxid, "); + "datistemplate, datconnlimit, datminmxid, "); if (fout->remoteVersion >= 170000) appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, "); else if (fout->remoteVersion >= 150000) @@ -3670,17 +3636,11 @@ dumpDatabase(Archive *fout) ii_oid, ii_relminmxid; - if (fout->remoteVersion >= 90300) - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u, %u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId, - LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid IN (%u, %u);\n", - LargeObjectRelationId, LargeObjectLOidPNIndexId); + appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n" + "FROM pg_catalog.pg_class\n" + "WHERE oid IN (%u, %u, %u, %u);\n", + LargeObjectRelationId, LargeObjectLOidPNIndexId, + LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId); lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK); @@ -4243,10 +4203,6 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - /* No policies before 9.5 */ - if (fout->remoteVersion < 90500) - return; - /* Skip if --no-policies was specified */ if (dopt->no_policies) return; @@ -4315,12 +4271,7 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) pg_log_info("reading row-level security policies"); printfPQExpBuffer(query, - "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, "); - if (fout->remoteVersion >= 100000) - appendPQExpBufferStr(query, "pol.polpermissive, "); - else - appendPQExpBufferStr(query, "'t' as polpermissive, "); - appendPQExpBuffer(query, + "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, pol.polpermissive, " "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE " " pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, " "pg_catalog.pg_get_expr(pol.polqual, pol.polrelid) AS polqual, " @@ -4534,7 +4485,7 @@ getPublications(Archive *fout) int i, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -4897,7 +4848,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (dopt->no_publications || fout->remoteVersion < 100000) + if (dopt->no_publications) return; query = createPQExpBuffer(); @@ -5187,7 +5138,7 @@ getSubscriptions(Archive *fout) int i, ntups; - if (dopt->no_subscriptions || fout->remoteVersion < 100000) + if (dopt->no_subscriptions) return; if (!is_superuser(fout)) @@ -6675,26 +6626,10 @@ getAccessMethods(Archive *fout) query = createPQExpBuffer(); - /* - * Select all access methods from pg_am table. v9.6 introduced CREATE - * ACCESS METHOD, so earlier versions usually have only built-in access - * methods. v9.6 also changed the access method API, replacing dozens of - * pg_am columns with amhandler. Even if a user created an access method - * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am - * columns to a v9.6+ CREATE ACCESS METHOD. Hence, before v9.6, read - * pg_am just to facilitate findAccessMethodByOid() providing the - * OID-to-name mapping. - */ - appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, "); - if (fout->remoteVersion >= 90600) - appendPQExpBufferStr(query, - "amtype, " - "amhandler::pg_catalog.regproc AS amhandler "); - else - appendPQExpBufferStr(query, - "'i'::pg_catalog.\"char\" AS amtype, " - "'-'::pg_catalog.regproc AS amhandler "); - appendPQExpBufferStr(query, "FROM pg_am"); + /* Select all access methods from pg_am table. */ + appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, amtype, " + "amhandler::pg_catalog.regproc AS amhandler " + "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6879,67 +6814,41 @@ getAggregates(Archive *fout) int i_proowner; int i_aggacl; int i_acldefault; + const char *agg_check; /* * Find all interesting aggregates. See comment in getFuncs() for the * rationale behind the filtering logic. */ - if (fout->remoteVersion >= 90600) - { - const char *agg_check; - - agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" - : "p.proisagg"); + agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'" + : "p.proisagg"); - appendPQExpBuffer(query, "SELECT p.tableoid, p.oid, " - "p.proname AS aggname, " - "p.pronamespace AS aggnamespace, " - "p.pronargs, p.proargtypes, " - "p.proowner, " - "p.proacl AS aggacl, " - "acldefault('f', p.proowner) AS acldefault " - "FROM pg_proc p " - "LEFT JOIN pg_init_privs pip ON " - "(p.oid = pip.objoid " - "AND pip.classoid = 'pg_proc'::regclass " - "AND pip.objsubid = 0) " - "WHERE %s AND (" - "p.pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog') OR " - "p.proacl IS DISTINCT FROM pip.initprivs", - agg_check); - if (dopt->binary_upgrade) - 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 - { - appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, " - "pronamespace AS aggnamespace, " - "pronargs, proargtypes, " - "proowner, " - "proacl AS aggacl, " - "acldefault('f', proowner) AS acldefault " - "FROM pg_proc p " - "WHERE proisagg AND (" - "pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')"); - if (dopt->binary_upgrade) - 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, ')'); - } + appendPQExpBuffer(query, "SELECT p.tableoid, p.oid, " + "p.proname AS aggname, " + "p.pronamespace AS aggnamespace, " + "p.pronargs, p.proargtypes, " + "p.proowner, " + "p.proacl AS aggacl, " + "acldefault('f', p.proowner) AS acldefault " + "FROM pg_proc p " + "LEFT JOIN pg_init_privs pip ON " + "(p.oid = pip.objoid " + "AND pip.classoid = 'pg_proc'::regclass " + "AND pip.objsubid = 0) " + "WHERE %s AND (" + "p.pronamespace != " + "(SELECT oid FROM pg_namespace " + "WHERE nspname = 'pg_catalog') OR " + "p.proacl IS DISTINCT FROM pip.initprivs", + agg_check); + if (dopt->binary_upgrade) + 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, ')'); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7022,6 +6931,7 @@ getFuncs(Archive *fout) int i_prorettype; int i_proacl; int i_acldefault; + const char *not_agg_check; /* * Find all interesting functions. This is a bit complicated: @@ -7044,93 +6954,49 @@ getFuncs(Archive *fout) * pg_catalog if they have an ACL different from what's shown in * pg_init_privs (so we have to join to pg_init_privs; annoying). */ - if (fout->remoteVersion >= 90600) - { - const char *not_agg_check; - - not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" - : "NOT p.proisagg"); + not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'" + : "NOT p.proisagg"); - appendPQExpBuffer(query, - "SELECT p.tableoid, p.oid, p.proname, p.prolang, " - "p.pronargs, p.proargtypes, p.prorettype, " - "p.proacl, " - "acldefault('f', p.proowner) AS acldefault, " - "p.pronamespace, " - "p.proowner " - "FROM pg_proc p " - "LEFT JOIN pg_init_privs pip ON " - "(p.oid = pip.objoid " - "AND pip.classoid = 'pg_proc'::regclass " - "AND pip.objsubid = 0) " - "WHERE %s" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > %u " - "\n AND p.oid = pg_cast.castfunc)" - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > %u AND " - "\n (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - not_agg_check, - g_last_builtin_oid, - g_last_builtin_oid); - if (dopt->binary_upgrade) - 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')"); + appendPQExpBuffer(query, + "SELECT p.tableoid, p.oid, p.proname, p.prolang, " + "p.pronargs, p.proargtypes, p.prorettype, " + "p.proacl, " + "acldefault('f', p.proowner) AS acldefault, " + "p.pronamespace, " + "p.proowner " + "FROM pg_proc p " + "LEFT JOIN pg_init_privs pip ON " + "(p.oid = pip.objoid " + "AND pip.classoid = 'pg_proc'::regclass " + "AND pip.objsubid = 0) " + "WHERE %s" + "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " + "WHERE classid = 'pg_proc'::regclass AND " + "objid = p.oid AND deptype = 'i')" + "\n AND (" + "\n pronamespace != " + "(SELECT oid FROM pg_namespace " + "WHERE nspname = 'pg_catalog')" + "\n OR EXISTS (SELECT 1 FROM pg_cast" + "\n WHERE pg_cast.oid > %u " + "\n AND p.oid = pg_cast.castfunc)" + "\n OR EXISTS (SELECT 1 FROM pg_transform" + "\n WHERE pg_transform.oid > %u AND " + "\n (p.oid = pg_transform.trffromsql" + "\n OR p.oid = pg_transform.trftosql))", + not_agg_check, + g_last_builtin_oid, + g_last_builtin_oid); + if (dopt->binary_upgrade) appendPQExpBufferStr(query, - "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); - appendPQExpBufferChar(query, ')'); - } - else - { - appendPQExpBuffer(query, - "SELECT tableoid, oid, proname, prolang, " - "pronargs, proargtypes, prorettype, proacl, " - "acldefault('f', proowner) AS acldefault, " - "pronamespace, " - "proowner " - "FROM pg_proc p " - "WHERE NOT proisagg" - "\n AND NOT EXISTS (SELECT 1 FROM pg_depend " - "WHERE classid = 'pg_proc'::regclass AND " - "objid = p.oid AND deptype = 'i')" - "\n AND (" - "\n pronamespace != " - "(SELECT oid FROM pg_namespace " - "WHERE nspname = 'pg_catalog')" - "\n OR EXISTS (SELECT 1 FROM pg_cast" - "\n WHERE pg_cast.oid > '%u'::oid" - "\n AND p.oid = pg_cast.castfunc)", - g_last_builtin_oid); - - if (fout->remoteVersion >= 90500) - appendPQExpBuffer(query, - "\n OR EXISTS (SELECT 1 FROM pg_transform" - "\n WHERE pg_transform.oid > '%u'::oid" - "\n AND (p.oid = pg_transform.trffromsql" - "\n OR p.oid = pg_transform.trftosql))", - g_last_builtin_oid); - - if (dopt->binary_upgrade) - 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, ')'); - } + "\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')"); + appendPQExpBufferStr(query, + "\n OR p.proacl IS DISTINCT FROM pip.initprivs"); + appendPQExpBufferChar(query, ')'); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7379,64 +7245,14 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "c.relhasoids, "); - 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 >= 90500) - appendPQExpBufferStr(query, - "c.relrowsecurity, c.relforcerowsecurity, "); - else - appendPQExpBufferStr(query, - "false AS relrowsecurity, " - "false AS relforcerowsecurity, "); - - if (fout->remoteVersion >= 90300) - appendPQExpBufferStr(query, - "c.relminmxid, tc.relminmxid AS tminmxid, "); - else - appendPQExpBufferStr(query, - "0 AS relminmxid, 0 AS tminmxid, "); - - 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 - appendPQExpBufferStr(query, - "c.reloptions, NULL AS checkoption, "); - - if (fout->remoteVersion >= 90600) - appendPQExpBufferStr(query, - "am.amname, "); - else - appendPQExpBufferStr(query, - "NULL AS amname, "); - - if (fout->remoteVersion >= 90600) - appendPQExpBufferStr(query, - "(d.deptype = 'i') IS TRUE AS is_identity_sequence, "); - else - appendPQExpBufferStr(query, - "false AS is_identity_sequence, "); - - if (fout->remoteVersion >= 100000) - appendPQExpBufferStr(query, - "c.relispartition AS ispartition "); - else - appendPQExpBufferStr(query, - "false AS ispartition "); + appendPQExpBufferStr(query, + "c.relispopulated, c.relreplident, c.relrowsecurity, " + "c.relforcerowsecurity, c.relminmxid, tc.relminmxid AS tminmxid, " + "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, " + "am.amname, (d.deptype = 'i') IS TRUE AS is_identity_sequence, " + "c.relispartition AS ispartition "); /* * Left join to pg_depend to pick up dependency info linking sequences to @@ -7453,12 +7269,9 @@ getTables(Archive *fout, int *numTables) "d.refclassid = 'pg_class'::regclass AND d.deptype IN ('a', 'i'))\n" "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n"); - /* - * In 9.6 and up, left join to pg_am to pick up the amname. - */ - if (fout->remoteVersion >= 90600) - appendPQExpBufferStr(query, - "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); + /* left join to pg_am to pick up the amname. */ + appendPQExpBufferStr(query, + "LEFT JOIN pg_am am ON (c.relam = am.oid)\n"); /* * We purposefully ignore toast OIDs for partitioned tables; the reason is @@ -8026,15 +7839,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) " WHERE attrelid = i.indexrelid) " "ELSE NULL END AS indattnames, " "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, " - "t.reloptions AS indreloptions, "); - - - if (fout->remoteVersion >= 90400) - appendPQExpBufferStr(query, - "i.indisreplident, "); - else - appendPQExpBufferStr(query, - "false AS indisreplident, "); + "t.reloptions AS indreloptions, i.indisreplident, "); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -8319,10 +8124,6 @@ getExtendedStatistics(Archive *fout) int i_stattarget; int i; - /* Extended statistics were new in v10 */ - if (fout->remoteVersion < 100000) - return; - query = createPQExpBuffer(); if (fout->remoteVersion < 130000) @@ -8989,10 +8790,6 @@ getEventTriggers(Archive *fout) i_evtenabled; int ntups; - /* Before 9.3, there are no event triggers */ - if (fout->remoteVersion < 90300) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, @@ -9259,10 +9056,6 @@ getTransforms(Archive *fout) int i_trffromsql; int i_trftosql; - /* Transforms didn't exist pre-9.5 */ - if (fout->remoteVersion < 90500) - return; - query = createPQExpBuffer(); appendPQExpBufferStr(query, "SELECT tableoid, oid, " @@ -9490,12 +9283,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) appendPQExpBufferStr(q, "'' AS attcompression,\n"); - if (fout->remoteVersion >= 100000) - appendPQExpBufferStr(q, - "a.attidentity,\n"); - else - appendPQExpBufferStr(q, - "'' AS attidentity,\n"); + appendPQExpBufferStr(q, + "a.attidentity,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(q, @@ -10898,76 +10687,73 @@ getAdditionalACLs(Archive *fout) PQclear(res); /* Fetch initial-privileges data */ - if (fout->remoteVersion >= 90600) - { - printfPQExpBuffer(query, - "SELECT objoid, classoid, objsubid, privtype, initprivs " - "FROM pg_init_privs"); + printfPQExpBuffer(query, + "SELECT objoid, classoid, objsubid, privtype, initprivs " + "FROM pg_init_privs"); - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); + res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - ntups = PQntuples(res); - for (i = 0; i < ntups; i++) - { - Oid objoid = atooid(PQgetvalue(res, i, 0)); - Oid classoid = atooid(PQgetvalue(res, i, 1)); - int objsubid = atoi(PQgetvalue(res, i, 2)); - char privtype = *(PQgetvalue(res, i, 3)); - char *initprivs = PQgetvalue(res, i, 4); - CatalogId objId; - DumpableObject *dobj; + ntups = PQntuples(res); + for (i = 0; i < ntups; i++) + { + Oid objoid = atooid(PQgetvalue(res, i, 0)); + Oid classoid = atooid(PQgetvalue(res, i, 1)); + int objsubid = atoi(PQgetvalue(res, i, 2)); + char privtype = *(PQgetvalue(res, i, 3)); + char *initprivs = PQgetvalue(res, i, 4); + CatalogId objId; + DumpableObject *dobj; - objId.tableoid = classoid; - objId.oid = objoid; - dobj = findObjectByCatalogId(objId); - /* OK to ignore entries we haven't got a DumpableObject for */ - if (dobj) + objId.tableoid = classoid; + objId.oid = objoid; + dobj = findObjectByCatalogId(objId); + /* OK to ignore entries we haven't got a DumpableObject for */ + if (dobj) + { + /* Cope with sub-object initprivs */ + if (objsubid != 0) { - /* Cope with sub-object initprivs */ - if (objsubid != 0) - { - if (dobj->objType == DO_TABLE) - { - /* For a column initprivs, set the table's ACL flags */ - dobj->components |= DUMP_COMPONENT_ACL; - ((TableInfo *) dobj)->hascolumnACLs = true; - } - else - pg_log_warning("unsupported pg_init_privs entry: %u %u %d", - classoid, objoid, objsubid); - continue; - } - - /* - * We ignore any pg_init_privs.initprivs entry for the public - * schema, as explained in getNamespaces(). - */ - if (dobj->objType == DO_NAMESPACE && - strcmp(dobj->name, "public") == 0) - continue; - - /* Else it had better be of a type we think has ACLs */ - if (dobj->objType == DO_NAMESPACE || - dobj->objType == DO_TYPE || - dobj->objType == DO_FUNC || - dobj->objType == DO_AGG || - dobj->objType == DO_TABLE || - dobj->objType == DO_PROCLANG || - dobj->objType == DO_FDW || - dobj->objType == DO_FOREIGN_SERVER) + if (dobj->objType == DO_TABLE) { - DumpableObjectWithAcl *daobj = (DumpableObjectWithAcl *) dobj; - - daobj->dacl.privtype = privtype; - daobj->dacl.initprivs = pstrdup(initprivs); + /* For a column initprivs, set the table's ACL flags */ + dobj->components |= DUMP_COMPONENT_ACL; + ((TableInfo *) dobj)->hascolumnACLs = true; } else pg_log_warning("unsupported pg_init_privs entry: %u %u %d", classoid, objoid, objsubid); + continue; + } + + /* + * We ignore any pg_init_privs.initprivs entry for the public + * schema, as explained in getNamespaces(). + */ + if (dobj->objType == DO_NAMESPACE && + strcmp(dobj->name, "public") == 0) + continue; + + /* Else it had better be of a type we think has ACLs */ + if (dobj->objType == DO_NAMESPACE || + dobj->objType == DO_TYPE || + dobj->objType == DO_FUNC || + dobj->objType == DO_AGG || + dobj->objType == DO_TABLE || + dobj->objType == DO_PROCLANG || + dobj->objType == DO_FDW || + dobj->objType == DO_FOREIGN_SERVER) + { + DumpableObjectWithAcl *daobj = (DumpableObjectWithAcl *) dobj; + + daobj->dacl.privtype = privtype; + daobj->dacl.initprivs = pstrdup(initprivs); } + else + pg_log_warning("unsupported pg_init_privs entry: %u %u %d", + classoid, objoid, objsubid); } - PQclear(res); } + PQclear(res); destroyPQExpBuffer(query); } @@ -11140,16 +10926,6 @@ fetchAttributeStats(Archive *fout) PGresult *res = NULL; static TocEntry *te; static bool restarted; - int max_rels = MAX_ATTR_STATS_RELS; - - /* - * Our query for retrieving statistics for multiple relations uses WITH - * ORDINALITY and multi-argument UNNEST(), both of which were introduced - * in v9.4. For older versions, we resort to gathering statistics for a - * single relation at a time. - */ - if (fout->remoteVersion < 90400) - max_rels = 1; /* If we're just starting, set our TOC pointer. */ if (!te) @@ -11179,7 +10955,7 @@ fetchAttributeStats(Archive *fout) * This is perhaps not the sturdiest assumption, so we verify it matches * reality in dumpRelationStats_dumper(). */ - for (; te != AH->toc && count < max_rels; te = te->next) + for (; te != AH->toc && count < MAX_ATTR_STATS_RELS; te = te->next) { if ((te->reqs & REQ_STATS) == 0 || strcmp(te->desc, "STATISTICS DATA") != 0) @@ -11321,16 +11097,11 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) * The results must be in the order of the relations supplied in the * parameters to ensure we remain in sync as we walk through the TOC. * - * For v9.4 through v18, the redundant filter clause on s.tablename = + * For pre-v18 servers, the redundant filter clause on s.tablename = * ANY(...) seems sufficient to convince the planner to use * pg_class_relname_nsp_index, which avoids a full scan of pg_stats. * In newer versions, pg_stats returns the table OIDs, eliminating the * need for that hack. - * - * Our query for retrieving statistics for multiple relations uses - * WITH ORDINALITY and multi-argument UNNEST(), both of which were - * introduced in v9.4. For older versions, we resort to gathering - * statistics for a single relation at a time. */ if (fout->remoteVersion >= 190000) appendPQExpBufferStr(query, @@ -11338,7 +11109,7 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "JOIN unnest($1) WITH ORDINALITY AS u (tableid, ord) " "ON s.tableid = u.tableid " "ORDER BY u.ord, s.attname, s.inherited"); - else if (fout->remoteVersion >= 90400) + else appendPQExpBufferStr(query, "FROM pg_catalog.pg_stats s " "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) " @@ -11346,12 +11117,6 @@ dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te) "AND s.tablename = u.tablename " "WHERE s.tablename = ANY($2) " "ORDER BY u.ord, s.attname, s.inherited"); - else - appendPQExpBufferStr(query, - "FROM pg_catalog.pg_stats s " - "WHERE s.schemaname = $1[1] " - "AND s.tablename = $2[1] " - "ORDER BY s.attname, s.inherited"); ExecuteSqlStatement(fout, query->data); @@ -13671,21 +13436,9 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n" "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n" - "proleakproof,\n"); - - if (fout->remoteVersion >= 90500) - appendPQExpBufferStr(query, - "array_to_string(protrftypes, ' ') AS protrftypes,\n"); - else - appendPQExpBufferStr(query, - "NULL AS protrftypes,\n"); - - if (fout->remoteVersion >= 90600) - appendPQExpBufferStr(query, - "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'u' AS proparallel,\n"); + "proleakproof,\n" + "array_to_string(protrftypes, ' ') AS protrftypes,\n" + "proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -15173,16 +14926,7 @@ dumpCollation(Archive *fout, const CollInfo *collinfo) qcollname = pg_strdup(fmtId(collinfo->dobj.name)); /* Get collation-specific details */ - appendPQExpBufferStr(query, "SELECT "); - - if (fout->remoteVersion >= 100000) - appendPQExpBufferStr(query, - "collprovider, " - "collversion, "); - else - appendPQExpBufferStr(query, - "'c' AS collprovider, " - "NULL AS collversion, "); + appendPQExpBufferStr(query, "SELECT collprovider, collversion, "); if (fout->remoteVersion >= 120000) appendPQExpBufferStr(query, @@ -15587,45 +15331,21 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "agginitval,\n" "aggsortop,\n" "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n" - "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"); - - if (fout->remoteVersion >= 90400) - appendPQExpBufferStr(query, - "aggkind,\n" - "aggmtransfn,\n" - "aggminvtransfn,\n" - "aggmfinalfn,\n" - "aggmtranstype::pg_catalog.regtype,\n" - "aggfinalextra,\n" - "aggmfinalextra,\n" - "aggtransspace,\n" - "aggmtransspace,\n" - "aggminitval,\n"); - else - appendPQExpBufferStr(query, - "'n' AS aggkind,\n" - "'-' AS aggmtransfn,\n" - "'-' AS aggminvtransfn,\n" - "'-' AS aggmfinalfn,\n" - "0 AS aggmtranstype,\n" - "false AS aggfinalextra,\n" - "false AS aggmfinalextra,\n" - "0 AS aggtransspace,\n" - "0 AS aggmtransspace,\n" - "NULL AS aggminitval,\n"); - - if (fout->remoteVersion >= 90600) - appendPQExpBufferStr(query, - "aggcombinefn,\n" - "aggserialfn,\n" - "aggdeserialfn,\n" - "proparallel,\n"); - else - appendPQExpBufferStr(query, - "'-' AS aggcombinefn,\n" - "'-' AS aggserialfn,\n" - "'-' AS aggdeserialfn,\n" - "'u' AS proparallel,\n"); + "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n" + "aggkind,\n" + "aggmtransfn,\n" + "aggminvtransfn,\n" + "aggmfinalfn,\n" + "aggmtranstype::pg_catalog.regtype,\n" + "aggfinalextra,\n" + "aggmfinalextra,\n" + "aggtransspace,\n" + "aggmtransspace,\n" + "aggminitval,\n" + "aggcombinefn,\n" + "aggserialfn,\n" + "aggdeserialfn,\n" + "proparallel,\n"); if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, @@ -17081,47 +16801,33 @@ dumpTable(Archive *fout, const TableInfo *tbinfo) if (!fout->is_prepared[PREPQUERY_GETCOLUMNACLS]) { - /* Set up query for column ACLs */ + /* + * Set up query for column ACLs. + * + * In principle we should call acldefault('c', relowner) to get + * the default ACL for a column. However, we don't currently + * store the numeric OID of the relowner in TableInfo. We could + * convert the owner name using regrole, but that creates a risk + * of failure due to concurrent role renames. Given that the + * default ACL for columns is empty and is likely to stay that + * way, it's not worth extra cycles and risk to avoid hard-wiring + * that knowledge here. + */ appendPQExpBufferStr(query, - "PREPARE getColumnACLs(pg_catalog.oid) AS\n"); - - if (fout->remoteVersion >= 90600) - { - /* - * In principle we should call acldefault('c', relowner) to - * get the default ACL for a column. However, we don't - * currently store the numeric OID of the relowner in - * TableInfo. We could convert the owner name using regrole, - * but that creates a risk of failure due to concurrent role - * renames. Given that the default ACL for columns is empty - * and is likely to stay that way, it's not worth extra cycles - * and risk to avoid hard-wiring that knowledge here. - */ - appendPQExpBufferStr(query, - "SELECT at.attname, " - "at.attacl, " - "'{}' AS acldefault, " - "pip.privtype, pip.initprivs " - "FROM pg_catalog.pg_attribute at " - "LEFT JOIN pg_catalog.pg_init_privs pip ON " - "(at.attrelid = pip.objoid " - "AND pip.classoid = 'pg_catalog.pg_class'::pg_catalog.regclass " - "AND at.attnum = pip.objsubid) " - "WHERE at.attrelid = $1 AND " - "NOT at.attisdropped " - "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " - "ORDER BY at.attnum"); - } - else - { - appendPQExpBufferStr(query, - "SELECT attname, attacl, '{}' AS acldefault, " - "NULL AS privtype, NULL AS initprivs " - "FROM pg_catalog.pg_attribute " - "WHERE attrelid = $1 AND NOT attisdropped " - "AND attacl IS NOT NULL " - "ORDER BY attnum"); - } + "PREPARE getColumnACLs(pg_catalog.oid) AS\n" + "SELECT at.attname, " + "at.attacl, " + "'{}' AS acldefault, " + "pip.privtype, pip.initprivs " + "FROM pg_catalog.pg_attribute at " + "LEFT JOIN pg_catalog.pg_init_privs pip ON " + "(at.attrelid = pip.objoid " + "AND pip.classoid = 'pg_catalog.pg_class'::pg_catalog.regclass " + "AND at.attnum = pip.objsubid) " + "WHERE at.attrelid = $1 AND " + "NOT at.attisdropped " + "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) " + "ORDER BY at.attnum"); ExecuteSqlStatement(fout, query->data); @@ -19411,17 +19117,11 @@ collectSequences(Archive *fout) const char *query; /* - * Before Postgres 10, sequence metadata is in the sequence itself. With - * some extra effort, we might be able to use the sorted table for those - * versions, but for now it seems unlikely to be worth it. - * * Since version 18, we can gather the sequence data in this query with * pg_get_sequence_data(), but we only do so for non-schema-only dumps. */ - if (fout->remoteVersion < 100000) - return; - else if (fout->remoteVersion < 180000 || - (!fout->dopt->dumpData && !fout->dopt->sequence_data)) + if (fout->remoteVersion < 180000 || + (!fout->dopt->dumpData && !fout->dopt->sequence_data)) query = "SELECT seqrelid, format_type(seqtypid, NULL), " "seqstart, seqincrement, " "seqmax, seqmin, " @@ -19478,59 +19178,19 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) PQExpBuffer delqry = createPQExpBuffer(); char *qseqname; TableInfo *owning_tab = NULL; + SequenceItem key = {0}; qseqname = pg_strdup(fmtId(tbinfo->dobj.name)); /* - * For versions >= 10, the sequence information is gathered in a sorted - * table before any calls to dumpSequence(). See collectSequences() for - * more information. + * The sequence information is gathered in a sorted table before any calls + * to dumpSequence(). See collectSequences() for more information. */ - if (fout->remoteVersion >= 100000) - { - SequenceItem key = {0}; - - Assert(sequences); - - key.oid = tbinfo->dobj.catId.oid; - seq = bsearch(&key, sequences, nsequences, - sizeof(SequenceItem), SequenceItemCmp); - } - else - { - PGresult *res; - - /* - * Before PostgreSQL 10, sequence metadata is in the sequence itself. - * - * Note: it might seem that 'bigint' potentially needs to be - * schema-qualified, but actually that's a keyword. - */ - appendPQExpBuffer(query, - "SELECT 'bigint' AS sequence_type, " - "start_value, increment_by, max_value, min_value, " - "cache_value, is_cycled FROM %s", - fmtQualifiedDumpable(tbinfo)); - - res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); - - if (PQntuples(res) != 1) - pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", - "query to get data of sequence \"%s\" returned %d rows (expected 1)", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); + Assert(sequences); - seq = pg_malloc0_object(SequenceItem); - seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0)); - seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10); - seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10); - seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10); - seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10); - seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10); - seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0); - - PQclear(res); - } + key.oid = tbinfo->dobj.catId.oid; + seq = bsearch(&key, sequences, nsequences, + sizeof(SequenceItem), SequenceItemCmp); /* Calculate default limits for a sequence of this type */ is_ascending = (seq->incby >= 0); @@ -19709,8 +19369,6 @@ dumpSequence(Archive *fout, const TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name, tbinfo->rolname, tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId); - if (fout->remoteVersion < 100000) - pg_free(seq); destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); free(qseqname); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index 20cdd2d92f0..69f21a1fb86 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -693,11 +693,11 @@ main(int argc, char *argv[]) fout->verbose = verbose; /* - * We allow the server to be back to 9.2, and up to any minor release + * We allow the server to be back to 10, and up to any minor release * of our own major version. (See also version check in * pg_dumpall.c.) */ - fout->minRemoteVersion = 90200; + fout->minRemoteVersion = 100000; fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99; fout->numWorkers = 1; diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 06134cf5d2e..22812b38ed5 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -28,7 +28,6 @@ static void check_for_incompatible_polymorphics(ClusterInfo *cluster); static void check_for_tables_with_oids(ClusterInfo *cluster); static void check_for_not_null_inheritance(ClusterInfo *cluster); static void check_for_gist_inet_ops(ClusterInfo *cluster); -static void check_for_pg_role_prefix(ClusterInfo *cluster); static void check_for_new_tablespace_dir(void); static void check_for_user_defined_encoding_conversions(ClusterInfo *cluster); static void check_for_unicode_update(ClusterInfo *cluster); @@ -128,26 +127,6 @@ static DataTypesUsageChecks data_types_usage_checks[] = .threshold_version = ALL_VERSIONS }, - /* - * 9.3 -> 9.4 Fully implement the 'line' data type in 9.4, which - * previously returned "not enabled" by default and was only functionally - * enabled with a compile-time switch; as of 9.4 "line" has a different - * on-disk representation format. - */ - { - .status = gettext_noop("Checking for incompatible \"line\" data type"), - .report_filename = "tables_using_line.txt", - .base_query = - "SELECT 'pg_catalog.line'::pg_catalog.regtype AS oid", - .report_text = - gettext_noop("Your installation contains the \"line\" data type in user tables.\n" - "This data type changed its internal and input/output format\n" - "between your old and new versions so this\n" - "cluster cannot currently be upgraded. You can\n" - "drop the problem columns and restart the upgrade.\n"), - .threshold_version = 903 - }, - /* * pg_upgrade only preserves these system values: pg_class.oid pg_type.oid * pg_enum.oid @@ -209,30 +188,6 @@ static DataTypesUsageChecks data_types_usage_checks[] = .threshold_version = 1500 }, - /* - * It's no longer allowed to create tables or views with "unknown"-type - * columns. We do not complain about views with such columns, because - * they should get silently converted to "text" columns during the DDL - * dump and reload; it seems unlikely to be worth making users do that by - * hand. However, if there's a table with such a column, the DDL reload - * will fail, so we should pre-detect that rather than failing - * mid-upgrade. Worse, if there's a matview with such a column, the DDL - * reload will silently change it to "text" which won't match the on-disk - * storage (which is like "cstring"). So we *must* reject that. - */ - { - .status = gettext_noop("Checking for invalid \"unknown\" user columns"), - .report_filename = "tables_using_unknown.txt", - .base_query = - "SELECT 'pg_catalog.unknown'::pg_catalog.regtype AS oid", - .report_text = - gettext_noop("Your installation contains the \"unknown\" data type in user tables.\n" - "This data type is no longer allowed in tables, so this cluster\n" - "cannot currently be upgraded. You can drop the problem columns\n" - "and restart the upgrade.\n"), - .threshold_version = 906 - }, - /* * PG 12 changed the 'sql_identifier' type storage to be based on name, * not varchar, which breaks on-disk format for existing data. So we need @@ -255,23 +210,6 @@ static DataTypesUsageChecks data_types_usage_checks[] = .threshold_version = 1100 }, - /* - * JSONB changed its storage format during 9.4 beta, so check for it. - */ - { - .status = gettext_noop("Checking for incompatible \"jsonb\" data type in user tables"), - .report_filename = "tables_using_jsonb.txt", - .base_query = - "SELECT 'pg_catalog.jsonb'::pg_catalog.regtype AS oid", - .report_text = - gettext_noop("Your installation contains the \"jsonb\" data type in user tables.\n" - "The internal format of \"jsonb\" changed during 9.4 beta so this\n" - "cluster cannot currently be upgraded. You can drop the problem \n" - "columns and restart the upgrade.\n"), - .threshold_version = MANUAL_CHECK, - .version_hook = jsonb_9_4_check_applicable - }, - /* * PG 12 removed types abstime, reltime, tinterval. */ @@ -712,20 +650,6 @@ check_and_dump_old_cluster(void) if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1800) check_for_gist_inet_ops(&old_cluster); - /* - * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged - * hash indexes - */ - if (GET_MAJOR_VERSION(old_cluster.major_version) <= 906) - { - if (user_opts.check) - old_9_6_invalidate_hash_indexes(&old_cluster, true); - } - - /* 9.5 and below should not have roles starting with pg_ */ - if (GET_MAJOR_VERSION(old_cluster.major_version) <= 905) - check_for_pg_role_prefix(&old_cluster); - /* * While not a check option, we do this now because this is the only time * the old server is running. @@ -772,20 +696,6 @@ check_new_cluster(void) * system boundaries. */ check_hard_link(TRANSFER_MODE_SWAP); - - /* - * There are a few known issues with using --swap to upgrade from - * versions older than 10. For example, the sequence tuple format - * changed in v10, and the visibility map format changed in 9.6. - * While such problems are not insurmountable (and we may have to - * deal with similar problems in the future, anyway), it doesn't - * seem worth the effort to support swap mode for upgrades from - * long-unsupported versions. - */ - if (GET_MAJOR_VERSION(old_cluster.major_version) < 1000) - pg_fatal("Swap mode can only upgrade clusters from PostgreSQL version %s and later.", - "10"); - break; } @@ -831,10 +741,6 @@ issue_warnings_and_set_wal_level(void) */ start_postmaster(&new_cluster, true); - /* Reindex hash indexes for old < 10.0 */ - if (GET_MAJOR_VERSION(old_cluster.major_version) <= 906) - old_9_6_invalidate_hash_indexes(&new_cluster, false); - report_extension_updates(&new_cluster); stop_postmaster(false); @@ -892,9 +798,9 @@ check_cluster_versions(void) * upgrades */ - if (GET_MAJOR_VERSION(old_cluster.major_version) < 902) + if (GET_MAJOR_VERSION(old_cluster.major_version) < 1000) pg_fatal("This utility can only upgrade from PostgreSQL version %s and later.", - "9.2"); + "10"); /* Only current PG version is supported as a target */ if (GET_MAJOR_VERSION(new_cluster.major_version) != GET_MAJOR_VERSION(PG_VERSION_NUM)) @@ -1567,19 +1473,13 @@ check_for_incompatible_polymorphics(ClusterInfo *cluster) appendPQExpBufferStr(&old_polymorphics, "'array_append(anyarray,anyelement)'" ", 'array_cat(anyarray,anyarray)'" - ", 'array_prepend(anyelement,anyarray)'"); - - if (GET_MAJOR_VERSION(cluster->major_version) >= 903) - appendPQExpBufferStr(&old_polymorphics, - ", 'array_remove(anyarray,anyelement)'" - ", 'array_replace(anyarray,anyelement,anyelement)'"); - - if (GET_MAJOR_VERSION(cluster->major_version) >= 905) - appendPQExpBufferStr(&old_polymorphics, - ", 'array_position(anyarray,anyelement)'" - ", 'array_position(anyarray,anyelement,integer)'" - ", 'array_positions(anyarray,anyelement)'" - ", 'width_bucket(anyelement,anyarray)'"); + ", 'array_prepend(anyelement,anyarray)'" + ", 'array_remove(anyarray,anyelement)'" + ", 'array_replace(anyarray,anyelement,anyelement)'" + ", 'array_position(anyarray,anyelement)'" + ", 'array_position(anyarray,anyelement,integer)'" + ", 'array_positions(anyarray,anyelement)'" + ", 'width_bucket(anyelement,anyarray)'"); /* * The query below hardcodes FirstNormalObjectId as 16384 rather than @@ -1870,63 +1770,6 @@ check_for_gist_inet_ops(ClusterInfo *cluster) check_ok(); } -/* - * check_for_pg_role_prefix() - * - * Versions older than 9.6 should not have any pg_* roles - */ -static void -check_for_pg_role_prefix(ClusterInfo *cluster) -{ - PGresult *res; - PGconn *conn = connectToServer(cluster, "template1"); - int ntups; - int i_roloid; - int i_rolname; - FILE *script = NULL; - char output_path[MAXPGPATH]; - - prep_status("Checking for roles starting with \"pg_\""); - - snprintf(output_path, sizeof(output_path), "%s/%s", - log_opts.basedir, - "pg_role_prefix.txt"); - - res = executeQueryOrDie(conn, - "SELECT oid AS roloid, rolname " - "FROM pg_catalog.pg_roles " - "WHERE rolname ~ '^pg_'"); - - ntups = PQntuples(res); - i_roloid = PQfnumber(res, "roloid"); - i_rolname = PQfnumber(res, "rolname"); - for (int rowno = 0; rowno < ntups; rowno++) - { - if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL) - pg_fatal("could not open file \"%s\": %m", output_path); - fprintf(script, "%s (oid=%s)\n", - PQgetvalue(res, rowno, i_rolname), - PQgetvalue(res, rowno, i_roloid)); - } - - PQclear(res); - - PQfinish(conn); - - if (script) - { - fclose(script); - pg_log(PG_REPORT, "fatal"); - pg_fatal("Your installation contains roles starting with \"pg_\".\n" - "\"pg_\" is a reserved prefix for system roles. The cluster\n" - "cannot be upgraded until these roles are renamed.\n" - "A list of roles starting with \"pg_\" is in the file:\n" - " %s", output_path); - } - else - check_ok(); -} - /* * Callback function for processing results of query for * check_for_user_defined_encoding_conversions()'s UpgradeTask. If the query diff --git a/src/bin/pg_upgrade/controldata.c b/src/bin/pg_upgrade/controldata.c index e18687226ae..a563efcb6d3 100644 --- a/src/bin/pg_upgrade/controldata.c +++ b/src/bin/pg_upgrade/controldata.c @@ -42,9 +42,6 @@ get_control_data(ClusterInfo *cluster) char bufin[MAX_STRING]; FILE *output; char *p; - bool got_tli = false; - bool got_log_id = false; - bool got_log_seg = false; bool got_xid = false; bool got_oid = false; bool got_multi = false; @@ -75,10 +72,6 @@ get_control_data(ClusterInfo *cluster) char *language = NULL; char *lc_all = NULL; char *lc_messages = NULL; - uint32 tli = 0; - uint32 logid = 0; - uint32 segno = 0; - char *resetwal_bin; int rc; bool live_check = (cluster == &old_cluster && user_opts.live_check); @@ -189,27 +182,15 @@ get_control_data(ClusterInfo *cluster) } } - /* pg_resetxlog has been renamed to pg_resetwal in version 10 */ - if (GET_MAJOR_VERSION(cluster->bin_version) <= 906) - resetwal_bin = "pg_resetxlog\" -n"; - else - resetwal_bin = "pg_resetwal\" -n"; snprintf(cmd, sizeof(cmd), "\"%s/%s \"%s\"", cluster->bindir, - live_check ? "pg_controldata\"" : resetwal_bin, + live_check ? "pg_controldata\"" : "pg_resetwal\" -n", cluster->pgdata); fflush(NULL); if ((output = popen(cmd, "r")) == NULL) pg_fatal("could not get control data using %s: %m", cmd); - /* Only in <= 9.2 */ - if (GET_MAJOR_VERSION(cluster->major_version) <= 902) - { - cluster->controldata.data_checksum_version = PG_DATA_CHECKSUM_OFF; - got_data_checksum_version = true; - } - /* we have the result of cmd in "output". so parse it line by line now */ while (fgets(bufin, sizeof(bufin), output)) { @@ -237,39 +218,6 @@ get_control_data(ClusterInfo *cluster) p++; /* remove ':' char */ cluster->controldata.cat_ver = str2uint(p); } - else if ((p = strstr(bufin, "Latest checkpoint's TimeLineID:")) != NULL) - { - p = strchr(p, ':'); - - if (p == NULL || strlen(p) <= 1) - pg_fatal("%d: controldata retrieval problem", __LINE__); - - p++; /* remove ':' char */ - tli = str2uint(p); - got_tli = true; - } - else if ((p = strstr(bufin, "First log file ID after reset:")) != NULL) - { - p = strchr(p, ':'); - - if (p == NULL || strlen(p) <= 1) - pg_fatal("%d: controldata retrieval problem", __LINE__); - - p++; /* remove ':' char */ - logid = str2uint(p); - got_log_id = true; - } - else if ((p = strstr(bufin, "First log file segment after reset:")) != NULL) - { - p = strchr(p, ':'); - - if (p == NULL || strlen(p) <= 1) - pg_fatal("%d: controldata retrieval problem", __LINE__); - - p++; /* remove ':' char */ - segno = str2uint(p); - got_log_seg = true; - } else if ((p = strstr(bufin, "Latest checkpoint's NextXID:")) != NULL) { p = strchr(p, ':'); @@ -280,23 +228,12 @@ get_control_data(ClusterInfo *cluster) p++; /* remove ':' char */ cluster->controldata.chkpnt_nxtepoch = str2uint(p); - /* - * Delimiter changed from '/' to ':' in 9.6. We don't test for - * the catalog version of the change because the catalog version - * is pulled from pg_controldata too, and it isn't worth adding an - * order dependency for this --- we just check the string. - */ - if (strchr(p, '/') != NULL) - p = strchr(p, '/'); - else if (GET_MAJOR_VERSION(cluster->major_version) >= 906) - p = strchr(p, ':'); - else - p = NULL; + p = strchr(p, ':'); if (p == NULL || strlen(p) <= 1) pg_fatal("%d: controldata retrieval problem", __LINE__); - p++; /* remove '/' or ':' char */ + p++; /* remove ':' char */ cluster->controldata.chkpnt_nxtxid = str2uint(p); got_xid = true; } @@ -568,22 +505,6 @@ get_control_data(ClusterInfo *cluster) pg_free(lc_all); pg_free(lc_messages); - /* - * Before 9.3, pg_resetwal reported the xlogid and segno of the first log - * file after reset as separate lines. Starting with 9.3, it reports the - * WAL file name. If the old cluster is older than 9.3, we construct the - * WAL file name from the xlogid and segno. - */ - if (GET_MAJOR_VERSION(cluster->major_version) <= 902) - { - if (got_tli && got_log_id && got_log_seg) - { - snprintf(cluster->controldata.nextxlogfile, 25, "%08X%08X%08X", - tli, logid, segno); - got_nextxlogfile = true; - } - } - /* * Pre-v18 database clusters don't have the default char signedness * information. We use the char signedness of the platform where @@ -602,14 +523,12 @@ get_control_data(ClusterInfo *cluster) /* verify that we got all the mandatory pg_control data */ if (!got_xid || !got_oid || !got_multi || !got_oldestxid || - (!got_oldestmulti && - cluster->controldata.cat_ver >= MULTIXACT_FORMATCHANGE_CAT_VER) || + !got_oldestmulti || !got_mxoff || (!live_check && !got_nextxlogfile) || !got_float8_pass_by_value || !got_align || !got_blocksz || !got_largesz || !got_walsz || !got_walseg || !got_ident || !got_index || !got_toast || - (!got_large_object && - cluster->controldata.ctrl_ver >= LARGE_OBJECT_SIZE_PG_CONTROL_VER) || + !got_large_object || !got_date_is_int || !got_data_checksum_version || (!got_default_char_signedness && cluster->controldata.cat_ver >= DEFAULT_CHAR_SIGNEDNESS_CAT_VER)) @@ -630,8 +549,7 @@ get_control_data(ClusterInfo *cluster) if (!got_multi) pg_log(PG_REPORT, " latest checkpoint next MultiXactId"); - if (!got_oldestmulti && - cluster->controldata.cat_ver >= MULTIXACT_FORMATCHANGE_CAT_VER) + if (!got_oldestmulti) pg_log(PG_REPORT, " latest checkpoint oldest MultiXactId"); if (!got_oldestxid) @@ -670,8 +588,7 @@ get_control_data(ClusterInfo *cluster) if (!got_toast) pg_log(PG_REPORT, " maximum TOAST chunk size"); - if (!got_large_object && - cluster->controldata.ctrl_ver >= LARGE_OBJECT_SIZE_PG_CONTROL_VER) + if (!got_large_object) pg_log(PG_REPORT, " large-object chunk size"); if (!got_date_is_int) diff --git a/src/bin/pg_upgrade/exec.c b/src/bin/pg_upgrade/exec.c index e1de61f36ee..beb255a5152 100644 --- a/src/bin/pg_upgrade/exec.c +++ b/src/bin/pg_upgrade/exec.c @@ -353,18 +353,8 @@ check_data_dir(ClusterInfo *cluster) check_single_dir(pg_data, "pg_subtrans"); check_single_dir(pg_data, PG_TBLSPC_DIR); check_single_dir(pg_data, "pg_twophase"); - - /* pg_xlog has been renamed to pg_wal in v10 */ - if (GET_MAJOR_VERSION(cluster->major_version) <= 906) - check_single_dir(pg_data, "pg_xlog"); - else - check_single_dir(pg_data, "pg_wal"); - - /* pg_clog has been renamed to pg_xact in v10 */ - if (GET_MAJOR_VERSION(cluster->major_version) <= 906) - check_single_dir(pg_data, "pg_clog"); - else - check_single_dir(pg_data, "pg_xact"); + check_single_dir(pg_data, "pg_wal"); + check_single_dir(pg_data, "pg_xact"); } @@ -404,11 +394,7 @@ check_bin_dir(ClusterInfo *cluster, bool check_versions) */ get_bin_version(cluster); - /* pg_resetxlog has been renamed to pg_resetwal in version 10 */ - if (GET_MAJOR_VERSION(cluster->bin_version) <= 906) - check_exec(cluster->bindir, "pg_resetxlog", check_versions); - else - check_exec(cluster->bindir, "pg_resetwal", check_versions); + check_exec(cluster->bindir, "pg_resetwal", check_versions); if (cluster == &new_cluster) { diff --git a/src/bin/pg_upgrade/file.c b/src/bin/pg_upgrade/file.c index 5b276008614..af82c0de490 100644 --- a/src/bin/pg_upgrade/file.c +++ b/src/bin/pg_upgrade/file.c @@ -20,12 +20,8 @@ #include #endif -#include "access/visibilitymapdefs.h" #include "common/file_perm.h" #include "pg_upgrade.h" -#include "storage/bufpage.h" -#include "storage/checksum.h" -#include "storage/checksum_impl.h" /* @@ -196,166 +192,6 @@ linkFile(const char *src, const char *dst, } -/* - * rewriteVisibilityMap() - * - * Transform a visibility map file, copying from src to dst. - * schemaName/relName are relation's SQL name (used for error messages only). - * - * In versions of PostgreSQL prior to catversion 201603011, PostgreSQL's - * visibility map included one bit per heap page; it now includes two. - * When upgrading a cluster from before that time to a current PostgreSQL - * version, we could refuse to copy visibility maps from the old cluster - * to the new cluster; the next VACUUM would recreate them, but at the - * price of scanning the entire table. So, instead, we rewrite the old - * visibility maps in the new format. That way, the all-visible bits - * remain set for the pages for which they were set previously. The - * all-frozen bits are never set by this conversion; we leave that to VACUUM. - */ -void -rewriteVisibilityMap(const char *fromfile, const char *tofile, - const char *schemaName, const char *relName) -{ - int src_fd; - int dst_fd; - PGIOAlignedBlock buffer; - PGIOAlignedBlock new_vmbuf; - ssize_t totalBytesRead = 0; - ssize_t src_filesize; - int rewriteVmBytesPerPage; - BlockNumber new_blkno = 0; - struct stat statbuf; - - /* Compute number of old-format bytes per new page */ - rewriteVmBytesPerPage = (BLCKSZ - SizeOfPageHeaderData) / 2; - - if ((src_fd = open(fromfile, O_RDONLY | PG_BINARY, 0)) < 0) - pg_fatal("error while copying relation \"%s.%s\": could not open file \"%s\": %m", - schemaName, relName, fromfile); - - if (fstat(src_fd, &statbuf) != 0) - pg_fatal("error while copying relation \"%s.%s\": could not stat file \"%s\": %m", - schemaName, relName, fromfile); - - if ((dst_fd = open(tofile, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, - pg_file_create_mode)) < 0) - pg_fatal("error while copying relation \"%s.%s\": could not create file \"%s\": %m", - schemaName, relName, tofile); - - /* Save old file size */ - src_filesize = statbuf.st_size; - - /* - * Turn each visibility map page into 2 pages one by one. Each new page - * has the same page header as the old one. If the last section of the - * last page is empty, we skip it, mostly to avoid turning one-page - * visibility maps for small relations into two pages needlessly. - */ - while (totalBytesRead < src_filesize) - { - ssize_t bytesRead; - char *old_cur; - char *old_break; - char *old_blkend; - PageHeaderData pageheader; - bool old_lastblk; - - if ((bytesRead = read(src_fd, buffer.data, BLCKSZ)) != BLCKSZ) - { - if (bytesRead < 0) - pg_fatal("error while copying relation \"%s.%s\": could not read file \"%s\": %m", - schemaName, relName, fromfile); - else - pg_fatal("error while copying relation \"%s.%s\": partial page found in file \"%s\"", - schemaName, relName, fromfile); - } - - totalBytesRead += BLCKSZ; - old_lastblk = (totalBytesRead == src_filesize); - - /* Save the page header data */ - memcpy(&pageheader, buffer.data, SizeOfPageHeaderData); - - /* - * These old_* variables point to old visibility map page. old_cur - * points to current position on old page. old_blkend points to end of - * old block. old_break is the end+1 position on the old page for the - * data that will be transferred to the current new page. - */ - old_cur = buffer.data + SizeOfPageHeaderData; - old_blkend = buffer.data + bytesRead; - old_break = old_cur + rewriteVmBytesPerPage; - - while (old_break <= old_blkend) - { - char *new_cur; - bool empty = true; - bool old_lastpart; - - /* First, copy old page header to new page */ - memcpy(new_vmbuf.data, &pageheader, SizeOfPageHeaderData); - - /* Rewriting the last part of the last old page? */ - old_lastpart = old_lastblk && (old_break == old_blkend); - - new_cur = new_vmbuf.data + SizeOfPageHeaderData; - - /* Process old page bytes one by one, and turn it into new page. */ - while (old_cur < old_break) - { - uint8 byte = *(uint8 *) old_cur; - uint16 new_vmbits = 0; - int i; - - /* Generate new format bits while keeping old information */ - for (i = 0; i < BITS_PER_BYTE; i++) - { - if (byte & (1 << i)) - { - empty = false; - new_vmbits |= - VISIBILITYMAP_ALL_VISIBLE << (BITS_PER_HEAPBLOCK * i); - } - } - - /* Copy new visibility map bytes to new-format page */ - new_cur[0] = (char) (new_vmbits & 0xFF); - new_cur[1] = (char) (new_vmbits >> 8); - - old_cur++; - new_cur += BITS_PER_HEAPBLOCK; - } - - /* If the last part of the last page is empty, skip writing it */ - if (old_lastpart && empty) - break; - - /* Set new checksum for visibility map page, if enabled */ - if (new_cluster.controldata.data_checksum_version != PG_DATA_CHECKSUM_OFF) - ((PageHeader) new_vmbuf.data)->pd_checksum = - pg_checksum_page(new_vmbuf.data, new_blkno); - - errno = 0; - if (write(dst_fd, new_vmbuf.data, BLCKSZ) != BLCKSZ) - { - /* if write didn't set errno, assume problem is no disk space */ - if (errno == 0) - errno = ENOSPC; - pg_fatal("error while copying relation \"%s.%s\": could not write file \"%s\": %m", - schemaName, relName, tofile); - } - - /* Advance for next new page */ - old_break += rewriteVmBytesPerPage; - new_blkno++; - } - } - - /* Clean up */ - close(dst_fd); - close(src_fd); -} - void check_file_clone(void) { diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c index 2127d297bfe..48e6f8e52a8 100644 --- a/src/bin/pg_upgrade/pg_upgrade.c +++ b/src/bin/pg_upgrade/pg_upgrade.c @@ -64,7 +64,7 @@ static void prepare_new_cluster(void); static void prepare_new_globals(void); static void create_new_objects(void); static void copy_xact_xlog_xid(void); -static void set_frozenxids(bool minmxid_only); +static void set_frozenxids(void); static void make_outputdirs(char *pgdata); static void setup(char *argv0); static void create_logical_replication_slots(void); @@ -576,7 +576,7 @@ prepare_new_globals(void) /* * Before we restore anything, set frozenxids of initdb-created tables. */ - set_frozenxids(false); + set_frozenxids(); /* * Now restore global objects (roles and tablespaces). @@ -714,13 +714,6 @@ create_new_objects(void) end_progress_output(); check_ok(); - /* - * We don't have minmxids for databases or relations in pre-9.3 clusters, - * so set those after we have restored the schema. - */ - if (GET_MAJOR_VERSION(old_cluster.major_version) <= 902) - set_frozenxids(true); - /* update new_cluster info now that we have objects in the databases */ get_db_rel_and_slot_infos(&new_cluster); } @@ -773,14 +766,8 @@ copy_subdir_files(const char *old_subdir, const char *new_subdir) static void copy_xact_xlog_xid(void) { - /* - * Copy old commit logs to new data dir. pg_clog has been renamed to - * pg_xact in post-10 clusters. - */ - copy_subdir_files(GET_MAJOR_VERSION(old_cluster.major_version) <= 906 ? - "pg_clog" : "pg_xact", - GET_MAJOR_VERSION(new_cluster.major_version) <= 906 ? - "pg_clog" : "pg_xact"); + /* Copy old commit logs to new data dir. */ + copy_subdir_files("pg_xact", "pg_xact"); prep_status("Setting oldest XID for new cluster"); exec_prog(UTILITY_LOG_FILE, NULL, true, true, @@ -809,7 +796,6 @@ copy_xact_xlog_xid(void) check_ok(); /* Copy or convert pg_multixact files */ - Assert(new_cluster.controldata.cat_ver >= MULTIXACT_FORMATCHANGE_CAT_VER); Assert(new_cluster.controldata.cat_ver >= MULTIXACTOFFSET_FORMATCHANGE_CAT_VER); if (old_cluster.controldata.cat_ver >= MULTIXACTOFFSET_FORMATCHANGE_CAT_VER) { @@ -844,25 +830,8 @@ copy_xact_xlog_xid(void) * Determine the range of multixacts to convert. */ nxtmulti = old_cluster.controldata.chkpnt_nxtmulti; - if (old_cluster.controldata.cat_ver >= MULTIXACT_FORMATCHANGE_CAT_VER) - { - /* Versions 9.3 - 18: convert all multixids */ - oldstMulti = old_cluster.controldata.chkpnt_oldstMulti; - } - else - { - /* - * In PostgreSQL 9.2 and below, multitransactions were only used - * for row locking, and as such don't need to be preserved during - * upgrade. In that case, we utilize rewrite_multixacts() just to - * initialize new, empty files in the new format. - * - * It's important that the oldest multi is set to the latest value - * used by the old system, so that multixact.c returns the empty - * set for multis that might be present on disk. - */ - oldstMulti = nxtmulti; - } + oldstMulti = old_cluster.controldata.chkpnt_oldstMulti; + /* handle wraparound */ if (nxtmulti < FirstMultiXactId) nxtmulti = FirstMultiXactId; @@ -914,18 +883,10 @@ copy_xact_xlog_xid(void) * * As we create user tables later, their relfrozenxid/relminmxid fields will * be restored properly by the binary-upgrade restore script. Likewise for - * user-database datfrozenxid/datminmxid. However, if we're upgrading from a - * pre-9.3 database, which does not store per-table or per-DB minmxid, then - * the relminmxid/datminmxid values filled in by the restore script will just - * be zeroes. - * - * Hence, with a pre-9.3 source database, a second call occurs after - * everything is restored, with minmxid_only = true. This pass will - * initialize all tables and databases, both those made by initdb and user - * objects, with the desired minmxid value. frozenxid values are left alone. + * user-database datfrozenxid/datminmxid. */ static void -set_frozenxids(bool minmxid_only) +set_frozenxids(void) { int dbnum; PGconn *conn, @@ -935,19 +896,15 @@ set_frozenxids(bool minmxid_only) int i_datname; int i_datallowconn; - if (!minmxid_only) - prep_status("Setting frozenxid and minmxid counters in new cluster"); - else - prep_status("Setting minmxid counter in new cluster"); + prep_status("Setting frozenxid and minmxid counters in new cluster"); conn_template1 = connectToServer(&new_cluster, "template1"); - if (!minmxid_only) - /* set pg_database.datfrozenxid */ - PQclear(executeQueryOrDie(conn_template1, - "UPDATE pg_catalog.pg_database " - "SET datfrozenxid = '%u'", - old_cluster.controldata.chkpnt_nxtxid)); + /* set pg_database.datfrozenxid */ + PQclear(executeQueryOrDie(conn_template1, + "UPDATE pg_catalog.pg_database " + "SET datfrozenxid = '%u'", + old_cluster.controldata.chkpnt_nxtxid)); /* set pg_database.datminmxid */ PQclear(executeQueryOrDie(conn_template1, @@ -983,17 +940,16 @@ set_frozenxids(bool minmxid_only) conn = connectToServer(&new_cluster, datname); - if (!minmxid_only) - /* set pg_class.relfrozenxid */ - PQclear(executeQueryOrDie(conn, - "UPDATE pg_catalog.pg_class " - "SET relfrozenxid = '%u' " - /* only heap, materialized view, and TOAST are vacuumed */ - "WHERE relkind IN (" - CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_MATVIEW) ", " - CppAsString2(RELKIND_TOASTVALUE) ")", - old_cluster.controldata.chkpnt_nxtxid)); + /* set pg_class.relfrozenxid */ + PQclear(executeQueryOrDie(conn, + "UPDATE pg_catalog.pg_class " + "SET relfrozenxid = '%u' " + /* only heap, materialized view, and TOAST are vacuumed */ + "WHERE relkind IN (" + CppAsString2(RELKIND_RELATION) ", " + CppAsString2(RELKIND_MATVIEW) ", " + CppAsString2(RELKIND_TOASTVALUE) ")", + old_cluster.controldata.chkpnt_nxtxid)); /* set pg_class.relminmxid */ PQclear(executeQueryOrDie(conn, diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h index 1d767bbda2d..16cf7d924fd 100644 --- a/src/bin/pg_upgrade/pg_upgrade.h +++ b/src/bin/pg_upgrade/pg_upgrade.h @@ -101,19 +101,6 @@ extern char *output_files[]; #endif -/* - * The format of visibility map was changed with this 9.6 commit. - */ -#define VISIBILITY_MAP_FROZEN_BIT_CAT_VER 201603011 - -/* - * pg_multixact format changed in 9.3 commit 0ac5ad5134f2769ccbaefec73844f85, - * ("Improve concurrency of foreign key locking") which also updated catalog - * version to this value. pg_upgrade behavior depends on whether old and new - * server versions are both newer than this, or only the new one is. - */ -#define MULTIXACT_FORMATCHANGE_CAT_VER 201301231 - /* * MultiXactOffset was changed from 32-bit to 64-bit in version 19, at this * catalog version. pg_multixact files need to be converted when upgrading @@ -121,17 +108,6 @@ extern char *output_files[]; */ #define MULTIXACTOFFSET_FORMATCHANGE_CAT_VER 202512091 -/* - * large object chunk size added to pg_controldata, - * commit 5f93c37805e7485488480916b4585e098d3cc883 - */ -#define LARGE_OBJECT_SIZE_PG_CONTROL_VER 942 - -/* - * change in JSONB format during 9.4 beta - */ -#define JSONB_FORMAT_CHANGE_CAT_VER 201409291 - /* * The control file was changed to have the default char signedness, * commit 44fe30fdab6746a287163e7cc093fd36cda8eb92 @@ -429,8 +405,6 @@ void copyFileByRange(const char *src, const char *dst, const char *schemaName, const char *relName); void linkFile(const char *src, const char *dst, const char *schemaName, const char *relName); -void rewriteVisibilityMap(const char *fromfile, const char *tofile, - const char *schemaName, const char *relName); void check_file_clone(void); void check_copy_file_range(void); void check_hard_link(transferMode transfer_mode); @@ -500,11 +474,7 @@ unsigned int str2uint(const char *str); /* version.c */ -bool jsonb_9_4_check_applicable(ClusterInfo *cluster); bool protocol_negotiation_supported(const ClusterInfo *cluster); -void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, - bool check_mode); - void report_extension_updates(ClusterInfo *cluster); /* multixact_rewrite.c */ diff --git a/src/bin/pg_upgrade/relfilenumber.c b/src/bin/pg_upgrade/relfilenumber.c index d5088447e0d..6c467bdc8a5 100644 --- a/src/bin/pg_upgrade/relfilenumber.c +++ b/src/bin/pg_upgrade/relfilenumber.c @@ -18,7 +18,7 @@ #include "pg_upgrade.h" static void transfer_single_new_db(FileNameMap *maps, int size, char *old_tablespace, char *new_tablespace); -static void transfer_relfile(FileNameMap *map, const char *type_suffix, bool vm_must_add_frozenbit); +static void transfer_relfile(FileNameMap *map, const char *type_suffix); /* * The following set of sync_queue_* functions are used for --swap to reduce @@ -496,25 +496,10 @@ transfer_single_new_db(FileNameMap *maps, int size, char *old_tablespace, char *new_tablespace) { int mapnum; - bool vm_must_add_frozenbit = false; - - /* - * Do we need to rewrite visibilitymap? - */ - if (old_cluster.controldata.cat_ver < VISIBILITY_MAP_FROZEN_BIT_CAT_VER && - new_cluster.controldata.cat_ver >= VISIBILITY_MAP_FROZEN_BIT_CAT_VER) - vm_must_add_frozenbit = true; /* --swap has its own subroutine */ if (user_opts.transfer_mode == TRANSFER_MODE_SWAP) { - /* - * We don't support --swap to upgrade from versions that require - * rewriting the visibility map. We should've failed already if - * someone tries to do that. - */ - Assert(!vm_must_add_frozenbit); - do_swap(maps, size, old_tablespace, new_tablespace); return; } @@ -525,13 +510,13 @@ transfer_single_new_db(FileNameMap *maps, int size, strcmp(maps[mapnum].old_tablespace, old_tablespace) == 0) { /* transfer primary file */ - transfer_relfile(&maps[mapnum], "", vm_must_add_frozenbit); + transfer_relfile(&maps[mapnum], ""); /* * Copy/link any fsm and vm files, if they exist */ - transfer_relfile(&maps[mapnum], "_fsm", vm_must_add_frozenbit); - transfer_relfile(&maps[mapnum], "_vm", vm_must_add_frozenbit); + transfer_relfile(&maps[mapnum], "_fsm"); + transfer_relfile(&maps[mapnum], "_vm"); } } } @@ -540,12 +525,10 @@ transfer_single_new_db(FileNameMap *maps, int size, /* * transfer_relfile() * - * Copy or link file from old cluster to new one. If vm_must_add_frozenbit - * is true, visibility map forks are converted and rewritten, even in link - * mode. + * Copy or link file from old cluster to new one. */ static void -transfer_relfile(FileNameMap *map, const char *type_suffix, bool vm_must_add_frozenbit) +transfer_relfile(FileNameMap *map, const char *type_suffix) { char old_file[MAXPGPATH]; char new_file[MAXPGPATH]; @@ -604,40 +587,32 @@ transfer_relfile(FileNameMap *map, const char *type_suffix, bool vm_must_add_fro /* Copying files might take some time, so give feedback. */ pg_log(PG_STATUS, "%s", old_file); - if (vm_must_add_frozenbit && strcmp(type_suffix, "_vm") == 0) + switch (user_opts.transfer_mode) { - /* Need to rewrite visibility map format */ - pg_log(PG_VERBOSE, "rewriting \"%s\" to \"%s\"", - old_file, new_file); - rewriteVisibilityMap(old_file, new_file, map->nspname, map->relname); + case TRANSFER_MODE_CLONE: + pg_log(PG_VERBOSE, "cloning \"%s\" to \"%s\"", + old_file, new_file); + cloneFile(old_file, new_file, map->nspname, map->relname); + break; + case TRANSFER_MODE_COPY: + pg_log(PG_VERBOSE, "copying \"%s\" to \"%s\"", + old_file, new_file); + copyFile(old_file, new_file, map->nspname, map->relname); + break; + case TRANSFER_MODE_COPY_FILE_RANGE: + pg_log(PG_VERBOSE, "copying \"%s\" to \"%s\" with copy_file_range", + old_file, new_file); + copyFileByRange(old_file, new_file, map->nspname, map->relname); + break; + case TRANSFER_MODE_LINK: + pg_log(PG_VERBOSE, "linking \"%s\" to \"%s\"", + old_file, new_file); + linkFile(old_file, new_file, map->nspname, map->relname); + break; + case TRANSFER_MODE_SWAP: + /* swap mode is handled in its own code path */ + pg_fatal("should never happen"); + break; } - else - switch (user_opts.transfer_mode) - { - case TRANSFER_MODE_CLONE: - pg_log(PG_VERBOSE, "cloning \"%s\" to \"%s\"", - old_file, new_file); - cloneFile(old_file, new_file, map->nspname, map->relname); - break; - case TRANSFER_MODE_COPY: - pg_log(PG_VERBOSE, "copying \"%s\" to \"%s\"", - old_file, new_file); - copyFile(old_file, new_file, map->nspname, map->relname); - break; - case TRANSFER_MODE_COPY_FILE_RANGE: - pg_log(PG_VERBOSE, "copying \"%s\" to \"%s\" with copy_file_range", - old_file, new_file); - copyFileByRange(old_file, new_file, map->nspname, map->relname); - break; - case TRANSFER_MODE_LINK: - pg_log(PG_VERBOSE, "linking \"%s\" to \"%s\"", - old_file, new_file); - linkFile(old_file, new_file, map->nspname, map->relname); - break; - case TRANSFER_MODE_SWAP: - /* swap mode is handled in its own code path */ - pg_fatal("should never happen"); - break; - } } } diff --git a/src/bin/pg_upgrade/server.c b/src/bin/pg_upgrade/server.c index 1eb8bc97c05..abaa59f090c 100644 --- a/src/bin/pg_upgrade/server.c +++ b/src/bin/pg_upgrade/server.c @@ -185,9 +185,7 @@ start_postmaster(ClusterInfo *cluster, bool report_and_exit_on_error) if (cluster->sockdir) snprintf(socket_string + strlen(socket_string), sizeof(socket_string) - strlen(socket_string), - " -c %s='%s'", - (GET_MAJOR_VERSION(cluster->major_version) <= 902) ? - "unix_socket_directory" : "unix_socket_directories", + " -c unix_socket_directories='%s'", cluster->sockdir); #endif diff --git a/src/bin/pg_upgrade/version.c b/src/bin/pg_upgrade/version.c index 047670d4acb..9e83d4659be 100644 --- a/src/bin/pg_upgrade/version.c +++ b/src/bin/pg_upgrade/version.c @@ -12,22 +12,6 @@ #include "fe_utils/string_utils.h" #include "pg_upgrade.h" -/* - * version_hook functions for check_for_data_types_usage in order to determine - * whether a data type check should be executed for the cluster in question or - * not. - */ -bool -jsonb_9_4_check_applicable(ClusterInfo *cluster) -{ - /* JSONB changed its storage format during 9.4 beta */ - if (GET_MAJOR_VERSION(cluster->major_version) == 904 && - cluster->controldata.cat_ver < JSONB_FORMAT_CHANGE_CAT_VER) - return true; - - return false; -} - /* * Older servers can't support newer protocol versions, so their connection * strings will need to lock max_protocol_version to 3.0. @@ -46,117 +30,6 @@ protocol_negotiation_supported(const ClusterInfo *cluster) return (GET_MAJOR_VERSION(cluster->major_version) >= 1100); } -/* - * old_9_6_invalidate_hash_indexes() - * 9.6 -> 10 - * Hash index binary format has changed from 9.6->10.0 - */ -void -old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, bool check_mode) -{ - int dbnum; - FILE *script = NULL; - bool found = false; - char *output_path = "reindex_hash.sql"; - - prep_status("Checking for hash indexes"); - - for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) - { - PGresult *res; - bool db_used = false; - int ntups; - int rowno; - int i_nspname, - i_relname; - DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(cluster, active_db->db_name); - - /* find hash indexes */ - res = executeQueryOrDie(conn, - "SELECT n.nspname, c.relname " - "FROM pg_catalog.pg_class c, " - " pg_catalog.pg_index i, " - " pg_catalog.pg_am a, " - " pg_catalog.pg_namespace n " - "WHERE i.indexrelid = c.oid AND " - " c.relam = a.oid AND " - " c.relnamespace = n.oid AND " - " a.amname = 'hash'" - ); - - ntups = PQntuples(res); - i_nspname = PQfnumber(res, "nspname"); - i_relname = PQfnumber(res, "relname"); - for (rowno = 0; rowno < ntups; rowno++) - { - found = true; - if (!check_mode) - { - if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL) - pg_fatal("could not open file \"%s\": %m", output_path); - if (!db_used) - { - PQExpBufferData connectbuf; - - initPQExpBuffer(&connectbuf); - appendPsqlMetaConnect(&connectbuf, active_db->db_name); - fputs(connectbuf.data, script); - termPQExpBuffer(&connectbuf); - db_used = true; - } - fprintf(script, "REINDEX INDEX %s.%s;\n", - quote_identifier(PQgetvalue(res, rowno, i_nspname)), - quote_identifier(PQgetvalue(res, rowno, i_relname))); - } - } - - PQclear(res); - - if (!check_mode && db_used) - { - /* mark hash indexes as invalid */ - PQclear(executeQueryOrDie(conn, - "UPDATE pg_catalog.pg_index i " - "SET indisvalid = false " - "FROM pg_catalog.pg_class c, " - " pg_catalog.pg_am a, " - " pg_catalog.pg_namespace n " - "WHERE i.indexrelid = c.oid AND " - " c.relam = a.oid AND " - " c.relnamespace = n.oid AND " - " a.amname = 'hash'")); - } - - PQfinish(conn); - } - - if (script) - fclose(script); - - if (found) - { - report_status(PG_WARNING, "warning"); - if (check_mode) - pg_log(PG_WARNING, "\n" - "Your installation contains hash indexes. These indexes have different\n" - "internal formats between your old and new clusters, so they must be\n" - "reindexed with the REINDEX command. After upgrading, you will be given\n" - "REINDEX instructions."); - else - pg_log(PG_WARNING, "\n" - "Your installation contains hash indexes. These indexes have different\n" - "internal formats between your old and new clusters, so they must be\n" - "reindexed with the REINDEX command. The file\n" - " %s\n" - "when executed by psql by the database superuser will recreate all invalid\n" - "indexes; until then, none of these indexes will be used.", - output_path); - } - else - check_ok(); -} - /* * Callback function for processing results of query for * report_extension_updates()'s UpgradeTask. If the query returned any rows, diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 493400f9090..e5fb3595598 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -4471,10 +4471,10 @@ connection_warnings(bool in_startup) /* * Warn if server's major version is newer than ours, or if server - * predates our support cutoff (currently 9.2). + * predates our support cutoff (currently 10). */ if (pset.sversion / 100 > client_ver / 100 || - pset.sversion < 90200) + pset.sversion < 100000) printf(_("WARNING: %s major version %s, server major version %s.\n" " Some psql features might not work.\n"), pset.progname, @@ -6272,38 +6272,22 @@ get_create_object_cmd(EditableObjectType obj_type, Oid oid, * ensure the right view gets replaced. Also, check relation kind * to be sure it's a view. * - * Starting with PG 9.4, views may have WITH [LOCAL|CASCADED] - * CHECK OPTION. These are not part of the view definition - * returned by pg_get_viewdef() and so need to be retrieved - * separately. Materialized views (introduced in 9.3) may have - * arbitrary storage parameter reloptions. + * Views may have WITH [LOCAL|CASCADED] CHECK OPTION. These are + * not part of the view definition returned by pg_get_viewdef() + * and so need to be retrieved separately. Materialized views may + * have arbitrary storage parameter reloptions. */ printfPQExpBuffer(query, "/* %s */\n", _("Get view's definition and details")); - if (pset.sversion >= 90400) - { - appendPQExpBuffer(query, - "SELECT nspname, relname, relkind, " - "pg_catalog.pg_get_viewdef(c.oid, true), " - "pg_catalog.array_remove(pg_catalog.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 " - "FROM pg_catalog.pg_class c " - "LEFT JOIN pg_catalog.pg_namespace n " - "ON c.relnamespace = n.oid WHERE c.oid = %u", - oid); - } - else - { - appendPQExpBuffer(query, - "SELECT nspname, relname, relkind, " - "pg_catalog.pg_get_viewdef(c.oid, true), " - "c.reloptions AS reloptions, " - "NULL AS checkoption " - "FROM pg_catalog.pg_class c " - "LEFT JOIN pg_catalog.pg_namespace n " - "ON c.relnamespace = n.oid WHERE c.oid = %u", - oid); - } + appendPQExpBuffer(query, + "SELECT nspname, relname, relkind, " + "pg_catalog.pg_get_viewdef(c.oid, true), " + "pg_catalog.array_remove(pg_catalog.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 " + "FROM pg_catalog.pg_class c " + "LEFT JOIN pg_catalog.pg_namespace n " + "ON c.relnamespace = n.oid WHERE c.oid = %u", + oid); break; } diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 4e8ff00394a..662df2d5448 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -3,9 +3,9 @@ * * Support for the various \d ("describe") commands. Note that the current * expectation is that all functions in this file will succeed when working - * with servers of versions 9.2 and up. It's okay to omit irrelevant + * with servers of versions 10 and up. It's okay to omit irrelevant * information for an old server, but not to fail outright. (But failing - * against a pre-9.2 server is allowed.) + * against a pre-10 server is allowed.) * * Copyright (c) 2000-2026, PostgreSQL Global Development Group * @@ -154,16 +154,6 @@ describeAccessMethods(const char *pattern, bool verbose) printQueryOpt myopt = pset.popt; static const bool translate_columns[] = {false, true, false, false}; - if (pset.sversion < 90600) - { - char sverbuf[32]; - - pg_log_error("The server (version %s) does not support access methods.", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); - return true; - } - initPQExpBuffer(&buf); printfPQExpBuffer(&buf, "/* %s */\n", _("Get matching access methods")); @@ -312,9 +302,6 @@ describeFunctions(const char *functypes, const char *func_pattern, printQueryOpt myopt = pset.popt; static const bool translate_columns[] = {false, false, false, false, true, true, true, false, true, true, false, false, false, false}; - /* No "Parallel" column before 9.6 */ - static const bool translate_columns_pre_96[] = {false, false, false, false, true, true, false, true, true, false, false, false, false}; - if (strlen(functypes) != strspn(functypes, df_options)) { pg_log_error("\\df only takes [%s] as options", df_options); @@ -400,20 +387,19 @@ describeFunctions(const char *functypes, const char *func_pattern, gettext_noop("stable"), gettext_noop("volatile"), gettext_noop("Volatility")); - if (pset.sversion >= 90600) - appendPQExpBuffer(&buf, - ",\n CASE\n" - " WHEN p.proparallel = " - CppAsString2(PROPARALLEL_RESTRICTED) " THEN '%s'\n" - " WHEN p.proparallel = " - CppAsString2(PROPARALLEL_SAFE) " THEN '%s'\n" - " WHEN p.proparallel = " - CppAsString2(PROPARALLEL_UNSAFE) " THEN '%s'\n" - " END as \"%s\"", - gettext_noop("restricted"), - gettext_noop("safe"), - gettext_noop("unsafe"), - gettext_noop("Parallel")); + appendPQExpBuffer(&buf, + ",\n CASE\n" + " WHEN p.proparallel = " + CppAsString2(PROPARALLEL_RESTRICTED) " THEN '%s'\n" + " WHEN p.proparallel = " + CppAsString2(PROPARALLEL_SAFE) " THEN '%s'\n" + " WHEN p.proparallel = " + CppAsString2(PROPARALLEL_UNSAFE) " THEN '%s'\n" + " END as \"%s\"", + gettext_noop("restricted"), + gettext_noop("safe"), + gettext_noop("unsafe"), + gettext_noop("Parallel")); appendPQExpBuffer(&buf, ",\n pg_catalog.pg_get_userbyid(p.proowner) as \"%s\"" ",\n CASE WHEN prosecdef THEN '%s' ELSE '%s' END AS \"%s\"" @@ -613,16 +599,8 @@ describeFunctions(const char *functypes, const char *func_pattern, myopt.title = _("List of functions"); myopt.translate_header = true; - if (pset.sversion >= 90600) - { - myopt.translate_columns = translate_columns; - myopt.n_translate_columns = lengthof(translate_columns); - } - else - { - myopt.translate_columns = translate_columns_pre_96; - myopt.n_translate_columns = lengthof(translate_columns_pre_96); - } + myopt.translate_columns = translate_columns; + myopt.n_translate_columns = lengthof(translate_columns); printQuery(res, &myopt, pset.queryFout, false, pset.logfile); @@ -1108,70 +1086,38 @@ permissionsList(const char *pattern, bool showSystem) " ), E'\\n') AS \"%s\"", gettext_noop("Column privileges")); - if (pset.sversion >= 90500 && pset.sversion < 100000) - appendPQExpBuffer(&buf, - ",\n pg_catalog.array_to_string(ARRAY(\n" - " SELECT polname\n" - " || CASE WHEN polcmd != '*' THEN\n" - " E' (' || polcmd::pg_catalog.text || E'):'\n" - " ELSE E':'\n" - " END\n" - " || CASE WHEN polqual IS NOT NULL THEN\n" - " E'\\n (u): ' || pg_catalog.pg_get_expr(polqual, polrelid)\n" - " ELSE E''\n" - " END\n" - " || CASE WHEN polwithcheck IS NOT NULL THEN\n" - " E'\\n (c): ' || pg_catalog.pg_get_expr(polwithcheck, polrelid)\n" - " ELSE E''\n" - " END" - " || CASE WHEN polroles <> '{0}' THEN\n" - " E'\\n to: ' || pg_catalog.array_to_string(\n" - " ARRAY(\n" - " SELECT rolname\n" - " FROM pg_catalog.pg_roles\n" - " WHERE oid = ANY (polroles)\n" - " ORDER BY 1\n" - " ), E', ')\n" - " ELSE E''\n" - " END\n" - " FROM pg_catalog.pg_policy pol\n" - " WHERE polrelid = c.oid), E'\\n')\n" - " AS \"%s\"", - gettext_noop("Policies")); - - if (pset.sversion >= 100000) - appendPQExpBuffer(&buf, - ",\n pg_catalog.array_to_string(ARRAY(\n" - " SELECT polname\n" - " || CASE WHEN NOT polpermissive THEN\n" - " E' (RESTRICTIVE)'\n" - " ELSE '' END\n" - " || CASE WHEN polcmd != '*' THEN\n" - " E' (' || polcmd::pg_catalog.text || E'):'\n" - " ELSE E':'\n" - " END\n" - " || CASE WHEN polqual IS NOT NULL THEN\n" - " E'\\n (u): ' || pg_catalog.pg_get_expr(polqual, polrelid)\n" - " ELSE E''\n" - " END\n" - " || CASE WHEN polwithcheck IS NOT NULL THEN\n" - " E'\\n (c): ' || pg_catalog.pg_get_expr(polwithcheck, polrelid)\n" - " ELSE E''\n" - " END" - " || CASE WHEN polroles <> '{0}' THEN\n" - " E'\\n to: ' || pg_catalog.array_to_string(\n" - " ARRAY(\n" - " SELECT rolname\n" - " FROM pg_catalog.pg_roles\n" - " WHERE oid = ANY (polroles)\n" - " ORDER BY 1\n" - " ), E', ')\n" - " ELSE E''\n" - " END\n" - " FROM pg_catalog.pg_policy pol\n" - " WHERE polrelid = c.oid), E'\\n')\n" - " AS \"%s\"", - gettext_noop("Policies")); + appendPQExpBuffer(&buf, + ",\n pg_catalog.array_to_string(ARRAY(\n" + " SELECT polname\n" + " || CASE WHEN NOT polpermissive THEN\n" + " E' (RESTRICTIVE)'\n" + " ELSE '' END\n" + " || CASE WHEN polcmd != '*' THEN\n" + " E' (' || polcmd::pg_catalog.text || E'):'\n" + " ELSE E':'\n" + " END\n" + " || CASE WHEN polqual IS NOT NULL THEN\n" + " E'\\n (u): ' || pg_catalog.pg_get_expr(polqual, polrelid)\n" + " ELSE E''\n" + " END\n" + " || CASE WHEN polwithcheck IS NOT NULL THEN\n" + " E'\\n (c): ' || pg_catalog.pg_get_expr(polwithcheck, polrelid)\n" + " ELSE E''\n" + " END" + " || CASE WHEN polroles <> '{0}' THEN\n" + " E'\\n to: ' || pg_catalog.array_to_string(\n" + " ARRAY(\n" + " SELECT rolname\n" + " FROM pg_catalog.pg_roles\n" + " WHERE oid = ANY (polroles)\n" + " ORDER BY 1\n" + " ), E', ')\n" + " ELSE E''\n" + " END\n" + " FROM pg_catalog.pg_policy pol\n" + " WHERE polrelid = c.oid), E'\\n')\n" + " AS \"%s\"", + gettext_noop("Policies")); appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_class c\n" " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n" @@ -1666,7 +1612,7 @@ describeOneTableDetails(const char *schemaname, : "''"), oid); } - else if (pset.sversion >= 100000) + else { appendPQExpBuffer(&buf, "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, " @@ -1683,57 +1629,6 @@ describeOneTableDetails(const char *schemaname, : "''"), oid); } - else if (pset.sversion >= 90500) - { - appendPQExpBuffer(&buf, - "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, " - "c.relhastriggers, c.relrowsecurity, c.relforcerowsecurity, " - "c.relhasoids, false as relispartition, %s, c.reltablespace, " - "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, " - "c.relpersistence, c.relreplident\n" - "FROM pg_catalog.pg_class c\n " - "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n" - "WHERE c.oid = '%s';", - (verbose ? - "pg_catalog.array_to_string(c.reloptions || " - "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n" - : "''"), - oid); - } - else if (pset.sversion >= 90400) - { - appendPQExpBuffer(&buf, - "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, " - "c.relhastriggers, false, false, c.relhasoids, " - "false as relispartition, %s, c.reltablespace, " - "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, " - "c.relpersistence, c.relreplident\n" - "FROM pg_catalog.pg_class c\n " - "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n" - "WHERE c.oid = '%s';", - (verbose ? - "pg_catalog.array_to_string(c.reloptions || " - "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n" - : "''"), - oid); - } - else - { - appendPQExpBuffer(&buf, - "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, " - "c.relhastriggers, false, false, c.relhasoids, " - "false as relispartition, %s, c.reltablespace, " - "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, " - "c.relpersistence\n" - "FROM pg_catalog.pg_class c\n " - "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n" - "WHERE c.oid = '%s';", - (verbose ? - "pg_catalog.array_to_string(c.reloptions || " - "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n" - : "''"), - oid); - } res = PSQLexec(buf.data); if (!res) @@ -1761,8 +1656,7 @@ describeOneTableDetails(const char *schemaname, tableinfo.reloftype = (strcmp(PQgetvalue(res, 0, 11), "") != 0) ? pg_strdup(PQgetvalue(res, 0, 11)) : NULL; tableinfo.relpersistence = *(PQgetvalue(res, 0, 12)); - tableinfo.relreplident = (pset.sversion >= 90400) ? - *(PQgetvalue(res, 0, 13)) : 'd'; + tableinfo.relreplident = *(PQgetvalue(res, 0, 13)); if (pset.sversion >= 120000) tableinfo.relam = PQgetisnull(res, 0, 14) ? NULL : pg_strdup(PQgetvalue(res, 0, 14)); @@ -1781,53 +1675,27 @@ describeOneTableDetails(const char *schemaname, char *footers[3] = {NULL, NULL, NULL}; printfPQExpBuffer(&buf, "/* %s */\n", _("Get sequence information")); - if (pset.sversion >= 100000) - { - appendPQExpBuffer(&buf, - "SELECT pg_catalog.format_type(seqtypid, NULL) AS \"%s\",\n" - " seqstart AS \"%s\",\n" - " seqmin AS \"%s\",\n" - " seqmax AS \"%s\",\n" - " seqincrement AS \"%s\",\n" - " CASE WHEN seqcycle THEN '%s' ELSE '%s' END AS \"%s\",\n" - " seqcache AS \"%s\"\n", - gettext_noop("Type"), - gettext_noop("Start"), - gettext_noop("Minimum"), - gettext_noop("Maximum"), - gettext_noop("Increment"), - gettext_noop("yes"), - gettext_noop("no"), - gettext_noop("Cycles?"), - gettext_noop("Cache")); - appendPQExpBuffer(&buf, - "FROM pg_catalog.pg_sequence\n" - "WHERE seqrelid = '%s';", - oid); - } - else - { - appendPQExpBuffer(&buf, - "SELECT 'bigint' AS \"%s\",\n" - " start_value AS \"%s\",\n" - " min_value AS \"%s\",\n" - " max_value AS \"%s\",\n" - " increment_by AS \"%s\",\n" - " CASE WHEN is_cycled THEN '%s' ELSE '%s' END AS \"%s\",\n" - " cache_value AS \"%s\"\n", - gettext_noop("Type"), - gettext_noop("Start"), - gettext_noop("Minimum"), - gettext_noop("Maximum"), - gettext_noop("Increment"), - gettext_noop("yes"), - gettext_noop("no"), - gettext_noop("Cycles?"), - gettext_noop("Cache")); - appendPQExpBuffer(&buf, "FROM %s", fmtId(schemaname)); - /* must be separate because fmtId isn't reentrant */ - appendPQExpBuffer(&buf, ".%s;", fmtId(relationname)); - } + appendPQExpBuffer(&buf, + "SELECT pg_catalog.format_type(seqtypid, NULL) AS \"%s\",\n" + " seqstart AS \"%s\",\n" + " seqmin AS \"%s\",\n" + " seqmax AS \"%s\",\n" + " seqincrement AS \"%s\",\n" + " CASE WHEN seqcycle THEN '%s' ELSE '%s' END AS \"%s\",\n" + " seqcache AS \"%s\"\n", + gettext_noop("Type"), + gettext_noop("Start"), + gettext_noop("Minimum"), + gettext_noop("Maximum"), + gettext_noop("Increment"), + gettext_noop("yes"), + gettext_noop("no"), + gettext_noop("Cycles?"), + gettext_noop("Cache")); + appendPQExpBuffer(&buf, + "FROM pg_catalog.pg_sequence\n" + "WHERE seqrelid = '%s';", + oid); res = PSQLexec(buf.data); if (!res) @@ -2045,10 +1913,7 @@ describeOneTableDetails(const char *schemaname, appendPQExpBufferStr(&buf, ",\n (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t\n" " WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation) AS attcollation"); attcoll_col = cols++; - if (pset.sversion >= 100000) - appendPQExpBufferStr(&buf, ",\n a.attidentity"); - else - appendPQExpBufferStr(&buf, ",\n ''::pg_catalog.char AS attidentity"); + appendPQExpBufferStr(&buf, ",\n a.attidentity"); attidentity_col = cols++; if (pset.sversion >= 120000) appendPQExpBufferStr(&buf, ",\n a.attgenerated"); @@ -2459,12 +2324,8 @@ describeOneTableDetails(const char *schemaname, "contype IN (" CppAsString2(CONSTRAINT_PRIMARY) "," CppAsString2(CONSTRAINT_UNIQUE) "," CppAsString2(CONSTRAINT_EXCLUSION) ") AND " - "condeferred) AS condeferred,\n"); - - if (pset.sversion >= 90400) - appendPQExpBufferStr(&buf, "i.indisreplident,\n"); - else - appendPQExpBufferStr(&buf, "false AS indisreplident,\n"); + "condeferred) AS condeferred,\n" + "i.indisreplident,\n"); if (pset.sversion >= 150000) appendPQExpBufferStr(&buf, "i.indnullsnotdistinct,\n"); @@ -2568,11 +2429,8 @@ describeOneTableDetails(const char *schemaname, "i.indisclustered, i.indisvalid, " "pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),\n " "pg_catalog.pg_get_constraintdef(con.oid, true), " - "contype, condeferrable, condeferred"); - if (pset.sversion >= 90400) - appendPQExpBufferStr(&buf, ", i.indisreplident"); - else - appendPQExpBufferStr(&buf, ", false AS indisreplident"); + "contype, condeferrable, condeferred, " + "i.indisreplident"); appendPQExpBufferStr(&buf, ", c2.reltablespace"); if (pset.sversion >= 180000) appendPQExpBufferStr(&buf, ", con.conperiod"); @@ -2823,88 +2681,78 @@ describeOneTableDetails(const char *schemaname, PQclear(result); /* print any row-level policies */ - if (pset.sversion >= 90500) - { - printfPQExpBuffer(&buf, "/* %s */\n", - _("Get row-level policies for this table")); - appendPQExpBuffer(&buf, "SELECT pol.polname,"); - if (pset.sversion >= 100000) - appendPQExpBufferStr(&buf, - " pol.polpermissive,\n"); - else - appendPQExpBufferStr(&buf, - " 't' as polpermissive,\n"); - appendPQExpBuffer(&buf, - " CASE WHEN pol.polroles = '{0}' THEN NULL ELSE pg_catalog.array_to_string(array(select rolname from pg_catalog.pg_roles where oid = any (pol.polroles) order by 1),',') END,\n" - " pg_catalog.pg_get_expr(pol.polqual, pol.polrelid),\n" - " pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid),\n" - " CASE pol.polcmd\n" - " WHEN 'r' THEN 'SELECT'\n" - " WHEN 'a' THEN 'INSERT'\n" - " WHEN 'w' THEN 'UPDATE'\n" - " WHEN 'd' THEN 'DELETE'\n" - " END AS cmd\n" - "FROM pg_catalog.pg_policy pol\n" - "WHERE pol.polrelid = '%s' ORDER BY 1;", - oid); + printfPQExpBuffer(&buf, "/* %s */\n", + _("Get row-level policies for this table")); + appendPQExpBuffer(&buf, "SELECT pol.polname, pol.polpermissive,\n"); + appendPQExpBuffer(&buf, + " CASE WHEN pol.polroles = '{0}' THEN NULL ELSE pg_catalog.array_to_string(array(select rolname from pg_catalog.pg_roles where oid = any (pol.polroles) order by 1),',') END,\n" + " pg_catalog.pg_get_expr(pol.polqual, pol.polrelid),\n" + " pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid),\n" + " CASE pol.polcmd\n" + " WHEN 'r' THEN 'SELECT'\n" + " WHEN 'a' THEN 'INSERT'\n" + " WHEN 'w' THEN 'UPDATE'\n" + " WHEN 'd' THEN 'DELETE'\n" + " END AS cmd\n" + "FROM pg_catalog.pg_policy pol\n" + "WHERE pol.polrelid = '%s' ORDER BY 1;", + oid); - result = PSQLexec(buf.data); - if (!result) - goto error_return; - else - tuples = PQntuples(result); + result = PSQLexec(buf.data); + if (!result) + goto error_return; + else + tuples = PQntuples(result); - /* - * Handle cases where RLS is enabled and there are policies, or - * there aren't policies, or RLS isn't enabled but there are - * policies - */ - if (tableinfo.rowsecurity && !tableinfo.forcerowsecurity && tuples > 0) - printTableAddFooter(&cont, _("Policies:")); + /* + * Handle cases where RLS is enabled and there are policies, or there + * aren't policies, or RLS isn't enabled but there are policies + */ + if (tableinfo.rowsecurity && !tableinfo.forcerowsecurity && tuples > 0) + printTableAddFooter(&cont, _("Policies:")); - if (tableinfo.rowsecurity && tableinfo.forcerowsecurity && tuples > 0) - printTableAddFooter(&cont, _("Policies (forced row security enabled):")); + if (tableinfo.rowsecurity && tableinfo.forcerowsecurity && tuples > 0) + printTableAddFooter(&cont, _("Policies (forced row security enabled):")); - if (tableinfo.rowsecurity && !tableinfo.forcerowsecurity && tuples == 0) - printTableAddFooter(&cont, _("Policies (row security enabled): (none)")); + if (tableinfo.rowsecurity && !tableinfo.forcerowsecurity && tuples == 0) + printTableAddFooter(&cont, _("Policies (row security enabled): (none)")); - if (tableinfo.rowsecurity && tableinfo.forcerowsecurity && tuples == 0) - printTableAddFooter(&cont, _("Policies (forced row security enabled): (none)")); + if (tableinfo.rowsecurity && tableinfo.forcerowsecurity && tuples == 0) + printTableAddFooter(&cont, _("Policies (forced row security enabled): (none)")); - if (!tableinfo.rowsecurity && tuples > 0) - printTableAddFooter(&cont, _("Policies (row security disabled):")); + if (!tableinfo.rowsecurity && tuples > 0) + printTableAddFooter(&cont, _("Policies (row security disabled):")); - /* Might be an empty set - that's ok */ - for (i = 0; i < tuples; i++) - { - printfPQExpBuffer(&buf, " POLICY \"%s\"", - PQgetvalue(result, i, 0)); + /* Might be an empty set - that's ok */ + for (i = 0; i < tuples; i++) + { + printfPQExpBuffer(&buf, " POLICY \"%s\"", + PQgetvalue(result, i, 0)); - if (*(PQgetvalue(result, i, 1)) == 'f') - appendPQExpBufferStr(&buf, " AS RESTRICTIVE"); + if (*(PQgetvalue(result, i, 1)) == 'f') + appendPQExpBufferStr(&buf, " AS RESTRICTIVE"); - if (!PQgetisnull(result, i, 5)) - appendPQExpBuffer(&buf, " FOR %s", - PQgetvalue(result, i, 5)); + if (!PQgetisnull(result, i, 5)) + appendPQExpBuffer(&buf, " FOR %s", + PQgetvalue(result, i, 5)); - if (!PQgetisnull(result, i, 2)) - { - appendPQExpBuffer(&buf, "\n TO %s", - PQgetvalue(result, i, 2)); - } + if (!PQgetisnull(result, i, 2)) + { + appendPQExpBuffer(&buf, "\n TO %s", + PQgetvalue(result, i, 2)); + } - if (!PQgetisnull(result, i, 3)) - appendPQExpBuffer(&buf, "\n USING (%s)", - PQgetvalue(result, i, 3)); + if (!PQgetisnull(result, i, 3)) + appendPQExpBuffer(&buf, "\n USING (%s)", + PQgetvalue(result, i, 3)); - if (!PQgetisnull(result, i, 4)) - appendPQExpBuffer(&buf, "\n WITH CHECK (%s)", - PQgetvalue(result, i, 4)); + if (!PQgetisnull(result, i, 4)) + appendPQExpBuffer(&buf, "\n WITH CHECK (%s)", + PQgetvalue(result, i, 4)); - printTableAddFooter(&cont, buf.data); - } - PQclear(result); + printTableAddFooter(&cont, buf.data); } + PQclear(result); /* print any extended statistics */ if (pset.sversion >= 140000) @@ -3007,7 +2855,7 @@ describeOneTableDetails(const char *schemaname, } PQclear(result); } - else if (pset.sversion >= 100000) + else { printfPQExpBuffer(&buf, "/* %s */\n", _("Get extended statistics for this table")); @@ -3173,118 +3021,115 @@ describeOneTableDetails(const char *schemaname, } /* print any publications */ - if (pset.sversion >= 100000) + printfPQExpBuffer(&buf, "/* %s */\n", + _("Get publications that publish this table")); + if (pset.sversion >= 150000) { - printfPQExpBuffer(&buf, "/* %s */\n", - _("Get publications that publish this table")); - if (pset.sversion >= 150000) + appendPQExpBuffer(&buf, + "SELECT pubname\n" + " , NULL\n" + " , NULL\n" + "FROM pg_catalog.pg_publication p\n" + " JOIN pg_catalog.pg_publication_namespace pn ON p.oid = pn.pnpubid\n" + " JOIN pg_catalog.pg_class pc ON pc.relnamespace = pn.pnnspid\n" + "WHERE pc.oid ='%s' and pg_catalog.pg_relation_is_publishable('%s')\n" + "UNION\n" + "SELECT pubname\n" + " , pg_get_expr(pr.prqual, c.oid)\n" + " , (CASE WHEN pr.prattrs IS NOT NULL THEN\n" + " (SELECT string_agg(attname, ', ')\n" + " FROM pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n" + " pg_catalog.pg_attribute\n" + " WHERE attrelid = pr.prrelid AND attnum = prattrs[s])\n" + " ELSE NULL END) " + "FROM pg_catalog.pg_publication p\n" + " JOIN pg_catalog.pg_publication_rel pr ON p.oid = pr.prpubid\n" + " JOIN pg_catalog.pg_class c ON c.oid = pr.prrelid\n" + "WHERE pr.prrelid = '%s'\n", + oid, oid, oid); + + if (pset.sversion >= 190000) { + /* + * Skip entries where this relation appears in the + * publication's EXCEPT list. + */ appendPQExpBuffer(&buf, + " AND NOT pr.prexcept\n" + "UNION\n" "SELECT pubname\n" " , NULL\n" " , NULL\n" "FROM pg_catalog.pg_publication p\n" - " JOIN pg_catalog.pg_publication_namespace pn ON p.oid = pn.pnpubid\n" - " JOIN pg_catalog.pg_class pc ON pc.relnamespace = pn.pnnspid\n" - "WHERE pc.oid ='%s' and pg_catalog.pg_relation_is_publishable('%s')\n" - "UNION\n" - "SELECT pubname\n" - " , pg_get_expr(pr.prqual, c.oid)\n" - " , (CASE WHEN pr.prattrs IS NOT NULL THEN\n" - " (SELECT string_agg(attname, ', ')\n" - " FROM pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n" - " pg_catalog.pg_attribute\n" - " WHERE attrelid = pr.prrelid AND attnum = prattrs[s])\n" - " ELSE NULL END) " - "FROM pg_catalog.pg_publication p\n" - " JOIN pg_catalog.pg_publication_rel pr ON p.oid = pr.prpubid\n" - " JOIN pg_catalog.pg_class c ON c.oid = pr.prrelid\n" - "WHERE pr.prrelid = '%s'\n", + "WHERE p.puballtables AND pg_catalog.pg_relation_is_publishable('%s')\n" + " AND NOT EXISTS (\n" + " SELECT 1\n" + " FROM pg_catalog.pg_publication_rel pr\n" + " WHERE pr.prpubid = p.oid AND\n" + " (pr.prrelid = '%s' OR pr.prrelid = pg_catalog.pg_partition_root('%s')))\n" + "ORDER BY 1;", oid, oid, oid); - - if (pset.sversion >= 190000) - { - /* - * Skip entries where this relation appears in the - * publication's EXCEPT list. - */ - appendPQExpBuffer(&buf, - " AND NOT pr.prexcept\n" - "UNION\n" - "SELECT pubname\n" - " , NULL\n" - " , NULL\n" - "FROM pg_catalog.pg_publication p\n" - "WHERE p.puballtables AND pg_catalog.pg_relation_is_publishable('%s')\n" - " AND NOT EXISTS (\n" - " SELECT 1\n" - " FROM pg_catalog.pg_publication_rel pr\n" - " WHERE pr.prpubid = p.oid AND\n" - " (pr.prrelid = '%s' OR pr.prrelid = pg_catalog.pg_partition_root('%s')))\n" - "ORDER BY 1;", - oid, oid, oid); - } - else - { - appendPQExpBuffer(&buf, - "UNION\n" - "SELECT pubname\n" - " , NULL\n" - " , NULL\n" - "FROM pg_catalog.pg_publication p\n" - "WHERE p.puballtables AND pg_catalog.pg_relation_is_publishable('%s')\n" - "ORDER BY 1;", - oid); - } } else { appendPQExpBuffer(&buf, + "UNION\n" "SELECT pubname\n" - " , NULL\n" - " , NULL\n" - "FROM pg_catalog.pg_publication p\n" - "JOIN pg_catalog.pg_publication_rel pr ON p.oid = pr.prpubid\n" - "WHERE pr.prrelid = '%s'\n" - "UNION ALL\n" - "SELECT pubname\n" - " , NULL\n" - " , NULL\n" + " , NULL\n" + " , NULL\n" "FROM pg_catalog.pg_publication p\n" "WHERE p.puballtables AND pg_catalog.pg_relation_is_publishable('%s')\n" "ORDER BY 1;", - oid, oid); + oid); } + } + else + { + appendPQExpBuffer(&buf, + "SELECT pubname\n" + " , NULL\n" + " , NULL\n" + "FROM pg_catalog.pg_publication p\n" + "JOIN pg_catalog.pg_publication_rel pr ON p.oid = pr.prpubid\n" + "WHERE pr.prrelid = '%s'\n" + "UNION ALL\n" + "SELECT pubname\n" + " , NULL\n" + " , NULL\n" + "FROM pg_catalog.pg_publication p\n" + "WHERE p.puballtables AND pg_catalog.pg_relation_is_publishable('%s')\n" + "ORDER BY 1;", + oid, oid); + } - result = PSQLexec(buf.data); - if (!result) - goto error_return; - else - tuples = PQntuples(result); + result = PSQLexec(buf.data); + if (!result) + goto error_return; + else + tuples = PQntuples(result); - if (tuples > 0) - printTableAddFooter(&cont, _("Publications:")); + if (tuples > 0) + printTableAddFooter(&cont, _("Publications:")); - /* Might be an empty set - that's ok */ - for (i = 0; i < tuples; i++) - { - printfPQExpBuffer(&buf, " \"%s\"", - PQgetvalue(result, i, 0)); + /* Might be an empty set - that's ok */ + for (i = 0; i < tuples; i++) + { + printfPQExpBuffer(&buf, " \"%s\"", + PQgetvalue(result, i, 0)); - /* column list (if any) */ - if (!PQgetisnull(result, i, 2)) - appendPQExpBuffer(&buf, " (%s)", - PQgetvalue(result, i, 2)); + /* column list (if any) */ + if (!PQgetisnull(result, i, 2)) + appendPQExpBuffer(&buf, " (%s)", + PQgetvalue(result, i, 2)); - /* row filter (if any) */ - if (!PQgetisnull(result, i, 1)) - appendPQExpBuffer(&buf, " WHERE %s", - PQgetvalue(result, i, 1)); + /* row filter (if any) */ + if (!PQgetisnull(result, i, 1)) + appendPQExpBuffer(&buf, " WHERE %s", + PQgetvalue(result, i, 1)); - printTableAddFooter(&cont, buf.data); - } - PQclear(result); + printTableAddFooter(&cont, buf.data); } + PQclear(result); /* Print publications where the table is in the EXCEPT clause */ if (pset.sversion >= 190000) @@ -3706,7 +3551,7 @@ describeOneTableDetails(const char *schemaname, "ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT'," " c.oid::pg_catalog.regclass::pg_catalog.text;", oid); - else if (pset.sversion >= 100000) + else appendPQExpBuffer(&buf, "SELECT c.oid::pg_catalog.regclass, c.relkind," " false AS inhdetachpending," @@ -3716,14 +3561,6 @@ describeOneTableDetails(const char *schemaname, "ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT'," " c.oid::pg_catalog.regclass::pg_catalog.text;", oid); - else - appendPQExpBuffer(&buf, - "SELECT c.oid::pg_catalog.regclass, c.relkind," - " false AS inhdetachpending, NULL\n" - "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n" - "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n" - "ORDER BY c.oid::pg_catalog.regclass::pg_catalog.text;", - oid); result = PSQLexec(buf.data); if (!result) @@ -3963,12 +3800,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem) appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description"); ncols++; } - appendPQExpBufferStr(&buf, "\n, r.rolreplication"); - - if (pset.sversion >= 90500) - { - appendPQExpBufferStr(&buf, "\n, r.rolbypassrls"); - } + appendPQExpBufferStr(&buf, "\n, r.rolreplication, r.rolbypassrls"); appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_roles r\n"); @@ -4023,9 +3855,8 @@ describeRoles(const char *pattern, bool verbose, bool showSystem) if (strcmp(PQgetvalue(res, i, (verbose ? 9 : 8)), "t") == 0) add_role_attribute(&buf, _("Replication")); - if (pset.sversion >= 90500) - if (strcmp(PQgetvalue(res, i, (verbose ? 10 : 9)), "t") == 0) - add_role_attribute(&buf, _("Bypass RLS")); + if (strcmp(PQgetvalue(res, i, (verbose ? 10 : 9)), "t") == 0) + add_role_attribute(&buf, _("Bypass RLS")); conns = atoi(PQgetvalue(res, i, 6)); if (conns >= 0) @@ -4514,19 +4345,6 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose) const char *tabletitle; bool mixed_output = false; - /* - * Note: Declarative table partitioning is only supported as of Pg 10.0. - */ - if (pset.sversion < 100000) - { - char sverbuf[32]; - - pg_log_error("The server (version %s) does not support declarative table partitioning.", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); - return true; - } - /* If no relation kind was selected, show them all */ if (!showTables && !showIndexes) showTables = showIndexes = true; @@ -5034,16 +4852,6 @@ listEventTriggers(const char *pattern, bool verbose) static const bool translate_columns[] = {false, false, false, true, false, false, false}; - if (pset.sversion < 90300) - { - char sverbuf[32]; - - pg_log_error("The server (version %s) does not support event triggers.", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); - return true; - } - initPQExpBuffer(&buf); printfPQExpBuffer(&buf, "/* %s */\n", _("Get matching event triggers")); @@ -5113,16 +4921,6 @@ listExtendedStats(const char *pattern, bool verbose) PGresult *res; printQueryOpt myopt = pset.popt; - if (pset.sversion < 100000) - { - char sverbuf[32]; - - pg_log_error("The server (version %s) does not support extended statistics.", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); - return true; - } - initPQExpBuffer(&buf); printfPQExpBuffer(&buf, "/* %s */\n", _("Get matching extended statistics")); @@ -5352,19 +5150,14 @@ listCollations(const char *pattern, bool verbose, bool showSystem) gettext_noop("Schema"), gettext_noop("Name")); - if (pset.sversion >= 100000) - appendPQExpBuffer(&buf, - " CASE c.collprovider " - "WHEN " CppAsString2(COLLPROVIDER_DEFAULT) " THEN 'default' " - "WHEN " CppAsString2(COLLPROVIDER_BUILTIN) " THEN 'builtin' " - "WHEN " CppAsString2(COLLPROVIDER_LIBC) " THEN 'libc' " - "WHEN " CppAsString2(COLLPROVIDER_ICU) " THEN 'icu' " - "END AS \"%s\",\n", - gettext_noop("Provider")); - else - appendPQExpBuffer(&buf, - " 'libc' AS \"%s\",\n", - gettext_noop("Provider")); + appendPQExpBuffer(&buf, + " CASE c.collprovider " + "WHEN " CppAsString2(COLLPROVIDER_DEFAULT) " THEN 'default' " + "WHEN " CppAsString2(COLLPROVIDER_BUILTIN) " THEN 'builtin' " + "WHEN " CppAsString2(COLLPROVIDER_LIBC) " THEN 'libc' " + "WHEN " CppAsString2(COLLPROVIDER_ICU) " THEN 'icu' " + "END AS \"%s\",\n", + gettext_noop("Provider")); appendPQExpBuffer(&buf, " c.collcollate AS \"%s\",\n" @@ -6688,16 +6481,6 @@ listPublications(const char *pattern) printQueryOpt myopt = pset.popt; static const bool translate_columns[] = {false, false, false, false, false, false, false, false, false, false}; - if (pset.sversion < 100000) - { - char sverbuf[32]; - - pg_log_error("The server (version %s) does not support publications.", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); - return true; - } - initPQExpBuffer(&buf); printfPQExpBuffer(&buf, "/* %s */\n", _("Get matching publications")); @@ -6835,16 +6618,6 @@ describePublications(const char *pattern) PQExpBufferData title; printTableContent cont; - if (pset.sversion < 100000) - { - char sverbuf[32]; - - pg_log_error("The server (version %s) does not support publications.", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); - return true; - } - has_pubsequence = (pset.sversion >= 190000); has_pubtruncate = (pset.sversion >= 110000); has_pubgencols = (pset.sversion >= 180000); @@ -7095,16 +6868,6 @@ describeSubscriptions(const char *pattern, bool verbose) false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}; - if (pset.sversion < 100000) - { - char sverbuf[32]; - - pg_log_error("The server (version %s) does not support subscriptions.", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); - return true; - } - initPQExpBuffer(&buf); printfPQExpBuffer(&buf, "/* %s */\n", _("Get matching subscriptions")); diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c index 9990f818942..abf0bf3b8dc 100644 --- a/src/bin/psql/tab-complete.in.c +++ b/src/bin/psql/tab-complete.in.c @@ -1208,6 +1208,18 @@ Keywords_for_list_of_owner_roles, "PUBLIC" " FROM pg_catalog.pg_timezone_names() "\ " WHERE pg_catalog.quote_literal(pg_catalog.lower(name)) LIKE pg_catalog.lower('%s')" +#define Query_for_list_of_publications \ +" SELECT pubname "\ +" FROM pg_catalog.pg_publication "\ +" WHERE pubname LIKE '%s'" + +#define Query_for_list_of_subscriptions \ +" SELECT s.subname "\ +" FROM pg_catalog.pg_subscription s, pg_catalog.pg_database d "\ +" WHERE s.subname LIKE '%s' "\ +" AND d.datname = pg_catalog.current_database() "\ +" AND s.subdbid = d.oid" + /* Privilege options shared between GRANT and REVOKE */ #define Privilege_options_of_grant_and_revoke \ "SELECT", "INSERT", "UPDATE", "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER", \ @@ -1242,32 +1254,6 @@ Copy_common_options, "DEFAULT", "FORCE_NOT_NULL", "FORCE_NULL", "FREEZE", \ #define Copy_to_options \ Copy_common_options, "FORCE_QUOTE", "FORCE_ARRAY" -/* - * These object types were introduced later than our support cutoff of - * server version 9.2. We use the VersionedQuery infrastructure so that - * we don't send certain-to-fail queries to older servers. - */ - -static const VersionedQuery Query_for_list_of_publications[] = { - {100000, - " SELECT pubname " - " FROM pg_catalog.pg_publication " - " WHERE pubname LIKE '%s'" - }, - {0, NULL} -}; - -static const VersionedQuery Query_for_list_of_subscriptions[] = { - {100000, - " SELECT s.subname " - " FROM pg_catalog.pg_subscription s, pg_catalog.pg_database d " - " WHERE s.subname LIKE '%s' " - " AND d.datname = pg_catalog.current_database() " - " AND s.subdbid = d.oid" - }, - {0, NULL} -}; - /* Known command-starting keywords. */ static const char *const sql_commands[] = { "ABORT", "ALTER", "ANALYZE", "BEGIN", "CALL", "CHECKPOINT", "CLOSE", "CLUSTER", @@ -1345,7 +1331,7 @@ static const pgsql_thing_t words_after_create[] = { {"POLICY", NULL, NULL, NULL}, {"PROCEDURE", NULL, NULL, Query_for_list_of_procedures}, {"PROPERTY GRAPH", NULL, NULL, &Query_for_list_of_propgraphs}, - {"PUBLICATION", NULL, Query_for_list_of_publications}, + {"PUBLICATION", Query_for_list_of_publications}, {"ROLE", Query_for_list_of_roles}, {"ROUTINE", NULL, NULL, &Query_for_list_of_routines, NULL, THING_NO_CREATE}, {"RULE", "SELECT rulename FROM pg_catalog.pg_rules WHERE rulename LIKE '%s'"}, @@ -1353,7 +1339,7 @@ static const pgsql_thing_t words_after_create[] = { {"SEQUENCE", NULL, NULL, &Query_for_list_of_sequences}, {"SERVER", Query_for_list_of_servers}, {"STATISTICS", NULL, NULL, &Query_for_list_of_statistics}, - {"SUBSCRIPTION", NULL, Query_for_list_of_subscriptions}, + {"SUBSCRIPTION", Query_for_list_of_subscriptions}, {"SYSTEM", NULL, NULL, NULL, NULL, THING_NO_CREATE | THING_NO_DROP}, {"TABLE", NULL, NULL, &Query_for_list_of_tables}, {"TABLESPACE", Query_for_list_of_tablespaces}, @@ -5672,9 +5658,9 @@ match_previous_words(int pattern_id, else if (TailMatchesCS("\\dP*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_relations); else if (TailMatchesCS("\\dRp*")) - COMPLETE_WITH_VERSIONED_QUERY(Query_for_list_of_publications); + COMPLETE_WITH_QUERY(Query_for_list_of_publications); else if (TailMatchesCS("\\dRs*")) - COMPLETE_WITH_VERSIONED_QUERY(Query_for_list_of_subscriptions); + COMPLETE_WITH_QUERY(Query_for_list_of_subscriptions); else if (TailMatchesCS("\\ds*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences); else if (TailMatchesCS("\\dt*")) -- 2.50.1 (Apple Git-155)