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![