0001-Fix-column-name-escaping-in-postgres_fdw-stats-import-efujita.patch

application/octet-stream

Filename: 0001-Fix-column-name-escaping-in-postgres_fdw-stats-import-efujita.patch
Type: application/octet-stream
Part: 0
Message: Re: [PATCH] Fix column name escaping in postgres_fdw stats import
diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out
index 10e87acabef..34bddd5a019 100644
--- a/contrib/postgres_fdw/expected/postgres_fdw.out
+++ b/contrib/postgres_fdw/expected/postgres_fdw.out
@@ -12917,11 +12917,23 @@ CREATE FOREIGN TABLE simport_fview (c1 int, c2 text)
 ALTER FOREIGN TABLE simport_fview OPTIONS (ADD restore_stats 'true');
 ANALYZE simport_fview;                    -- should fail
 WARNING:  could not import statistics for foreign table "public.simport_fview" --- remote table "public.simport_view" is of relkind "v" which cannot have statistics
+-- Test deparsing column names in build_remattrmap() that include single
+-- quotes or backslashes
+CREATE TABLE dtest_table ("col'quote" int, "col\backslash" int);
+CREATE FOREIGN TABLE dtest_ftable ("col'quote" int, "col\backslash" int)
+       SERVER loopback OPTIONS (table_name 'dtest_table', restore_stats 'true');
+INSERT INTO dtest_table SELECT g, g FROM generate_series(1, 10) g;
+ANALYZE dtest_table;
+ANALYZE VERBOSE dtest_ftable;             -- should work
+INFO:  importing statistics for foreign table "public.dtest_ftable"
+INFO:  finished importing statistics for foreign table "public.dtest_ftable"
 -- cleanup
 DROP FOREIGN TABLE simport_ftable;
 DROP FOREIGN TABLE simport_fview;
 DROP VIEW simport_view;
 DROP TABLE simport_table;
+DROP FOREIGN TABLE dtest_ftable;
+DROP TABLE dtest_table;
 -- ===================================================================
 -- test for postgres_fdw_get_connections function with check_conn = true
 -- ===================================================================
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index 86b2cdf4f63..cdb555727f8 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -5886,7 +5886,7 @@ fetch_attstats(PGconn *conn, int server_version_num,
 						   " AND tablename = ");
 	deparseStringLiteral(&sql, remote_relname);
 	appendStringInfo(&sql,
-					 " AND attname = ANY('%s'::text[])",
+					 " AND attname = ANY(%s)",
 					 column_list);
 
 	/* inherited is supported since Postgres 9.0 */
@@ -5921,7 +5921,7 @@ build_remattrmap(Relation relation, List *va_cols,
 
 	remattrmap = palloc_array(RemoteAttributeMapping, tupdesc->natts);
 	initStringInfo(column_list);
-	appendStringInfoChar(column_list, '{');
+	appendStringInfoString(column_list, "ARRAY[");
 	for (int i = 0; i < tupdesc->natts; i++)
 	{
 		Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
@@ -5954,7 +5954,7 @@ build_remattrmap(Relation relation, List *va_cols,
 
 		if (attrcnt > 0)
 			appendStringInfoString(column_list, ", ");
-		appendStringInfoString(column_list, quote_identifier(remote_attname));
+		deparseStringLiteral(column_list, remote_attname);
 
 		remattrmap[attrcnt].local_attnum = attnum;
 		strncpy(remattrmap[attrcnt].local_attname, attname, NAMEDATALEN);
@@ -5962,7 +5962,7 @@ build_remattrmap(Relation relation, List *va_cols,
 		remattrmap[attrcnt].res_index = -1;
 		attrcnt++;
 	}
-	appendStringInfoChar(column_list, '}');
+	appendStringInfoChar(column_list, ']');
 
 	/* Sort mapping by remote attribute name if needed. */
 	if (attrcnt > 1)
diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql
index 79ad5be8bf9..298e06a9e43 100644
--- a/contrib/postgres_fdw/sql/postgres_fdw.sql
+++ b/contrib/postgres_fdw/sql/postgres_fdw.sql
@@ -4573,11 +4573,24 @@ ALTER FOREIGN TABLE simport_fview OPTIONS (ADD restore_stats 'true');
 
 ANALYZE simport_fview;                    -- should fail
 
+-- Test deparsing column names in build_remattrmap() that include single
+-- quotes or backslashes
+CREATE TABLE dtest_table ("col'quote" int, "col\backslash" int);
+CREATE FOREIGN TABLE dtest_ftable ("col'quote" int, "col\backslash" int)
+       SERVER loopback OPTIONS (table_name 'dtest_table', restore_stats 'true');
+
+INSERT INTO dtest_table SELECT g, g FROM generate_series(1, 10) g;
+ANALYZE dtest_table;
+
+ANALYZE VERBOSE dtest_ftable;             -- should work
+
 -- cleanup
 DROP FOREIGN TABLE simport_ftable;
 DROP FOREIGN TABLE simport_fview;
 DROP VIEW simport_view;
 DROP TABLE simport_table;
+DROP FOREIGN TABLE dtest_ftable;
+DROP TABLE dtest_table;
 
 -- ===================================================================
 -- test for postgres_fdw_get_connections function with check_conn = true