diesel/query_builder/
mod.rs

1//! Contains traits responsible for the actual construction of SQL statements
2//!
3//! The types in this module are part of Diesel's public API, but are generally
4//! only useful for implementing Diesel plugins. Applications should generally
5//! not need to care about the types inside of this module.
6
7#[macro_use]
8mod query_id;
9#[macro_use]
10mod clause_macro;
11
12mod ast_pass;
13pub mod bind_collector;
14mod debug_query;
15mod delete_statement;
16mod distinct_clause;
17#[doc(hidden)]
18pub mod functions;
19mod group_by_clause;
20mod insert_statement;
21mod limit_clause;
22pub(crate) mod locking_clause;
23#[doc(hidden)]
24pub mod nodes;
25mod offset_clause;
26mod order_clause;
27mod returning_clause;
28mod select_clause;
29mod select_statement;
30mod sql_query;
31mod update_statement;
32mod where_clause;
33
34pub use self::ast_pass::AstPass;
35pub use self::bind_collector::BindCollector;
36pub use self::debug_query::DebugQuery;
37pub use self::delete_statement::{BoxedDeleteStatement, DeleteStatement};
38#[doc(inline)]
39pub use self::insert_statement::{
40    IncompleteInsertStatement, InsertStatement, UndecoratedInsertRecord, ValuesClause,
41};
42pub use self::query_id::QueryId;
43#[doc(hidden)]
44pub use self::select_statement::{BoxedSelectStatement, SelectStatement};
45pub use self::sql_query::SqlQuery;
46#[cfg(feature = "with-deprecated")]
47#[allow(deprecated)]
48pub use self::update_statement::IncompleteUpdateStatement;
49#[doc(inline)]
50pub use self::update_statement::{
51    AsChangeset, BoxedUpdateStatement, IntoUpdateTarget, UpdateStatement, UpdateTarget,
52};
53
54pub(crate) use self::insert_statement::ColumnList;
55
56use std::error::Error;
57
58use backend::Backend;
59use result::QueryResult;
60
61#[doc(hidden)]
62pub type Binds = Vec<Option<Vec<u8>>>;
63/// A specialized Result type used with the query builder.
64pub type BuildQueryResult = Result<(), Box<dyn Error + Send + Sync>>;
65
66/// Constructs a SQL query from a Diesel AST.
67///
68/// The only reason you should ever need to interact with this trait is if you
69/// are extending Diesel with support for a new backend. Plugins which extend
70/// the query builder with new capabilities will interact with [`AstPass`]
71/// instead.
72///
73/// [`AstPass`]: struct.AstPass.html
74pub trait QueryBuilder<DB: Backend> {
75    /// Add `sql` to the end of the query being constructed.
76    fn push_sql(&mut self, sql: &str);
77
78    /// Quote `identifier`, and add it to the end of the query being
79    /// constructed.
80    fn push_identifier(&mut self, identifier: &str) -> QueryResult<()>;
81
82    /// Add a placeholder for a bind parameter to the end of the query being
83    /// constructed.
84    fn push_bind_param(&mut self);
85
86    /// Returns the constructed SQL query.
87    fn finish(self) -> String;
88}
89
90/// A complete SQL query with a return type.
91///
92/// This can be a select statement, or a command such as `update` or `insert`
93/// with a `RETURNING` clause. Unlike [`Expression`], types implementing this
94/// trait are guaranteed to be executable on their own.
95///
96/// A type which doesn't implement this trait may still represent a complete SQL
97/// query. For example, an `INSERT` statement without a `RETURNING` clause will
98/// not implement this trait, but can still be executed.
99///
100/// [`Expression`]: ../expression/trait.Expression.html
101pub trait Query {
102    /// The SQL type that this query represents.
103    ///
104    /// This is the SQL type of the `SELECT` clause for select statements, and
105    /// the SQL type of the `RETURNING` clause for insert, update, or delete
106    /// statements.
107    type SqlType;
108}
109
110impl<'a, T: Query> Query for &'a T {
111    type SqlType = T::SqlType;
112}
113
114/// Indicates that a type is a `SELECT` statement.
115///
116/// This trait differs from `Query` in two ways:
117/// - It is implemented only for select statements, rather than all queries
118///   which return a value.
119/// - It has looser constraints. A type implementing `SelectQuery` is known to
120///   be potentially valid if used as a subselect, but it is not necessarily
121///   able to be executed.
122pub trait SelectQuery {
123    /// The SQL type of the `SELECT` clause
124    type SqlType;
125}
126
127/// An untyped fragment of SQL.
128///
129/// This may be a complete SQL command (such as an update statement without a
130/// `RETURNING` clause), or a subsection (such as our internal types used to
131/// represent a `WHERE` clause). Implementations of [`ExecuteDsl`] and
132/// [`LoadQuery`] will generally require that this trait be implemented.
133///
134/// [`ExecuteDsl`]: ../query_dsl/methods/trait.ExecuteDsl.html
135/// [`LoadQuery`]: ../query_dsl/methods/trait.LoadQuery.html
136pub trait QueryFragment<DB: Backend> {
137    /// Walk over this `QueryFragment` for all passes.
138    ///
139    /// This method is where the actual behavior of an AST node is implemented.
140    /// This method will contain the behavior required for all possible AST
141    /// passes. See [`AstPass`] for more details.
142    ///
143    /// [`AstPass`]: struct.AstPass.html
144    fn walk_ast(&self, pass: AstPass<DB>) -> QueryResult<()>;
145
146    /// Converts this `QueryFragment` to its SQL representation.
147    ///
148    /// This method should only be called by implementations of `Connection`.
149    fn to_sql(&self, out: &mut DB::QueryBuilder) -> QueryResult<()> {
150        self.walk_ast(AstPass::to_sql(out))
151    }
152
153    /// Serializes all bind parameters in this query.
154    ///
155    /// A bind parameter is a value which is sent separately from the query
156    /// itself. It is represented in SQL with a placeholder such as `?` or `$1`.
157    ///
158    /// This method should only be called by implementations of `Connection`.
159    fn collect_binds(
160        &self,
161        out: &mut DB::BindCollector,
162        metadata_lookup: &DB::MetadataLookup,
163    ) -> QueryResult<()> {
164        self.walk_ast(AstPass::collect_binds(out, metadata_lookup))
165    }
166
167    /// Is this query safe to store in the prepared statement cache?
168    ///
169    /// In order to keep our prepared statement cache at a reasonable size, we
170    /// avoid caching any queries which represent a potentially unbounded number
171    /// of SQL queries. Generally this will only return `true` for queries for
172    /// which `to_sql` will always construct exactly identical SQL.
173    ///
174    /// Some examples of where this method will return `false` are:
175    ///
176    /// - `SqlLiteral` (We don't know if the SQL was constructed dynamically, so
177    ///   we must assume that it was)
178    /// - `In` and `NotIn` (Each value requires a separate bind param
179    ///   placeholder)
180    ///
181    /// This method should only be called by implementations of `Connection`.
182    fn is_safe_to_cache_prepared(&self) -> QueryResult<bool> {
183        let mut result = true;
184        self.walk_ast(AstPass::is_safe_to_cache_prepared(&mut result))?;
185        Ok(result)
186    }
187
188    #[doc(hidden)]
189    /// Does walking this AST have any effect?
190    fn is_noop(&self) -> QueryResult<bool> {
191        let mut result = true;
192        self.walk_ast(AstPass::is_noop(&mut result))?;
193        Ok(result)
194    }
195}
196
197impl<T: ?Sized, DB> QueryFragment<DB> for Box<T>
198where
199    DB: Backend,
200    T: QueryFragment<DB>,
201{
202    fn walk_ast(&self, pass: AstPass<DB>) -> QueryResult<()> {
203        QueryFragment::walk_ast(&**self, pass)
204    }
205}
206
207impl<'a, T: ?Sized, DB> QueryFragment<DB> for &'a T
208where
209    DB: Backend,
210    T: QueryFragment<DB>,
211{
212    fn walk_ast(&self, pass: AstPass<DB>) -> QueryResult<()> {
213        QueryFragment::walk_ast(&**self, pass)
214    }
215}
216
217impl<DB: Backend> QueryFragment<DB> for () {
218    fn walk_ast(&self, _: AstPass<DB>) -> QueryResult<()> {
219        Ok(())
220    }
221}
222
223impl<T, DB> QueryFragment<DB> for Option<T>
224where
225    DB: Backend,
226    T: QueryFragment<DB>,
227{
228    fn walk_ast(&self, out: AstPass<DB>) -> QueryResult<()> {
229        match *self {
230            Some(ref c) => c.walk_ast(out),
231            None => Ok(()),
232        }
233    }
234}
235
236/// Types that can be converted into a complete, typed SQL query.
237///
238/// This is used internally to automatically add the right select clause when
239/// none is specified, or to automatically add `RETURNING *` in certain contexts.
240///
241/// A type which implements this trait is guaranteed to be valid for execution.
242pub trait AsQuery {
243    /// The SQL type of `Self::Query`
244    type SqlType;
245
246    /// What kind of query does this type represent?
247    type Query: Query<SqlType = Self::SqlType>;
248
249    /// Converts a type which semantically represents a SQL query into the
250    /// actual query being executed. See the trait level docs for more.
251    fn as_query(self) -> Self::Query;
252}
253
254impl<T: Query> AsQuery for T {
255    type SqlType = <Self as Query>::SqlType;
256    type Query = Self;
257
258    fn as_query(self) -> Self::Query {
259        self
260    }
261}
262
263/// Takes a query `QueryFragment` expression as an argument and returns a type
264/// that implements `fmt::Display` and `fmt::Debug` to show the query.
265///
266/// The `Display` implementation will show the exact query being sent to the
267/// server, with a comment showing the values of the bind parameters. The
268/// `Debug` implementation will include the same information in a more
269/// structured form, and respects pretty printing.
270///
271/// # Example
272///
273/// ### Returning SQL from a count statement:
274///
275/// ```rust
276/// # include!("../doctest_setup.rs");
277/// #
278/// # #[macro_use] extern crate diesel;
279/// # use diesel::*;
280/// # use schema::*;
281/// #
282/// # fn main() {
283/// #   use schema::users::dsl::*;
284/// let sql = debug_query::<DB, _>(&users.count()).to_string();
285/// # if cfg!(feature = "postgres") {
286/// #     assert_eq!(sql, r#"SELECT COUNT(*) FROM "users" -- binds: []"#);
287/// # } else {
288/// assert_eq!(sql, "SELECT COUNT(*) FROM `users` -- binds: []");
289/// # }
290///
291/// let query = users.find(1);
292/// let debug = debug_query::<DB, _>(&query);
293/// # if cfg!(feature = "postgres") {
294/// #     assert_eq!(debug.to_string(), "SELECT \"users\".\"id\", \"users\".\"name\" \
295/// #         FROM \"users\" WHERE \"users\".\"id\" = $1 -- binds: [1]");
296/// # } else {
297/// assert_eq!(debug.to_string(), "SELECT `users`.`id`, `users`.`name` FROM `users` \
298///     WHERE `users`.`id` = ? -- binds: [1]");
299/// # }
300///
301/// let debug = format!("{:?}", debug);
302/// # if !cfg!(feature = "postgres") { // Escaping that string is a pain
303/// let expected = "Query { \
304///     sql: \"SELECT `users`.`id`, `users`.`name` FROM `users` WHERE \
305///         `users`.`id` = ?\", \
306///     binds: [1] \
307/// }";
308/// assert_eq!(debug, expected);
309/// # }
310/// # }
311/// ```
312pub fn debug_query<DB, T>(query: &T) -> DebugQuery<T, DB> {
313    DebugQuery::new(query)
314}