-
-
Notifications
You must be signed in to change notification settings - Fork 644
Description
Description
The story began with me trying to join 5 tables. As currently find_with_related is implemented for only three tables, I decided to fallback to manual joins.
In order to process the results, I made the following "result" structure:
#[derive(FromQueryResult)]
pub struct Joined {
#[sea_orm(nested)]
table1: entities::table1::Model,
#[sea_orm(nested)]
table2: Option<entities::table2::Model>
}The important thing to note here that table2 is joined by LEFT JOIN, so it might be optional.
And in case it's optional, query will fail with DbErr::Type("{column_name} is null") .
This is because, first of all, FromQueryResult is implemented for Entity in such way, so that when try_get would return TryGetErr it's converted into DbErr by ? operator and secondly, macro implements from_query_result_nullable just by calling from_query_result.
Therefore the implementation of FromQueryResult on Option<T> wouldn't catch the error, as it's implemented like this:
fn from_query_result_nullable(res: &QueryResult, pre: &str) -> Result<Self, TryGetError> {
match T::from_query_result_nullable(res, pre) {
Ok(v) => Ok(Some(v)),
Err(TryGetError::Null(_)) => Ok(None),
Err(err @ TryGetError::DbErr(_)) => Err(err),
}
}So in the end, the error gets propagated back up as "database/programming error", when in reality it's incorrectly implemented macros.
Steps to Reproduce
- Left join two entities
- Create structure to hold results, where "right table" model is wrapped in
Option
Expected Behavior
The optional field should be None.
Actual Behavior
query will fail with DbErr::Type("{column_name} is null")
Reproduces How Often
Always.
Workarounds
Manually implement FromQueryResult, where you explicitly call from_query_result_optional for Optional<T> fields.
Versions
sea-orm = 1.1.12
rust = 1.87.0
macOS 15.5