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