Fix array-element quoting in postgres_fdw import statistics
Hi,
build_remattrmap() used quote_identifier() to format column names
for a text[] array literal passed to the remote pg_stats query.
quote_identifier() applies SQL identifier quoting, which doubles
double-quote characters but does not escape backslashes. However,
inside a PostgreSQL array literal, backslash is an escape character.
Column names containing backslashes (e.g. "a\b") were silently
mangled by the array parser—"a\b" became "ab"—causing the
WHERE attname = ANY('{...}') filter to miss those columns. The
statistics import would then fail with a WARNING about missing
attribute statistics. This is a very corner cases because usually
backslash is not included in the column names. Anyways attached
a draft patch. Please take a look and let me know what you think.
-- Setup
CREATE TABLE bs_test (id int PRIMARY KEY, "a\b" int, normal_col text);
INSERT INTO bs_test SELECT g, g, 'val' FROM generate_series(1,1000) g;
ANALYZE bs_test;
CREATE SERVER loopback FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host '127.0.0.1', port '5432', dbname 'testdb', restore_stats
'true');
CREATE USER MAPPING FOR CURRENT_USER SERVER loopback OPTIONS (user
'postgres');
CREATE FOREIGN TABLE fbs_test (id int, "a\b" int, normal_col text)
SERVER loopback OPTIONS (schema_name 'public', table_name 'bs_test');
ANALYZE fbs_test;
-- WARNING: could not import statistics for foreign table "public.fbs_test"
--- no attribute statistics found for column "a\b" of remote table
"public.bs_test"
Thanks,
Satya
Attachments:
v1-0001-postgres_fdw-fix-array-quoting.patchapplication/octet-stream; name=v1-0001-postgres_fdw-fix-array-quoting.patchDownload+16-1
On Sun, Apr 12, 2026 at 12:13 PM SATYANARAYANA NARLAPURAM
<satyanarlapuram@gmail.com> wrote:
build_remattrmap() used quote_identifier() to format column names
for a text[] array literal passed to the remote pg_stats query.
quote_identifier() applies SQL identifier quoting, which doubles
double-quote characters but does not escape backslashes. However,
inside a PostgreSQL array literal, backslash is an escape character.Column names containing backslashes (e.g. "a\b") were silently
mangled by the array parser—"a\b" became "ab"—causing the
WHERE attname = ANY('{...}') filter to miss those columns. The
statistics import would then fail with a WARNING about missing
attribute statistics. This is a very corner cases because usually
backslash is not included in the column names. Anyways attached
a draft patch. Please take a look and let me know what you think.-- Setup
CREATE TABLE bs_test (id int PRIMARY KEY, "a\b" int, normal_col text);
INSERT INTO bs_test SELECT g, g, 'val' FROM generate_series(1,1000) g;
ANALYZE bs_test;CREATE SERVER loopback FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host '127.0.0.1', port '5432', dbname 'testdb', restore_stats 'true');
CREATE USER MAPPING FOR CURRENT_USER SERVER loopback OPTIONS (user 'postgres');CREATE FOREIGN TABLE fbs_test (id int, "a\b" int, normal_col text)
SERVER loopback OPTIONS (schema_name 'public', table_name 'bs_test');ANALYZE fbs_test; -- WARNING: could not import statistics for foreign table "public.fbs_test" --- no attribute statistics found for column "a\b" of remote table "public.bs_test"
Good catch! I will look into this as well. I added it to the open
items list as well.
Thanks for the report and patch, again!
Best regards,
Etsuro Fujita
On Sun, Apr 12, 2026 at 3:46 PM Etsuro Fujita <etsuro.fujita@gmail.com> wrote:
On Sun, Apr 12, 2026 at 12:13 PM SATYANARAYANA NARLAPURAM
<satyanarlapuram@gmail.com> wrote:build_remattrmap() used quote_identifier() to format column names
for a text[] array literal passed to the remote pg_stats query.
quote_identifier() applies SQL identifier quoting, which doubles
double-quote characters but does not escape backslashes. However,
inside a PostgreSQL array literal, backslash is an escape character.Column names containing backslashes (e.g. "a\b") were silently
mangled by the array parser—"a\b" became "ab"—causing the
WHERE attname = ANY('{...}') filter to miss those columns. The
statistics import would then fail with a WARNING about missing
attribute statistics. This is a very corner cases because usually
backslash is not included in the column names. Anyways attached
a draft patch. Please take a look and let me know what you think.
Good catch! I will look into this as well.
I think your analysis is correct, but a simpler solution for this
issue is to use deparseStringLiteral() for column names, instead of
quote_identifier(), as proposed in [1]/messages/by-id/CAJTYsWWGhVDFjr+smdYdU-Q_TT9YMzXA4QcLCr7rizDOyrEEow@mail.gmail.com.
Best regards,
Etsuro Fujita
[1]: /messages/by-id/CAJTYsWWGhVDFjr+smdYdU-Q_TT9YMzXA4QcLCr7rizDOyrEEow@mail.gmail.com