| From: | Nikolay Samokhvalov <nik(at)postgres(dot)ai> |
|---|---|
| To: | pgsql-hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Cc: | etsuro(dot)fujita(at)gmail(dot)com, Corey Huinker <corey(dot)huinker(at)gmail(dot)com>, ashutosh(dot)bapat(dot)oss(at)gmail(dot)com |
| Subject: | [PG19][PATCH] Make postgres_fdw statistics import atomic |
| Date: | 2026-09-15 09:36:14 |
| Message-ID: | CAM527d-gHX4zZOhi9vvX+OsgEb+b2+fPbLUq8XRjAPYWQxDWjw@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi hackers,
postgres_fdw can leave partial pg_statistic changes behind when statistics
import fails and analyze falls back to sampling.
My AI correctness harness found this while I was testing new PG19 features.
It also prepared and tested the attached patch. I have not fully reviewed
that patch by hand because I am testing many PG19 areas in parallel. I
nevertheless think it is useful to post: I mostly trust this harness, and
the exact reproducer and patch passed its independent execution and review
gates. Please treat the patch as AI-prepared and review it in the usual way.
import_fetched_statistics() deletes and updates one attribute at a time.
attribute_statistics_update_internal() can update a partial row and return
false after a conversion warning. Earlier attributes have already been
updated too. If the fallback sample is empty, analyze does not replace
attribute statistics, so those changes commit.
Here is a complete reproducer. Run it with psql as a superuser against a
fresh PG19 server that accepts a loopback connection on its Unix socket:
create extension postgres_fdw;
create table remote_t (a, b) as values (11, '21'::text), (11, '21');
analyze remote_t;
create server loopback foreign data wrapper postgres_fdw
options (host :'HOST', port :'PORT', dbname :'DBNAME');
create user mapping for current_user server loopback options (user :'USER');
create foreign table ft (a int, b int) server loopback
options (table_name 'remote_t', import_stats 'true');
analyze ft;
update remote_t set a = 111, b = 'bad-x';
analyze remote_t;
delete from remote_t;
analyze ft;
select attname, coalesce(most_common_vals::text, 'NULL') as mcv
from pg_stats
where tablename = 'ft'
order by attname;
On REL_19_STABLE at e7c1b57012b the decisive output is below (psql's file
and line prefixes are omitted):
WARNING: invalid input syntax for type integer: "bad-x"
WARNING: could not import statistics for foreign table "public.ft"
--- attribute statistics import failed for column "b" of this foreign
table
attname | mcv
---------+-------
a | {111}
b | NULL
(2 rows)
The attached patch runs the local catalog import in an internal
subtransaction. It releases the subtransaction on success and rolls it
back when the import returns false. Errors are rolled back and rethrown.
The remote fetch stays outside the subtransaction.
The new regression test fails without the code change with the same partial
update. With the patch, the old coherent statistics survive:
attname | mcv
---------+------
a | {11}
b | {21}
(2 rows)
postgres_fdw regression and isolation tests pass. I also applied the exact
attachment to a clean REL_19_STABLE checkout and reran both suites.
Nik
| Attachment | Content-Type | Size |
|---|---|---|
| 0001-postgres_fdw-Make-statistics-import-atomic.patch | application/octet-stream | 6.7 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Virender Singla | 2026-09-15 09:42:20 | Re: [PATCH] Corruption Issue: Fix missing tts_tid in ExecForceStoreHeapTuple |
| Previous Message | Jan Nidzwetzki | 2026-09-15 09:35:36 | Re: [PATCH] Speed up repeat() for larger counts |