Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vc76v-002CLC-2B for pgsql-hackers@arkaria.postgresql.org; Sat, 03 Jan 2026 19:16:26 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vc76u-00DZRR-1v for pgsql-hackers@arkaria.postgresql.org; Sat, 03 Jan 2026 19:16:25 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vc76u-00DZRI-0x for pgsql-hackers@lists.postgresql.org; Sat, 03 Jan 2026 19:16:25 +0000 Received: from sss.pgh.pa.us ([68.162.161.243]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vc76t-00413M-1Q for pgsql-hackers@lists.postgresql.org; Sat, 03 Jan 2026 19:16:24 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 603JGKeL517386; Sat, 3 Jan 2026 14:16:20 -0500 From: Tom Lane To: Andreas Karlsson cc: Marcos Pegoraro , Pavel Stehule , jian he , PostgreSQL Hackers Subject: Re: not fully correct error message In-reply-to: References: <8fa16ea7-09a1-4ec2-b668-1e36d4c8ace4@proxel.se> <409108.1767463422@sss.pgh.pa.us> Comments: In-reply-to Andreas Karlsson message dated "Sat, 03 Jan 2026 19:44:44 +0100" MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0" Content-ID: <517310.1767467750.0@sss.pgh.pa.us> Date: Sat, 03 Jan 2026 14:16:20 -0500 Message-ID: <517385.1767467780@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <517310.1767467750.1@sss.pgh.pa.us> Content-Transfer-Encoding: quoted-printable Andreas Karlsson writes: > On 1/3/26 7:03 PM, Tom Lane wrote: >> Yeah, I like just adding "or procedure" and calling it good. >> I do not think we need a regression test, either ... > Yeah, let's keep it simple. >> Poking around, I also found this: >> src/backend/commands/wait.c: errdetail("WA= IT FOR cannot be executed from a function or a procedure or within a trans= action with an isolation level higher than READ COMMITTED.")); >> which is also not great grammar. What do you think of "WAIT FOR >> cannot be executed from a function or procedure, nor within a >> transaction with an isolation level higher than READ COMMITTED." ? > Much better! Putting that all together, and fixing affected regression tests (yes, this code was covered already), I get the attached. regards, tom lane ------- =_aaaaaaaaaa0 Content-Type: text/x-diff; name="v2-improve-vacuum-error-message.patch"; charset="us-ascii" Content-ID: <517310.1767467750.2@sss.pgh.pa.us> Content-Description: v2-improve-vacuum-error-message.patch Content-Transfer-Encoding: quoted-printable diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transa= m/xact.c index 842faa44232..c857e23552f 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -3695,7 +3695,8 @@ PreventInTransactionBlock(bool isTopLevel, const cha= r *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 procedure", + stmtType))); = /* If we got past IsTransactionBlock test, should be in default state */ if (CurrentTransactionState->blockState !=3D TBLOCK_DEFAULT && diff --git a/src/backend/commands/wait.c b/src/backend/commands/wait.c index d43dfd642d6..e4509fffe06 100644 --- a/src/backend/commands/wait.c +++ b/src/backend/commands/wait.c @@ -131,8 +131,8 @@ ExecWaitStmt(ParseState *pstate, WaitStmt *stmt, DestR= eceiver *dest) if (HaveRegisteredOrActiveSnapshot()) 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 COMMITTE= D.")); + errmsg("WAIT FOR must be called without an active or registered snaps= hot"), + errdetail("WAIT FOR cannot be executed from a function or procedure, = nor within a transaction with an isolation level higher than READ COMMITTE= D.")); = /* * As the result we should hold no snapshot, and correspondingly our xmi= n diff --git a/src/test/recovery/t/049_wait_for_lsn.pl b/src/test/recovery/t= /049_wait_for_lsn.pl index e0ddb06a2f0..5f415b9af51 100644 --- a/src/test/recovery/t/049_wait_for_lsn.pl +++ b/src/test/recovery/t/049_wait_for_lsn.pl @@ -102,7 +102,7 @@ $node_standby->psql( "BEGIN ISOLATION LEVEL REPEATABLE READ; SELECT 1; WAIT FOR LSN '${lsn3}'= ;", stderr =3D> \$stderr); ok( $stderr =3D~ - /WAIT FOR must be only called without an active or registered snapshot= /, + /WAIT FOR must be called without an active or registered snapshot/, "get an error when running in a transaction with an isolation level high= er than REPEATABLE READ" ); = @@ -122,7 +122,7 @@ $node_standby->psql( "SELECT pg_wal_replay_wait_wrap('${lsn3}');", stderr =3D> \$stderr); ok( $stderr =3D~ - /WAIT FOR must be only called without an active or registered snapshot= /, + /WAIT FOR must be called without an active or registered snapshot/, "get an error when running within another function"); = # 5. Check parameter validation error cases on standby before promotion diff --git a/src/test/regress/expected/subscription.out b/src/test/regress= /expected/subscription.out index 327d1e7731f..b3eccd8afe3 100644 --- a/src/test/regress/expected/subscription.out +++ b/src/test/regress/expected/subscription.out @@ -357,7 +357,7 @@ END; CREATE FUNCTION func() RETURNS VOID AS $$ ALTER SUBSCRIPTION regress_testsub SET PUBLICATION mypub WITH (refresh= =3D true) $$ LANGUAGE SQL; SELECT func(); -ERROR: ALTER SUBSCRIPTION with refresh cannot be executed from a functio= n +ERROR: ALTER SUBSCRIPTION with refresh cannot be executed from a functio= n or procedure CONTEXT: SQL function "func" statement 1 ALTER SUBSCRIPTION regress_testsub DISABLE; ALTER SUBSCRIPTION regress_testsub SET (slot_name =3D NONE); ------- =_aaaaaaaaaa0--