diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index edff54e734e..fac4e12c13c 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -314,6 +314,16 @@ ExecRepack(ParseState *pstate, RepackStmt *stmt, bool isTopLevel) PreventInTransactionBlock(isTopLevel, "REPACK (CONCURRENTLY)"); } + else if ((params.options & CLUOPT_ANALYZE) != 0) + { + /* + * REPACK (ANALYZE) performs transaction management internally. + * It therefore cannot be executed inside a transaction block or + * from a function or procedure. + */ + PreventInTransactionBlock(isTopLevel, "REPACK (ANALYZE)"); + } + /* * If a single relation is specified, process it and we're done ... unless * the relation is a partitioned table, in which case we fall through. diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out index d1bc8a13286..36dd1f3804c 100644 --- a/src/test/regress/expected/cluster.out +++ b/src/test/regress/expected/cluster.out @@ -796,6 +796,11 @@ ORDER BY 1; clstr_tst_pkey (3 rows) +-- REPACK (ANALYZE) must not be executed inside a transaction block +BEGIN; +REPACK (ANALYZE) clstr_tst; +ERROR: REPACK (ANALYZE) cannot run inside a transaction block +ROLLBACK; -- Verify partial analyze works REPACK (ANALYZE) clstr_tst (a); REPACK (ANALYZE) clstr_tst; diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql index e7a62367adf..cb170731147 100644 --- a/src/test/regress/sql/cluster.sql +++ b/src/test/regress/sql/cluster.sql @@ -380,6 +380,10 @@ INSERT INTO clstr_tst (b, c) VALUES (1111, 'this should fail'); SELECT conname FROM pg_constraint WHERE conrelid = 'clstr_tst'::regclass ORDER BY 1; +-- REPACK (ANALYZE) must not be executed inside a transaction block +BEGIN; +REPACK (ANALYZE) clstr_tst; +ROLLBACK; -- Verify partial analyze works REPACK (ANALYZE) clstr_tst (a); REPACK (ANALYZE) clstr_tst;