Skip to content

FromQueryResult fails when having nested Option<Model> #2617

@hdbg

Description

@hdbg

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

  1. Left join two entities
  2. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions