iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🐬

Why Prepared Statements with `ORDER BY ?` Freeze in MySQL 8.0.22

に公開
2025/11/29

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