On Tue, Jun 16, 2026 at 11:07:22AM +0900, Michael Paquier wrote:
> Sharing the check for a STATISTICS DATA TOC entry on table and index
> names was making me ticking a bit, as this is not entirely
> collision-proof for the names, but it also looks like we do things the
> same way with TABLE DATA and INDEX, so..  At the end, applied down to
> v18 as suggested.

And I am having second thoughts on this one.  Take for example this
case:
CREATE SCHEMA s1;
CREATE SCHEMA s2;
CREATE TABLE s1.foo (id int);
INSERT INTO s1.foo SELECT generate_series(1,100);
ANALYZE s1.foo;
CREATE TABLE s2.bar (id int);
CREATE INDEX foo ON s2.bar(id);
INSERT INTO s2.bar SELECT generate_series(1,100);
ANALYZE s2.bar;

And then this:
pg_dump --statistics -Fc -f stats.dump mydb
pg_restore --statistics-only --index=foo -f stats_foo.sql stats.dump

On HEAD, we get relation and attribute we should not in stats_foo.sql,
getting also some data from the table s1.foo.  With the patch
attached, that strengthens the name check based on the type of the
depending TOC entries, we only get the relation stats of s2.foo,
nothing about the table s1.foo.  This feels too funky to write a test
for, wasting cycles compared to the existing coverage.

pg_restore --index is as old as e8f69be054e9, so it's not like we
could just remove it, but I'd say that with the schema-level restore
this would be tempting.  

Anyway, let's improve this situation with the attached, for HEAD and
v18.
--
Michael
From f0021e89b087b9b12930a6a02a803f1e3c35a554 Mon Sep 17 00:00:00 2001
From: Michael Paquier <[email protected]>
Date: Tue, 16 Jun 2026 12:22:40 +0900
Subject: [PATCH] Use dependency-based matching for STATISTICS DATA in selTypes

The previous approach was weaker in terms of name matching, as an
--index=foo could match with a table with the same name but from a
different schema, pulling in more data than necessary.
---
 src/bin/pg_dump/pg_backup_archiver.c | 39 +++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 10 deletions(-)

diff --git a/src/bin/pg_dump/pg_backup_archiver.c 
b/src/bin/pg_dump/pg_backup_archiver.c
index 4fa6cc1c566a..4ec43f29622e 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -3250,17 +3250,36 @@ _tocEntryRequired(TocEntry *te, teSection curSection, 
ArchiveHandle *AH)
                                bool            dumpthis = false;
 
                                /*
-                                * Statistics data can be assigned for tables 
or indexes, so
-                                * check both.
+                                * Statistics data entries can be for tables or 
indexes. Check
+                                * the parent dependency to determine which 
type this entry
+                                * belongs to, then apply the appropriate name 
filter.
                                 */
-                               if (ropt->selTable &&
-                                       (ropt->tableNames.head == NULL ||
-                                        
simple_string_list_member(&ropt->tableNames, te->tag)))
-                                       dumpthis = true;
-                               if (ropt->selIndex &&
-                                       (ropt->indexNames.head == NULL ||
-                                        
simple_string_list_member(&ropt->indexNames, te->tag)))
-                                       dumpthis = true;
+                               for (int i = 0; i < te->nDeps; i++)
+                               {
+                                       TocEntry   *pte = 
getTocEntryByDumpId(AH, te->dependencies[i]);
+
+                                       if (!pte)
+                                               continue;
+
+                                       if (ropt->selTable &&
+                                               (strcmp(pte->desc, "TABLE") == 
0 ||
+                                                strcmp(pte->desc, "VIEW") == 0 
||
+                                                strcmp(pte->desc, "FOREIGN 
TABLE") == 0 ||
+                                                strcmp(pte->desc, 
"MATERIALIZED VIEW") == 0))
+                                       {
+                                               if (ropt->tableNames.head == 
NULL ||
+                                                       
simple_string_list_member(&ropt->tableNames, pte->tag))
+                                                       dumpthis = true;
+                                       }
+
+                                       if (ropt->selIndex &&
+                                               strcmp(pte->desc, "INDEX") == 0)
+                                       {
+                                               if (ropt->indexNames.head == 
NULL ||
+                                                       
simple_string_list_member(&ropt->indexNames, pte->tag))
+                                                       dumpthis = true;
+                                       }
+                               }
                                if (!dumpthis)
                                        return 0;
                        }
-- 
2.54.0

Attachment: signature.asc
Description: PGP signature

Reply via email to