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)] impl<'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 &*(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 &*(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 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);