Re: BUG #18984: Empty prepared statement from psql \parse triggers assert in PortalRunMulti - Mailing list pgsql-bugs

From Tom Lane
Subject Re: BUG #18984: Empty prepared statement from psql \parse triggers assert in PortalRunMulti
Date
Msg-id 792012.1752530750@sss.pgh.pa.us
Whole thread Raw
In response to Re: BUG #18984: Empty prepared statement from psql \parse triggers assert in PortalRunMulti  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-bugs
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

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);


pgsql-bugs by date:

Previous
From: Tom Lane
Date:
Subject: Re: BUG #18984: Empty prepared statement from psql \parse triggers assert in PortalRunMulti
Next
From: Tom Lane
Date:
Subject: Re: BUG #18984: Empty prepared statement from psql \parse triggers assert in PortalRunMulti