On Mon, Jun 15, 2026 at 11:51:40AM +0800, Chao Li wrote:
> If the fix direction is to make pg_restore behave consistently with
> pg_dump, then I think Michael's change is correct.

I have been checking for a few hours, and well..  There was more.

> See the attached v2 for details.

That's nice, unfortunately incomplete.  I have found a different
pattern that behaves incorrectly, reusing your script of upthread:
pg_restore --statistics --table t \
  -f /tmp/archive-s1-stats.sql /tmp/stats.dump
pg_restore --statistics-only --table t \
  -f /tmp/archive-s1-stats.sql /tmp/stats.dump

With "--statistics --table t", we restore the definition of table "t"
and its data (correct), miss the stats (incorrect!).  With
"--statistics-only --table t", we restore no definition and no data
(correct), and still miss the stats (incorrect!).  So we still have a
borked restore of the stats when selecting an individual table.  We
don't care about extended stats with this case, as extstats are
objects defined at schema level and we cannot filter them, but I think
that we definitely care about attribute and relation stats here.

This case requires a second change in _tocEntryRequired() even after
the first fix so as it is possible to select a STATISTICS DATA that
depends on a table part of the authorized list close to the list that
includes the "SEQUENCE SET".

With all that in mind, I have the attached.  I have expanded the tests
with the --table case, using dump and restore commands, and that seems
to work correctly now with the restores, including the cases with
extstats.

And I'm planning to apply that down to v18 tomorrow, after a second
round of lookups.
--
Michael
From b8ef48cb646e28ee62c6f219b5d59394245d4f58 Mon Sep 17 00:00:00 2001
From: Michael Paquier <[email protected]>
Date: Mon, 15 Jun 2026 16:50:50 +0900
Subject: [PATCH v3] Fix pg_restore with --schema/--table and
 --statistics[-only]

Attempting to restore a schema or a table with only statistics skipped
all the statistics of the schema, but it should not.  A second set of
problems existed for --table, where the presence of --statistics or
--statistics-only with a table skipped the restore of the stats.

Some tests are added for both cases.
---
 src/bin/pg_dump/pg_backup_archiver.c |  4 +--
 src/bin/pg_dump/t/002_pg_dump.pl     | 40 ++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/src/bin/pg_dump/pg_backup_archiver.c 
b/src/bin/pg_dump/pg_backup_archiver.c
index 2fd773ad84f3..b38b1995d1c4 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -3175,7 +3175,6 @@ _tocEntryRequired(TocEntry *te, teSection curSection, 
ArchiveHandle *AH)
         */
        if (strcmp(te->desc, "ACL") == 0 ||
                strcmp(te->desc, "COMMENT") == 0 ||
-               strcmp(te->desc, "STATISTICS DATA") == 0 ||
                strcmp(te->desc, "SECURITY LABEL") == 0)
        {
                /* Database properties react to createDB, not selectivity 
options. */
@@ -3253,7 +3252,8 @@ _tocEntryRequired(TocEntry *te, teSection curSection, 
ArchiveHandle *AH)
                                strcmp(te->desc, "MATERIALIZED VIEW") == 0 ||
                                strcmp(te->desc, "MATERIALIZED VIEW DATA") == 0 
||
                                strcmp(te->desc, "SEQUENCE") == 0 ||
-                               strcmp(te->desc, "SEQUENCE SET") == 0)
+                               strcmp(te->desc, "SEQUENCE SET") == 0 ||
+                               strcmp(te->desc, "STATISTICS DATA") == 0)
                        {
                                if (!ropt->selTable)
                                        return 0;
diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl
index 3ee9fda50e4c..f3abb8982f8e 100644
--- a/src/bin/pg_dump/t/002_pg_dump.pl
+++ b/src/bin/pg_dump/t/002_pg_dump.pl
@@ -587,6 +587,42 @@ my %pgdump_runs = (
                        'postgres',
                ],
        },
+       statistics_only_with_schema => {
+               dump_cmd => [
+                       'pg_dump', '--no-sync',
+                       '--format' => 'custom',
+                       '--file' => "$tempdir/statistics_only_with_schema.dump",
+                       '--statistics-only',
+                       '--schema' => 'dump_test',
+                       'postgres',
+               ],
+               restore_cmd => [
+                       'pg_restore',
+                       '--format' => 'custom',
+                       '--file' => "$tempdir/statistics_only_with_schema.sql",
+                       '--statistics-only',
+                       '--schema' => 'dump_test',
+                       "$tempdir/statistics_only_with_schema.dump",
+               ],
+       },
+       statistics_only_with_table => {
+               dump_cmd => [
+                       'pg_dump', '--no-sync',
+                       '--format' => 'custom',
+                       '--file' => "$tempdir/statistics_only_with_table.dump",
+                       '--statistics',
+                       'postgres',
+               ],
+               restore_cmd => [
+                       'pg_restore',
+                       '--format' => 'custom',
+                       '--file' => "$tempdir/statistics_only_with_table.sql",
+                       '--statistics-only',
+                       '--table' => 'test_table',
+                       '--schema' => 'dump_test',
+                       "$tempdir/statistics_only_with_table.dump",
+               ],
+       },
        no_schema => {
                dump_cmd => [
                        'pg_dump', '--no-sync',
@@ -4850,6 +4886,7 @@ my %tests = (
                        no_schema => 1,
                        section_post_data => 1,
                        statistics_only => 1,
+                       statistics_only_with_schema => 1,
                        schema_only_with_statistics => 1,
                },
                unlike => {
@@ -4878,6 +4915,7 @@ my %tests = (
                        no_schema => 1,
                        section_post_data => 1,
                        statistics_only => 1,
+                       statistics_only_with_schema => 1,
                        schema_only_with_statistics => 1,
                },
                unlike => {
@@ -4907,6 +4945,8 @@ my %tests = (
                        section_data => 1,
                        section_post_data => 1,
                        statistics_only => 1,
+                       statistics_only_with_schema => 1,
+                       statistics_only_with_table => 1,
                        schema_only_with_statistics => 1,
                },
                unlike => {
-- 
2.54.0

Attachment: signature.asc
Description: PGP signature

Reply via email to