MySQL: a cancelled prepare leaves its response on the stream

#4427 · open · 0 comments

View on GitHub ↗

gronke

### I have found these related issues/pull requests #563 covers cancellation in the middle of a packet read; this reproduces with responses too small for that window. ### Description `prepare_statement` reads the COM_STMT_PREPARE response inline and records nothing in `waiting`, while `run` has already queued `Waiting::Result`. A prepare cancelled before its response is read leaves stmt-prepare-ok and the definition packets on the stream. The drain takes stmt-prepare-ok for the queued result, and the next command reads a column definition (`0x03`) as its reply. A failed parameter-count check leaves the same queued entry without any cancellation, and the next command hangs. ### Reproduction steps ```rust // sqlx = { version = "=0.9.0", default-features = false, features = ["mysql", "runtime-tokio"] } // tokio = { version = "1", features = ["macros", "rt"] } use sqlx::{Connection, MySqlConnection}; #[tokio::main(flavor = "current_thread")] async fn main() -> Result<(), Box<dyn std::error::Error>> { let mut conn = MySqlConnection::connect(&std::env::var("DATABASE_URL")?).await?; for i in 0..100 { // Poll the query once, which sends COM_STMT_PREPARE, then drop it. tokio::select! { biased; r = sqlx::query("SELECT ? AS a, 'b' AS b, 'c' AS c, 'd' AS d") .bind(1i64) .fetch_all(&mut conn) => { r?; } _ = std::future::ready(()) => {} } conn.ping().await.map_err(|e| format!("iteration {i}: {e}"))?; } println!("ok"); Ok(()) } ``` On 0.9.0 and on main (b54008a3) the ping fails at iteration 0 in 10 of 10 runs: `expected 0x00 or 0xfe (OK_Packet) but found 0x03`. Without a cancellation, `sqlx::query("SELECT ?").execute(&mut conn)` fails its parameter-count check, and the next `conn.ping()` hangs (3 of 3 runs on each). ### SQLx version 0.9.0; the same on main (b54008a3). ### Enabled SQLx features mysql, runtime-tokio ### Database server and version MariaDB 11.4.13 ### Operating system Debian 13, Linux 6.12 x86_64 ### Rust version 1.97.0

Comments