Repository navigation
Description
I have found these related issues/pull requests
I encountered an unexpected runtime decoding error while using sqlx::query_as! with MariaDB.
The application compiled successfully, but at runtime failed with:
error occurred while decoding column N:
out of range integral type conversion attempted
The affected column was either a MariaDB YEAR or SMALLINT column mapped to a Rust u16.
At the time the issue occurred, adding the following derives to the destination struct made the runtime error disappear:
#[derive(Debug, Serialize, ToSchema, Clone, sqlx::FromRow)]Although query_as! should not require FromRow, and neither Clone nor FromRow should affect primitive value decoding, the behavior changed after adding these derives.
Unfortunately, I have not yet been able to construct a minimal reproducible example, so I cannot determine whether these derives are the root cause or whether they only changed the generated code path.
Query
sqlx::query_as!(
Class,
"SELECT id, major_id, name, enrollment_year, created_at, updated_at
FROM classes
WHERE id = ?",
id
)
.fetch_one(pool)
.awaitExpected Behavior
The runtime decoding behavior of query_as! should not depend on unrelated derives such as Clone or sqlx::FromRow.
Notes
I understand that this report is currently incomplete because I cannot provide a reliable minimal reproduction.
I'm opening this issue mainly to ask whether this behavior is already known or whether there are existing issues involving MariaDB, query_as!, and decoding YEAR/SMALLINT into u16.
If needed, I'd be happy to continue investigating and provide a minimal reproducible example.
Description
I encountered an unexpected decoding issue when using sqlx::query_as! with MariaDB.
When selecting a YEAR or SMALLINT column into a Rust u16 field, the query fails with:
error occurred while decoding column N:
out of range integral type conversion attempted
However, after deriving both:
#[derive(sqlx::FromRow, Clone)]for the destination struct, the exact same query succeeds without changing:
- SQL
- database schema
- database contents
- field types
This behavior is unexpected because query_as! should not require FromRow, and Clone should not affect primitive value decoding.
I understand that this report is currently incomplete because I cannot provide a reliable minimal reproduction.
I'm opening this issue mainly to ask whether this behavior is already known or whether there are existing issues involving MariaDB, query_as!, and decoding YEAR/SMALLINT into u16.
If needed, I'd be happy to continue investigating and provide a minimal reproducible example.
Reproduction steps
The destination struct was similar to:
type Id = u64;
#[derive(Debug, Serialize, ToSchema)]
pub struct Class {
pub id: Id,
pub major_id: Id,
pub name: String,
pub enrollment_year: u16,
pub created_at: OffsetDateTime,
pub updated_at: OffsetDateTime,
}After changing it to:
type Id = u64;
#[derive(Debug, Serialize, ToSchema, Clone, sqlx::FromRow)]
pub struct Class {
pub id: Id,
pub major_id: Id,
pub name: String,
pub enrollment_year: u16,
pub created_at: OffsetDateTime,
pub updated_at: OffsetDateTime,
}the runtime error disappeared.
SQLx version
0.8.6
Enabled SQLx features
mysql, runtime-tokio, macros, time
Database server and version
10.6.23-MariaDB-0ubuntu0.22.04.1
Operating system
ArchLinux
Rust version
rustc 1.91.1 (ed61e7d7e 2025-11-07)
Activity
x0710 commentedon Aug 1, 2026
I found that this error mysteriously disappeared after I split the project into multiple crates. I still don't know the exact cause of the issue, but I believe the underlying problem definitely still exists somewhere.
x0710 commentedon Aug 24, 2026
Reason
It looks like the MySQL YEAR type inference prefers u8 because it is the first compatible integer type in the recommendation list.
Although YEAR is encoded as a one-byte value in the MySQL protocol, its SQL value domain is:
1901 - 2155
Therefore, u8 cannot represent all valid YEAR values.
Expected behavior
The inferred Rust type should be able to represent the complete range of valid MySQL YEAR values.
Possible mappings:
YEAR -> u16
or:
YEAR -> i32
Alternatively, u8 should not be selected as the default recommended type for YEAR.
Fix
Using an explicit override works:
but this requires users to know the internal inference behavior and manually override every YEAR column.
flawand commentedon Oct 16, 2026
@x0710 I opened a PR to fix this issue can you have a look?
x0710 commentedon Oct 19, 2026
I think the problem has been solved. Thank you.
flawand commentedon Oct 19, 2026
@x0710 my PR is still open and I recreated the bug before I applied the fix. Are you sure this issue has been fixed?