From 0f59d89a839df0255239cce19dba0fe2e49d400c Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Sat, 23 Aug 2025 09:33:53 -0500 Subject: [PATCH 1/2] doc: Note privileges required for vacuumdb --missing-stats-only. --- doc/src/sgml/ref/vacuumdb.sgml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml index 53147480515e..84c76d7350c8 100644 --- a/doc/src/sgml/ref/vacuumdb.sgml +++ b/doc/src/sgml/ref/vacuumdb.sgml @@ -292,6 +292,14 @@ PostgreSQL documentation This option can only be used in conjunction with or . + + Note that requires + SELECT privileges on + pg_statistic + and + pg_statistic_ext_data, + which are restricted to superusers by default. + From c82f4b4ce1060a103592664d9572fa043e7c78dc Mon Sep 17 00:00:00 2001 From: Yugo Nagata Date: Mon, 25 Aug 2025 06:18:04 +0900 Subject: [PATCH 2/2] vacuumdb: check SELECT privilege on pg_statitis or pg_statistic_ext_data --- src/bin/scripts/vacuumdb.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c index fd236087e90a..2087b4131a2e 100644 --- a/src/bin/scripts/vacuumdb.c +++ b/src/bin/scripts/vacuumdb.c @@ -801,6 +801,30 @@ retrieve_objects(PGconn *conn, vacuumingOptions *vacopts, SimpleStringList *found_objs = palloc0(sizeof(SimpleStringList)); bool objects_listed = false; + if (vacopts->missing_stats_only) + { + PQExpBufferData aclcheck; + + initPQExpBuffer(&aclcheck); + appendPQExpBufferStr(&aclcheck, + "SELECT has_table_privilege('pg_catalog.pg_statistic', 'select'), " + "has_table_privilege('pg_catalog.pg_statistic_ext_data', 'select')"); + res = executeQuery(conn, aclcheck.data, echo); + termPQExpBuffer(&aclcheck); + if (strcmp(PQgetvalue(res, 0, 0), "t") != 0) + { + PQfinish(conn); + pg_fatal("--missing-stats-only requires SELECT privileges on pg_statistic"); + } + else if (strcmp(PQgetvalue(res, 0, 1), "t") != 0) + { + PQfinish(conn); + pg_fatal("--missing-stats-only requires SELECT privileges on pg_statistic_ext_data"); + } + + termPQExpBuffer(&aclcheck); + } + initPQExpBuffer(&catalog_query); for (cell = objects ? objects->head : NULL; cell; cell = cell->next) {