Skip to content

Commit 393e29d

Browse files
committed
doc(mysql): document difference between Uuid and uuid::fmt::Hyphenated
1 parent 028084b commit 393e29d

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

sqlx-mysql/src/types/mod.rs

+27-3
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,33 @@
115115
//!
116116
//! | Rust type | MySQL/MariaDB type(s) |
117117
//! |---------------------------------------|------------------------------------------------------|
118-
//! | `uuid::Uuid` | BINARY(16), VARCHAR, CHAR, TEXT |
119-
//! | `uuid::fmt::Hyphenated` | CHAR(36), UUID (MariaDB-only) |
120-
//! | `uuid::fmt::Simple` | CHAR(32) |
118+
//! | `uuid::Uuid` | BINARY(16) (see note) |
119+
//! | `uuid::fmt::Hyphenated` | CHAR(36), VARCHAR, TEXT, UUID (MariaDB-only) |
120+
//! | `uuid::fmt::Simple` | CHAR(32), VARCHAR, TEXT |
121+
//!
122+
//! #### Note: `Uuid` uses binary format
123+
//!
124+
//! MySQL does not have a native datatype for UUIDs.
125+
//! The `UUID()` function returns a 36-character `TEXT` value,
126+
//! which encourages storing UUIDs as text.
127+
//!
128+
//! MariaDB's `UUID` type stores and retrieves as text, though it has a better representation
129+
//! for index sorting (see [MariaDB manual: UUID data-type][mariadb-uuid] for details).
130+
//!
131+
//! As an opinionated library, SQLx chose to map `Uuid` to/from binary format by default
132+
//! (16 bytes, the raw value of a UUID; SQL type `BINARY(16)`).
133+
//! This saves 20 bytes over the text format for each value.
134+
//!
135+
//! The `impl Decode<MySql> for Uuid` does not support the text format, and will return an error.
136+
//!
137+
//! If you want to use the text format compatible with the `UUID()` function,
138+
//! use [`uuid::fmt::Hyphenated`][::uuid::fmt::Hyphenated] in the place of `Uuid`.
139+
//!
140+
//! The MySQL official blog has an article showing how to support both binary and text format UUIDs
141+
//! by storing the binary and adding a generated column for the text format, though this is rather
142+
//! verbose and fiddly: <https://dev.mysql.com/blog-archive/storing-uuid-values-in-mysql-tables/>
143+
//!
144+
//! [mariadb-uuid]: https://mariadb.com/kb/en/uuid-data-type/
121145
//!
122146
//! ### [`json`](https://crates.io/crates/serde_json)
123147
//!

sqlx-mysql/src/types/uuid.rs

+9
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@ impl Decode<'_, MySql> for Uuid {
3333
// delegate to the &[u8] type to decode from MySQL
3434
let bytes = <&[u8] as Decode<MySql>>::decode(value)?;
3535

36+
if bytes.len() != 16 {
37+
return Err(format!(
38+
"Expected 16 bytes, got {}; `Uuid` uses binary format for MySQL/MariaDB. \
39+
For text-formatted UUIDs, use `uuid::fmt::Hyphenated` instead of `Uuid`.",
40+
bytes.len(),
41+
)
42+
.into());
43+
}
44+
3645
// construct a Uuid from the returned bytes
3746
Uuid::from_slice(bytes).map_err(Into::into)
3847
}

0 commit comments

Comments
 (0)