Hi čt 1. 1. 2026 v 11:05 odesílatel jian he <[email protected]> napsal:
> On Thu, Jan 1, 2026 at 3:10 PM Pavel Stehule <[email protected]> > wrote: > > > > Hi > > > > I tested one use case, and maybe I found little bit possible error > message > > > > create procedure test() > > as $$ > > begin > > vacuum; > > end; > > $$ language plpgsql; > > > > (2026-01-01 08:04:05) postgres=# call test(); > > ERROR: 25001: VACUUM cannot be executed from a function > > CONTEXT: SQL statement "vacuum" > > PL/pgSQL function test() line 3 at SQL statement > > LOCATION: PreventInTransactionBlock, xact.c:3695 > > (2026-01-01 08:09:18) postgres=# > > > > should be "VACUUM cannot be executed from a function or a procedure" > instead ? > > > > hi. > "VACUUM cannot be executed from a function or a procedure" > looks good to me. > > similarly, in ExecWaitStmt we have: > ereport(ERROR, > errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), > errmsg("WAIT FOR must be only called without an active > or registered snapshot"), > errdetail("WAIT FOR cannot be executed from a function > or a procedure or within a transaction with an isolation level higher > than READ COMMITTED.")); > > PreventInTransactionBlock is used in so many places, but this error > message: > `` > (errmsg("%s cannot be executed from a function", stmtType))); > `` > only appears once in the regress tests. > maybe we can add some dummy tests for it. > here is a patch (with small regress test) Regards Pavel
From aa57e3a80e5ee7bce121addc607d198e67941fc7 Mon Sep 17 00:00:00 2001 From: "[email protected]" <[email protected]> Date: Sat, 3 Jan 2026 07:32:26 +0100 Subject: [PATCH] VACUUM cannot be executed inside a function or a procedure --- src/backend/access/transam/xact.c | 2 +- .../plpgsql/src/expected/plpgsql_transaction.out | 13 +++++++++++++ src/pl/plpgsql/src/sql/plpgsql_transaction.sql | 14 ++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 842faa44232..5cf85e2f35c 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -3695,7 +3695,7 @@ PreventInTransactionBlock(bool isTopLevel, const char *stmtType) ereport(ERROR, (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION), /* translator: %s represents an SQL statement name */ - errmsg("%s cannot be executed from a function", stmtType))); + errmsg("%s cannot be executed from a function or a procedure", stmtType))); /* If we got past IsTransactionBlock test, should be in default state */ if (CurrentTransactionState->blockState != TBLOCK_DEFAULT && diff --git a/src/pl/plpgsql/src/expected/plpgsql_transaction.out b/src/pl/plpgsql/src/expected/plpgsql_transaction.out index adff10fa6d6..bcdf7958823 100644 --- a/src/pl/plpgsql/src/expected/plpgsql_transaction.out +++ b/src/pl/plpgsql/src/expected/plpgsql_transaction.out @@ -736,6 +736,19 @@ SELECT * FROM test1; 2 | (2 rows) +-- VACUUM cannot be executed inside a function or a procedure +CREATE PROCEDURE vacuum_inside_procedure() +LANGUAGE plpgsql AS $$ +BEGIN + VACUUM; +END; +$$; +-- error +CALL vacuum_inside_procedure(); +ERROR: VACUUM cannot be executed from a function or a procedure +CONTEXT: SQL statement "VACUUM" +PL/pgSQL function vacuum_inside_procedure() line 3 at SQL statement +DROP PROCEDURE vacuum_inside_procedure(); DROP TABLE test1; DROP TABLE test2; DROP TABLE test3; diff --git a/src/pl/plpgsql/src/sql/plpgsql_transaction.sql b/src/pl/plpgsql/src/sql/plpgsql_transaction.sql index c73fca7e03e..5e8da3ec4c4 100644 --- a/src/pl/plpgsql/src/sql/plpgsql_transaction.sql +++ b/src/pl/plpgsql/src/sql/plpgsql_transaction.sql @@ -631,6 +631,20 @@ $$; SELECT * FROM test1; +-- VACUUM cannot be executed inside a function or a procedure + +CREATE PROCEDURE vacuum_inside_procedure() +LANGUAGE plpgsql AS $$ +BEGIN + VACUUM; +END; +$$; + +-- error +CALL vacuum_inside_procedure(); + +DROP PROCEDURE vacuum_inside_procedure(); + DROP TABLE test1; DROP TABLE test2; DROP TABLE test3; -- 2.52.0
