Fix regression in vacuumdb --analyze-in-stages for partitioned tables

From: Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com>
To: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Cc: Fujii Masao <masao(dot)fujii(at)gmail(dot)com>, Álvaro Herrera <alvherre(at)kurilemu(dot)de>, Antonin Houska <ah(at)cybertec(dot)at>, Laurenz Albe <laurenz(dot)albe(at)cybertec(dot)at>
Subject: Fix regression in vacuumdb --analyze-in-stages for partitioned tables
Date: 2026-05-29 08:40:56
Message-ID: EDFF0AFB-050F-4FBF-8D4F-B44DC454D957@gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

While testing "vacuumdb: Make vacuumdb --analyze-only process partitioned tables”, I found a regression from later commit c4067383cb2.

The original feature commit 6429e5b77 made "--analyze-in-stages" work for partitioned tables, as the doc change states:
```
--- a/doc/src/sgml/ref/vacuumdb.sgml
+++ b/doc/src/sgml/ref/vacuumdb.sgml
@@ -397,6 +397,15 @@ PostgreSQL documentation
Multiple tables can be vacuumed by writing multiple
<option>-t</option> switches.
</para>
+ <para>
+ If no tables are specified with the <option>--table</option> option,
+ <application>vacuumdb</application> will clean all regular tables
+ and materialized views in the connected database.
+ If <option>--analyze-only</option> or
+ <option>--analyze-in-stages</option> is also specified,
+ it will analyze all regular tables, partitioned tables,
+ and materialized views (but not foreign tables).
+ </para>
```

The corresponding code was:
```
+ /*
+ * vacuumdb should generally follow the behavior of the underlying
+ * VACUUM and ANALYZE commands. If analyze_only is true, process
+ * regular tables, materialized views, and partitioned tables, just
+ * like ANALYZE (with no specific target tables) does. Otherwise,
+ * process only regular tables and materialized views, since VACUUM
+ * skips partitioned tables when no target tables are specified.
+ */
+ if (vacopts->analyze_only)
+ appendPQExpBufferStr(&catalog_query,
+ " AND c.relkind OPERATOR(pg_catalog.=) ANY (array["
+ CppAsString2(RELKIND_RELATION) ", "
+ CppAsString2(RELKIND_MATVIEW) ", "
+ CppAsString2(RELKIND_PARTITIONED_TABLE) "])\n");
```

However, the refactoring commit c4067383cb2 removed the `analyze_only` field from `vacuumingOptions` and switched to a new `mode` field. The new code is:
```
+ /*
+ * vacuumdb should generally follow the behavior of the underlying
+ * VACUUM and ANALYZE commands. In MODE_ANALYZE mode, process regular
+ * tables, materialized views, and partitioned tables, just like
+ * ANALYZE (with no specific target tables) does. Otherwise, process
+ * only regular tables and materialized views, since VACUUM skips
+ * partitioned tables when no target tables are specified.
+ */
+ if (vacopts->mode == MODE_ANALYZE)
+ appendPQExpBufferStr(&catalog_query,
+ " AND c.relkind OPERATOR(pg_catalog.=) ANY (array["
+ CppAsString2(RELKIND_RELATION) ", "
+ CppAsString2(RELKIND_MATVIEW) ", "
+ CppAsString2(RELKIND_PARTITIONED_TABLE) "])\n");
```

analyze_only used to be true when "--analyze-in-stages" was specified, but that meaning was lost in c4067383cb2:
```
case 3:
- analyze_in_stages = vacopts.analyze_only = true;
+ vacopts.mode = MODE_ANALYZE_IN_STAGES;
break;
```

The fix is very straightforward, just add check for vacopts->mode == MODE_ANALYZE_IN_STAGES. I also added a test. If we had had this test earlier, the regression should have been caught.

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/

Attachment Content-Type Size
v1-0001-vacuumdb-Analyze-partitioned-tables-with-analyze-.patch application/octet-stream 3.1 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Joel Jacobson 2026-05-29 08:54:20 Re: Key joins
Previous Message Peter Smith 2026-05-29 08:24:16 Re: Support EXCEPT for TABLES IN SCHEMA publications