]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
postgres_fdw: Report ANALYZE to pgstats after importing statistics.
authorEtsuro Fujita <efujita@postgresql.org>
Tue, 7 Jul 2026 09:40:00 +0000 (18:40 +0900)
committerEtsuro Fujita <efujita@postgresql.org>
Tue, 7 Jul 2026 09:40:00 +0000 (18:40 +0900)
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

contrib/postgres_fdw/expected/postgres_fdw.out
contrib/postgres_fdw/postgres_fdw.c
contrib/postgres_fdw/sql/postgres_fdw.sql

index 0805c56cb1ba5b6f875528b6f4c9631dc4512a71..5ebae1cedc2f61cf1e9ced92157d947a5a3baa4a 100644 (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"
index 6fa45773c30d68e0ec78abf6f8843cfc6fba5381..0ea72a64ce5024f389b8c455d4df368cb8244fc1 100644 (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:
index 8162c5496bfd29ef50f050d955d3ad4e7c2a4abd..e868da00ace7f476f6e94f80db5a5dc39fd273d4 100644 (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