iTranslated by AI
Why Prepared Statements with `ORDER BY ?` Freeze in MySQL 8.0.22
This is a follow-up to https://zenn.dev/tmtms/articles/202011-mysql-8022-prepared-statement.
I previously wrote that the client freezes with ORDER BY ? in a prepared statement when using the C API, but since there was feedback that it works fine in Go, I traced the MySQL protocol.
When a prepared statement is issued, packets typically flow as follows:
=> COM_STMT_PREPARE "SELECT ?,?,? FROM tbl"
<= Statement ID, number of result set columns (3), number of placeholders (3)
<= Mystery packet
<= Mystery packet
<= Mystery packet
<= EOF packet
There are as many "mystery packets" as there are placeholders, but they are just discarded, so they truly are a mystery.
However, in 8.0.22, with ORDER BY ?, it happens like this:
=> COM_STMT_PREPARE "SELECT a,b,c FROM tbl ORDER BY ?"
<= Statement ID, number of result columns (3), number of placeholders (1)
<= EOF packet
The number of placeholders is 1, yet no mystery packets are sent.
The implementation of the C API mysql_stmt_prepare() is designed to skip as many mystery packets as there are placeholders and then wait for an EOF packet. Therefore, it reads the EOF packet thinking it is a mystery packet, and then continues waiting for another EOF packet.
The Go implementation is designed to skip packets until an EOF packet arrives, regardless of the number of placeholders. Thus, even if there are no mystery packets, it considers it fine as long as an EOF packet arrives, so no issue occurs.
Well, the C API should probably be updated to skip packets until an EOF packet arrives, just like Go. However, I suspect the server-side response is incorrect, so this is likely a server-side issue (I haven't read the server implementation).
Writing in English is a hassle, and since I don't use it myself, I don't feel like writing a bug report...
Discussion