diff --git a/src/expression/mod.rs b/src/expression/mod.rs index be34d65f6a0e..4d7fd2fbb38a 100644 --- a/src/expression/mod.rs +++ b/src/expression/mod.rs @@ -119,6 +119,18 @@ pub trait Expression { } } +impl Expression for Box { + type SqlType = T::SqlType; + + fn to_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult { + Expression::to_sql(&**self, out) + } + + fn to_insert_sql(&self, out: &mut QueryBuilder) -> BuildQueryResult { + Expression::to_insert_sql(&**self, out) + } +} + pub trait AsExpression { type Expression: Expression; @@ -139,5 +151,24 @@ pub trait SelectableExpression< >: Expression { } +impl SelectableExpression for Box where + T: SelectableExpression, + ST: NativeSqlType, + Box: Expression, +{ +} + pub trait NonAggregate: Expression { } + +impl NonAggregate for Box { +} + +pub trait BoxableExpression: Expression + SelectableExpression + NonAggregate { +} + +impl BoxableExpression for T where + ST: NativeSqlType, + T: Expression + SelectableExpression + NonAggregate, +{ +} diff --git a/src/lib.rs b/src/lib.rs index 38db0bbc5fcc..70bc3707c197 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,7 +25,7 @@ pub mod helper_types { mod macros; pub use connection::{Connection, Cursor}; -pub use expression::{Expression, SelectableExpression}; +pub use expression::{Expression, SelectableExpression, BoxableExpression}; pub use query_dsl::*; pub use query_source::{QuerySource, Queriable, Table, Column, JoinTo}; pub use result::{TransactionError, TransactionResult, ConnectionError, ConnectionResult}; diff --git a/tests/filter.rs b/tests/filter.rs index 28a36056a3c8..88f4e0bfcdd1 100644 --- a/tests/filter.rs +++ b/tests/filter.rs @@ -230,3 +230,23 @@ fn or_doesnt_mess_with_precidence_of_previous_statements() { assert_eq!(Some(0), count); } + +sql_function!(lower, lower_t, (x: VarChar) -> VarChar); + +#[test] +fn filter_by_boxed_predicate() { + fn by_name(name: &str) -> Box> { + Box::new(lower(users::name).eq(name.to_string())) + } + + let connection = connection_with_sean_and_tess_in_users_table(); + let sean = User::new(1, "Sean"); + let tess = User::new(2, "Tess"); + let queried_sean = users::table.filter(by_name("sean")).first(&connection) + .unwrap(); + let queried_tess = users::table.filter(by_name("tess")).first(&connection) + .unwrap(); + + assert_eq!(Some(sean), queried_sean); + assert_eq!(Some(tess), queried_tess); +}