Skip to main content

diesel/query_builder/insert_statement/
mod.rs

1pub(crate) mod batch_insert;
2mod column_list;
3mod insert_from_select;
4
5pub(crate) use self::batch_insert::BatchInsert;
6pub(crate) use self::column_list::ColumnList;
7pub(crate) use self::insert_from_select::InsertFromSelect;
8pub(crate) use self::private::Insert;
9pub use self::private::{InsertOrIgnore, Replace};#[diesel_derives::__diesel_public_if(
10    feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
11)]
12pub(crate) use self::private::{InsertOrIgnore, Replace};
13
14use super::returning_clause::*;
15use crate::backend::{DieselReserveSpecialization, SqlDialect, sql_dialect};
16use crate::expression::grouped::Grouped;
17use crate::expression::operators::Eq;
18use crate::expression::{Expression, NonAggregate, SelectableExpression};
19use crate::query_builder::*;
20use crate::query_dsl::RunQueryDsl;
21use crate::query_source::{Column, Table};
22use crate::{QuerySource, insertable::*};
23use core::marker::PhantomData;
24
25pub(crate) use self::private::InsertAutoTypeHelper;
26
27#[cfg(feature = "__sqlite-shared")]
28mod insert_with_default_for_sqlite;
29
30/// The structure returned by [`insert_into`].
31///
32/// The provided methods [`values`] and [`default_values`] will insert
33/// data into the targeted table.
34///
35/// [`insert_into`]: crate::insert_into()
36/// [`values`]: IncompleteInsertStatement::values()
37/// [`default_values`]: IncompleteInsertStatement::default_values()
38#[derive(#[automatically_derived]
impl<T: ::core::fmt::Debug, Op: ::core::fmt::Debug> ::core::fmt::Debug for
    IncompleteInsertStatement<T, Op> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "IncompleteInsertStatement", "target", &self.target, "operator",
            &&self.operator)
    }
}Debug, #[automatically_derived]
impl<T: ::core::clone::Clone, Op: ::core::clone::Clone> ::core::clone::Clone
    for IncompleteInsertStatement<T, Op> {
    #[inline]
    fn clone(&self) -> IncompleteInsertStatement<T, Op> {
        IncompleteInsertStatement {
            target: ::core::clone::Clone::clone(&self.target),
            operator: ::core::clone::Clone::clone(&self.operator),
        }
    }
}Clone, #[automatically_derived]
impl<T: ::core::marker::Copy, Op: ::core::marker::Copy> ::core::marker::Copy
    for IncompleteInsertStatement<T, Op> {
}Copy)]
39#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
40pub struct IncompleteInsertStatement<T, Op = Insert> {
41    target: T,
42    operator: Op,
43}
44
45/// Represents the return type of [`diesel::insert_or_ignore_into`](crate::insert_or_ignore_into)
46pub type IncompleteInsertOrIgnoreStatement<T> = IncompleteInsertStatement<T, InsertOrIgnore>;
47
48/// Represents a complete `INSERT OR IGNORE` statement.
49pub type InsertOrIgnoreStatement<T, U, Ret = NoReturningClause> =
50    InsertStatement<T, U, InsertOrIgnore, Ret>;
51
52/// Represents the return type of [`diesel::replace_into`](crate::replace_into)
53pub type IncompleteReplaceStatement<T> = IncompleteInsertStatement<T, Replace>;
54
55/// Represents a complete `INSERT OR REPLACE` statement.
56pub type ReplaceStatement<T, U, Ret = NoReturningClause> = InsertStatement<T, U, Replace, Ret>;
57
58impl<T, Op> IncompleteInsertStatement<T, Op>
59where
60    T: QuerySource,
61{
62    pub(crate) fn new(target: T, operator: Op) -> Self {
63        IncompleteInsertStatement { target, operator }
64    }
65
66    /// Inserts `DEFAULT VALUES` into the targeted table.
67    ///
68    /// ```rust
69    /// # include!("../../doctest_setup.rs");
70    /// #
71    /// # table! {
72    /// #     users (name) {
73    /// #         name -> Text,
74    /// #         hair_color -> Text,
75    /// #     }
76    /// # }
77    /// #
78    /// # fn main() {
79    /// #     run_test();
80    /// # }
81    /// #
82    /// # fn run_test() -> QueryResult<()> {
83    /// #     use diesel::insert_into;
84    /// #     use self::users::dsl::*;
85    /// #     let connection = &mut connection_no_data();
86    /// diesel::sql_query(
87    ///     "CREATE TABLE users (
88    ///     name VARCHAR(255) NOT NULL DEFAULT 'Sean',
89    ///     hair_color VARCHAR(255) NOT NULL DEFAULT 'Green'
90    /// )",
91    /// )
92    /// .execute(connection)?;
93    ///
94    /// insert_into(users)
95    ///     .default_values()
96    ///     .execute(connection)
97    ///     .unwrap();
98    /// let inserted_user = users.first(connection)?;
99    /// let expected_data = (String::from("Sean"), String::from("Green"));
100    ///
101    /// assert_eq!(expected_data, inserted_user);
102    /// #     Ok(())
103    /// # }
104    /// ```
105    pub fn default_values(self) -> InsertStatement<T, DefaultValues, Op> {
106        self.values(DefaultValues)
107    }
108
109    /// Inserts the given values into the table passed to `insert_into`.
110    ///
111    /// See the documentation of [`insert_into`] for
112    /// usage examples.
113    ///
114    /// This method can sometimes produce extremely opaque error messages due to
115    /// limitations of the Rust language. If you receive an error about
116    /// "overflow evaluating requirement" as a result of calling this method,
117    /// you may need an `&` in front of the argument to this method.
118    ///
119    /// `#[derive(Insertable)]` usually generates implementations for both owned
120    /// and borrowed records, but `#[diesel(serialize_as)]` consumes the field
121    /// value via `.into()`. In that case, only the owned form implements
122    /// `Insertable`, so call `.values(record)` instead of `.values(&record)`.
123    ///
124    /// [`insert_into`]: crate::insert_into()
125    pub fn values<U>(self, records: U) -> InsertStatement<T, U::Values, Op>
126    where
127        U: Insertable<T>,
128    {
129        InsertStatement::new(
130            self.target,
131            records.values(),
132            self.operator,
133            NoReturningClause,
134        )
135    }
136}
137
138/// A fully constructed insert statement.
139///
140/// The parameters of this struct represent:
141///
142/// - `T`: The table we are inserting into
143/// - `U`: The data being inserted
144/// - `Op`: The operation being performed. The specific types used to represent
145///   this are private, but correspond to SQL such as `INSERT` or `REPLACE`.
146///   You can safely rely on the default type representing `INSERT`
147/// - `Ret`: The `RETURNING` clause of the query. The specific types used to
148///   represent this are private. You can safely rely on the default type
149///   representing a query without a `RETURNING` clause.
150#[doc = " A fully constructed insert statement."]
#[doc = ""]
#[doc = " The parameters of this struct represent:"]
#[doc = ""]
#[doc = " - `T`: The table we are inserting into"]
#[doc = " - `U`: The data being inserted"]
#[doc =
" - `Op`: The operation being performed. The specific types used to represent"]
#[doc =
"   this are private, but correspond to SQL such as `INSERT` or `REPLACE`."]
#[doc = "   You can safely rely on the default type representing `INSERT`"]
#[doc =
" - `Ret`: The `RETURNING` clause of the query. The specific types used to"]
#[doc =
"   represent this are private. You can safely rely on the default type"]
#[doc = "   representing a query without a `RETURNING` clause."]
#[must_use =
"Queries are only executed when calling `load`, `get_result` or similar."]
#[non_exhaustive]
pub struct InsertStatement<T: QuerySource, U, Op = Insert, Ret =
    NoReturningClause> {
    #[doc = " The operator used by this InsertStatement"]
    #[doc = ""]
    #[doc = " Corresponds to either `Insert` or `Replace`"]
    pub operator: Op,
    #[doc = " The table we are inserting into"]
    pub target: T,
    #[doc = " The data which should be inserted"]
    pub records: U,
    #[doc = " An optional returning clause"]
    pub returning: Ret,
    into_clause: T::FromClause,
}#[diesel_derives::__diesel_public_if(
151    feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
152    public_fields(operator, target, records, returning)
153)]
154#[derive(#[automatically_derived]
impl<T: ::core::fmt::Debug + QuerySource, U: ::core::fmt::Debug,
    Op: ::core::fmt::Debug, Ret: ::core::fmt::Debug> ::core::fmt::Debug for
    InsertStatement<T, U, Op, Ret> where T::FromClause: ::core::fmt::Debug {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field5_finish(f,
            "InsertStatement", "operator", &self.operator, "target",
            &self.target, "records", &self.records, "returning",
            &self.returning, "into_clause", &&self.into_clause)
    }
}Debug, #[automatically_derived]
impl<T: ::core::marker::Copy + QuerySource, U: ::core::marker::Copy,
    Op: ::core::marker::Copy, Ret: ::core::marker::Copy> ::core::marker::Copy
    for InsertStatement<T, U, Op, Ret> where
    T::FromClause: ::core::marker::Copy {
}Copy, #[automatically_derived]
impl<T: ::core::clone::Clone + QuerySource, U: ::core::clone::Clone,
    Op: ::core::clone::Clone, Ret: ::core::clone::Clone> ::core::clone::Clone
    for InsertStatement<T, U, Op, Ret> where
    T::FromClause: ::core::clone::Clone {
    #[inline]
    fn clone(&self) -> InsertStatement<T, U, Op, Ret> {
        InsertStatement {
            operator: ::core::clone::Clone::clone(&self.operator),
            target: ::core::clone::Clone::clone(&self.target),
            records: ::core::clone::Clone::clone(&self.records),
            returning: ::core::clone::Clone::clone(&self.returning),
            into_clause: ::core::clone::Clone::clone(&self.into_clause),
        }
    }
}Clone)]
155#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
156pub struct InsertStatement<T: QuerySource, U, Op = Insert, Ret = NoReturningClause> {
157    /// The operator used by this InsertStatement
158    ///
159    /// Corresponds to either `Insert` or `Replace`
160    operator: Op,
161    /// The table we are inserting into
162    target: T,
163    /// The data which should be inserted
164    records: U,
165    /// An optional returning clause
166    returning: Ret,
167    into_clause: T::FromClause,
168}
169
170impl<T, U, Op, Ret> QueryId for InsertStatement<T, U, Op, Ret>
171where
172    T: QuerySource + QueryId + 'static,
173    U: QueryId,
174    Op: QueryId,
175    Ret: QueryId,
176{
177    type QueryId = InsertStatement<T, U::QueryId, Op::QueryId, Ret::QueryId>;
178
179    const HAS_STATIC_QUERY_ID: bool = T::HAS_STATIC_QUERY_ID
180        && U::HAS_STATIC_QUERY_ID
181        && Op::HAS_STATIC_QUERY_ID
182        && Ret::HAS_STATIC_QUERY_ID;
183}
184
185impl<T: QuerySource, U, Op, Ret> InsertStatement<T, U, Op, Ret> {
186    /// Create a new InsertStatement instance
187    #[diesel_derives::__diesel_public_if(
188        feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
189    )]
190    pub(crate) fn new(target: T, records: U, operator: Op, returning: Ret) -> Self {
191        InsertStatement {
192            into_clause: target.from_clause(),
193            operator,
194            target,
195            records,
196            returning,
197        }
198    }
199
200    pub(crate) fn replace_values<F, V>(self, f: F) -> InsertStatement<T, V, Op, Ret>
201    where
202        F: FnOnce(U) -> V,
203    {
204        InsertStatement::new(self.target, f(self.records), self.operator, self.returning)
205    }
206}
207
208impl<T: QuerySource, U, C, Op, Ret> InsertStatement<T, InsertFromSelect<U, C>, Op, Ret> {
209    /// Set the column list when inserting from a select statement
210    ///
211    /// See the documentation for [`insert_into`] for usage examples.
212    ///
213    /// [`insert_into`]: crate::insert_into()
214    pub fn into_columns<C2>(
215        self,
216        columns: C2,
217    ) -> InsertStatement<T, InsertFromSelect<U, C2>, Op, Ret>
218    where
219        C2: ColumnList<Table = T> + Expression,
220        U: Query<SqlType = C2::SqlType>,
221    {
222        InsertStatement::new(
223            self.target,
224            self.records.with_columns(columns),
225            self.operator,
226            self.returning,
227        )
228    }
229}
230
231// This is a separate free standing function
232// so that the debug impl for sqlite can use it with
233// slightly adjusted types
234pub(super) fn walk_ast_intern<'b, T, U, Op, Ret, DB>(
235    mut out: AstPass<'_, 'b, DB>,
236    records: &'b U,
237    into_clause: &'b T::FromClause,
238    operator: &'b Op,
239    returning: &'b Ret,
240) -> QueryResult<()>
241where
242    DB: Backend + DieselReserveSpecialization,
243    T: Table,
244    T::FromClause: QueryFragment<DB>,
245    U: QueryFragment<DB> + CanInsertInSingleQuery<DB>,
246    Op: QueryFragment<DB>,
247    Ret: QueryFragment<DB>,
248{
249    if records.rows_to_insert() == Some(0) {
250        out.push_sql("SELECT 1 FROM ");
251        into_clause.walk_ast(out.reborrow())?;
252        out.push_sql(" WHERE 1=0");
253        return Ok(());
254    }
255
256    operator.walk_ast(out.reborrow())?;
257    out.push_sql(" INTO ");
258    into_clause.walk_ast(out.reborrow())?;
259    out.push_sql(" ");
260    records.walk_ast(out.reborrow())?;
261    returning.walk_ast(out.reborrow())?;
262    Ok(())
263}
264
265impl<T, U, Op, Ret, DB> QueryFragment<DB> for InsertStatement<T, U, Op, Ret>
266where
267    DB: Backend + DieselReserveSpecialization,
268    T: Table,
269    T::FromClause: QueryFragment<DB>,
270    U: QueryFragment<DB> + CanInsertInSingleQuery<DB>,
271    Op: QueryFragment<DB>,
272    Ret: QueryFragment<DB>,
273{
274    fn walk_ast<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
275        walk_ast_intern::<T, U, Op, Ret, DB>(
276            out,
277            &self.records,
278            &self.into_clause,
279            &self.operator,
280            &self.returning,
281        )
282    }
283}
284
285impl<T, U, Op> AsQuery for InsertStatement<T, U, Op, NoReturningClause>
286where
287    T: Table,
288    InsertStatement<T, U, Op, ReturningClause<T::AllColumns>>: Query,
289{
290    type SqlType = <Self::Query as Query>::SqlType;
291    type Query = InsertStatement<T, U, Op, ReturningClause<T::AllColumns>>;
292
293    fn as_query(self) -> Self::Query {
294        self.returning(T::all_columns())
295    }
296}
297
298impl<T, U, Op, Ret> Query for InsertStatement<T, U, Op, ReturningClause<Ret>>
299where
300    T: QuerySource,
301    Ret: Expression + SelectableExpression<T> + NonAggregate,
302{
303    type SqlType = Ret::SqlType;
304}
305
306impl<T: QuerySource, U, Op, Ret, Conn> RunQueryDsl<Conn> for InsertStatement<T, U, Op, Ret> {}
307
308impl<T: QuerySource, U, Op> InsertStatement<T, U, Op> {
309    /// Specify what expression is returned after execution of the `insert`.
310    /// # Examples
311    ///
312    /// ### Inserting records:
313    ///
314    /// ```rust
315    /// # include!("../../doctest_setup.rs");
316    /// #
317    /// # #[cfg(feature = "postgres")]
318    /// # fn main() {
319    /// #     use schema::users::dsl::*;
320    /// #     let connection = &mut establish_connection();
321    /// let inserted_names = diesel::insert_into(users)
322    ///     .values(&vec![name.eq("Timmy"), name.eq("Jimmy")])
323    ///     .returning(name)
324    ///     .get_results(connection)
325    ///     .unwrap();
326    /// // Note that the returned order is not guaranteed to be preserved
327    /// assert_eq!(inserted_names.len(), 2);
328    /// assert!(inserted_names.contains(&"Timmy".to_string()));
329    /// assert!(inserted_names.contains(&"Jimmy".to_string()));
330    /// # }
331    /// # #[cfg(not(feature = "postgres"))]
332    /// # fn main() {}
333    /// ```
334    pub fn returning<E>(self, returns: E) -> InsertStatement<T, U, Op, ReturningClause<E>>
335    where
336        InsertStatement<T, U, Op, ReturningClause<E>>: Query,
337    {
338        InsertStatement::new(
339            self.target,
340            self.records,
341            self.operator,
342            ReturningClause(returns),
343        )
344    }
345}
346
347/// Marker trait to indicate that no additional operations have been added
348/// to a record for insert.
349///
350/// This is used to prevent things like
351/// `.on_conflict_do_nothing().on_conflict_do_nothing()`
352/// from compiling.
353#[cfg_attr(
354    feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
355    cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")
356)]
357pub trait UndecoratedInsertRecord<Table> {}
358
359impl<T, Tab> UndecoratedInsertRecord<Tab> for &T where T: ?Sized + UndecoratedInsertRecord<Tab> {}
360
361impl<T, U> UndecoratedInsertRecord<T::Table> for ColumnInsertValue<T, U> where T: Column {}
362
363impl<T, U> UndecoratedInsertRecord<T::Table>
364    for DefaultableColumnInsertValue<ColumnInsertValue<T, U>>
365where
366    T: Column,
367{
368}
369
370impl<T, Table> UndecoratedInsertRecord<Table> for [T] where T: UndecoratedInsertRecord<Table> {}
371
372impl<T, Table, QId, const STATIC_QUERY_ID: bool> UndecoratedInsertRecord<Table>
373    for BatchInsert<T, Table, QId, STATIC_QUERY_ID>
374where
375    T: UndecoratedInsertRecord<Table>,
376{
377}
378
379impl<T, Table> UndecoratedInsertRecord<Table> for Vec<T> where [T]: UndecoratedInsertRecord<Table> {}
380
381impl<Lhs, Rhs> UndecoratedInsertRecord<Lhs::Table> for Eq<Lhs, Rhs> where Lhs: Column {}
382
383impl<Lhs, Rhs, Tab> UndecoratedInsertRecord<Tab> for Option<Eq<Lhs, Rhs>> where
384    Eq<Lhs, Rhs>: UndecoratedInsertRecord<Tab>
385{
386}
387
388impl<Lhs, Rhs> UndecoratedInsertRecord<Lhs::Table> for Grouped<Eq<Lhs, Rhs>> where Lhs: Column {}
389
390impl<Lhs, Rhs, Tab> UndecoratedInsertRecord<Tab> for Option<Grouped<Eq<Lhs, Rhs>>> where
391    Eq<Lhs, Rhs>: UndecoratedInsertRecord<Tab>
392{
393}
394
395impl<T, Table> UndecoratedInsertRecord<Table> for ValuesClause<T, Table> where
396    T: UndecoratedInsertRecord<Table>
397{
398}
399
400#[derive(#[automatically_derived]
impl ::core::fmt::Debug for DefaultValues {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "DefaultValues")
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for DefaultValues {
    #[inline]
    fn clone(&self) -> DefaultValues { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for DefaultValues { }Copy, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl diesel::query_builder::QueryId for DefaultValues {
            type QueryId = DefaultValues<>;
            const HAS_STATIC_QUERY_ID: bool = true;
            const IS_WINDOW_FUNCTION: bool = false;
        }
    };QueryId)]
401#[doc(hidden)]
402pub struct DefaultValues;
403
404impl<DB: Backend> CanInsertInSingleQuery<DB> for DefaultValues {
405    fn rows_to_insert(&self) -> Option<usize> {
406        Some(1)
407    }
408}
409
410impl<Tab> Insertable<Tab> for DefaultValues {
411    type Values = DefaultValues;
412
413    fn values(self) -> Self::Values {
414        self
415    }
416}
417
418impl<Tab> Insertable<Tab> for &DefaultValues {
419    type Values = DefaultValues;
420
421    fn values(self) -> Self::Values {
422        *self
423    }
424}
425
426impl<DB> QueryFragment<DB> for DefaultValues
427where
428    DB: Backend,
429    Self: QueryFragment<DB, DB::DefaultValueClauseForInsert>,
430{
431    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
432        <Self as QueryFragment<DB, DB::DefaultValueClauseForInsert>>::walk_ast(self, pass)
433    }
434}
435
436impl<DB> QueryFragment<DB, sql_dialect::default_value_clause::AnsiDefaultValueClause>
437    for DefaultValues
438where
439    DB: Backend
440        + SqlDialect<
441            DefaultValueClauseForInsert = sql_dialect::default_value_clause::AnsiDefaultValueClause,
442        >,
443{
444    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
445        out.push_sql("DEFAULT VALUES");
446        Ok(())
447    }
448}
449
450/// This type represents a values clause used as part of insert statements
451///
452/// Diesel exposes this type for third party backends so that
453/// they can implement batch insert support
454#[cfg_attr(
455    feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
456    cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")
457)]
458#[derive(#[automatically_derived]
impl<T: ::core::fmt::Debug, Tab: ::core::fmt::Debug> ::core::fmt::Debug for
    ValuesClause<T, Tab> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "ValuesClause",
            "values", &self.values, "_marker", &&self._marker)
    }
}Debug, #[automatically_derived]
impl<T: ::core::clone::Clone, Tab: ::core::clone::Clone> ::core::clone::Clone
    for ValuesClause<T, Tab> {
    #[inline]
    fn clone(&self) -> ValuesClause<T, Tab> {
        ValuesClause {
            values: ::core::clone::Clone::clone(&self.values),
            _marker: ::core::clone::Clone::clone(&self._marker),
        }
    }
}Clone, #[automatically_derived]
impl<T: ::core::marker::Copy, Tab: ::core::marker::Copy> ::core::marker::Copy
    for ValuesClause<T, Tab> {
}Copy, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl<T: diesel::query_builder::QueryId,
            Tab: diesel::query_builder::QueryId>
            diesel::query_builder::QueryId for ValuesClause<T, Tab> {
            type QueryId =
                ValuesClause<<T as diesel::query_builder::QueryId>::QueryId,
                <Tab as diesel::query_builder::QueryId>::QueryId>;
            const HAS_STATIC_QUERY_ID: bool =
                <T as diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
                        <Tab as diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID
                    && true;
            const IS_WINDOW_FUNCTION: bool =
                <T as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
                        <Tab as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION
                    || false;
        }
    };QueryId)]
459pub struct ValuesClause<T, Tab> {
460    /// Values to insert
461    pub values: T,
462    _marker: PhantomData<Tab>,
463}
464
465impl<T: Default, Tab> Default for ValuesClause<T, Tab> {
466    fn default() -> Self {
467        Self::new(T::default())
468    }
469}
470
471impl<T, Tab> ValuesClause<T, Tab> {
472    pub(crate) fn new(values: T) -> Self {
473        Self {
474            values,
475            _marker: PhantomData,
476        }
477    }
478}
479
480impl<T, Tab, DB> CanInsertInSingleQuery<DB> for ValuesClause<T, Tab>
481where
482    DB: Backend,
483    T: CanInsertInSingleQuery<DB>,
484{
485    fn rows_to_insert(&self) -> Option<usize> {
486        self.values.rows_to_insert()
487    }
488}
489
490impl<T, Tab, DB> QueryFragment<DB> for ValuesClause<T, Tab>
491where
492    DB: Backend,
493    Tab: Table,
494    T: InsertValues<DB, Tab>,
495    DefaultValues: QueryFragment<DB>,
496{
497    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
498        if self.values.is_noop(out.backend())? {
499            DefaultValues.walk_ast(out)?;
500        } else {
501            out.push_sql("(");
502            self.values.column_names(out.reborrow())?;
503            out.push_sql(") VALUES (");
504            self.values.walk_ast(out.reborrow())?;
505            out.push_sql(")");
506        }
507        Ok(())
508    }
509}
510
511mod private {
512    use super::InsertStatement;
513    use crate::QueryResult;
514    use crate::QuerySource;
515    use crate::backend::{Backend, DieselReserveSpecialization};
516    use crate::query_builder::{AstPass, QueryFragment, QueryId};
517
518    #[derive(#[automatically_derived]
impl ::core::fmt::Debug for Insert {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "Insert")
    }
}Debug, #[automatically_derived]
impl ::core::marker::Copy for Insert { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Insert {
    #[inline]
    fn clone(&self) -> Insert { *self }
}Clone, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl diesel::query_builder::QueryId for Insert {
            type QueryId = Insert<>;
            const HAS_STATIC_QUERY_ID: bool = true;
            const IS_WINDOW_FUNCTION: bool = false;
        }
    };QueryId)]
519    pub struct Insert;
520
521    impl<DB> QueryFragment<DB> for Insert
522    where
523        DB: Backend + DieselReserveSpecialization,
524    {
525        fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
526            out.push_sql("INSERT");
527            Ok(())
528        }
529    }
530
531    /// A marker type for insert or ignore statements
532    #[derive(#[automatically_derived]
impl ::core::fmt::Debug for InsertOrIgnore {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "InsertOrIgnore")
    }
}Debug, #[automatically_derived]
impl ::core::marker::Copy for InsertOrIgnore { }Copy, #[automatically_derived]
impl ::core::clone::Clone for InsertOrIgnore {
    #[inline]
    fn clone(&self) -> InsertOrIgnore { *self }
}Clone, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl diesel::query_builder::QueryId for InsertOrIgnore {
            type QueryId = InsertOrIgnore<>;
            const HAS_STATIC_QUERY_ID: bool = true;
            const IS_WINDOW_FUNCTION: bool = false;
        }
    };QueryId)]
533    pub struct InsertOrIgnore;
534
535    #[cfg(feature = "__sqlite-shared")]
536    impl QueryFragment<crate::sqlite::Sqlite> for InsertOrIgnore {
537        fn walk_ast<'b>(
538            &'b self,
539            mut out: AstPass<'_, 'b, crate::sqlite::Sqlite>,
540        ) -> QueryResult<()> {
541            out.push_sql("INSERT OR IGNORE");
542            Ok(())
543        }
544    }
545
546    #[cfg(feature = "mysql_backend")]
547    impl QueryFragment<crate::mysql::Mysql> for InsertOrIgnore {
548        fn walk_ast<'b>(
549            &'b self,
550            mut out: AstPass<'_, 'b, crate::mysql::Mysql>,
551        ) -> QueryResult<()> {
552            out.push_sql("INSERT IGNORE");
553            Ok(())
554        }
555    }
556
557    /// A marker type for replace statements
558    #[derive(#[automatically_derived]
impl ::core::fmt::Debug for Replace {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "Replace")
    }
}Debug, #[automatically_derived]
impl ::core::marker::Copy for Replace { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Replace {
    #[inline]
    fn clone(&self) -> Replace { *self }
}Clone, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl diesel::query_builder::QueryId for Replace {
            type QueryId = Replace<>;
            const HAS_STATIC_QUERY_ID: bool = true;
            const IS_WINDOW_FUNCTION: bool = false;
        }
    };QueryId)]
559    pub struct Replace;
560
561    #[cfg(feature = "__sqlite-shared")]
562    impl QueryFragment<crate::sqlite::Sqlite> for Replace {
563        fn walk_ast<'b>(
564            &'b self,
565            mut out: AstPass<'_, 'b, crate::sqlite::Sqlite>,
566        ) -> QueryResult<()> {
567            out.push_sql("REPLACE");
568            Ok(())
569        }
570    }
571
572    #[cfg(feature = "mysql_backend")]
573    impl QueryFragment<crate::mysql::Mysql> for Replace {
574        fn walk_ast<'b>(
575            &'b self,
576            mut out: AstPass<'_, 'b, crate::mysql::Mysql>,
577        ) -> QueryResult<()> {
578            out.push_sql("REPLACE");
579            Ok(())
580        }
581    }
582
583    // otherwise rustc complains at a different location that this trait is more private than the other item that uses it
584    #[allow(unreachable_pub)]
585    pub trait InsertAutoTypeHelper {
586        type Table;
587        type Op;
588        type Values;
589        type Ret;
590    }
591
592    impl<T, Op> InsertAutoTypeHelper for crate::query_builder::IncompleteInsertStatement<T, Op> {
593        type Table = T;
594        type Op = Op;
595        type Values = ();
596        type Ret = crate::query_builder::returning_clause::NoReturningClause;
597    }
598
599    impl<T, U, Op, Ret> InsertAutoTypeHelper for InsertStatement<T, U, Op, Ret>
600    where
601        T: QuerySource,
602    {
603        type Table = T;
604        type Op = Op;
605        type Values = U;
606        type Ret = Ret;
607    }
608}