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