Skip to main content

diesel/query_builder/
sql_query.rs

1use super::Query;
2use crate::backend::{Backend, DieselReserveSpecialization};
3use crate::query_builder::{AstPass, QueryFragment, QueryId};
4use crate::query_dsl::RunQueryDslSupport;
5use crate::result::QueryResult;
6use crate::serialize::ToSql;
7use crate::sql_types::{HasSqlType, Untyped};
8use alloc::boxed::Box;
9use alloc::string::String;
10use alloc::string::ToString;
11use alloc::sync::Arc;
12use alloc::vec::Vec;
13use core::marker::PhantomData;
14
15#[derive(#[automatically_derived]impl<Inner: ::core::fmt::Debug> ::core::fmt::Debug for
    SqlQuery<Inner> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "SqlQuery inner query", &self.inner, &&self.query)
    }
}Debug, #[automatically_derived]impl<Inner: ::core::clone::Clone> ::core::clone::Clone
    for SqlQuery<Inner> {
    #[inline]
    fn clone(&self) -> Self {
        SqlQuery {
            inner: ::core::clone::Clone::clone(&self.inner),
            query: ::core::clone::Clone::clone(&self.query),
        }
    }
}Clone)]
16#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
17/// The return value of `sql_query`.
18///
19/// Unlike most queries in Diesel, `SqlQuery` loads its data by column name,
20/// rather than by index. This means that you cannot deserialize this query into
21/// a tuple, and any structs used must implement `QueryableByName`.
22///
23/// See [`sql_query`](crate::sql_query()) for examples.
24pub struct SqlQuery<Inner = self::private::Empty> {
25    inner: Inner,
26    query: String,
27}
28
29impl<Inner> SqlQuery<Inner> {
30    pub(crate) fn new(inner: Inner, query: String) -> Self {
31        SqlQuery { inner, query }
32    }
33
34    /// Bind a value for use with this SQL query. The given query should have
35    /// placeholders that vary based on the database type,
36    /// like [SQLite Parameter](https://sqlite.org/lang_expr.html#varparam) syntax,
37    /// [PostgreSQL PREPARE syntax](https://www.postgresql.org/docs/current/sql-prepare.html),
38    /// or [MySQL bind syntax](https://dev.mysql.com/doc/refman/8.0/en/mysql-stmt-bind-param.html).
39    ///
40    /// For binding a variable number of values in a loop, use `into_boxed` first.
41    ///
42    /// # Safety
43    ///
44    /// This function should be used with care, as Diesel cannot validate that
45    /// the value is of the right type nor can it validate that you have passed
46    /// the correct number of parameters.
47    ///
48    /// # Example
49    ///
50    /// ```
51    /// # include!("../doctest_setup.rs");
52    /// #
53    /// # use schema::users;
54    /// #
55    /// # #[derive(QueryableByName, Debug, PartialEq)]
56    /// # struct User {
57    /// #     id: i32,
58    /// #     name: String,
59    /// # }
60    /// #
61    /// # // Reading the query result requires reading memory allocated by the
62    /// # // native sqlite library, which miri cannot track provenance for.
63    /// # #[cfg(miri)]
64    /// # fn main() {}
65    /// # #[cfg(not(miri))]
66    /// # fn main() {
67    /// #     use diesel::sql_query;
68    /// #     use diesel::sql_types::{Integer, Text};
69    /// #
70    /// #     let connection = &mut establish_connection();
71    /// #     diesel::insert_into(users::table)
72    /// #         .values(users::name.eq("Jim"))
73    /// #         .execute(connection).unwrap();
74    /// # #[cfg(feature = "postgres")]
75    /// # let users = sql_query("SELECT * FROM users WHERE id > $1 AND name != $2");
76    /// # #[cfg(not(feature = "postgres"))]
77    /// // sqlite/mysql bind syntax
78    /// let users = sql_query("SELECT * FROM users WHERE id > ? AND name <> ?")
79    /// # ;
80    /// # let users = users
81    ///     .bind::<Integer, _>(1)
82    ///     .bind::<Text, _>("Tess")
83    ///     .get_results(connection);
84    /// let expected_users = vec![User {
85    ///     id: 3,
86    ///     name: "Jim".into(),
87    /// }];
88    /// assert_eq!(Ok(expected_users), users);
89    /// # }
90    /// ```
91    pub fn bind<ST, Value>(self, value: Value) -> UncheckedBind<Self, Value, ST> {
92        UncheckedBind::new(self, value)
93    }
94
95    /// Internally boxes the query, which allows to  calls `bind` and `sql` so that they don't
96    /// change the type nor the instance. This allows to call `bind` or `sql`
97    /// in a loop, e.g.:
98    ///
99    /// ```
100    /// # include!("../doctest_setup.rs");
101    /// #
102    /// # use schema::users;
103    /// #
104    /// # #[derive(QueryableByName, Debug, PartialEq)]
105    /// # struct User {
106    /// #     id: i32,
107    /// #     name: String,
108    /// # }
109    /// #
110    /// # // Reading the query result requires reading memory allocated by the
111    /// # // native sqlite library, which miri cannot track provenance for.
112    /// # #[cfg(miri)]
113    /// # fn main() {}
114    /// # #[cfg(not(miri))]
115    /// # fn main() {
116    /// #     use diesel::sql_query;
117    /// #     use diesel::sql_types::{Integer};
118    /// #
119    /// #     let connection = &mut establish_connection();
120    /// #     diesel::insert_into(users::table)
121    /// #         .values(users::name.eq("Jim"))
122    /// #         .execute(connection).unwrap();
123    /// let mut q = diesel::sql_query("SELECT * FROM users WHERE id IN(").into_boxed();
124    /// for (idx, user_id) in [3, 4, 5].into_iter().enumerate() {
125    ///     if idx != 0 {
126    ///         q = q.sql(", ");
127    ///     }
128    /// # #[cfg(feature = "postgres")]
129    /// # {
130    ///     q = q
131    ///         // postgresql bind syntax
132    ///         .sql(format!("${}", idx + 1))
133    ///         .bind::<Integer, _>(user_id);
134    /// # }
135    /// # #[cfg(not(feature = "postgres"))]
136    /// # {
137    /// #   q = q
138    /// #       .sql(format!("?"))
139    /// #       .bind::<Integer, _>(user_id);
140    /// # }
141    /// }
142    /// let users = q.sql(");").get_results(connection);
143    /// let expected_users = vec![User {
144    ///     id: 3,
145    ///     name: "Jim".into(),
146    /// }];
147    /// assert_eq!(Ok(expected_users), users);
148    /// # }
149    /// ```
150    ///
151    /// This allows doing things you otherwise couldn't do, e.g. `bind`ing in a
152    /// loop.
153    ///
154    /// Boxed queries are not cloneable.
155    /// If you need cloning, use [`into_boxed_clone`] to create a [`BoxedCloneSqlQuery`].
156    ///
157    /// [`into_boxed_clone`]: SqlQuery::into_boxed_clone()
158    pub fn into_boxed<'f, DB: Backend>(self) -> BoxedSqlQuery<'f, DB, Self> {
159        BoxedSqlQuery::new(self)
160    }
161
162    /// Internally wraps the query in an [`Arc`], which allows to  calls `bind` and `sql` so that
163    /// they don't change the type nor the instance. This allows to clone the query and call
164    /// `bind` or `sql` in a loop, e.g.:
165    ///
166    /// ```
167    /// # include!("../doctest_setup.rs");
168    /// #
169    /// # use schema::users;
170    /// #
171    /// # #[derive(QueryableByName, Debug, PartialEq)]
172    /// # struct User {
173    /// #     id: i32,
174    /// #     name: String,
175    /// # }
176    /// #
177    /// # // Reading the query result requires reading memory allocated by the
178    /// # // native sqlite library, which miri cannot track provenance for.
179    /// # #[cfg(miri)]
180    /// # fn main() {}
181    /// # #[cfg(not(miri))]
182    /// # fn main() {
183    /// #     use diesel::sql_query;
184    /// #     use diesel::sql_types::{Integer};
185    /// #
186    /// #     let connection = &mut establish_connection();
187    /// #     diesel::insert_into(users::table)
188    /// #         .values(users::name.eq("Jim"))
189    /// #         .execute(connection).unwrap();
190    /// let q = diesel::sql_query("SELECT * FROM users WHERE id IN(").into_boxed_clone();
191    /// let mut q = q.clone();
192    /// for (idx, user_id) in [3, 4, 5].into_iter().enumerate() {
193    ///     if idx != 0 {
194    ///         q = q.sql(", ");
195    ///     }
196    /// # #[cfg(feature = "postgres")]
197    /// # {
198    ///     q = q
199    ///         // postgresql bind syntax
200    ///         .sql(format!("${}", idx + 1))
201    ///         .bind::<Integer, _>(user_id);
202    /// # }
203    /// # #[cfg(not(feature = "postgres"))]
204    /// # {
205    /// #   q = q
206    /// #       .sql(format!("?"))
207    /// #       .bind::<Integer, _>(user_id);
208    /// # }
209    /// }
210    /// let users = q.sql(");").get_results(connection);
211    /// let expected_users = vec![User {
212    ///     id: 3,
213    ///     name: "Jim".into(),
214    /// }];
215    /// assert_eq!(Ok(expected_users), users);
216    /// # }
217    /// ```
218    ///
219    /// This allows doing things you otherwise couldn't do, e.g. `bind`ing in a
220    /// loop.
221    ///
222    /// In cases where the query does not need to be cloned, [`BoxedSqlQuery`] (created with
223    /// [`into_boxed`]) provides better performance.
224    ///
225    /// [`into_boxed`]: SqlQuery::into_boxed()
226    pub fn into_boxed_clone<'f, DB: Backend>(self) -> BoxedCloneSqlQuery<'f, DB, Self> {
227        BoxedCloneSqlQuery::new(self)
228    }
229
230    /// Appends a piece of SQL code at the end.
231    ///
232    /// # Safety
233    ///
234    /// Diesel passes the given string to the database as written. It must
235    /// therefore never contain values that come from outside your own code,
236    /// because anything interpolated into the SQL text can carry an SQL
237    /// injection. Pass such values with [`bind`] instead.
238    ///
239    /// [`bind`]: SqlQuery::bind()
240    pub fn sql<T: AsRef<str>>(mut self, sql: T) -> Self {
241        self.query += sql.as_ref();
242        self
243    }
244}
245
246impl SqlQuery {
247    pub(crate) fn from_sql(query: String) -> SqlQuery {
248        Self {
249            inner: self::private::Empty,
250            query,
251        }
252    }
253}
254
255impl<DB, Inner> QueryFragment<DB> for SqlQuery<Inner>
256where
257    DB: Backend + DieselReserveSpecialization,
258    Inner: QueryFragment<DB>,
259{
260    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
261        out.unsafe_to_cache_prepared();
262        self.inner.walk_ast(out.reborrow())?;
263        out.push_sql(&self.query);
264        Ok(())
265    }
266}
267
268impl<Inner> QueryId for SqlQuery<Inner> {
269    type QueryId = ();
270
271    const HAS_STATIC_QUERY_ID: bool = false;
272}
273
274impl<Inner> Query for SqlQuery<Inner> {
275    type SqlType = Untyped;
276}
277
278impl<Inner> RunQueryDslSupport for SqlQuery<Inner> {}
279
280#[derive(#[automatically_derived]impl<Query: ::core::fmt::Debug,
    Value: ::core::fmt::Debug, ST: ::core::fmt::Debug> ::core::fmt::Debug for
    UncheckedBind<Query, Value, ST> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "UncheckedBind query value _marker", &self.query, &self.value,
            &&self._marker)
    }
}Debug, #[automatically_derived]impl<Query: ::core::clone::Clone,
    Value: ::core::clone::Clone, ST: ::core::clone::Clone>
    ::core::clone::Clone for UncheckedBind<Query, Value, ST> {
    #[inline]
    fn clone(&self) -> Self {
        UncheckedBind {
            query: ::core::clone::Clone::clone(&self.query),
            value: ::core::clone::Clone::clone(&self.value),
            _marker: ::core::clone::Clone::clone(&self._marker),
        }
    }
}Clone, #[automatically_derived]impl<Query: ::core::marker::Copy,
    Value: ::core::marker::Copy, ST: ::core::marker::Copy>
    ::core::marker::Copy for UncheckedBind<Query, Value, ST> {
}Copy)]
281#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
282/// Returned by the [`SqlQuery::bind()`] method when binding a value to a fragment of SQL.
283pub struct UncheckedBind<Query, Value, ST> {
284    query: Query,
285    value: Value,
286    _marker: PhantomData<ST>,
287}
288
289impl<Query, Value, ST> UncheckedBind<Query, Value, ST> {
290    pub fn new(query: Query, value: Value) -> Self {
291        UncheckedBind {
292            query,
293            value,
294            _marker: PhantomData,
295        }
296    }
297
298    pub fn bind<ST2, Value2>(self, value: Value2) -> UncheckedBind<Self, Value2, ST2> {
299        UncheckedBind::new(self, value)
300    }
301
302    pub fn into_boxed<'f, DB: Backend>(self) -> BoxedSqlQuery<'f, DB, Self> {
303        BoxedSqlQuery::new(self)
304    }
305
306    pub fn into_boxed_clone<'f, DB: Backend>(self) -> BoxedCloneSqlQuery<'f, DB, Self> {
307        BoxedCloneSqlQuery::new(self)
308    }
309
310    /// Append raw SQL after this query and the values bound to it.
311    ///
312    /// The wrapped query renders first, then the given SQL text. This allows
313    /// interleaving raw SQL fragments with [`bind`] calls when the query
314    /// builder cannot express the statement as a whole.
315    ///
316    /// # Safety
317    ///
318    /// Diesel passes the given string to the database as written. It must
319    /// therefore never contain values that come from outside your own code,
320    /// because anything interpolated into the SQL text can carry an SQL
321    /// injection. Pass such values with [`bind`] instead.
322    ///
323    /// # Examples
324    ///
325    /// ```rust
326    /// # include!("../doctest_setup.rs");
327    /// #
328    /// # use schema::users;
329    /// #
330    /// # #[derive(QueryableByName, Debug, PartialEq)]
331    /// # struct User {
332    /// #     id: i32,
333    /// #     name: String,
334    /// # }
335    /// #
336    /// # // Reading the query result requires reading memory allocated by the
337    /// # // native sqlite library, which miri cannot track provenance for.
338    /// # #[cfg(miri)]
339    /// # fn main() {}
340    /// # #[cfg(not(miri))]
341    /// # fn main() {
342    /// #     use diesel::sql_query;
343    /// #     use diesel::sql_types::Integer;
344    /// #
345    /// #     let connection = &mut establish_connection();
346    /// # #[cfg(feature = "postgres")]
347    /// # let base = sql_query("SELECT id, name FROM users WHERE id >= $1");
348    /// # #[cfg(not(feature = "postgres"))]
349    /// // Checkout the documentation of your database for the correct
350    /// // bind placeholder
351    /// let base = sql_query("SELECT id, name FROM users WHERE id >= ?");
352    /// // The appended fragment decides the order of the returned rows.
353    /// let users = base
354    ///     .bind::<Integer, _>(1)
355    ///     .sql(" ORDER BY id DESC")
356    ///     .load::<User>(connection);
357    /// assert_eq!(
358    ///     Ok(vec![
359    ///         User {
360    ///             id: 2,
361    ///             name: "Tess".into()
362    ///         },
363    ///         User {
364    ///             id: 1,
365    ///             name: "Sean".into()
366    ///         }
367    ///     ]),
368    ///     users
369    /// );
370    /// # }
371    /// ```
372    ///
373    /// [`bind`]: Self::bind()
374    pub fn sql<T: Into<String>>(self, sql: T) -> SqlQuery<Self> {
375        SqlQuery::new(self, sql.into())
376    }
377}
378
379impl<Query, Value, ST> QueryId for UncheckedBind<Query, Value, ST>
380where
381    Query: QueryId,
382    ST: QueryId,
383{
384    type QueryId = UncheckedBind<Query::QueryId, (), ST::QueryId>;
385
386    const HAS_STATIC_QUERY_ID: bool = Query::HAS_STATIC_QUERY_ID && ST::HAS_STATIC_QUERY_ID;
387}
388
389impl<Query, Value, ST, DB> QueryFragment<DB> for UncheckedBind<Query, Value, ST>
390where
391    DB: Backend + HasSqlType<ST> + DieselReserveSpecialization,
392    Query: QueryFragment<DB>,
393    Value: ToSql<ST, DB>,
394{
395    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
396        self.query.walk_ast(out.reborrow())?;
397        out.push_bind_param_value_only(&self.value)?;
398        Ok(())
399    }
400}
401
402impl<Q, Value, ST> Query for UncheckedBind<Q, Value, ST> {
403    type SqlType = Untyped;
404}
405
406impl<Query, Value, ST> RunQueryDslSupport for UncheckedBind<Query, Value, ST> {}
407
408#[must_use = "Queries are only executed when calling `load`, `get_result`, or similar."]
409/// See [`SqlQuery::into_boxed`].
410///
411/// [`SqlQuery::into_boxed`]: SqlQuery::into_boxed()
412#[allow(missing_debug_implementations)]
413pub struct BoxedSqlQuery<'f, DB: Backend, Query> {
414    query: Query,
415    sql: String,
416    binds: Vec<Box<dyn QueryFragment<DB> + Send + 'f>>,
417}
418
419#[derive(#[automatically_derived]#[allow(missing_debug_implementations)]
impl<'f, DB: ::core::clone::Clone + Backend, Query: ::core::clone::Clone>
    ::core::clone::Clone for BoxedCloneSqlQuery<'f, DB, Query> {
    #[inline]
    fn clone(&self) -> Self {
        BoxedCloneSqlQuery {
            query: ::core::clone::Clone::clone(&self.query),
            sql: ::core::clone::Clone::clone(&self.sql),
            binds: ::core::clone::Clone::clone(&self.binds),
        }
    }
}Clone)]
420#[must_use = "Queries are only executed when calling `load`, `get_result`, or similar."]
421/// See [`SqlQuery::into_boxed_clone`].
422///
423/// [`SqlQuery::into_boxed_clone`]: SqlQuery::into_boxed_clone()
424#[allow(missing_debug_implementations)]
425pub struct BoxedCloneSqlQuery<'f, DB: Backend, Query> {
426    query: Query,
427    sql: String,
428    binds: Vec<Arc<dyn QueryFragment<DB> + Send + Sync + 'f>>,
429}
430
431struct RawBind<ST, U> {
432    value: U,
433    p: PhantomData<ST>,
434}
435
436impl<ST, U, DB> QueryFragment<DB> for RawBind<ST, U>
437where
438    DB: Backend + HasSqlType<ST>,
439    U: ToSql<ST, DB>,
440{
441    fn walk_ast<'b>(&'b self, mut pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
442        pass.push_bind_param_value_only(&self.value)
443    }
444}
445
446impl<'f, DB: Backend, Query> BoxedSqlQuery<'f, DB, Query> {
447    pub(crate) fn new(query: Query) -> Self {
448        BoxedSqlQuery {
449            query,
450            sql: "".to_string(),
451            binds: ::alloc::vec::Vec::new()alloc::vec![],
452        }
453    }
454
455    /// See [`SqlQuery::bind`].
456    ///
457    /// [`SqlQuery::bind`]: SqlQuery::bind()
458    pub fn bind<BindSt, Value>(mut self, b: Value) -> Self
459    where
460        DB: HasSqlType<BindSt>,
461        Value: ToSql<BindSt, DB> + Send + 'f,
462        BindSt: Send + 'f,
463    {
464        self.binds.push(Box::new(RawBind {
465            value: b,
466            p: PhantomData,
467        }) as Box<_>);
468        self
469    }
470
471    /// See [`SqlQuery::sql`].
472    ///
473    /// [`SqlQuery::sql`]: SqlQuery::sql()
474    pub fn sql<T: AsRef<str>>(mut self, sql: T) -> Self {
475        self.sql += sql.as_ref();
476        self
477    }
478}
479
480/// Walk a boxed SQL query, whichever pointer holds its binds.
481fn walk_boxed_sql_query<'b, DB, Query, P>(
482    query: &'b Query,
483    sql: &'b str,
484    binds: &'b [P],
485    mut out: AstPass<'_, 'b, DB>,
486) -> QueryResult<()>
487where
488    DB: Backend,
489    Query: QueryFragment<DB>,
490    P: QueryFragment<DB>,
491{
492    out.unsafe_to_cache_prepared();
493    query.walk_ast(out.reborrow())?;
494    out.push_sql(sql);
495
496    for b in binds {
497        b.walk_ast(out.reborrow())?;
498    }
499    Ok(())
500}
501
502impl<DB, Query> QueryFragment<DB> for BoxedSqlQuery<'_, DB, Query>
503where
504    DB: Backend + DieselReserveSpecialization,
505    Query: QueryFragment<DB>,
506{
507    fn walk_ast<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
508        walk_boxed_sql_query(&self.query, &self.sql, &self.binds, out)
509    }
510}
511
512impl<DB: Backend, Query> QueryId for BoxedSqlQuery<'_, DB, Query> {
513    type QueryId = ();
514
515    const HAS_STATIC_QUERY_ID: bool = false;
516}
517
518impl<DB, Q> Query for BoxedSqlQuery<'_, DB, Q>
519where
520    DB: Backend,
521{
522    type SqlType = Untyped;
523}
524
525impl<DB: Backend, Query> RunQueryDslSupport for BoxedSqlQuery<'_, DB, Query> {}
526
527impl<'f, DB: Backend, Query> BoxedCloneSqlQuery<'f, DB, Query> {
528    pub(crate) fn new(query: Query) -> Self {
529        BoxedCloneSqlQuery {
530            query,
531            sql: "".to_string(),
532            binds: ::alloc::vec::Vec::new()alloc::vec![],
533        }
534    }
535
536    /// See [`SqlQuery::bind`].
537    ///
538    /// [`SqlQuery::bind`]: SqlQuery::bind()
539    pub fn bind<BindSt, Value>(mut self, b: Value) -> Self
540    where
541        DB: HasSqlType<BindSt>,
542        Value: ToSql<BindSt, DB> + Send + Sync + 'f,
543        BindSt: Send + Sync + 'f,
544    {
545        self.binds.push(Arc::new(RawBind {
546            value: b,
547            p: PhantomData,
548        }) as Arc<_>);
549        self
550    }
551
552    /// See [`SqlQuery::sql`].
553    ///
554    /// [`SqlQuery::sql`]: SqlQuery::sql()
555    pub fn sql<T: AsRef<str>>(mut self, sql: T) -> Self {
556        self.sql += sql.as_ref();
557        self
558    }
559}
560
561impl<DB, Query> QueryFragment<DB> for BoxedCloneSqlQuery<'_, DB, Query>
562where
563    DB: Backend + DieselReserveSpecialization,
564    Query: QueryFragment<DB>,
565{
566    fn walk_ast<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
567        walk_boxed_sql_query(&self.query, &self.sql, &self.binds, out)
568    }
569}
570
571impl<DB: Backend, Query> QueryId for BoxedCloneSqlQuery<'_, DB, Query> {
572    type QueryId = ();
573
574    const HAS_STATIC_QUERY_ID: bool = false;
575}
576
577impl<DB, Q> Query for BoxedCloneSqlQuery<'_, DB, Q>
578where
579    DB: Backend,
580{
581    type SqlType = Untyped;
582}
583
584impl<DB: Backend, Query> RunQueryDslSupport for BoxedCloneSqlQuery<'_, DB, Query> {}
585
586mod private {
587    use crate::backend::{Backend, DieselReserveSpecialization};
588    use crate::query_builder::{QueryFragment, QueryId};
589
590    #[derive(#[automatically_derived]impl ::core::fmt::Debug for Empty {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "Empty")
    }
}Debug, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for Empty {
}
#[automatically_derived]impl ::core::clone::Clone for Empty {
    #[inline]
    fn clone(&self) -> Self { *self }
}Clone, #[automatically_derived]impl ::core::marker::Copy for Empty { }Copy, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl diesel::query_builder::QueryId for Empty {
            type QueryId = Empty<>;
            const HAS_STATIC_QUERY_ID: bool = true;
            const IS_WINDOW_FUNCTION: bool = false;
        }
    };QueryId)]
591    pub struct Empty;
592
593    impl<DB> QueryFragment<DB> for Empty
594    where
595        DB: Backend + DieselReserveSpecialization,
596    {
597        fn walk_ast<'b>(
598            &'b self,
599            _pass: crate::query_builder::AstPass<'_, 'b, DB>,
600        ) -> crate::QueryResult<()> {
601            Ok(())
602        }
603    }
604}
605
606#[cfg(test)]
607mod tests {
608    fn assert_send<S: Send>(_: S) {}
609
610    #[diesel_test_helper::test]
611    fn check_boxed_sql_query_is_send() {
612        let query = crate::sql_query("SELECT 1")
613            .into_boxed::<<crate::test_helpers::TestConnection as crate::Connection>::Backend>(
614        );
615
616        assert_send(query);
617    }
618}