1//! The `ReturningQuerySource<StmtKind, T>` wrapper used to type-check `RETURNING`
2//! clauses, the statement-kind markers it is parameterized over, and the
3//! [`InsertStmtKind`] dispatch trait.
4//!
5//! This module holds the items needed to type-check `RETURNING` clauses that are not specific
6//! to a particular backend.
78use crate::expression::nullable::Nullable;
9use crate::expression::{AppearsOnTable, BoxableExpression, Expression, SelectableExpression};
10use crate::query_source::{
11AppearsInFromClause, Never, Once, QueryRelation, QuerySource, TableNotEqual,
12};
13use alloc::boxed::Box;
14use core::marker::PhantomData;
1516/// Statement-kind marker
17#[derive(#[automatically_derived]
impl ::core::fmt::Debug for InsertStmtWithoutOnConflictDoUpdate {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
"InsertStmtWithoutOnConflictDoUpdate")
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for InsertStmtWithoutOnConflictDoUpdate { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for
InsertStmtWithoutOnConflictDoUpdate {
}
#[automatically_derived]
impl ::core::clone::Clone for InsertStmtWithoutOnConflictDoUpdate {
#[inline]
fn clone(&self) -> Self { *self }
}Clone)]
18pub struct InsertStmtWithoutOnConflictDoUpdate;
1920/// Statement-kind marker
21#[derive(#[automatically_derived]
impl ::core::fmt::Debug for UpdateStmt {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "UpdateStmt")
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for UpdateStmt { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for UpdateStmt { }
#[automatically_derived]
impl ::core::clone::Clone for UpdateStmt {
#[inline]
fn clone(&self) -> Self { *self }
}Clone)]
22pub struct UpdateStmt;
2324/// Statement-kind marker
25#[derive(#[automatically_derived]
impl ::core::fmt::Debug for DeleteStmt {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "DeleteStmt")
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for DeleteStmt { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for DeleteStmt { }
#[automatically_derived]
impl ::core::clone::Clone for DeleteStmt {
#[inline]
fn clone(&self) -> Self { *self }
}Clone)]
26pub struct DeleteStmt;
2728/// Statement-kind marker
29#[derive(#[automatically_derived]
impl ::core::fmt::Debug for InsertStmtWithOnConflictDoUpdate {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
"InsertStmtWithOnConflictDoUpdate")
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for InsertStmtWithOnConflictDoUpdate { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for InsertStmtWithOnConflictDoUpdate {
}
#[automatically_derived]
impl ::core::clone::Clone for InsertStmtWithOnConflictDoUpdate {
#[inline]
fn clone(&self) -> Self { *self }
}Clone)]
30pub struct InsertStmtWithOnConflictDoUpdate;
3132/// Synthetic query source used as the `QS` parameter of
33/// [`SelectableExpression`](crate::expression::SelectableExpression) /
34/// [`AppearsOnTable`](crate::expression::AppearsOnTable) when type-checking
35/// `RETURNING` clauses.
36///
37/// `StmtKind` is one of the marker structs above; `T` is the table that the
38/// `INSERT`/`UPDATE`/`DELETE` is acting on.
39#[derive(#[automatically_derived]
impl<StmtKind: ::core::fmt::Debug, T: ::core::fmt::Debug> ::core::fmt::Debug
for ReturningQuerySource<StmtKind, T> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ReturningQuerySource", &&self.0)
}
}Debug, #[automatically_derived]
impl<StmtKind: ::core::clone::Clone, T: ::core::clone::Clone>
::core::clone::Clone for ReturningQuerySource<StmtKind, T> {
#[inline]
fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&self.0)) }
}Clone, #[automatically_derived]
impl<StmtKind: ::core::marker::Copy, T: ::core::marker::Copy>
::core::marker::Copy for ReturningQuerySource<StmtKind, T> {
}Copy)]
40pub struct ReturningQuerySource<StmtKind, T>(PhantomData<(StmtKind, T)>);
4142impl<StmtKind, T> QuerySourcefor ReturningQuerySource<StmtKind, T>
43where
44T: QuerySource + Default,
45 T::DefaultSelection: SelectableExpression<Self>,
46{
47type FromClause = T::FromClause;
48type DefaultSelection = T::DefaultSelection;
4950fn from_clause(&self) -> Self::FromClause {
51 T::default().from_clause()
52 }
5354fn default_selection(&self) -> Self::DefaultSelection {
55 T::default().default_selection()
56 }
57}
5859impl<StmtKind, T1, T2> AppearsInFromClause<T1> for ReturningQuerySource<StmtKind, T2>
60where
61T1: TableNotEqual<T2> + QueryRelation,
62 T2: QueryRelation,
63{
64type Count = Never;
65}
6667/// Maps an `InsertStatement` `Values` shape to the statement-kind marker that
68/// should be used when type-checking that statement's `RETURNING` clause.
69///
70/// This is what makes `RETURNING old(col)` accept `INSERT ... ON CONFLICT
71/// ... DO UPDATE` (where the marker is [`InsertStmtWithOnConflictDoUpdate`], for
72/// which `Nullable<Old<C>>` is a valid `RETURNING` element) but reject plain
73/// `INSERT` (where the marker is [`InsertStmtWithoutOnConflictDoUpdate`], for which `Old<C>` does not
74/// implement `SelectableExpression`).
75///
76/// The trait is sealed in spirit — it only has impls for the values shapes
77/// `diesel` itself produces — but it is exposed publicly under the
78/// `i-implement-a-third-party-backend-and-opt-into-breaking-changes` feature
79/// so third-party backends that introduce new values shapes can add their own
80/// impls.
81pub trait InsertStmtKind {
82/// The statement-kind marker (see e.g. [`InsertStmtWithoutOnConflictDoUpdate`],
83 /// [`InsertStmtWithOnConflictDoUpdate`]) used as the `StmtKind` parameter of
84 /// [`ReturningQuerySource`] for `INSERT` statements with this `Values`
85 /// shape.
86type StmtKind;
87}
8889impl<T, Tab> InsertStmtKindfor crate::query_builder::ValuesClause<T, Tab> {
90type StmtKind = InsertStmtWithoutOnConflictDoUpdate;
91}
9293impl<V, Tab, QId, const STABLE_QUERY_ID: bool> InsertStmtKind94for crate::query_builder::BatchInsert<V, Tab, QId, STABLE_QUERY_ID>
95{
96type StmtKind = InsertStmtWithoutOnConflictDoUpdate;
97}
9899impl InsertStmtKindfor crate::query_builder::insert_statement::DefaultValues {
100type StmtKind = InsertStmtWithoutOnConflictDoUpdate;
101}
102103impl<S, C> InsertStmtKindfor crate::query_builder::insert_statement::InsertFromSelect<S, C> {
104type StmtKind = InsertStmtWithoutOnConflictDoUpdate;
105}
106107impl<V, Target, T, WhereClause> InsertStmtKind108for crate::query_builder::upsert::on_conflict_clause::OnConflictValues<
109 V,
110 Target,
111crate::query_builder::upsert::on_conflict_actions::DoNothing<T>,
112 WhereClause,
113 >
114{
115// ON CONFLICT DO NOTHING does not return the lines that conflicted if using RETURNING
116 // so it's unnecessary (and would even be misleading) to allow RETURNING old.xxx
117 // in this case.
118type StmtKind = InsertStmtWithoutOnConflictDoUpdate;
119}
120121impl<V, Target, Changeset, Tab, WhereClause> InsertStmtKind122for crate::query_builder::upsert::on_conflict_clause::OnConflictValues<
123 V,
124 Target,
125crate::query_builder::upsert::on_conflict_actions::DoUpdate<Changeset, Tab>,
126 WhereClause,
127 >
128{
129type StmtKind = InsertStmtWithOnConflictDoUpdate;
130}
131132/// Make `Box<dyn BoxableExpression<table>>` be `SelectableExpression` in returning clauses.
133/// This is necessary for backwards-compatibility.
134///
135/// Unfortunately we cannot implement this directly for `dyn BoxableExpression`
136/// (and rely on our existing generic impls for `Box<T>`) because the compiler
137/// complains that there is already an automatic implementation of `SelectableExpression` for
138/// `dyn BoxableExpression`, even though the `QS` type is different.
139/// As a workaround, we implement it for `Box<dyn BoxableExpression<table>>`, which should
140/// cover for most users.
141impl<'a, QS, ST, DB, GB, IsAggregate, StmtKind>
142SelectableExpression<ReturningQuerySource<StmtKind, QS>>
143for Box<dyn BoxableExpression<QS, DB, GB, IsAggregate, SqlType = ST> + 'a>
144where
145Box<dyn BoxableExpression<QS, DB, GB, IsAggregate, SqlType = ST> + 'a>: Expression,
146{
147}
148/// See comment on `SelectableExpression` impl above.
149impl<'a, QS, ST, DB, GB, IsAggregate, StmtKind> AppearsOnTable<ReturningQuerySource<StmtKind, QS>>
150for Box<dyn BoxableExpression<QS, DB, GB, IsAggregate, SqlType = ST> + 'a>
151where
152Box<dyn BoxableExpression<QS, DB, GB, IsAggregate, SqlType = ST> + 'a>: Expression,
153{
154}
155156impl<StmtKind, E, T> SelectableExpression<ReturningQuerySource<StmtKind, T>> for Nullable<E>
157where
158Self: AppearsOnTable<ReturningQuerySource<StmtKind, T>>,
159 E: SelectableExpression<ReturningQuerySource<StmtKind, T>>,
160{
161}
162163impl<StmtKind, E, T> SelectableExpression<ReturningQuerySource<StmtKind, T>>
164for crate::expression::assume_not_null::AssumeNotNull<E>
165where
166Self: AppearsOnTable<ReturningQuerySource<StmtKind, T>>,
167 E: SelectableExpression<ReturningQuerySource<StmtKind, T>>,
168{
169}
170171/// Represents the identifier `old` or `old_value` in the `RETURNING` clause.
172/// It is independent of the table of the column, and used as QS in marker in AppearsInFromClause.
173///
174/// We use this to typecheck that there is only one `old` or `old_value` identifier when we use `old` or `old_value`, so that
175/// there is no ambiguity, and also as a generic
176/// "any valid OLD statement-kind marker for ReturningQuerySource".
177#[derive(#[automatically_derived]
impl ::core::fmt::Debug for OldIdent {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "OldIdent")
}
}Debug, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for OldIdent { }
#[automatically_derived]
impl ::core::clone::Clone for OldIdent {
#[inline]
fn clone(&self) -> Self { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for OldIdent { }Copy)]
178pub struct OldIdent;
179180/// There is an `old.` or `old_value()` in ReturningQuerySource<UpdateStmt, T>
181///
182/// Useful to check non-ambiguity of `old` or `old_value`
183impl<StmtKind, T> AppearsInFromClause<OldIdent> for ReturningQuerySource<StmtKind, T> {
184type Count = Once;
185}
186/// There isn't one directly on tables
187/// (this is useful for typechecking `old` or `old_value` in subqueries in returning)
188impl<T> AppearsInFromClause<OldIdent> for T
189where
190T: QueryRelation,
191{
192type Count = Never;
193}
194/// There is an `old.` or `old_value` for T in ReturningQuerySource<UpdateStmt, T>
195impl<T> AppearsInFromClause<ReturningQuerySource<OldIdent, T>>
196for ReturningQuerySource<UpdateStmt, T>
197{
198type Count = Once;
199}
200/// There is an `old.` or `old_value` for T in ReturningQuerySource<InsertStmtWithOnConflictDoUpdate, T>
201impl<T> AppearsInFromClause<ReturningQuerySource<OldIdent, T>>
202for ReturningQuerySource<InsertStmtWithOnConflictDoUpdate, T>
203{
204type Count = Once;
205}