postgres_fdw: Report ANALYZE to pgstats after importing statistics.

Commit 28972b6fc should have done this, but didn't.

While at it, remove an extra blank line in fetch_remote_statistics()
introduced by that commit.

Reported-by: Chao Li <lic@highgo.com>
Co-authored-by: Chao Li <lic@highgo.com>
Co-authored-by: Etsuro Fujita <etsuro.fujita@gmail.com>
Discussion: https://postgr.es/m/6ED81190-B398-44C9-A1E9-8EFE4ED183AF%40gmail.com
Backpatch-through: 19
This commit is contained in:
Etsuro Fujita 2026-07-07 18:40:00 +09:00
parent 7f0998f87b
commit 0021794f4c
3 changed files with 67 additions and 1 deletions

View file

@ -12973,9 +12973,29 @@ ALTER FOREIGN TABLE simport_ftable OPTIONS (ADD restore_stats 'true');
ANALYZE simport_ftable; -- should fail
WARNING: could not import statistics for foreign table "public.simport_ftable" --- remote table "public.simport_table" has no relation statistics to import
ANALYZE simport_table;
SELECT pg_stat_reset_single_table_counters('public.simport_ftable'::regclass);
pg_stat_reset_single_table_counters
-------------------------------------
(1 row)
ANALYZE VERBOSE simport_ftable; -- should work
INFO: importing statistics for foreign table "public.simport_ftable"
INFO: finished importing statistics for foreign table "public.simport_ftable"
SELECT pg_stat_force_next_flush();
pg_stat_force_next_flush
--------------------------
(1 row)
SELECT pg_stat_get_live_tuples('public.simport_ftable'::regclass),
pg_stat_get_dead_tuples('public.simport_ftable'::regclass),
pg_stat_get_analyze_count('public.simport_ftable'::regclass);
pg_stat_get_live_tuples | pg_stat_get_dead_tuples | pg_stat_get_analyze_count
-------------------------+-------------------------+---------------------------
0 | 0 | 1
(1 row)
ALTER TABLE simport_table ALTER COLUMN c1 SET STATISTICS 0;
ALTER TABLE simport_table ALTER COLUMN c2 SET STATISTICS 0;
INSERT INTO simport_table VALUES (1, 'foo'), (1, 'foo'), (2, 'bar'), (2, 'bar');
@ -12988,9 +13008,29 @@ ANALYZE simport_ftable; -- should fail
WARNING: could not import statistics for foreign table "public.simport_ftable" --- no attribute statistics found for column "c2" of remote table "public.simport_table"
ALTER TABLE simport_table ALTER COLUMN c2 SET STATISTICS DEFAULT;
ANALYZE simport_table;
SELECT pg_stat_reset_single_table_counters('public.simport_ftable'::regclass);
pg_stat_reset_single_table_counters
-------------------------------------
(1 row)
ANALYZE VERBOSE simport_ftable; -- should work
INFO: importing statistics for foreign table "public.simport_ftable"
INFO: finished importing statistics for foreign table "public.simport_ftable"
SELECT pg_stat_force_next_flush();
pg_stat_force_next_flush
--------------------------
(1 row)
SELECT pg_stat_get_live_tuples('public.simport_ftable'::regclass),
pg_stat_get_dead_tuples('public.simport_ftable'::regclass),
pg_stat_get_analyze_count('public.simport_ftable'::regclass);
pg_stat_get_live_tuples | pg_stat_get_dead_tuples | pg_stat_get_analyze_count
-------------------------+-------------------------+---------------------------
4 | 0 | 1
(1 row)
ANALYZE VERBOSE simport_ftable (c1); -- should work
INFO: importing statistics for foreign table "public.simport_ftable"
INFO: finished importing statistics for foreign table "public.simport_ftable"

View file

@ -41,6 +41,7 @@
#include "optimizer/restrictinfo.h"
#include "optimizer/tlist.h"
#include "parser/parsetree.h"
#include "pgstat.h"
#include "postgres_fdw.h"
#include "statistics/statistics.h"
#include "storage/latch.h"
@ -52,6 +53,7 @@
#include "utils/rel.h"
#include "utils/sampling.h"
#include "utils/selfuncs.h"
#include "utils/timestamp.h"
PG_MODULE_MAGIC_EXT(
.name = "postgres_fdw",
@ -336,6 +338,8 @@ typedef struct
PGresult *rel;
PGresult *att;
int server_version_num;
double livetuples;
double deadtuples;
} RemoteStatsResults;
/* Column order in relation stats query */
@ -5597,6 +5601,7 @@ postgresImportForeignStatistics(Relation relation, List *va_cols, int elevel)
RemoteStatsResults remstats = {.rel = NULL, .att = NULL};
RemoteAttributeMapping *remattrmap = NULL;
int attrcnt = 0;
TimestampTz starttime = 0;
bool restore_stats = false;
bool ok = false;
ListCell *lc;
@ -5656,6 +5661,8 @@ postgresImportForeignStatistics(Relation relation, List *va_cols, int elevel)
(errmsg("importing statistics for foreign table \"%s.%s\"",
schemaname, relname)));
starttime = GetCurrentTimestamp();
ok = fetch_remote_statistics(relation, va_cols,
table, schemaname, relname,
&attrcnt, &remattrmap, &remstats);
@ -5665,9 +5672,15 @@ postgresImportForeignStatistics(Relation relation, List *va_cols, int elevel)
attrcnt, remattrmap, &remstats);
if (ok)
{
pgstat_report_analyze(relation,
remstats.livetuples, remstats.deadtuples,
(va_cols == NIL), starttime);
ereport(elevel,
(errmsg("finished importing statistics for foreign table \"%s.%s\"",
schemaname, relname)));
}
PQclear(remstats.rel);
PQclear(remstats.att);
@ -5780,7 +5793,6 @@ fetch_remote_statistics(Relation relation,
goto fetch_cleanup;
}
if (reltuples > 0)
{
StringInfoData column_list;
@ -5807,6 +5819,10 @@ fetch_remote_statistics(Relation relation,
}
}
/* We assume that we have no dead tuple. */
remstats->deadtuples = 0.0;
remstats->livetuples = reltuples;
ok = true;
fetch_cleanup:

View file

@ -4587,7 +4587,12 @@ ANALYZE simport_ftable; -- should fail
ANALYZE simport_table;
SELECT pg_stat_reset_single_table_counters('public.simport_ftable'::regclass);
ANALYZE VERBOSE simport_ftable; -- should work
SELECT pg_stat_force_next_flush();
SELECT pg_stat_get_live_tuples('public.simport_ftable'::regclass),
pg_stat_get_dead_tuples('public.simport_ftable'::regclass),
pg_stat_get_analyze_count('public.simport_ftable'::regclass);
ALTER TABLE simport_table ALTER COLUMN c1 SET STATISTICS 0;
ALTER TABLE simport_table ALTER COLUMN c2 SET STATISTICS 0;
@ -4604,7 +4609,12 @@ ANALYZE simport_ftable; -- should fail
ALTER TABLE simport_table ALTER COLUMN c2 SET STATISTICS DEFAULT;
ANALYZE simport_table;
SELECT pg_stat_reset_single_table_counters('public.simport_ftable'::regclass);
ANALYZE VERBOSE simport_ftable; -- should work
SELECT pg_stat_force_next_flush();
SELECT pg_stat_get_live_tuples('public.simport_ftable'::regclass),
pg_stat_get_dead_tuples('public.simport_ftable'::regclass),
pg_stat_get_analyze_count('public.simport_ftable'::regclass);
ANALYZE VERBOSE simport_ftable (c1); -- should work