Skip to content

fix: re-Parse unprepared statements in protocol.bind for cursors - #1339

Closed
Solaris-star wants to merge 1 commit into
MagicStack:masterfrom
Solaris-star:fix/1335-unnamed-stmt-collision
Closed

fix: re-Parse unprepared statements in protocol.bind for cursors#1339
Solaris-star wants to merge 1 commit into
MagicStack:masterfrom
Solaris-star:fix/1335-unnamed-stmt-collision

Conversation

@Solaris-star

Copy link
Copy Markdown

Description

With statement_cache_size=0, prepare(name=None) creates the unnamed statement "" (since #1245 / 0.31.0). When the result type needs introspection (e.g. an enum), asyncpg's type-introspection query also uses "", which replaces the user statement on the server. The client marks the user statement unprepared.

bind_execute already re-Parses when state.prepared is False. Cursor paths use protocol.bind, which did not re-Parse, so:

asyncpg.exceptions.ProtocolViolationError:
bind message supplies N parameters, but prepared statement "" requires M

Fix

  1. protocol.bind: if not state.prepared, call _send_parse_message before Bind (same as bind_execute).
  2. _process__bind: accept ParseComplete (b'1') when re-parsing.
  3. Regression test: statement_cache_size=0 + enum + prepare + cursor.

Linked Issue

Closes #1335

When statement_cache_size=0, prepare(name=None) uses the unnamed
statement "". Type introspection also uses "", which clobbers the user
statement and marks it unprepared.

bind_execute already re-Parses when state.prepared is False, but
cursor.bind did not. Opening a server-side cursor after prepare then
failed with ProtocolViolationError about mismatched bind parameters.

Re-Parse before Bind in protocol.bind, and accept ParseComplete in
_process__bind, matching bind_execute.

Fixes #1335
@Solaris-star Solaris-star closed this by deleting the head repository Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant