From: Tom Lane <tgl@sss.pgh.pa.us>
To: Aleksander Alekseev <aleksander@tigerdata.com>
Cc: pgsql-bugs@lists.postgresql.org
Cc: exclusion@gmail.com
Subject: Re: BUG #18984: Empty prepared statement from psql \parse triggers assert in PortalRunMulti
Date: Mon, 14 Jul 2025 18:05:50 -0400
Message-ID: <792012.1752530750@sss.pgh.pa.us> (raw)
In-Reply-To: <743115.1752529222@sss.pgh.pa.us>
References: <18984-0f4778a6599ac3ae@postgresql.org>
<715434.1752521761@sss.pgh.pa.us>
<CAJ7c6TOoGUosKwdXt1LwJpThvP2-ZNpuv0H=owYdp6omwQ=keA@mail.gmail.com>
<743115.1752529222@sss.pgh.pa.us>
I wrote:
> The attached quick draft (needs attention to comments) results in
> regression=# \parse s
> regression=# execute s;
> EXECUTE
> which matches the behavior of pre-v12 servers.
Another way that's perhaps a bit less magical is to make
ExecuteQuery substitute the right thing, as attached.
I'm not entirely sure whether this leaves any other code
paths that can reach that Assert; but on the other hand,
if there are any, CMDTAG_EXECUTE is probably wrong for them.
BTW, the reason why EXPLAIN EXECUTE isn't at risk is that it's
going to return CMDTAG_EXPLAIN.
regards, tom lane
Attachments:
[text/x-diff] wip2-avoid-failure-with-empty-prepared-query.patch (1.2K, ../792012.1752530750@sss.pgh.pa.us/2-wip2-avoid-failure-with-empty-prepared-query.patch)
download | inline diff:diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.cindex 34b6410d6a2..6ecc24fdba8 100644--- a/src/backend/commands/prepare.c+++ b/src/backend/commands/prepare.c@@ -159,6 +159,7 @@ ExecuteQuery(ParseState *pstate,
EState *estate = NULL;
Portal portal;
char *query_string;
+ CommandTag commandTag;
int eflags;
long count;
@@ -196,6 +197,15 @@ ExecuteQuery(ParseState *pstate,
cplan = GetCachedPlan(entry->plansource, paramLI, NULL, NULL);
plan_list = cplan->stmt_list;
+ /*+ * Normally the PlanSource will have a usable commandTag, but if it has an+ * empty statement list, then not so much. Substitute EXECUTE to avoid+ * failing because we have no commandTag to report to the client.+ */+ commandTag = entry->plansource->commandTag;+ if (commandTag == CMDTAG_UNKNOWN)+ commandTag = CMDTAG_EXECUTE;+
/*
* DO NOT add any logic that could possibly throw an error between
* GetCachedPlan and PortalDefineQuery, or you'll leak the plan refcount.
@@ -203,7 +213,7 @@ ExecuteQuery(ParseState *pstate,
PortalDefineQuery(portal,
NULL,
query_string,
- entry->plansource->commandTag,+ commandTag,
plan_list,
cplan);
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-bugs@postgresql.org
Cc: tgl@sss.pgh.pa.us, aleksander@tigerdata.com, pgsql-bugs@lists.postgresql.org, exclusion@gmail.com
Subject: Re: BUG #18984: Empty prepared statement from psql \parse triggers assert in PortalRunMulti
In-Reply-To: <792012.1752530750@sss.pgh.pa.us>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox