1 //! AST types representing various typed SQL expressions. 2 //! 3 //! Almost all types implement either [`Expression`](trait.Expression.html) or 4 //! [`AsExpression`](trait.AsExpression.html). 5 //! 6 //! The most common expression to work with is a 7 //! [`Column`](../query_source/trait.Column.html). There are various methods 8 //! that you can call on these, found in 9 //! [`expression_methods`](../expression_methods). 10 //! 11 //! You can also use numeric operators such as `+` on expressions of the 12 //! appropriate type. 13 //! 14 //! Any primitive which implements [`ToSql`](../serialize/trait.ToSql.html) will 15 //! also implement [`AsExpression`](trait.AsExpression.html), allowing it to be 16 //! used as an argument to any of the methods described here. 17 #[macro_use] 18 #[doc(hidden)] 19 pub mod ops; 20 #[doc(hidden)] 21 #[macro_use] 22 pub mod functions; 23 24 #[doc(hidden)] 25 pub mod array_comparison; 26 #[doc(hidden)] 27 pub mod bound; 28 #[doc(hidden)] 29 pub mod coerce; 30 #[doc(hidden)] 31 pub mod count; 32 #[doc(hidden)] 33 pub mod exists; 34 #[doc(hidden)] 35 pub mod grouped; 36 #[doc(hidden)] 37 pub mod helper_types; 38 mod not; 39 #[doc(hidden)] 40 pub mod nullable; 41 #[doc(hidden)] 42 #[macro_use] 43 pub mod operators; 44 #[doc(hidden)] 45 pub mod sql_literal; 46 #[doc(hidden)] 47 pub mod subselect; 48 49 #[doc(hidden)] 50 #[allow(non_camel_case_types)] 51 pub mod dsl { 52 use dsl::SqlTypeOf; 53 54 #[doc(inline)] 55 pub use super::count::*; 56 #[doc(inline)] 57 pub use super::exists::exists; 58 #[doc(inline)] 59 pub use super::functions::aggregate_folding::*; 60 #[doc(inline)] 61 pub use super::functions::aggregate_ordering::*; 62 #[doc(inline)] 63 pub use super::functions::date_and_time::*; 64 #[doc(inline)] 65 pub use super::not::not; 66 #[doc(inline)] 67 pub use super::sql_literal::sql; 68 69 #[cfg(feature = "postgres")] 70 pub use pg::expression::dsl::*; 71 72 /// The return type of [`count(expr)`](../dsl/fn.count.html) 73 pub type count<Expr> = super::count::count::HelperType<SqlTypeOf<Expr>, Expr>; 74 75 /// The return type of [`count_star)(`](../dsl/fn.count_star.html) 76 pub type count_star = super::count::CountStar; 77 78 /// The return type of [`date(expr)`](../dsl/fn.date.html) 79 pub type date<Expr> = super::functions::date_and_time::date::HelperType<Expr>; 80 } 81 82 #[doc(inline)] 83 pub use self::sql_literal::{SqlLiteral, UncheckedBind}; 84 85 use backend::Backend; 86 use dsl::AsExprOf; 87 88 /// Represents a typed fragment of SQL. 89 /// 90 /// Apps should not need to implement this type directly, but it may be common 91 /// to use this in where clauses. Libraries should consider using 92 /// [`diesel_infix_operator!`](../macro.diesel_infix_operator.html) or 93 /// [`diesel_postfix_operator!`](../macro.diesel_postfix_operator.html) instead of 94 /// implementing this directly. 95 pub trait Expression { 96 /// The type that this expression represents in SQL 97 type SqlType; 98 } 99 100 impl<T: Expression + ?Sized> Expression for Box<T> { 101 type SqlType = T::SqlType; 102 } 103 104 impl<'a, T: Expression + ?Sized> Expression for &'a T { 105 type SqlType = T::SqlType; 106 } 107 108 /// Converts a type to its representation for use in Diesel's query builder. 109 /// 110 /// This trait is used directly. Apps should typically use [`IntoSql`] instead. 111 /// 112 /// Implementations of this trait will generally do one of 3 things: 113 /// 114 /// - Return `self` for types which are already parts of Diesel's query builder 115 /// - Perform some implicit coercion (for example, allowing [`now`] to be used as 116 /// both [`Timestamp`] and [`Timestamptz`]. 117 /// - Indicate that the type has data which will be sent separately from the 118 /// query. This is generally referred as a "bind parameter". Types which 119 /// implement [`ToSql`] will generally implement `AsExpression` this way. 120 /// 121 /// [`IntoSql`]: trait.IntoSql.html 122 /// [`now`]: ../dsl/struct.now.html 123 /// [`Timestamp`]: ../sql_types/struct.Timestamp.html 124 /// [`Timestamptz`]: ../pg/types/sql_types/struct.Timestamptz.html 125 /// [`ToSql`]: ../serialize/trait.ToSql.html 126 /// 127 /// ## Deriving 128 /// 129 /// This trait can be automatically derived for any type which implements `ToSql`. 130 /// The type must be annotated with `#[sql_type = "SomeType"]`. 131 /// If that annotation appears multiple times, 132 /// implementations will be generated for each one of them. 133 /// 134 /// This will generate the following impls: 135 /// 136 /// - `impl AsExpression<SqlType> for YourType` 137 /// - `impl AsExpression<Nullable<SqlType>> for YourType` 138 /// - `impl AsExpression<SqlType> for &'a YourType` 139 /// - `impl AsExpression<Nullable<SqlType>> for &'a YourType` 140 /// - `impl AsExpression<SqlType> for &'a &'b YourType` 141 /// - `impl AsExpression<Nullable<SqlType>> for &'a &'b YourType` 142 /// 143 /// If your type is unsized, 144 /// you can specify this by adding the annotation `#[diesel(not_sized)]`. 145 /// This will skip the impls for non-reference types. 146 pub trait AsExpression<T> { 147 /// The expression being returned 148 type Expression: Expression<SqlType = T>; 149 150 /// Perform the conversion as_expression(self) -> Self::Expression151 fn as_expression(self) -> Self::Expression; 152 } 153 154 impl<T: Expression> AsExpression<T::SqlType> for T { 155 type Expression = Self; 156 as_expression(self) -> Self157 fn as_expression(self) -> Self { 158 self 159 } 160 } 161 162 /// Converts a type to its representation for use in Diesel's query builder. 163 /// 164 /// This trait only exists to make usage of `AsExpression` more ergonomic when 165 /// the `SqlType` cannot be inferred. It is generally used when you need to use 166 /// a Rust value as the left hand side of an expression, or when you want to 167 /// select a constant value. 168 /// 169 /// # Example 170 /// 171 /// ```rust 172 /// # #[macro_use] extern crate diesel; 173 /// # include!("../doctest_setup.rs"); 174 /// # use schema::users; 175 /// # 176 /// # fn main() { 177 /// use diesel::sql_types::Text; 178 /// # let conn = establish_connection(); 179 /// let names = users::table 180 /// .select("The Amazing ".into_sql::<Text>().concat(users::name)) 181 /// .load(&conn); 182 /// let expected_names = vec![ 183 /// "The Amazing Sean".to_string(), 184 /// "The Amazing Tess".to_string(), 185 /// ]; 186 /// assert_eq!(Ok(expected_names), names); 187 /// # } 188 /// ``` 189 pub trait IntoSql { 190 /// Convert `self` to an expression for Diesel's query builder. 191 /// 192 /// There is no difference in behavior between `x.into_sql::<Y>()` and 193 /// `AsExpression::<Y>::as_expression(x)`. into_sql<T>(self) -> AsExprOf<Self, T> where Self: AsExpression<T> + Sized,194 fn into_sql<T>(self) -> AsExprOf<Self, T> 195 where 196 Self: AsExpression<T> + Sized, 197 { 198 self.as_expression() 199 } 200 201 /// Convert `&self` to an expression for Diesel's query builder. 202 /// 203 /// There is no difference in behavior between `x.as_sql::<Y>()` and 204 /// `AsExpression::<Y>::as_expression(&x)`. as_sql<'a, T>(&'a self) -> AsExprOf<&'a Self, T> where &'a Self: AsExpression<T>,205 fn as_sql<'a, T>(&'a self) -> AsExprOf<&'a Self, T> 206 where 207 &'a Self: AsExpression<T>, 208 { 209 self.as_expression() 210 } 211 } 212 213 impl<T> IntoSql for T {} 214 215 /// Indicates that all elements of an expression are valid given a from clause. 216 /// 217 /// This is used to ensure that `users.filter(posts::id.eq(1))` fails to 218 /// compile. This constraint is only used in places where the nullability of a 219 /// SQL type doesn't matter (everything except `select` and `returning`). For 220 /// places where nullability is important, `SelectableExpression` is used 221 /// instead. 222 pub trait AppearsOnTable<QS: ?Sized>: Expression {} 223 224 impl<T: ?Sized, QS> AppearsOnTable<QS> for Box<T> 225 where 226 T: AppearsOnTable<QS>, 227 Box<T>: Expression, 228 { 229 } 230 231 impl<'a, T: ?Sized, QS> AppearsOnTable<QS> for &'a T 232 where 233 T: AppearsOnTable<QS>, 234 &'a T: Expression, 235 { 236 } 237 238 /// Indicates that an expression can be selected from a source. 239 /// 240 /// Columns will implement this for their table. Certain special types, like 241 /// `CountStar` and `Bound` will implement this for all sources. Most compound 242 /// expressions will implement this if each of their parts implement it. 243 /// 244 /// Notably, columns will not implement this trait for the right side of a left 245 /// join. To select a column or expression using a column from the right side of 246 /// a left join, you must call `.nullable()` on it. 247 pub trait SelectableExpression<QS: ?Sized>: AppearsOnTable<QS> {} 248 249 impl<T: ?Sized, QS> SelectableExpression<QS> for Box<T> 250 where 251 T: SelectableExpression<QS>, 252 Box<T>: AppearsOnTable<QS>, 253 { 254 } 255 256 impl<'a, T: ?Sized, QS> SelectableExpression<QS> for &'a T 257 where 258 T: SelectableExpression<QS>, 259 &'a T: AppearsOnTable<QS>, 260 { 261 } 262 263 /// Marker trait to indicate that an expression does not include any aggregate 264 /// functions. 265 /// 266 /// Used to ensure that aggregate expressions aren't mixed with 267 /// non-aggregate expressions in a select clause, and that they're never 268 /// included in a where clause. 269 pub trait NonAggregate {} 270 271 impl<T: NonAggregate + ?Sized> NonAggregate for Box<T> {} 272 273 impl<'a, T: NonAggregate + ?Sized> NonAggregate for &'a T {} 274 275 use query_builder::{QueryFragment, QueryId}; 276 277 /// Helper trait used when boxing expressions. 278 /// 279 /// In Rust you cannot create a trait object with more than one trait. 280 /// This type has all of the additional traits you would want when using 281 /// `Box<Expression>` as a single trait object. 282 /// 283 /// This is typically used as the return type of a function. 284 /// For cases where you want to dynamically construct a query, 285 /// [boxing the query] is usually more ergonomic. 286 /// 287 /// [boxing the query]: ../query_dsl/trait.QueryDsl.html#method.into_boxed 288 /// 289 /// # Examples 290 /// 291 /// ```rust 292 /// # #[macro_use] extern crate diesel; 293 /// # include!("../doctest_setup.rs"); 294 /// # use schema::users; 295 /// use diesel::sql_types::Bool; 296 /// 297 /// # fn main() { 298 /// # run_test().unwrap(); 299 /// # } 300 /// # 301 /// # fn run_test() -> QueryResult<()> { 302 /// # let conn = establish_connection(); 303 /// enum Search { 304 /// Id(i32), 305 /// Name(String), 306 /// } 307 /// 308 /// # /* 309 /// type DB = diesel::sqlite::Sqlite; 310 /// # */ 311 /// 312 /// fn find_user(search: Search) -> Box<BoxableExpression<users::table, DB, SqlType = Bool>> { 313 /// match search { 314 /// Search::Id(id) => Box::new(users::id.eq(id)), 315 /// Search::Name(name) => Box::new(users::name.eq(name)), 316 /// } 317 /// } 318 /// 319 /// let user_one = users::table 320 /// .filter(find_user(Search::Id(1))) 321 /// .first(&conn)?; 322 /// assert_eq!((1, String::from("Sean")), user_one); 323 /// 324 /// let tess = users::table 325 /// .filter(find_user(Search::Name("Tess".into()))) 326 /// .first(&conn)?; 327 /// assert_eq!((2, String::from("Tess")), tess); 328 /// # Ok(()) 329 /// # } 330 /// ``` 331 pub trait BoxableExpression<QS, DB> 332 where 333 DB: Backend, 334 Self: Expression, 335 Self: SelectableExpression<QS>, 336 Self: NonAggregate, 337 Self: QueryFragment<DB>, 338 { 339 } 340 341 impl<QS, T, DB> BoxableExpression<QS, DB> for T 342 where 343 DB: Backend, 344 T: Expression, 345 T: SelectableExpression<QS>, 346 T: NonAggregate, 347 T: QueryFragment<DB>, 348 { 349 } 350 351 impl<'a, QS, ST, DB> QueryId for dyn BoxableExpression<QS, DB, SqlType = ST> + 'a { 352 type QueryId = (); 353 354 const HAS_STATIC_QUERY_ID: bool = false; 355 } 356 357 /// Converts a tuple of values into a tuple of Diesel expressions. 358 /// 359 /// This trait is similar to [`AsExpression`], but it operates on tuples. 360 /// The expressions must all be of the same SQL type. 361 /// 362 /// [`AsExpression`]: trait.AsExpression.html 363 pub trait AsExpressionList<ST> { 364 /// The final output expression 365 type Expression; 366 367 /// Perform the conversion as_expression_list(self) -> Self::Expression368 fn as_expression_list(self) -> Self::Expression; 369 } 370