Skip to content

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

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

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 MagicStack#1335
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