diesel/query_builder/insert_statement/
insert_with_default_for_sqlite.rs

1use super::{BatchInsert, InsertStatement};
2use crate::insertable::InsertValues;
3use crate::insertable::{CanInsertInSingleQuery, ColumnInsertValue, DefaultableColumnInsertValue};
4use crate::prelude::*;
5use crate::query_builder::upsert::on_conflict_clause::OnConflictValues;
6use crate::query_builder::{AstPass, QueryId, ValuesClause};
7use crate::query_builder::{DebugQuery, QueryFragment};
8use crate::query_dsl::{methods::ExecuteDsl, LoadQuery};
9use crate::sqlite::Sqlite;
10use std::fmt::{self, Debug, Display};
11
12pub trait DebugQueryHelper<ContainsDefaultableValue> {
13    fn fmt_debug(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
14    fn fmt_display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
15}
16
17impl<T, V, QId, Op, Ret, const STATIC_QUERY_ID: bool> DebugQueryHelper<Yes>
18    for DebugQuery<
19        '_,
20        InsertStatement<T, BatchInsert<Vec<ValuesClause<V, T>>, T, QId, STATIC_QUERY_ID>, Op, Ret>,
21        Sqlite,
22    >
23where
24    V: QueryFragment<Sqlite>,
25    T: Copy + QuerySource,
26    Op: Copy,
27    Ret: Copy,
28    for<'b> InsertStatement<T, &'b ValuesClause<V, T>, Op, Ret>: QueryFragment<Sqlite>,
29{
30    fn fmt_debug(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        let mut statements = vec![String::from("BEGIN")];
32        for record in self.query.records.values.iter() {
33            let stmt = InsertStatement::new(
34                self.query.target,
35                record,
36                self.query.operator,
37                self.query.returning,
38            );
39            statements.push(crate::debug_query(&stmt).to_string());
40        }
41        statements.push("COMMIT".into());
42
43        f.debug_struct("Query")
44            .field("sql", &statements)
45            .field("binds", &[] as &[i32; 0])
46            .finish()
47    }
48
49    fn fmt_display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50        writeln!(f, "BEGIN;")?;
51        for record in self.query.records.values.iter() {
52            let stmt = InsertStatement::new(
53                self.query.target,
54                record,
55                self.query.operator,
56                self.query.returning,
57            );
58            writeln!(f, "{}", crate::debug_query(&stmt))?;
59        }
60        writeln!(f, "COMMIT;")?;
61        Ok(())
62    }
63}
64
65#[allow(unsafe_code)] // cast to transparent wrapper type
66impl<'a, T, V, QId, Op, const STATIC_QUERY_ID: bool> DebugQueryHelper<No>
67    for DebugQuery<'a, InsertStatement<T, BatchInsert<V, T, QId, STATIC_QUERY_ID>, Op>, Sqlite>
68where
69    T: Copy + QuerySource,
70    Op: Copy,
71    DebugQuery<
72        'a,
73        InsertStatement<T, SqliteBatchInsertWrapper<V, T, QId, STATIC_QUERY_ID>, Op>,
74        Sqlite,
75    >: Debug + Display,
76{
77    fn fmt_debug(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78        let value = unsafe {
79            // This cast is safe as `SqliteBatchInsertWrapper` is #[repr(transparent)]
80            &*(self as *const DebugQuery<
81                'a,
82                InsertStatement<T, BatchInsert<V, T, QId, STATIC_QUERY_ID>, Op>,
83                Sqlite,
84            >
85                as *const DebugQuery<
86                    'a,
87                    InsertStatement<T, SqliteBatchInsertWrapper<V, T, QId, STATIC_QUERY_ID>, Op>,
88                    Sqlite,
89                >)
90        };
91        <_ as Debug>::fmt(value, f)
92    }
93
94    fn fmt_display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95        let value = unsafe {
96            // This cast is safe as `SqliteBatchInsertWrapper` is #[repr(transparent)]
97            &*(self as *const DebugQuery<
98                'a,
99                InsertStatement<T, BatchInsert<V, T, QId, STATIC_QUERY_ID>, Op>,
100                Sqlite,
101            >
102                as *const DebugQuery<
103                    'a,
104                    InsertStatement<T, SqliteBatchInsertWrapper<V, T, QId, STATIC_QUERY_ID>, Op>,
105                    Sqlite,
106                >)
107        };
108        <_ as Display>::fmt(value, f)
109    }
110}
111
112impl<T, V, QId, Op, O, const STATIC_QUERY_ID: bool> Display
113    for DebugQuery<
114        '_,
115        InsertStatement<T, BatchInsert<Vec<ValuesClause<V, T>>, T, QId, STATIC_QUERY_ID>, Op>,
116        Sqlite,
117    >
118where
119    T: QuerySource,
120    V: ContainsDefaultableValue<Out = O>,
121    Self: DebugQueryHelper<O>,
122{
123    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124        self.fmt_display(f)
125    }
126}
127
128impl<T, V, QId, Op, O, const STATIC_QUERY_ID: bool> Debug
129    for DebugQuery<
130        '_,
131        InsertStatement<T, BatchInsert<Vec<ValuesClause<V, T>>, T, QId, STATIC_QUERY_ID>, Op>,
132        Sqlite,
133    >
134where
135    T: QuerySource,
136    V: ContainsDefaultableValue<Out = O>,
137    Self: DebugQueryHelper<O>,
138{
139    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
140        self.fmt_debug(f)
141    }
142}
143
144#[allow(missing_debug_implementations, missing_copy_implementations)]
145pub struct Yes;
146
147impl Default for Yes {
148    fn default() -> Self {
149        Yes
150    }
151}
152
153#[allow(missing_debug_implementations, missing_copy_implementations)]
154pub struct No;
155
156impl Default for No {
157    fn default() -> Self {
158        No
159    }
160}
161
162pub trait Any<Rhs> {
163    type Out: Any<Yes> + Any<No>;
164}
165
166impl Any<No> for No {
167    type Out = No;
168}
169
170impl Any<Yes> for No {
171    type Out = Yes;
172}
173
174impl Any<No> for Yes {
175    type Out = Yes;
176}
177
178impl Any<Yes> for Yes {
179    type Out = Yes;
180}
181
182pub trait ContainsDefaultableValue {
183    type Out: Any<Yes> + Any<No>;
184}
185
186impl<C, B> ContainsDefaultableValue for ColumnInsertValue<C, B> {
187    type Out = No;
188}
189
190impl<I> ContainsDefaultableValue for DefaultableColumnInsertValue<I> {
191    type Out = Yes;
192}
193
194impl<I, const SIZE: usize> ContainsDefaultableValue for [I; SIZE]
195where
196    I: ContainsDefaultableValue,
197{
198    type Out = I::Out;
199}
200
201impl<I, T> ContainsDefaultableValue for ValuesClause<I, T>
202where
203    I: ContainsDefaultableValue,
204{
205    type Out = I::Out;
206}
207
208impl<T> ContainsDefaultableValue for &T
209where
210    T: ContainsDefaultableValue,
211{
212    type Out = T::Out;
213}
214
215impl<V, T, QId, C, Op, O, const STATIC_QUERY_ID: bool> ExecuteDsl<C, Sqlite>
216    for InsertStatement<T, BatchInsert<Vec<ValuesClause<V, T>>, T, QId, STATIC_QUERY_ID>, Op>
217where
218    T: QuerySource,
219    C: Connection<Backend = Sqlite>,
220    V: ContainsDefaultableValue<Out = O>,
221    O: Default,
222    (O, Self): ExecuteDsl<C, Sqlite>,
223{
224    fn execute(query: Self, conn: &mut C) -> QueryResult<usize> {
225        <(O, Self) as ExecuteDsl<C, Sqlite>>::execute((O::default(), query), conn)
226    }
227}
228
229impl<V, T, QId, C, Op, O, Target, ConflictOpt, const STATIC_QUERY_ID: bool> ExecuteDsl<C, Sqlite>
230    for InsertStatement<
231        T,
232        OnConflictValues<
233            BatchInsert<Vec<ValuesClause<V, T>>, T, QId, STATIC_QUERY_ID>,
234            Target,
235            ConflictOpt,
236        >,
237        Op,
238    >
239where
240    T: QuerySource,
241    C: Connection<Backend = Sqlite>,
242    V: ContainsDefaultableValue<Out = O>,
243    O: Default,
244    (O, Self): ExecuteDsl<C, Sqlite>,
245{
246    fn execute(query: Self, conn: &mut C) -> QueryResult<usize> {
247        <(O, Self) as ExecuteDsl<C, Sqlite>>::execute((O::default(), query), conn)
248    }
249}
250
251impl<V, T, QId, C, Op, const STATIC_QUERY_ID: bool> ExecuteDsl<C, Sqlite>
252    for (
253        Yes,
254        InsertStatement<T, BatchInsert<Vec<ValuesClause<V, T>>, T, QId, STATIC_QUERY_ID>, Op>,
255    )
256where
257    C: Connection<Backend = Sqlite>,
258    T: Table + Copy + QueryId + 'static,
259    T::FromClause: QueryFragment<Sqlite>,
260    Op: Copy + QueryId + QueryFragment<Sqlite>,
261    V: InsertValues<Sqlite, T> + CanInsertInSingleQuery<Sqlite> + QueryId,
262{
263    fn execute((Yes, query): Self, conn: &mut C) -> QueryResult<usize> {
264        conn.transaction(|conn| {
265            let mut result = 0;
266            for record in &query.records.values {
267                let stmt =
268                    InsertStatement::new(query.target, record, query.operator, query.returning);
269                result += stmt.execute(conn)?;
270            }
271            Ok(result)
272        })
273    }
274}
275
276impl<'query, V, T, QId, Op, O, U, B, const STATIC_QUERY_ID: bool>
277    LoadQuery<'query, SqliteConnection, U, B>
278    for InsertStatement<T, BatchInsert<Vec<ValuesClause<V, T>>, T, QId, STATIC_QUERY_ID>, Op>
279where
280    T: QuerySource,
281    V: ContainsDefaultableValue<Out = O>,
282    O: Default,
283    (O, Self): LoadQuery<'query, SqliteConnection, U, B>,
284{
285    type RowIter<'conn> = <(O, Self) as LoadQuery<'query, SqliteConnection, U, B>>::RowIter<'conn>;
286
287    fn internal_load(self, conn: &mut SqliteConnection) -> QueryResult<Self::RowIter<'_>> {
288        <(O, Self) as LoadQuery<'query, SqliteConnection, U, B>>::internal_load(
289            (O::default(), self),
290            conn,
291        )
292    }
293}
294
295impl<'query, V, T, QId, Op, O, U, B, Target, ConflictOpt, const STATIC_QUERY_ID: bool>
296    LoadQuery<'query, SqliteConnection, U, B>
297    for InsertStatement<
298        T,
299        OnConflictValues<
300            BatchInsert<Vec<ValuesClause<V, T>>, T, QId, STATIC_QUERY_ID>,
301            Target,
302            ConflictOpt,
303        >,
304        Op,
305    >
306where
307    T: QuerySource,
308    V: ContainsDefaultableValue<Out = O>,
309    O: Default,
310    (O, Self): LoadQuery<'query, SqliteConnection, U, B>,
311{
312    type RowIter<'conn> = <(O, Self) as LoadQuery<'query, SqliteConnection, U, B>>::RowIter<'conn>;
313
314    fn internal_load(self, conn: &mut SqliteConnection) -> QueryResult<Self::RowIter<'_>> {
315        <(O, Self) as LoadQuery<'query, SqliteConnection, U, B>>::internal_load(
316            (O::default(), self),
317            conn,
318        )
319    }
320}
321
322impl<V, T, QId, Op, O, const STATIC_QUERY_ID: bool> RunQueryDsl<SqliteConnection>
323    for (
324        O,
325        InsertStatement<T, BatchInsert<Vec<ValuesClause<V, T>>, T, QId, STATIC_QUERY_ID>, Op>,
326    )
327where
328    T: QuerySource,
329    V: ContainsDefaultableValue<Out = O>,
330    O: Default,
331    InsertStatement<T, BatchInsert<Vec<ValuesClause<V, T>>, T, QId, STATIC_QUERY_ID>, Op>:
332        RunQueryDsl<SqliteConnection>,
333{
334}
335
336impl<V, T, QId, Op, O, Target, ConflictOpt, const STATIC_QUERY_ID: bool>
337    RunQueryDsl<SqliteConnection>
338    for (
339        O,
340        InsertStatement<
341            T,
342            OnConflictValues<
343                BatchInsert<Vec<ValuesClause<V, T>>, T, QId, STATIC_QUERY_ID>,
344                Target,
345                ConflictOpt,
346            >,
347            Op,
348        >,
349    )
350where
351    T: QuerySource,
352    V: ContainsDefaultableValue<Out = O>,
353    O: Default,
354    InsertStatement<
355        T,
356        OnConflictValues<
357            BatchInsert<Vec<ValuesClause<V, T>>, T, QId, STATIC_QUERY_ID>,
358            Target,
359            ConflictOpt,
360        >,
361        Op,
362    >: RunQueryDsl<SqliteConnection>,
363{
364}
365
366#[diagnostic::do_not_recommend]
367impl<'query, V, T, QId, Op, U, B, const STATIC_QUERY_ID: bool>
368    LoadQuery<'query, SqliteConnection, U, B>
369    for (
370        Yes,
371        InsertStatement<T, BatchInsert<Vec<ValuesClause<V, T>>, T, QId, STATIC_QUERY_ID>, Op>,
372    )
373where
374    T: Table + Copy + QueryId + 'static,
375    Op: Copy + QueryId + QueryFragment<Sqlite>,
376    InsertStatement<T, ValuesClause<V, T>, Op>: LoadQuery<'query, SqliteConnection, U, B>,
377    Self: RunQueryDsl<SqliteConnection>,
378{
379    type RowIter<'conn> = std::vec::IntoIter<QueryResult<U>>;
380
381    fn internal_load(self, conn: &mut SqliteConnection) -> QueryResult<Self::RowIter<'_>> {
382        let (Yes, query) = self;
383
384        conn.transaction(|conn| {
385            let mut results = Vec::with_capacity(query.records.values.len());
386
387            for record in query.records.values {
388                let stmt =
389                    InsertStatement::new(query.target, record, query.operator, query.returning);
390
391                let result = stmt
392                    .internal_load(conn)?
393                    .next()
394                    .ok_or(crate::result::Error::NotFound)?;
395
396                match &result {
397                    Ok(_) | Err(crate::result::Error::DeserializationError(_)) => {
398                        results.push(result)
399                    }
400                    Err(_) => {
401                        result?;
402                    }
403                };
404            }
405
406            Ok(results.into_iter())
407        })
408    }
409}
410
411#[diagnostic::do_not_recommend]
412impl<'query, V, T, QId, Op, U, B, Target, ConflictOpt, const STATIC_QUERY_ID: bool>
413    LoadQuery<'query, SqliteConnection, U, B>
414    for (
415        Yes,
416        InsertStatement<
417            T,
418            OnConflictValues<
419                BatchInsert<Vec<ValuesClause<V, T>>, T, QId, STATIC_QUERY_ID>,
420                Target,
421                ConflictOpt,
422            >,
423            Op,
424        >,
425    )
426where
427    T: Table + Copy + QueryId + 'static,
428    T::FromClause: Copy,
429    Op: Copy,
430    Target: Copy,
431    ConflictOpt: Copy,
432    InsertStatement<T, OnConflictValues<ValuesClause<V, T>, Target, ConflictOpt>, Op>:
433        LoadQuery<'query, SqliteConnection, U, B>,
434    Self: RunQueryDsl<SqliteConnection>,
435{
436    type RowIter<'conn> = std::vec::IntoIter<QueryResult<U>>;
437
438    fn internal_load(self, conn: &mut SqliteConnection) -> QueryResult<Self::RowIter<'_>> {
439        let (Yes, query) = self;
440
441        conn.transaction(|conn| {
442            let mut results = Vec::with_capacity(query.records.values.values.len());
443
444            for record in query.records.values.values {
445                let stmt = InsertStatement {
446                    operator: query.operator,
447                    target: query.target,
448                    records: OnConflictValues {
449                        values: record,
450                        target: query.records.target,
451                        action: query.records.action,
452                        where_clause: query.records.where_clause,
453                    },
454                    returning: query.returning,
455                    into_clause: query.into_clause,
456                };
457
458                let result = stmt
459                    .internal_load(conn)?
460                    .next()
461                    .ok_or(crate::result::Error::NotFound)?;
462
463                match &result {
464                    Ok(_) | Err(crate::result::Error::DeserializationError(_)) => {
465                        results.push(result)
466                    }
467                    Err(_) => {
468                        result?;
469                    }
470                };
471            }
472
473            Ok(results.into_iter())
474        })
475    }
476}
477
478#[allow(missing_debug_implementations, missing_copy_implementations)]
479#[repr(transparent)]
480pub struct SqliteBatchInsertWrapper<V, T, QId, const STATIC_QUERY_ID: bool>(
481    BatchInsert<V, T, QId, STATIC_QUERY_ID>,
482);
483
484impl<V, Tab, QId, const STATIC_QUERY_ID: bool> QueryFragment<Sqlite>
485    for SqliteBatchInsertWrapper<Vec<ValuesClause<V, Tab>>, Tab, QId, STATIC_QUERY_ID>
486where
487    ValuesClause<V, Tab>: QueryFragment<Sqlite>,
488    V: QueryFragment<Sqlite>,
489{
490    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Sqlite>) -> QueryResult<()> {
491        if !STATIC_QUERY_ID {
492            out.unsafe_to_cache_prepared();
493        }
494
495        let mut values = self.0.values.iter();
496        if let Some(value) = values.next() {
497            value.walk_ast(out.reborrow())?;
498        }
499        for value in values {
500            out.push_sql(", (");
501            value.values.walk_ast(out.reborrow())?;
502            out.push_sql(")");
503        }
504        Ok(())
505    }
506}
507
508#[allow(missing_copy_implementations, missing_debug_implementations)]
509#[repr(transparent)]
510pub struct SqliteCanInsertInSingleQueryHelper<T: ?Sized>(T);
511
512impl<V, T, QId, const STATIC_QUERY_ID: bool> CanInsertInSingleQuery<Sqlite>
513    for SqliteBatchInsertWrapper<Vec<ValuesClause<V, T>>, T, QId, STATIC_QUERY_ID>
514where
515    // We constrain that here on an internal helper type
516    // to make sure that this does not accidentally leak
517    // so that none does really implement normal batch
518    // insert for inserts with default values here
519    SqliteCanInsertInSingleQueryHelper<V>: CanInsertInSingleQuery<Sqlite>,
520{
521    fn rows_to_insert(&self) -> Option<usize> {
522        Some(self.0.values.len())
523    }
524}
525
526impl<T> CanInsertInSingleQuery<Sqlite> for SqliteCanInsertInSingleQueryHelper<T>
527where
528    T: CanInsertInSingleQuery<Sqlite>,
529{
530    fn rows_to_insert(&self) -> Option<usize> {
531        self.0.rows_to_insert()
532    }
533}
534
535impl<V, T, QId, const STATIC_QUERY_ID: bool> QueryId
536    for SqliteBatchInsertWrapper<V, T, QId, STATIC_QUERY_ID>
537where
538    BatchInsert<V, T, QId, STATIC_QUERY_ID>: QueryId,
539{
540    type QueryId = <BatchInsert<V, T, QId, STATIC_QUERY_ID> as QueryId>::QueryId;
541
542    const HAS_STATIC_QUERY_ID: bool =
543        <BatchInsert<V, T, QId, STATIC_QUERY_ID> as QueryId>::HAS_STATIC_QUERY_ID;
544}
545
546impl<V, T, QId, C, Op, const STATIC_QUERY_ID: bool> ExecuteDsl<C, Sqlite>
547    for (
548        No,
549        InsertStatement<T, BatchInsert<V, T, QId, STATIC_QUERY_ID>, Op>,
550    )
551where
552    C: Connection<Backend = Sqlite>,
553    T: Table + QueryId + 'static,
554    T::FromClause: QueryFragment<Sqlite>,
555    Op: QueryFragment<Sqlite> + QueryId,
556    SqliteBatchInsertWrapper<V, T, QId, STATIC_QUERY_ID>:
557        QueryFragment<Sqlite> + QueryId + CanInsertInSingleQuery<Sqlite>,
558{
559    fn execute((No, query): Self, conn: &mut C) -> QueryResult<usize> {
560        let query = InsertStatement {
561            records: SqliteBatchInsertWrapper(query.records),
562            operator: query.operator,
563            target: query.target,
564            returning: query.returning,
565            into_clause: query.into_clause,
566        };
567        query.execute(conn)
568    }
569}
570
571impl<V, T, QId, C, Op, Target, ConflictOpt, const STATIC_QUERY_ID: bool> ExecuteDsl<C, Sqlite>
572    for (
573        No,
574        InsertStatement<
575            T,
576            OnConflictValues<BatchInsert<V, T, QId, STATIC_QUERY_ID>, Target, ConflictOpt>,
577            Op,
578        >,
579    )
580where
581    C: Connection<Backend = Sqlite>,
582    T: Table + QueryId + 'static,
583    T::FromClause: QueryFragment<Sqlite>,
584    Op: QueryFragment<Sqlite> + QueryId,
585    OnConflictValues<SqliteBatchInsertWrapper<V, T, QId, STATIC_QUERY_ID>, Target, ConflictOpt>:
586        QueryFragment<Sqlite> + CanInsertInSingleQuery<Sqlite> + QueryId,
587{
588    fn execute((No, query): Self, conn: &mut C) -> QueryResult<usize> {
589        let query = InsertStatement {
590            operator: query.operator,
591            target: query.target,
592            records: OnConflictValues {
593                values: SqliteBatchInsertWrapper(query.records.values),
594                target: query.records.target,
595                action: query.records.action,
596                where_clause: query.records.where_clause,
597            },
598            returning: query.returning,
599            into_clause: query.into_clause,
600        };
601        query.execute(conn)
602    }
603}
604
605#[diagnostic::do_not_recommend]
606impl<'query, V, T, QId, Op, U, B, const STATIC_QUERY_ID: bool>
607    LoadQuery<'query, SqliteConnection, U, B>
608    for (
609        No,
610        InsertStatement<T, BatchInsert<V, T, QId, STATIC_QUERY_ID>, Op>,
611    )
612where
613    T: Table + QueryId + 'static,
614    InsertStatement<T, SqliteBatchInsertWrapper<V, T, QId, STATIC_QUERY_ID>, Op>:
615        LoadQuery<'query, SqliteConnection, U, B>,
616    Self: RunQueryDsl<SqliteConnection>,
617{
618    type RowIter<'conn> = <InsertStatement<
619        T,
620        SqliteBatchInsertWrapper<V, T, QId, STATIC_QUERY_ID>,
621        Op,
622    > as LoadQuery<'query, SqliteConnection, U, B>>::RowIter<'conn>;
623
624    fn internal_load(self, conn: &mut SqliteConnection) -> QueryResult<Self::RowIter<'_>> {
625        let (No, query) = self;
626
627        let query = InsertStatement {
628            records: SqliteBatchInsertWrapper(query.records),
629            operator: query.operator,
630            target: query.target,
631            returning: query.returning,
632            into_clause: query.into_clause,
633        };
634
635        query.internal_load(conn)
636    }
637}
638
639#[diagnostic::do_not_recommend]
640impl<'query, V, T, QId, Op, U, B, Target, ConflictOpt, const STATIC_QUERY_ID: bool>
641    LoadQuery<'query, SqliteConnection, U, B>
642    for (
643        No,
644        InsertStatement<
645            T,
646            OnConflictValues<BatchInsert<V, T, QId, STATIC_QUERY_ID>, Target, ConflictOpt>,
647            Op,
648        >,
649    )
650where
651    T: Table + QueryId + 'static,
652    InsertStatement<
653        T,
654        OnConflictValues<SqliteBatchInsertWrapper<V, T, QId, STATIC_QUERY_ID>, Target, ConflictOpt>,
655        Op,
656    >: LoadQuery<'query, SqliteConnection, U, B>,
657    Self: RunQueryDsl<SqliteConnection>,
658{
659    type RowIter<'conn> = <InsertStatement<
660        T,
661        OnConflictValues<SqliteBatchInsertWrapper<V, T, QId, STATIC_QUERY_ID>, Target, ConflictOpt>,
662        Op,
663    > as LoadQuery<'query, SqliteConnection, U, B>>::RowIter<'conn>;
664
665    fn internal_load(self, conn: &mut SqliteConnection) -> QueryResult<Self::RowIter<'_>> {
666        let (No, query) = self;
667
668        let query = InsertStatement {
669            operator: query.operator,
670            target: query.target,
671            records: OnConflictValues {
672                values: SqliteBatchInsertWrapper(query.records.values),
673                target: query.records.target,
674                action: query.records.action,
675                where_clause: query.records.where_clause,
676            },
677            returning: query.returning,
678            into_clause: query.into_clause,
679        };
680
681        query.internal_load(conn)
682    }
683}
684
685macro_rules! tuple_impls {
686        ($(
687            $Tuple:tt {
688                $(($idx:tt) -> $T:ident, $ST:ident, $TT:ident,)+
689            }
690        )+) => {
691            $(
692                impl_contains_defaultable_value!($($T,)*);
693            )*
694        }
695    }
696
697macro_rules! impl_contains_defaultable_value {
698      (
699        @build
700        start_ts = [$($ST: ident,)*],
701        ts = [$T1: ident,],
702        bounds = [$($bounds: tt)*],
703        out = [$($out: tt)*],
704    )=> {
705        impl<$($ST,)*> ContainsDefaultableValue for ($($ST,)*)
706        where
707            $($ST: ContainsDefaultableValue,)*
708            $($bounds)*
709            $T1::Out: Any<$($out)*>,
710        {
711            type Out = <$T1::Out as Any<$($out)*>>::Out;
712        }
713
714    };
715    (
716        @build
717        start_ts = [$($ST: ident,)*],
718        ts = [$T1: ident, $($T: ident,)+],
719        bounds = [$($bounds: tt)*],
720        out = [$($out: tt)*],
721    )=> {
722        impl_contains_defaultable_value! {
723            @build
724            start_ts = [$($ST,)*],
725            ts = [$($T,)*],
726            bounds = [$($bounds)* $T1::Out: Any<$($out)*>,],
727            out = [<$T1::Out as Any<$($out)*>>::Out],
728        }
729    };
730    ($T1: ident, $($T: ident,)+) => {
731        impl_contains_defaultable_value! {
732            @build
733            start_ts = [$T1, $($T,)*],
734            ts = [$($T,)*],
735            bounds = [],
736            out = [$T1::Out],
737        }
738    };
739    ($T1: ident,) => {
740        impl<$T1> ContainsDefaultableValue for ($T1,)
741        where $T1: ContainsDefaultableValue,
742        {
743            type Out = <$T1 as ContainsDefaultableValue>::Out;
744        }
745    }
746}
747
748diesel_derives::__diesel_for_each_tuple!(tuple_impls);