From: Antonin Houska Date: Fri, 28 Aug 2026 19:53:26 +0200 Subject: [PATCH] Do not allow REPACK (ANALYZE) in function and in transaction block. If REPACK (ANALYZE) is called from a pl/pgsql function, cluster_rel() might start a new transaction while SPI session is in progress. Use PreventInTransactionBlock() to avoid that. That function also raises error if REPACK (ANALYZE) is called in a transaction block, but that's fine: VACUUM (FULL, ANALYZE) - a synonym of REPACK (ANALYZE) - also raises ERROR in that case. --- src/backend/commands/repack.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 477c86b2ba6..81877029199 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -314,6 +314,20 @@ ExecRepack(ParseState *pstate, RepackStmt *stmt, bool isTopLevel) */ PreventInTransactionBlock(isTopLevel, "REPACK (CONCURRENTLY)"); } + else if ((params.options & CLUOPT_ANALYZE) != 0) + { + /* + * Technically, transaction block is not a problem for REPACK + * (ANALYZE), but if it's called from a pl/pgsql function, + * cluster_rel() might start a new transaction while SPI session is in + * progress. Make sure ERROR is raised instead. + * + * This way we also prohibit execution in a transaction block, but + * that's just consistent with VACUUM (FULL, ANALYZE), which is a + * synonym for REPACK (ANALYZE). + */ + PreventInTransactionBlock(isTopLevel, "REPACK (ANALYZE)"); + } /* * If a single relation is specified, process it and we're done ... unless -- 2.52.0 --=-=-=--