doc(mysql): document difference between Uuid and uuid::fmt::Hyphenated (#3580)

This commit is contained in:
Austin Bonander 2024-10-28 16:39:43 -07:00 committed by GitHub
parent 709226c19d
commit 82d332f4b4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 36 additions and 3 deletions

View file

@ -115,9 +115,33 @@
//!
//! | Rust type | MySQL/MariaDB type(s) |
//! |---------------------------------------|------------------------------------------------------|
//! | `uuid::Uuid` | BINARY(16), VARCHAR, CHAR, TEXT |
//! | `uuid::fmt::Hyphenated` | CHAR(36), UUID (MariaDB-only) |
//! | `uuid::fmt::Simple` | CHAR(32) |
//! | `uuid::Uuid` | BINARY(16) (see note) |
//! | `uuid::fmt::Hyphenated` | CHAR(36), VARCHAR, TEXT, UUID (MariaDB-only) |
//! | `uuid::fmt::Simple` | CHAR(32), VARCHAR, TEXT |
//!
//! #### Note: `Uuid` uses binary format
//!
//! MySQL does not have a native datatype for UUIDs.
//! The `UUID()` function returns a 36-character `TEXT` value,
//! which encourages storing UUIDs as text.
//!
//! MariaDB's `UUID` type stores and retrieves as text, though it has a better representation
//! for index sorting (see [MariaDB manual: UUID data-type][mariadb-uuid] for details).
//!
//! As an opinionated library, SQLx chose to map `uuid::Uuid` to/from binary format by default
//! (16 bytes, the raw value of a UUID; SQL type `BINARY(16)`).
//! This saves 20 bytes over the text format for each value.
//!
//! The `impl Decode<MySql> for Uuid` does not support the text format, and will return an error.
//!
//! If you want to use the text format compatible with the `UUID()` function,
//! use [`uuid::fmt::Hyphenated`][::uuid::fmt::Hyphenated] in the place of `Uuid`.
//!
//! The MySQL official blog has an article showing how to support both binary and text format UUIDs
//! by storing the binary and adding a generated column for the text format, though this is rather
//! verbose and fiddly: <https://dev.mysql.com/blog-archive/storing-uuid-values-in-mysql-tables/>
//!
//! [mariadb-uuid]: https://mariadb.com/kb/en/uuid-data-type/
//!
//! ### [`json`](https://crates.io/crates/serde_json)
//!

View file

@ -33,6 +33,15 @@ impl Decode<'_, MySql> for Uuid {
// delegate to the &[u8] type to decode from MySQL
let bytes = <&[u8] as Decode<MySql>>::decode(value)?;
if bytes.len() != 16 {
return Err(format!(
"Expected 16 bytes, got {}; `Uuid` uses binary format for MySQL/MariaDB. \
For text-formatted UUIDs, use `uuid::fmt::Hyphenated` instead of `Uuid`.",
bytes.len(),
)
.into());
}
// construct a Uuid from the returned bytes
Uuid::from_slice(bytes).map_err(Into::into)
}