Trait diesel::expression::BoxableExpression[][src]

pub trait BoxableExpression<QS, DB, GB = (), IsAggregate = No> where
    DB: Backend,
    Self: Expression,
    Self: SelectableExpression<QS>,
    Self: QueryFragment<DB>,
    Self: Send
{ }

Helper trait used when boxing expressions.

In Rust you cannot create a trait object with more than one trait. This type has all of the additional traits you would want when using Box<Expression> as a single trait object.

By default BoxableExpression is not usable in queries that have a custom group by clause. Setting the generic parameters GB and IsAggregate allows to configure the expression to be used with a specific group by clause.

This is typically used as the return type of a function. For cases where you want to dynamically construct a query, boxing the query is usually more ergonomic.


Usage without group by clause

use diesel::sql_types::Bool;

enum Search {

type DB = diesel::sqlite::Sqlite;

fn find_user(search: Search) -> Box<dyn BoxableExpression<users::table, DB, SqlType = Bool>> {
    match search {
        Search::Id(id) => Box::new(users::id.eq(id)),
        Search::Name(name) => Box::new(users::name.eq(name)),

let user_one = users::table
assert_eq!((1, String::from("Sean")), user_one);

let tess = users::table
assert_eq!((2, String::from("Tess")), tess);

Allow usage with group by clause

use diesel::sql_types::Text;
use diesel::dsl;
use diesel::expression::ValidGrouping;

enum NameOrConst {

type DB = diesel::sqlite::Sqlite;

fn selection<GB>(
    selection: NameOrConst
) -> Box<
    dyn BoxableExpression<
        <users::name as ValidGrouping<GB>>::IsAggregate,
        SqlType = Text
    users::name: BoxableExpression<
            <users::name as ValidGrouping<GB>>::IsAggregate,
            SqlType = Text
        > + ValidGrouping<GB>,
    match selection {
        NameOrConst::Name => Box::new(users::name),
        NameOrConst::Const(name) => Box::new(name.into_sql::<Text>()),

let user_one = users::table
assert_eq!(String::from("Sean"), user_one);

let with_name = users::table
    .select(selection(NameOrConst::Const("Jane Doe".into())))
assert_eq!(String::from("Jane Doe"), with_name);

More advanced query source

This example is a bit contrived, but in general, if you want to for example filter based on different criteria on a joined table, you can use InnerJoinQuerySource and LeftJoinQuerySource in the QS parameter of BoxableExpression.

use diesel::sql_types::Bool;
use diesel::dsl::InnerJoinQuerySource;

enum UserPostFilter {

type DB = diesel::sqlite::Sqlite;

fn filter_user_posts(
    filter: UserPostFilter,
) -> Box<dyn BoxableExpression<InnerJoinQuerySource<users::table, posts::table>, DB, SqlType = Bool>>
    match filter {
        UserPostFilter::User(user_id) => Box::new(users::id.eq(user_id)),
        UserPostFilter::Post(post_id) => Box::new(posts::id.eq(post_id)),

let post_by_user_one = users::table
    .select((posts::title, users::name))
    .first::<(String, String)>(conn)?;

    ("My first post too".to_string(), "Tess".to_string()),

Trait Implementations

impl<'a, QS, ST, DB, GB, IsAggregate> QueryId for dyn BoxableExpression<QS, DB, GB, IsAggregate, SqlType = ST> + 'a[src]

type QueryId = ()

A type which uniquely represents Self in a SQL query. Read more

impl<'a, QS, ST, DB, GB, IsAggregate> ValidGrouping<GB> for dyn BoxableExpression<QS, DB, GB, IsAggregate, SqlType = ST> + 'a[src]

type IsAggregate = IsAggregate

Is this expression aggregate? Read more


impl<QS, T, DB, GB, IsAggregate> BoxableExpression<QS, DB, GB, IsAggregate> for T where
    DB: Backend,
    T: Expression,
    T: SelectableExpression<QS>,
    T: ValidGrouping<GB>,
    T: QueryFragment<DB>,
    T: Send,
    T::IsAggregate: MixedAggregates<IsAggregate, Output = IsAggregate>, 

Loading content...