pg.ddx.io  pgsql-bugs@postgresql.org mailing list archive  
help / color / mirror / Atom feed
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.c
index 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);
 

view thread (21+ messages)  latest in thread

Message-ID: <792012.1752530750@sss.pgh.pa.us>
Permalink:  ../792012.1752530750@sss.pgh.pa.us/
Also on:    postgresql.org/message-id/792012.1752530750@sss.pgh.pa.us

 ·  · 

reply

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