1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
use backend::Backend; use expression::Expression; use query_builder::*; use result::QueryResult; use types::{Foldable, HasSqlType}; macro_rules! fold_function { ($fn_name:ident, $type_name:ident, $operator:expr, $docs:expr) => { #[doc=$docs] pub fn $fn_name<ST, T>(t: T) -> $type_name<T> where ST: Foldable, T: Expression<SqlType=ST>, { $type_name { target: t, } } #[derive(Debug, Clone, Copy)] pub struct $type_name<T> { target: T, } impl<ST, T> Expression for $type_name<T> where ST: Foldable, T: Expression<SqlType=ST> { type SqlType = <<T as Expression>::SqlType as Foldable>::$type_name; } impl<T, DB> QueryFragment<DB> for $type_name<T> where T: Expression + QueryFragment<DB>, DB: Backend + HasSqlType<T::SqlType>, { fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> { out.push_sql(concat!($operator, "(")); self.target.walk_ast(out.reborrow())?; out.push_sql(")"); Ok(()) } } impl_query_id!($type_name<T>); impl_selectable_expression!($type_name<T>); } } fold_function!(sum, Sum, "SUM", "Represents a SQL `SUM` function. This function can only take types which are Foldable. # Examples ```rust # #[macro_use] extern crate diesel; # include!(\"src/doctest_setup.rs\"); # use diesel::expression::dsl::*; # # table! { # users { # id -> Integer, # name -> VarChar, # } # } # # fn main() { # use self::animals::dsl::*; # let connection = establish_connection(); assert_eq!(Ok(Some(12i64)), animals.select(sum(legs)).first(&connection)); # } "); fold_function!(avg, Avg, "AVG", "Represents a SQL `AVG` function. This function can only take types which are Foldable. # Examples ```rust # #[macro_use] extern crate diesel; # include!(\"src/doctest_setup.rs\"); # use diesel::expression::dsl::*; # # table! { # users { # id -> Integer, # name -> VarChar, # } # } # # fn main() { # use self::animals::dsl::*; # let connection = establish_connection(); // assert_eq!(Ok(Some(6f64)), animals.select(avg(legs)).first(&connection)); // TODO: There doesn't currently seem to be a way to use avg with integers, since // they return a `Numeric` which doesn't have a corresponding Rust type. # } ``` ");