From 9e0ec7b7ef694a96ad08b960b2e08407d4a82f43 Mon Sep 17 00:00:00 2001 From: onenewcode Date: Fri, 31 Jul 2026 13:53:44 +0800 Subject: [PATCH] fix(mysql): handle nullable view collation --- crates/dbx-core/src/db/mysql.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/crates/dbx-core/src/db/mysql.rs b/crates/dbx-core/src/db/mysql.rs index fec7beb2e..9cfc1aea6 100644 --- a/crates/dbx-core/src/db/mysql.rs +++ b/crates/dbx-core/src/db/mysql.rs @@ -142,8 +142,10 @@ fn nonblank(value: String) -> Option { } async fn query_first_nonblank_string(conn: &mut mysql_async::Conn, sql: &str) -> Option { - match conn.query_first::(sql).await { - Ok(Some(value)) => nonblank(value), + // MySQL reports nullable metadata such as TABLE_COLLATION as NULL for views. + // Reading it as String makes mysql_async panic during row conversion. + match conn.query_first::, _>(sql).await { + Ok(Some(value)) => value.and_then(nonblank), Ok(None) => None, Err(error) => { log::debug!("Failed to read optional MySQL database information with `{sql}`: {error}"); @@ -4951,6 +4953,14 @@ mod tests { assert!(!sql.contains("AS ENUM_VALUES")); } + #[test] + fn mysql_nullable_table_collation_uses_optional_string_conversion() { + let collation = mysql_async::from_value_opt::>(mysql_async::Value::NULL) + .expect("Option must accept NULL MySQL metadata values"); + + assert_eq!(collation, None); + } + #[test] fn mysql_column_charset_metadata_clears_values_matching_table_default() { let mut columns = vec![