diesel

Macro alias

Source
macro_rules! alias {
    ($($($table: ident)::+ as $alias: ident),* $(,)?) => { ... };
    ($($($table: ident)::+ as $alias_name: ident: $alias_ty: ident),* $(,)?) => { ... };
    ($($vis: vis const $const_name: ident: Alias<$alias_ty: ident> = $($table: ident)::+ as $alias_sql_name: ident);* $(;)?) => { ... };
    (NoConst $($($table: ident)::+ as $alias_sql_name: ident: $vis: vis $alias_ty: ident),* $(,)?) => { ... };
}
Expand description

Declare a new alias for a table

This macro creates a value of the type Alias

§Example usage

fn main() {
    use schema::users;
    let connection = &mut establish_connection();
    let (users1, users2) = diesel::alias!(schema::users as user1, schema::users as user2);
    let res = users1
        .inner_join(users2.on(users1.field(users::id).eq(users2.field(users::id))))
        .select((users1.fields((users::id, users::name)), users2.field(users::name)))
        .order_by(users2.field(users::id))
        .load::<((i32, String), String)>(connection);
    assert_eq!(
        res,
        Ok(vec![
            ((1, "Sean".to_owned()), "Sean".to_owned()),
            ((2, "Tess".to_owned()), "Tess".to_owned()),
        ]),
    );
}

§Make type expressible

It may sometimes be useful to declare an alias at the module level, in such a way that the type of a query using it can be expressed (to not declare it anonymously).

This can be achieved in the following way

use diesel::{query_source::Alias, dsl};

diesel::alias!(schema::users as users_alias: UsersAlias);
// or
diesel::alias!{
    pub const USERS_ALIAS_2: Alias<UsersAlias2> = schema::users as users_alias_2;
}

fn some_function_that_returns_a_query_fragment(
) -> dsl::InnerJoin<schema::posts::table, Alias<UsersAlias>>
{
    schema::posts::table.inner_join(users_alias)
}

Note that you may also use this form within a function, in the following way:

fn main() {
    diesel::alias!(schema::users as users_alias: UsersAlias);
    users_alias.inner_join(schema::posts::table);
}

§Troubleshooting and limitations

If you encounter a compilation error where “the trait AppearsInFromClause<Alias<your_alias>> is not implemented”, when trying to use two aliases to the same table within a single query note the following two limitations:

  • You will need to declare these in a single alias! call.
  • The path to the table module will have to be expressed in the exact same manner. (That is, you can do alias!(schema::users as user1, schema::users as user2) or alias!(users as user1, users as user2), but not alias!(schema::users as user1, users as user2))