Search code examples
rustrust-diesel

How can I remove the `Nullable` wrapper on a column when I know it isn't nullable due to filters?


If I have the schema.rs:

table! {
    Foo (id) {
        id -> Integer,
        label -> Nullable<Text>,
    }
}

And I filter like:

let result: String = foo_dsl::Foo
    .select(foo_dsl::label)
    .filter(foo_dsl::label.is_not_null())
    .first(&conn)
    .unwrap();

I get this error:

error[E0277]: the trait bound `*const str: FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, Mysql>` is not satisfied
    --> src/main.rs:21:10
     |
21   |         .first(&conn)
     |          ^^^^^ the trait `FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, Mysql>` is not implemented for `*const str`
     |
     = help: the following other types implement trait `FromSql<A, DB>`:
               <*const str as FromSql<diesel::sql_types::Text, DB>>
               <std::string::String as FromSql<ST, DB>>
     = note: required because of the requirements on the impl of `FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, Mysql>` for `std::string::String`
     = note: required because of the requirements on the impl of `Queryable<diesel::sql_types::Nullable<diesel::sql_types::Text>, Mysql>` for `std::string::String`
     = note: required because of the requirements on the impl of `LoadQuery<MysqlConnection, std::string::String>` for `diesel::query_builder::SelectStatement<table, query_builder::select_clause::SelectClause<columns::label>, query_builder::distinct_clause::NoDistinctClause, query_builder::where_clause::WhereClause<IsNotNull<columns::label>>, query_builder::order_clause::NoOrderClause, query_builder::limit_clause::LimitClause<diesel::expression::bound::Bound<BigInt, i64>>>`
note: required by a bound in `first`
    --> /home/kmdreko/.cargo/registry/src/github.com-1ecc6299db9ec823/diesel-1.4.8/src/query_dsl/mod.rs:1343:22
     |
1343 |         Limit<Self>: LoadQuery<Conn, U>,
     |                      ^^^^^^^^^^^^^^^^^^ required by this bound in `first`

This makes sense; the field is specified as Nullable and will work if I used Option<String>. But for this query I know that the value exists, since I filter by .is_not_null(). Is it possible to strip the Nullable column wrapper or do I need to manually unwrap after the query result?


Solution

  • You have several options there:

    • Use .unwrap() or a similar method on the result
    • Use an explicit select clause + .assume_not_null(). (Note that this method is only available on diesel 2.0, as your question is missing information about the diesel version it's hard to tell if you can use this directly or if you need to implement something like this on your own).