Re: BUG #18984: Empty prepared statement from psql \parse triggers assert in PortalRunMulti
Michael Paquier <michael@paquier.xyz>
From: Michael Paquier <michael@paquier.xyz>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: exclusion@gmail.com, pgsql-bugs@lists.postgresql.org
Date: 2025-07-15T04:52:37Z
Lists: pgsql-bugs
On Mon, Jul 14, 2025 at 07:17:47PM -0400, Tom Lane wrote: > I think I fat-fingered something, because now I can only reproduce back > to v13. Bisecting says the crash started at the v13-era commit > > which is unsurprising because that's what introduced the > Assert we're hitting. Yep. > which is another reason not to start throwing an error. > (I did not look into how come that works... the correct > command tag must be getting filled in later, but where?) With some extra logs: WARNING: 01000: BOOBOO exec_simple_query commandTag = EXECUTE LOCATION: exec_simple_query, postgres.c:1120 WARNING: 01000: BOOBOO PortalDefineQuery commandTag = EXECUTE LOCATION: PortalDefineQuery, portalmem.c:301 WARNING: 01000: BOOBOO PortalDefineQuery commandTag = ??? LOCATION: PortalDefineQuery, portalmem.c:301 The first pass in PortalDefineQuery() is done in exec_simple_query(). The second pass of PortalDefineQuery() is the relevant one, I guess: #0 PortalDefineQuery (portal=0x564cf7cc9240, prepStmtName=0x0, sourceText=0x564cf7c74d80 "", commandTag=CMDTAG_UNKNOWN, stmts=0x0, cplan=0x564cf7c817a8) at portalmem.c:289 #1 0x0000564cd98d4328 in ExecuteQuery (pstate=0x564cf7c7b740, stmt=0x564cf7c48d38, intoClause=0x0, params=0x0, dest=0x564cf7c48de0, qc=0x7fffb8e7b4a0) at prepare.c:203 #2 0x0000564cda3f6427 in standard_ProcessUtility (pstmt=0x564cf7c48550, queryString=0x564cf7c47590 "execute s;", readOnlyTree=false, context=PROCESS_UTILITY_TOPLEVEL, params=0x0, queryEnv=0x0, dest=0x564cf7c48de0, qc=0x7fffb8e7b4a0) at utility.c:759 #3 0x0000564cda3f541f in ProcessUtility (pstmt=0x564cf7c48550, queryString=0x564cf7c47590 "execute s;", readOnlyTree=false, context=PROCESS_UTILITY_TOPLEVEL, params=0x0, queryEnv=0x0, dest=0x564cf7c48de0, qc=0x7fffb8e7b4a0) at utility.c:523 #4 0x0000564cda3f2214 in PortalRunUtility (portal=0x564cf7cc9130, pstmt=0x564cf7c48550, isTopLevel=true, setHoldSnapshot=false, dest=0x564cf7c48de0, qc=0x7fffb8e7b4a0) at pquery.c:1153 #5 0x0000564cda3f2a40 in PortalRunMulti (portal=0x564cf7cc9130, isTopLevel=true, setHoldSnapshot=false, dest=0x564cf7c48de0, altdest=0x564cf7c48de0, qc=0x7fffb8e7b4a0) at pquery.c:1310 #6 0x0000564cda3f09a4 in PortalRun (portal=0x564cf7cc9130, count=9223372036854775807, isTopLevel=true, dest=0x564cf7c48de0, altdest=0x564cf7c48de0, qc=0x7fffb8e7b4a0) at pquery.c:788 #7 0x0000564cda3e240a in exec_simple_query (query_string=0x564cf7c47590 "execute s;") at postgres.c:1274 #8 0x0000564cda3eb78f in PostgresMain (dbname=0x564cf7c84730 "ioltas", username=0x564cf7c84718 "ioltas") at postgres.c:4767 So the QueryCompletion given to PortalRunMulti() is initialized at the beginning of PortalRun with an unknown tag, and we miss to fill it when running the individual queries because CopyQueryCompletion() happens at the end of PortalRunMulti(). We can be more proactive when updating the tag by doing one in ExecuteQuery() as you are suggesting, but I am wondering if we should not just nuke the assertion at the end of PortalRunMulti() instead, relying on the same check done at the beginning of ProcessUtility(). -- Michael
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Minor cosmetic tweaks
- e76221bd95f0 19 (unreleased) landed
-
Simplify coding in ProcessQuery
- a27c40bfe8ab 19 (unreleased) landed
-
Remove assertion from PortalRunMulti
- e0d3f3cfb6f2 18.0 landed
- c2720ac6010a 15.14 landed
- b9a89682846f 14.19 landed
- b8926a5b4bb8 19 (unreleased) landed
- 4871c1e9cb6e 16.10 landed
- 43cd85962755 13.22 landed
- 0c466f5e0b34 17.6 landed
-
Represent command completion tags as structs
- 2f9661311b83 13.0 cited