Skip to main content

diesel/query_builder/returning/
returning_clause.rs

1use crate::QuerySource;
2use crate::backend::{Backend, DieselReserveSpecialization};
3use crate::query_builder::{
4    AstPass, DeleteStatement, InsertStatement, QueryFragment, QueryId, UpdateStatement,
5};
6use crate::result::QueryResult;
7
8/// Marker type for `INSERT`/`UPDATE`/`DELETE` ASTs that do not have a
9/// `RETURNING` clause attached yet.
10///
11/// This is the default `Ret` parameter of [`InsertStatement`],
12/// [`UpdateStatement`] and [`DeleteStatement`]. Calling `.returning(...)` on
13/// such a statement swaps it out for a [`ReturningClause`].
14#[derive(#[automatically_derived]
impl ::core::fmt::Debug for NoReturningClause {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "NoReturningClause")
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for NoReturningClause {
    #[inline]
    fn clone(&self) -> NoReturningClause { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for NoReturningClause { }Copy, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl diesel::query_builder::QueryId for NoReturningClause {
            type QueryId = NoReturningClause<>;
            const HAS_STATIC_QUERY_ID: bool = true;
            const IS_WINDOW_FUNCTION: bool = false;
        }
    };QueryId)]
15pub struct NoReturningClause;
16
17impl<DB> QueryFragment<DB> for NoReturningClause
18where
19    DB: Backend + DieselReserveSpecialization,
20{
21    fn walk_ast<'b>(&'b self, _: AstPass<'_, 'b, DB>) -> QueryResult<()> {
22        Ok(())
23    }
24}
25
26/// This type represents a SQL `Returning` clause
27///
28/// Custom backends can specialize the [`QueryFragment`]
29/// implementation via
30/// [`SqlDialect::ReturningClause`](crate::backend::SqlDialect::ReturningClause)
31#[cfg_attr(
32    feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
33    cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")
34)]
35#[derive(#[automatically_derived]
impl<Expr: ::core::fmt::Debug> ::core::fmt::Debug for ReturningClause<Expr> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f,
            "ReturningClause", &&self.0)
    }
}Debug, #[automatically_derived]
impl<Expr: ::core::clone::Clone> ::core::clone::Clone for
    ReturningClause<Expr> {
    #[inline]
    fn clone(&self) -> ReturningClause<Expr> {
        ReturningClause(::core::clone::Clone::clone(&self.0))
    }
}Clone, #[automatically_derived]
impl<Expr: ::core::marker::Copy> ::core::marker::Copy for
    ReturningClause<Expr> {
}Copy, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl<Expr: diesel::query_builder::QueryId>
            diesel::query_builder::QueryId for ReturningClause<Expr> {
            type QueryId =
                ReturningClause<<Expr as
                diesel::query_builder::QueryId>::QueryId>;
            const HAS_STATIC_QUERY_ID: bool =
                <Expr as diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID
                    && true;
            const IS_WINDOW_FUNCTION: bool =
                <Expr as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION
                    || false;
        }
    };QueryId)]
36pub struct ReturningClause<Expr>(pub Expr);
37
38impl<Expr, DB> QueryFragment<DB> for ReturningClause<Expr>
39where
40    DB: Backend,
41    Self: QueryFragment<DB, DB::ReturningClause>,
42{
43    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
44        <Self as QueryFragment<DB, DB::ReturningClause>>::walk_ast(self, pass)
45    }
46}
47
48impl<Expr, DB>
49    QueryFragment<DB, crate::backend::sql_dialect::returning_clause::PgLikeReturningClause>
50    for ReturningClause<Expr>
51where
52    DB: Backend<
53        ReturningClause = crate::backend::sql_dialect::returning_clause::PgLikeReturningClause,
54    >,
55    Expr: QueryFragment<DB>,
56{
57    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
58        out.push_sql(" RETURNING ");
59        self.0.walk_ast(out.reborrow())?;
60        Ok(())
61    }
62}
63
64/// Helper trait that maps an `INSERT`/`UPDATE`/`DELETE` statement type to
65/// the same statement type with an explicit [`ReturningClause<S>`] attached.
66///
67/// This is used to spell the return type of `.returning(...)` in the `dsl`
68/// module without naming each individual statement type.
69pub trait ReturningClauseHelper<S> {
70    /// `Self` with a `RETURNING S` clause attached.
71    type WithReturning;
72}
73
74impl<S, T, U, Op> ReturningClauseHelper<S> for InsertStatement<T, U, Op>
75where
76    T: QuerySource,
77{
78    type WithReturning = InsertStatement<T, U, Op, ReturningClause<S>>;
79}
80
81impl<S, T, U, V> ReturningClauseHelper<S> for UpdateStatement<T, U, V>
82where
83    T: QuerySource,
84{
85    type WithReturning = UpdateStatement<T, U, V, ReturningClause<S>>;
86}
87
88impl<S, T, U> ReturningClauseHelper<S> for DeleteStatement<T, U>
89where
90    T: QuerySource,
91{
92    type WithReturning = DeleteStatement<T, U, ReturningClause<S>>;
93}