From bea01b825c077e73b009be0a6f000ed643490ae9 Mon Sep 17 00:00:00 2001 From: Etsuro Fujita Date: Fri, 18 Sep 2026 17:45:00 +0900 Subject: [PATCH] postgres_fdw: Fix oversights in fetch_attstats(). The query to get attribute statistics from a remote server applied the "C" collation to a column of type name without checking the server's version. Since the name type was made collatable in Postgres 12, this could break attribute statistics import if the server was older. Fix by casting the column value to text before collating it if the server is older. Also, fix a typo in the if-test in the same function. Oversights in commit 28972b6fc; the former was reported by Fujii Masao. Reported-by: Fujii Masao Author: Etsuro Fujita Reviewed-by: Corey Huinker Discussion: https://postgr.es/m/CAHGQGwGvA_3q7Wg7GXQkuugGZj3%3DkxDRjDsKgVvK1uwAxHTopQ%40mail.gmail.com Backpatch-through: 19 --- contrib/postgres_fdw/postgres_fdw.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index d890bc02b77..fbe01fdde85 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -6003,12 +6003,23 @@ fetch_attstats(PGconn *conn, int server_version_num, StringInfoData sql; PGresult *res; - /* The caller guarantees the remote server is v9.1 or later. */ + /* + * The caller guarantees the remote server is v9.1, which supported + * COLLATE "C", or later + */ Assert(server_version_num >= 90100); initStringInfo(&sql); + + /* Type name is collatable since Postgres 12 */ + if (server_version_num >= 120000) + appendStringInfoString(&sql, + "SELECT DISTINCT ON (attname COLLATE \"C\") attname,"); + else + appendStringInfoString(&sql, + "SELECT DISTINCT ON (attname::text COLLATE \"C\") attname,"); + appendStringInfoString(&sql, - "SELECT DISTINCT ON (attname COLLATE \"C\") attname," " null_frac," " avg_width," " n_distinct," @@ -6018,7 +6029,7 @@ fetch_attstats(PGconn *conn, int server_version_num, " correlation,"); /* Elements stats are supported since Postgres 9.2 */ - if (server_version_num >= 92000) + if (server_version_num >= 90200) appendStringInfoString(&sql, " most_common_elems," " most_common_elem_freqs," @@ -6049,11 +6060,15 @@ fetch_attstats(PGconn *conn, int server_version_num, column_list); /* - * inherited and COLLATE are supported since Postgres 9.0 and 9.1, - * respectively. + * Type name is collatable since Postgres 12 (inherited is supported + * since Postgres 9.0) */ - appendStringInfoString(&sql, - " ORDER BY attname COLLATE \"C\", inherited DESC"); + if (server_version_num >= 120000) + appendStringInfoString(&sql, + " ORDER BY attname COLLATE \"C\", inherited DESC"); + else + appendStringInfoString(&sql, + " ORDER BY attname::text COLLATE \"C\", inherited DESC"); res = pgfdw_exec_query(conn, sql.data, NULL); if (PQresultStatus(res) != PGRES_TUPLES_OK)