Skip to main content

diesel/
insertable.rs

1use crate::backend::{Backend, DieselReserveSpecialization, SqlDialect, sql_dialect};
2use crate::expression::grouped::Grouped;
3use crate::expression::{AppearsOnTable, Expression};
4use crate::query_builder::{
5    AstPass, BatchInsert, InsertStatement, NoFromClause, QueryFragment, QueryId,
6    UndecoratedInsertRecord, ValuesClause,
7};
8use crate::query_source::{Column, Table};
9use crate::result::QueryResult;
10use alloc::boxed::Box;
11use alloc::vec::Vec;
12use core::marker::PhantomData;
13
14/// Represents that a structure can be used to insert a new row into the
15/// database. This is automatically implemented for `&[T]` and `&Vec<T>` for
16/// inserting more than one record.
17///
18/// This trait can be [derived](derive@Insertable)
19pub trait Insertable<T> {
20    /// The `VALUES` clause to insert these records
21    ///
22    /// The types used here are generally internal to Diesel.
23    /// Implementations of this trait should use the `Values`
24    /// type of other `Insertable` types.
25    /// For example `<diesel::dsl::Eq<column, &str> as Insertable<table>>::Values`.
26    type Values;
27
28    /// Construct `Self::Values`
29    ///
30    /// Implementations of this trait typically call `.values`
31    /// on other `Insertable` types.
32    fn values(self) -> Self::Values;
33
34    /// Insert `self` into a given table.
35    ///
36    /// `foo.insert_into(table)` is identical to `insert_into(table).values(foo)`.
37    /// However, when inserting from a select statement,
38    /// this form is generally preferred.
39    ///
40    /// # Example
41    ///
42    /// ```rust
43    /// # include!("doctest_setup.rs");
44    /// #
45    /// # // Reading the query result requires reading memory allocated by the
46    /// # // native sqlite library, which miri cannot track provenance for.
47    /// # #[cfg(miri)]
48    /// # fn main() {}
49    /// # #[cfg(not(miri))]
50    /// # fn main() {
51    /// #     run_test().unwrap();
52    /// # }
53    /// #
54    /// # fn run_test() -> QueryResult<()> {
55    /// #     use schema::{posts, users};
56    /// #     let conn = &mut establish_connection();
57    /// #     diesel::delete(posts::table).execute(conn)?;
58    /// users::table
59    ///     .select((users::name.concat("'s First Post"), users::id))
60    ///     .insert_into(posts::table)
61    ///     .into_columns((posts::title, posts::user_id))
62    ///     .execute(conn)?;
63    ///
64    /// let inserted_posts = posts::table.select(posts::title).load::<String>(conn)?;
65    /// let expected = vec!["Sean's First Post", "Tess's First Post"];
66    /// assert_eq!(expected, inserted_posts);
67    /// #     Ok(())
68    /// # }
69    /// ```
70    fn insert_into(self, table: T) -> InsertStatement<T, Self::Values>
71    where
72        T: Table,
73        Self: Sized,
74    {
75        crate::insert_into(table).values(self)
76    }
77}
78
79#[doc(inline)]
80pub use diesel_derives::Insertable;
81
82pub trait CanInsertInSingleQuery<DB: Backend> {
83    /// How many rows will this query insert?
84    ///
85    /// This function should only return `None` when the query is valid on all
86    /// backends, regardless of how many rows get inserted.
87    fn rows_to_insert(&self) -> Option<usize>;
88}
89
90impl<T, DB> CanInsertInSingleQuery<DB> for &T
91where
92    T: ?Sized + CanInsertInSingleQuery<DB>,
93    DB: Backend,
94{
95    fn rows_to_insert(&self) -> Option<usize> {
96        (*self).rows_to_insert()
97    }
98}
99
100impl<T, U, DB> CanInsertInSingleQuery<DB> for ColumnInsertValue<T, U>
101where
102    DB: Backend,
103{
104    fn rows_to_insert(&self) -> Option<usize> {
105        Some(1)
106    }
107}
108
109impl<V, DB> CanInsertInSingleQuery<DB> for DefaultableColumnInsertValue<V>
110where
111    DB: Backend,
112    V: CanInsertInSingleQuery<DB>,
113{
114    fn rows_to_insert(&self) -> Option<usize> {
115        Some(1)
116    }
117}
118
119pub trait InsertValues<DB: Backend, T: Table>: QueryFragment<DB> {
120    fn column_names(&self, out: AstPass<'_, '_, DB>) -> QueryResult<()>;
121}
122
123#[derive(#[automatically_derived]impl<Col: ::core::fmt::Debug,
    Expr: ::core::fmt::Debug> ::core::fmt::Debug for
    ColumnInsertValue<Col, Expr> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "ColumnInsertValue expr p", &self.expr, &&self.p)
    }
}Debug, #[automatically_derived]impl<Col: ::core::marker::Copy,
    Expr: ::core::marker::Copy> ::core::marker::Copy for
    ColumnInsertValue<Col, Expr> {
}Copy, #[automatically_derived]impl<Col: ::core::clone::Clone,
    Expr: ::core::clone::Clone> ::core::clone::Clone for
    ColumnInsertValue<Col, Expr> {
    #[inline]
    fn clone(&self) -> Self {
        ColumnInsertValue {
            expr: ::core::clone::Clone::clone(&self.expr),
            p: ::core::clone::Clone::clone(&self.p),
        }
    }
}Clone, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl<Col: diesel::query_builder::QueryId,
            Expr: diesel::query_builder::QueryId>
            diesel::query_builder::QueryId for ColumnInsertValue<Col, Expr> {
            type QueryId =
                ColumnInsertValue<<Col as
                diesel::query_builder::QueryId>::QueryId,
                <Expr as diesel::query_builder::QueryId>::QueryId>;
            const HAS_STATIC_QUERY_ID: bool =
                <Col as diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID
                        &&
                        <Expr as
                            diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
                    true;
            const IS_WINDOW_FUNCTION: bool =
                <Col as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
                        <Expr as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION
                    || false;
        }
    };QueryId)]
124#[doc(hidden)]
125pub struct ColumnInsertValue<Col, Expr> {
126    pub(crate) expr: Expr,
127    p: PhantomData<Col>,
128}
129
130impl<Col, Expr> ColumnInsertValue<Col, Expr> {
131    pub(crate) fn new(expr: Expr) -> Self {
132        Self {
133            expr,
134            p: PhantomData,
135        }
136    }
137}
138
139#[derive(#[automatically_derived]impl<T: ::core::fmt::Debug> ::core::fmt::Debug for
    DefaultableColumnInsertValue<T> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::Expression(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Expression", &__self_0),
            Self::Default => ::core::fmt::Formatter::write_str(f, "Default"),
        }
    }
}Debug, #[automatically_derived]impl<T> ::core::default::Default for
    DefaultableColumnInsertValue<T> {
    #[inline]
    fn default() -> Self { Self::Default }
}Default, #[automatically_derived]impl<T: ::core::marker::Copy> ::core::marker::Copy for
    DefaultableColumnInsertValue<T> {
}Copy, #[automatically_derived]impl<T: ::core::clone::Clone> ::core::clone::Clone for
    DefaultableColumnInsertValue<T> {
    #[inline]
    fn clone(&self) -> Self {
        match self {
            Self::Expression(__self_0) =>
                DefaultableColumnInsertValue::Expression(::core::clone::Clone::clone(__self_0)),
            Self::Default => DefaultableColumnInsertValue::Default,
        }
    }
}Clone)]
140#[doc(hidden)]
141pub enum DefaultableColumnInsertValue<T> {
142    Expression(T),
143    #[default]
144    Default,
145}
146
147impl<T> QueryId for DefaultableColumnInsertValue<T> {
148    type QueryId = ();
149    const HAS_STATIC_QUERY_ID: bool = false;
150}
151
152impl<Col, Expr, DB> InsertValues<DB, Col::Table>
153    for DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>
154where
155    DB: Backend + SqlDialect<InsertWithDefaultKeyword = sql_dialect::default_keyword_for_insert::IsoSqlDefaultKeyword>,
156    Col: Column,
157    Expr: Expression<SqlType = Col::SqlType> + AppearsOnTable<NoFromClause>,
158    Self: QueryFragment<DB>,
159{
160    fn column_names(&self, mut out: AstPass<'_, '_, DB>) -> QueryResult<()> {
161        out.push_identifier(Col::NAME)?;
162        Ok(())
163    }
164}
165
166impl<Col, Expr, DB> InsertValues<DB, Col::Table> for ColumnInsertValue<Col, Expr>
167where
168    DB: Backend,
169    Col: Column,
170    Expr: Expression<SqlType = Col::SqlType> + AppearsOnTable<NoFromClause>,
171    Self: QueryFragment<DB>,
172{
173    fn column_names(&self, mut out: AstPass<'_, '_, DB>) -> QueryResult<()> {
174        out.push_identifier(Col::NAME)?;
175        Ok(())
176    }
177}
178
179impl<Expr, DB> QueryFragment<DB> for DefaultableColumnInsertValue<Expr>
180where
181    DB: Backend,
182    Self: QueryFragment<DB, DB::InsertWithDefaultKeyword>,
183{
184    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
185        <Self as QueryFragment<DB, DB::InsertWithDefaultKeyword>>::walk_ast(self, pass)
186    }
187}
188
189impl<Expr, DB> QueryFragment<DB, sql_dialect::default_keyword_for_insert::IsoSqlDefaultKeyword> for DefaultableColumnInsertValue<Expr>
190where
191    DB: Backend + SqlDialect<InsertWithDefaultKeyword = sql_dialect::default_keyword_for_insert::IsoSqlDefaultKeyword>,
192    Expr: QueryFragment<DB>,
193{
194    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
195        out.unsafe_to_cache_prepared();
196        if let Self::Expression(ref inner) = *self {
197            inner.walk_ast(out.reborrow())?;
198        } else {
199            out.push_sql("DEFAULT");
200        }
201        Ok(())
202    }
203}
204
205impl<Col, Expr, DB> QueryFragment<DB> for ColumnInsertValue<Col, Expr>
206where
207    DB: Backend + DieselReserveSpecialization,
208    Expr: QueryFragment<DB>,
209{
210    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
211        self.expr.walk_ast(pass)
212    }
213}
214
215#[cfg(feature = "__sqlite-shared")]
216impl<Col, Expr> InsertValues<crate::sqlite::Sqlite, Col::Table>
217    for DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>
218where
219    Col: Column,
220    Expr: Expression<SqlType = Col::SqlType> + AppearsOnTable<NoFromClause>,
221    Self: QueryFragment<crate::sqlite::Sqlite>,
222{
223    fn column_names(&self, mut out: AstPass<'_, '_, crate::sqlite::Sqlite>) -> QueryResult<()> {
224        if let Self::Expression(..) = *self {
225            out.push_identifier(Col::NAME)?;
226        }
227        Ok(())
228    }
229}
230
231#[cfg(feature = "__sqlite-shared")]
232impl<Col, Expr>
233    QueryFragment<
234        crate::sqlite::Sqlite,
235        crate::backend::sql_dialect::default_keyword_for_insert::DoesNotSupportDefaultKeyword,
236    > for DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>
237where
238    Expr: QueryFragment<crate::sqlite::Sqlite>,
239{
240    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, crate::sqlite::Sqlite>) -> QueryResult<()> {
241        if let Self::Expression(ref inner) = *self {
242            inner.walk_ast(out.reborrow())?;
243        }
244        Ok(())
245    }
246}
247
248impl<'a, T, Tab> Insertable<Tab> for &'a [T]
249where
250    &'a T: UndecoratedInsertRecord<Tab> + Insertable<Tab>,
251{
252    type Values = BatchInsert<Vec<<&'a T as Insertable<Tab>>::Values>, Tab, (), false>;
253
254    fn values(self) -> Self::Values {
255        let values = self.iter().map(Insertable::values).collect::<Vec<_>>();
256        BatchInsert::new(values)
257    }
258}
259
260impl<'a, T, Tab> Insertable<Tab> for &'a Vec<T>
261where
262    &'a [T]: Insertable<Tab>,
263{
264    type Values = <&'a [T] as Insertable<Tab>>::Values;
265
266    fn values(self) -> Self::Values {
267        (&**self).values()
268    }
269}
270
271impl<T, Tab> Insertable<Tab> for Vec<T>
272where
273    T: Insertable<Tab> + UndecoratedInsertRecord<Tab>,
274{
275    type Values = BatchInsert<Vec<T::Values>, Tab, (), false>;
276
277    fn values(self) -> Self::Values {
278        let values = self.into_iter().map(Insertable::values).collect::<Vec<_>>();
279        BatchInsert::new(values)
280    }
281}
282
283impl<T, Tab, const N: usize> Insertable<Tab> for [T; N]
284where
285    T: Insertable<Tab>,
286{
287    type Values = BatchInsert<Vec<T::Values>, Tab, [T::Values; N], true>;
288
289    fn values(self) -> Self::Values {
290        let values = self.into_iter().map(Insertable::values).collect::<Vec<_>>();
291        BatchInsert::new(values)
292    }
293}
294
295impl<'a, T, Tab, const N: usize> Insertable<Tab> for &'a [T; N]
296where
297    T: Insertable<Tab>,
298    &'a T: Insertable<Tab>,
299{
300    // We can reuse the query id for [T; N] here as this
301    // compiles down to the same query
302    type Values = BatchInsert<Vec<<&'a T as Insertable<Tab>>::Values>, Tab, [T::Values; N], true>;
303
304    fn values(self) -> Self::Values {
305        let values = self.iter().map(Insertable::values).collect();
306        BatchInsert::new(values)
307    }
308}
309
310impl<T, Tab, const N: usize> Insertable<Tab> for Box<[T; N]>
311where
312    T: Insertable<Tab>,
313{
314    // We can reuse the query id for [T; N] here as this
315    // compiles down to the same query
316    type Values = BatchInsert<Vec<T::Values>, Tab, [T::Values; N], true>;
317
318    fn values(self) -> Self::Values {
319        let v = Vec::from(self as Box<[T]>);
320        let values = v.into_iter().map(Insertable::values).collect::<Vec<_>>();
321        BatchInsert::new(values)
322    }
323}
324
325impl<T, Tab, const N: usize> Insertable<Tab> for alloc::rc::Rc<[T; N]>
326where
327    T: Insertable<Tab> + core::clone::Clone,
328{
329    // We can reuse the query id for [T; N] here as this compiles down to the
330    // same query. `T: Clone` is required because shared ownership of `Rc`
331    // prevents moving the array elements out; we clone via `<[T]>::to_vec()`.
332    // The `Box<[T; N]>` impl above does not need this bound because it owns
333    // the array exclusively and can move elements out via `Vec::from`.
334    type Values = BatchInsert<Vec<T::Values>, Tab, [T::Values; N], true>;
335
336    fn values(self) -> Self::Values {
337        let v = self.to_vec();
338        let values = v.into_iter().map(Insertable::values).collect::<Vec<_>>();
339        BatchInsert::new(values)
340    }
341}
342
343impl<T, Tab, const N: usize> Insertable<Tab> for alloc::sync::Arc<[T; N]>
344where
345    T: Insertable<Tab> + core::clone::Clone,
346{
347    // See the `Rc<[T; N]>` impl above for the `T: Clone` rationale.
348    type Values = BatchInsert<Vec<T::Values>, Tab, [T::Values; N], true>;
349
350    fn values(self) -> Self::Values {
351        let v = self.to_vec();
352        let values = v.into_iter().map(Insertable::values).collect::<Vec<_>>();
353        BatchInsert::new(values)
354    }
355}
356
357mod private {
358    // This helper exists to differentiate between
359    // Insertable implementations for tuples and for single values
360    #[allow(missing_debug_implementations)]
361    pub struct InsertableOptionHelper<T, V>(
362        pub(crate) Option<T>,
363        pub(crate) core::marker::PhantomData<V>,
364    );
365}
366
367pub(crate) use self::private::InsertableOptionHelper;
368
369impl<T, Tab, V> Insertable<Tab> for Option<T>
370where
371    T: Insertable<Tab, Values = ValuesClause<V, Tab>>,
372    InsertableOptionHelper<T, V>: Insertable<Tab>,
373{
374    type Values = <InsertableOptionHelper<T, V> as Insertable<Tab>>::Values;
375
376    fn values(self) -> Self::Values {
377        InsertableOptionHelper(self, PhantomData).values()
378    }
379}
380
381impl<T, Tab, Expr, Col> Insertable<Tab> for InsertableOptionHelper<T, ColumnInsertValue<Col, Expr>>
382where
383    T: Insertable<Tab, Values = ValuesClause<ColumnInsertValue<Col, Expr>, Tab>>,
384{
385    type Values = ValuesClause<DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>, Tab>;
386
387    fn values(self) -> Self::Values {
388        ValuesClause::new(
389            self.0
390                .map(|v| DefaultableColumnInsertValue::Expression(Insertable::values(v).values))
391                .unwrap_or_default(),
392        )
393    }
394}
395
396impl<'a, T, Tab> Insertable<Tab> for &'a Option<T>
397where
398    Option<&'a T>: Insertable<Tab>,
399{
400    type Values = <Option<&'a T> as Insertable<Tab>>::Values;
401
402    fn values(self) -> Self::Values {
403        self.as_ref().values()
404    }
405}
406
407impl<L, R, Tab> Insertable<Tab> for Grouped<crate::expression::operators::Eq<L, R>>
408where
409    crate::expression::operators::Eq<L, R>: Insertable<Tab>,
410{
411    type Values = <crate::expression::operators::Eq<L, R> as Insertable<Tab>>::Values;
412
413    fn values(self) -> Self::Values {
414        self.0.values()
415    }
416}
417
418impl<'a, L, R, Tab> Insertable<Tab> for &'a Grouped<crate::expression::operators::Eq<L, R>>
419where
420    &'a crate::expression::operators::Eq<L, R>: Insertable<Tab>,
421{
422    type Values = <&'a crate::expression::operators::Eq<L, R> as Insertable<Tab>>::Values;
423
424    fn values(self) -> Self::Values {
425        self.0.values()
426    }
427}