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
signature.asc
Description: PGP signature
