Thread

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Add default_char_signedness field to ControlFileData.

  2. Add defenses against running with a wrong selection of LOBLKSIZE.

  1. [PATCH v1 1/1] remove pg_dump, pg_dumpall, and pg_upgrade support for pre-10 servers

    Nathan Bossart <nathan@postgresql.org> — 2026-04-08T15:40:38Z

    ---
     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 <application>pg_dump</application> has no choice
             but to abort the dump.
            </para>
    -       <para>
    -        To perform a parallel dump, the database server needs to support
    -        synchronized snapshots, a feature that was introduced in
    -        <productname>PostgreSQL</productname> 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.
    -        <command>pg_dump -j</command> 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.
    -       </para>
           </listitem>
          </varlistentry>
     
    @@ -1718,7 +1706,7 @@ CREATE DATABASE foo WITH TEMPLATE template0;
        <productname>PostgreSQL</productname> server versions newer than
        <application>pg_dump</application>'s version.  <application>pg_dump</application> can also
        dump from <productname>PostgreSQL</productname> servers older than its own version.
    -   (Currently, servers back to version 9.2 are supported.)
    +   (Currently, servers back to version 10 are supported.)
        However, <application>pg_dump</application> cannot dump from
        <productname>PostgreSQL</productname> 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
      </para>
     
       <para>
    -   <application>pg_upgrade</application> supports upgrades from 9.2.X and later to the current
    +   <application>pg_upgrade</application> supports upgrades from 10.X and later to the current
        major release of <productname>PostgreSQL</productname>, including snapshot and beta releases.
       </para>
     
    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 <linux/fs.h>
     #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)
    
    
    --Kb32uh2GnCIDdWt+--