sea_query/query/
insert.rs

1use crate::{
2    backend::QueryBuilder, error::*, prepare::*, types::*, OnConflict, QueryStatementBuilder,
3    QueryStatementWriter, ReturningClause, SelectStatement, SimpleExpr, SubQueryStatement, Values,
4    WithClause, WithQuery,
5};
6use inherent::inherent;
7
8/// Represents a value source that can be used in an insert query.
9///
10/// [`InsertValueSource`] is a node in the expression tree and can represent a raw value set
11/// ('VALUES') or a select query.
12#[derive(Debug, Clone, PartialEq)]
13pub(crate) enum InsertValueSource {
14    Values(Vec<Vec<SimpleExpr>>),
15    Select(Box<SelectStatement>),
16}
17
18/// Insert any new rows into an existing table
19///
20/// # Examples
21///
22/// ```
23/// use sea_query::{tests_cfg::*, *};
24///
25/// let query = Query::insert()
26///     .into_table(Glyph::Table)
27///     .columns([Glyph::Aspect, Glyph::Image])
28///     .values_panic([5.15.into(), "12A".into()])
29///     .values_panic([4.21.into(), "123".into()])
30///     .to_owned();
31///
32/// assert_eq!(
33///     query.to_string(MysqlQueryBuilder),
34///     r#"INSERT INTO `glyph` (`aspect`, `image`) VALUES (5.15, '12A'), (4.21, '123')"#
35/// );
36/// assert_eq!(
37///     query.to_string(PostgresQueryBuilder),
38///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (5.15, '12A'), (4.21, '123')"#
39/// );
40/// assert_eq!(
41///     query.to_string(SqliteQueryBuilder),
42///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (5.15, '12A'), (4.21, '123')"#
43/// );
44/// ```
45#[derive(Debug, Default, Clone, PartialEq)]
46pub struct InsertStatement {
47    pub(crate) replace: bool,
48    pub(crate) table: Option<Box<TableRef>>,
49    pub(crate) columns: Vec<DynIden>,
50    pub(crate) source: Option<InsertValueSource>,
51    pub(crate) on_conflict: Option<OnConflict>,
52    pub(crate) returning: Option<ReturningClause>,
53    pub(crate) default_values: Option<u32>,
54    pub(crate) with: Option<WithClause>,
55}
56
57impl InsertStatement {
58    /// Construct a new [`InsertStatement`]
59    pub fn new() -> Self {
60        Self::default()
61    }
62
63    /// Use REPLACE instead of INSERT
64    ///
65    /// # Examples
66    ///
67    /// ```
68    /// use sea_query::{tests_cfg::*, *};
69    ///
70    /// let query = Query::insert()
71    ///     .replace()
72    ///     .into_table(Glyph::Table)
73    ///     .columns([Glyph::Aspect, Glyph::Image])
74    ///     .values_panic([5.15.into(), "12A".into()])
75    ///     .to_owned();
76    ///
77    /// assert_eq!(
78    ///     query.to_string(MysqlQueryBuilder),
79    ///     r#"REPLACE INTO `glyph` (`aspect`, `image`) VALUES (5.15, '12A')"#
80    /// );
81    /// assert_eq!(
82    ///     query.to_string(SqliteQueryBuilder),
83    ///     r#"REPLACE INTO "glyph" ("aspect", "image") VALUES (5.15, '12A')"#
84    /// );
85    /// ```
86    #[cfg(any(feature = "backend-sqlite", feature = "backend-mysql"))]
87    pub fn replace(&mut self) -> &mut Self {
88        self.replace = true;
89        self
90    }
91
92    /// Specify which table to insert into.
93    ///
94    /// # Examples
95    ///
96    /// See [`InsertStatement::values`]
97    pub fn into_table<T>(&mut self, tbl_ref: T) -> &mut Self
98    where
99        T: IntoTableRef,
100    {
101        self.table = Some(Box::new(tbl_ref.into_table_ref()));
102        self
103    }
104
105    /// Specify what columns to insert.
106    ///
107    /// # Examples
108    ///
109    /// See [`InsertStatement::values`]
110    pub fn columns<C, I>(&mut self, columns: I) -> &mut Self
111    where
112        C: IntoIden,
113        I: IntoIterator<Item = C>,
114    {
115        self.columns = columns.into_iter().map(|c| c.into_iden()).collect();
116        self
117    }
118
119    /// Specify a select query whose values to be inserted.
120    ///
121    /// # Examples
122    ///
123    /// ```
124    /// use sea_query::{tests_cfg::*, *};
125    ///
126    /// let query = Query::insert()
127    ///     .into_table(Glyph::Table)
128    ///     .columns([Glyph::Aspect, Glyph::Image])
129    ///     .select_from(Query::select()
130    ///         .column(Glyph::Aspect)
131    ///         .column(Glyph::Image)
132    ///         .from(Glyph::Table)
133    ///         .and_where(Expr::col(Glyph::Image).like("0%"))
134    ///         .to_owned()
135    ///     )
136    ///     .unwrap()
137    ///     .to_owned();
138    ///
139    /// assert_eq!(
140    ///     query.to_string(MysqlQueryBuilder),
141    ///     r#"INSERT INTO `glyph` (`aspect`, `image`) SELECT `aspect`, `image` FROM `glyph` WHERE `image` LIKE '0%'"#
142    /// );
143    /// assert_eq!(
144    ///     query.to_string(PostgresQueryBuilder),
145    ///     r#"INSERT INTO "glyph" ("aspect", "image") SELECT "aspect", "image" FROM "glyph" WHERE "image" LIKE '0%'"#
146    /// );
147    /// assert_eq!(
148    ///     query.to_string(SqliteQueryBuilder),
149    ///     r#"INSERT INTO "glyph" ("aspect", "image") SELECT "aspect", "image" FROM "glyph" WHERE "image" LIKE '0%'"#
150    /// );
151    /// ```
152    ///
153    /// ```
154    /// use sea_query::{tests_cfg::*, *};
155    /// let query = Query::insert()
156    ///     .into_table(Glyph::Table)
157    ///     .columns([Glyph::Image])
158    ///     .select_from(
159    ///         Query::select()
160    ///             .expr(Expr::val("hello"))
161    ///             .cond_where(Cond::all().not().add(Expr::exists(
162    ///                 Query::select().expr(Expr::val("world")).to_owned(),
163    ///             )))
164    ///             .to_owned(),
165    ///     )
166    ///     .unwrap()
167    ///     .to_owned();
168    ///
169    /// assert_eq!(
170    ///     query.to_string(SqliteQueryBuilder),
171    ///     r#"INSERT INTO "glyph" ("image") SELECT 'hello' WHERE NOT EXISTS(SELECT 'world')"#
172    /// );
173    /// ```
174    pub fn select_from<S>(&mut self, select: S) -> Result<&mut Self>
175    where
176        S: Into<SelectStatement>,
177    {
178        let statement = select.into();
179
180        if self.columns.len() != statement.selects.len() {
181            return Err(Error::ColValNumMismatch {
182                col_len: self.columns.len(),
183                val_len: statement.selects.len(),
184            });
185        }
186
187        self.source = Some(InsertValueSource::Select(Box::new(statement)));
188        Ok(self)
189    }
190
191    /// Specify a row of values to be inserted.
192    ///
193    /// # Examples
194    ///
195    /// ```
196    /// use sea_query::{tests_cfg::*, *};
197    ///
198    /// let query = Query::insert()
199    ///     .into_table(Glyph::Table)
200    ///     .columns([Glyph::Aspect, Glyph::Image])
201    ///     .values([
202    ///         2.into(),
203    ///         Func::cast_as("2020-02-02 00:00:00", Alias::new("DATE")).into(),
204    ///     ])
205    ///     .unwrap()
206    ///     .to_owned();
207    ///
208    /// assert_eq!(
209    ///     query.to_string(MysqlQueryBuilder),
210    ///     r#"INSERT INTO `glyph` (`aspect`, `image`) VALUES (2, CAST('2020-02-02 00:00:00' AS DATE))"#
211    /// );
212    /// assert_eq!(
213    ///     query.to_string(PostgresQueryBuilder),
214    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2, CAST('2020-02-02 00:00:00' AS DATE))"#
215    /// );
216    /// assert_eq!(
217    ///     query.to_string(SqliteQueryBuilder),
218    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2, CAST('2020-02-02 00:00:00' AS DATE))"#
219    /// );
220    /// ```
221    pub fn values<I>(&mut self, values: I) -> Result<&mut Self>
222    where
223        I: IntoIterator<Item = SimpleExpr>,
224    {
225        let values = values.into_iter().collect::<Vec<SimpleExpr>>();
226        if self.columns.len() != values.len() {
227            return Err(Error::ColValNumMismatch {
228                col_len: self.columns.len(),
229                val_len: values.len(),
230            });
231        }
232        if !values.is_empty() {
233            let values_source = if let Some(InsertValueSource::Values(values)) = &mut self.source {
234                values
235            } else {
236                self.source = Some(InsertValueSource::Values(Default::default()));
237                if let Some(InsertValueSource::Values(values)) = &mut self.source {
238                    values
239                } else {
240                    unreachable!();
241                }
242            };
243            values_source.push(values);
244        }
245        Ok(self)
246    }
247
248    /// Specify a row of values to be inserted, variation of [`InsertStatement::values`].
249    ///
250    /// # Examples
251    ///
252    /// ```
253    /// use sea_query::{tests_cfg::*, *};
254    ///
255    /// let query = Query::insert()
256    ///     .into_table(Glyph::Table)
257    ///     .columns([Glyph::Aspect, Glyph::Image])
258    ///     .values_panic([2.1345.into(), "24B".into()])
259    ///     .values_panic([5.15.into(), "12A".into()])
260    ///     .to_owned();
261    ///
262    /// assert_eq!(
263    ///     query.to_string(MysqlQueryBuilder),
264    ///     r#"INSERT INTO `glyph` (`aspect`, `image`) VALUES (2.1345, '24B'), (5.15, '12A')"#
265    /// );
266    /// assert_eq!(
267    ///     query.to_string(PostgresQueryBuilder),
268    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
269    /// );
270    /// assert_eq!(
271    ///     query.to_string(SqliteQueryBuilder),
272    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
273    /// );
274    /// ```
275    pub fn values_panic<I>(&mut self, values: I) -> &mut Self
276    where
277        I: IntoIterator<Item = SimpleExpr>,
278    {
279        self.values(values).unwrap()
280    }
281
282    /// Add rows to be inserted from an iterator, variation of [`InsertStatement::values_panic`].
283    ///
284    /// # Examples
285    ///
286    /// ```
287    /// use sea_query::{tests_cfg::*, *};
288    ///
289    /// let rows = vec![[2.1345.into(), "24B".into()], [5.15.into(), "12A".into()]];
290    ///
291    /// let query = Query::insert()
292    ///     .into_table(Glyph::Table)
293    ///     .columns([Glyph::Aspect, Glyph::Image])
294    ///     .values_from_panic(rows)
295    ///     .to_owned();
296    ///
297    /// assert_eq!(
298    ///     query.to_string(MysqlQueryBuilder),
299    ///     r#"INSERT INTO `glyph` (`aspect`, `image`) VALUES (2.1345, '24B'), (5.15, '12A')"#
300    /// );
301    /// assert_eq!(
302    ///     query.to_string(PostgresQueryBuilder),
303    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
304    /// );
305    /// assert_eq!(
306    ///     query.to_string(SqliteQueryBuilder),
307    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
308    /// );
309    /// ```
310    pub fn values_from_panic<I>(&mut self, values_iter: impl IntoIterator<Item = I>) -> &mut Self
311    where
312        I: IntoIterator<Item = SimpleExpr>,
313    {
314        values_iter.into_iter().for_each(|values| {
315            self.values_panic(values);
316        });
317        self
318    }
319
320    /// ON CONFLICT expression
321    ///
322    /// # Examples
323    ///
324    /// - [`OnConflict::update_columns`]: Update column value of existing row with inserting value
325    /// - [`OnConflict::update_values`]: Update column value of existing row with value
326    /// - [`OnConflict::update_exprs`]: Update column value of existing row with expression
327    pub fn on_conflict(&mut self, on_conflict: OnConflict) -> &mut Self {
328        self.on_conflict = Some(on_conflict);
329        self
330    }
331
332    /// RETURNING expressions.
333    ///
334    /// # Examples
335    ///
336    /// ```
337    /// use sea_query::{tests_cfg::*, *};
338    ///
339    /// let query = Query::insert()
340    ///     .into_table(Glyph::Table)
341    ///     .columns([Glyph::Image])
342    ///     .values_panic(["12A".into()])
343    ///     .returning(Query::returning().columns([Glyph::Id]))
344    ///     .to_owned();
345    ///
346    /// assert_eq!(
347    ///     query.to_string(MysqlQueryBuilder),
348    ///     "INSERT INTO `glyph` (`image`) VALUES ('12A')"
349    /// );
350    /// assert_eq!(
351    ///     query.to_string(PostgresQueryBuilder),
352    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
353    /// );
354    /// assert_eq!(
355    ///     query.to_string(SqliteQueryBuilder),
356    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
357    /// );
358    /// ```
359    pub fn returning(&mut self, returning: ReturningClause) -> &mut Self {
360        self.returning = Some(returning);
361        self
362    }
363
364    /// RETURNING expressions for a column.
365    ///
366    /// # Examples
367    ///
368    /// ```
369    /// use sea_query::{tests_cfg::*, *};
370    ///
371    /// let query = Query::insert()
372    ///     .into_table(Glyph::Table)
373    ///     .columns([Glyph::Image])
374    ///     .values_panic(["12A".into()])
375    ///     .returning_col(Glyph::Id)
376    ///     .to_owned();
377    ///
378    /// assert_eq!(
379    ///     query.to_string(MysqlQueryBuilder),
380    ///     "INSERT INTO `glyph` (`image`) VALUES ('12A')"
381    /// );
382    /// assert_eq!(
383    ///     query.to_string(PostgresQueryBuilder),
384    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
385    /// );
386    /// assert_eq!(
387    ///     query.to_string(SqliteQueryBuilder),
388    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
389    /// );
390    /// ```
391    pub fn returning_col<C>(&mut self, col: C) -> &mut Self
392    where
393        C: IntoColumnRef,
394    {
395        self.returning(ReturningClause::Columns(vec![col.into_column_ref()]))
396    }
397
398    /// RETURNING expressions all columns.
399    ///
400    /// # Examples
401    ///
402    /// ```
403    /// use sea_query::{tests_cfg::*, *};
404    ///
405    /// let query = Query::insert()
406    ///     .into_table(Glyph::Table)
407    ///     .columns([Glyph::Image])
408    ///     .values_panic(["12A".into()])
409    ///     .returning_all()
410    ///     .to_owned();
411    ///
412    /// assert_eq!(
413    ///     query.to_string(MysqlQueryBuilder),
414    ///     "INSERT INTO `glyph` (`image`) VALUES ('12A')"
415    /// );
416    /// assert_eq!(
417    ///     query.to_string(PostgresQueryBuilder),
418    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING *"#
419    /// );
420    /// assert_eq!(
421    ///     query.to_string(SqliteQueryBuilder),
422    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING *"#
423    /// );
424    /// ```
425    pub fn returning_all(&mut self) -> &mut Self {
426        self.returning(ReturningClause::All)
427    }
428
429    /// Create a [WithQuery] by specifying a [WithClause] to execute this query with.
430    ///
431    /// # Examples
432    ///
433    /// ```
434    /// use sea_query::{*, IntoCondition, IntoIden, tests_cfg::*};
435    ///
436    /// let select = SelectStatement::new()
437    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
438    ///         .from(Glyph::Table)
439    ///         .to_owned();
440    ///     let cte = CommonTableExpression::new()
441    ///         .query(select)
442    ///         .column(Glyph::Id)
443    ///         .column(Glyph::Image)
444    ///         .column(Glyph::Aspect)
445    ///         .table_name(Alias::new("cte"))
446    ///         .to_owned();
447    ///     let with_clause = WithClause::new().cte(cte).to_owned();
448    ///     let select = SelectStatement::new()
449    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
450    ///         .from(Alias::new("cte"))
451    ///         .to_owned();
452    ///     let mut insert = Query::insert();
453    ///     insert
454    ///         .into_table(Glyph::Table)
455    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
456    ///         .select_from(select)
457    ///         .unwrap();
458    ///     let query = insert.with(with_clause);
459    ///
460    /// assert_eq!(
461    ///     query.to_string(MysqlQueryBuilder),
462    ///     r#"WITH `cte` (`id`, `image`, `aspect`) AS (SELECT `id`, `image`, `aspect` FROM `glyph`) INSERT INTO `glyph` (`id`, `image`, `aspect`) SELECT `id`, `image`, `aspect` FROM `cte`"#
463    /// );
464    /// assert_eq!(
465    ///     query.to_string(PostgresQueryBuilder),
466    ///     r#"WITH "cte" ("id", "image", "aspect") AS (SELECT "id", "image", "aspect" FROM "glyph") INSERT INTO "glyph" ("id", "image", "aspect") SELECT "id", "image", "aspect" FROM "cte""#
467    /// );
468    /// assert_eq!(
469    ///     query.to_string(SqliteQueryBuilder),
470    ///     r#"WITH "cte" ("id", "image", "aspect") AS (SELECT "id", "image", "aspect" FROM "glyph") INSERT INTO "glyph" ("id", "image", "aspect") SELECT "id", "image", "aspect" FROM "cte""#
471    /// );
472    /// ```
473    pub fn with(self, clause: WithClause) -> WithQuery {
474        clause.query(self)
475    }
476
477    /// Create a Common Table Expression by specifying a [CommonTableExpression] or [WithClause] to execute this query with.
478    ///
479    /// # Examples
480    ///
481    /// ```
482    /// use sea_query::{*, IntoCondition, IntoIden, tests_cfg::*};
483    ///
484    /// let select = SelectStatement::new()
485    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
486    ///         .from(Glyph::Table)
487    ///         .to_owned();
488    ///     let cte = CommonTableExpression::new()
489    ///         .query(select)
490    ///         .column(Glyph::Id)
491    ///         .column(Glyph::Image)
492    ///         .column(Glyph::Aspect)
493    ///         .table_name(Alias::new("cte"))
494    ///         .to_owned();
495    ///     let with_clause = WithClause::new().cte(cte).to_owned();
496    ///     let select = SelectStatement::new()
497    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
498    ///         .from(Alias::new("cte"))
499    ///         .to_owned();
500    ///     let mut query = Query::insert();
501    ///     query
502    ///         .with_cte(with_clause)
503    ///         .into_table(Glyph::Table)
504    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
505    ///         .select_from(select)
506    ///         .unwrap();
507    ///
508    /// assert_eq!(
509    ///     query.to_string(MysqlQueryBuilder),
510    ///     r#"WITH `cte` (`id`, `image`, `aspect`) AS (SELECT `id`, `image`, `aspect` FROM `glyph`) INSERT INTO `glyph` (`id`, `image`, `aspect`) SELECT `id`, `image`, `aspect` FROM `cte`"#
511    /// );
512    /// assert_eq!(
513    ///     query.to_string(PostgresQueryBuilder),
514    ///     r#"WITH "cte" ("id", "image", "aspect") AS (SELECT "id", "image", "aspect" FROM "glyph") INSERT INTO "glyph" ("id", "image", "aspect") SELECT "id", "image", "aspect" FROM "cte""#
515    /// );
516    /// assert_eq!(
517    ///     query.to_string(SqliteQueryBuilder),
518    ///     r#"WITH "cte" ("id", "image", "aspect") AS (SELECT "id", "image", "aspect" FROM "glyph") INSERT INTO "glyph" ("id", "image", "aspect") SELECT "id", "image", "aspect" FROM "cte""#
519    /// );
520    /// ```
521    pub fn with_cte<C: Into<WithClause>>(&mut self, clause: C) -> &mut Self {
522        self.with = Some(clause.into());
523        self
524    }
525
526    /// Insert with default values if columns and values are not supplied.
527    ///
528    /// # Examples
529    ///
530    /// ```
531    /// use sea_query::{tests_cfg::*, *};
532    ///
533    /// // Insert default
534    /// let query = Query::insert()
535    ///     .into_table(Glyph::Table)
536    ///     .or_default_values()
537    ///     .to_owned();
538    ///
539    /// assert_eq!(
540    ///     query.to_string(MysqlQueryBuilder),
541    ///     r#"INSERT INTO `glyph` VALUES ()"#
542    /// );
543    /// assert_eq!(
544    ///     query.to_string(PostgresQueryBuilder),
545    ///     r#"INSERT INTO "glyph" VALUES (DEFAULT)"#
546    /// );
547    /// assert_eq!(
548    ///     query.to_string(SqliteQueryBuilder),
549    ///     r#"INSERT INTO "glyph" DEFAULT VALUES"#
550    /// );
551    ///
552    /// // Ordinary insert as columns and values are supplied
553    /// let query = Query::insert()
554    ///     .into_table(Glyph::Table)
555    ///     .or_default_values()
556    ///     .columns([Glyph::Image])
557    ///     .values_panic(["ABC".into()])
558    ///     .to_owned();
559    ///
560    /// assert_eq!(
561    ///     query.to_string(MysqlQueryBuilder),
562    ///     r#"INSERT INTO `glyph` (`image`) VALUES ('ABC')"#
563    /// );
564    /// assert_eq!(
565    ///     query.to_string(PostgresQueryBuilder),
566    ///     r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
567    /// );
568    /// assert_eq!(
569    ///     query.to_string(SqliteQueryBuilder),
570    ///     r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
571    /// );
572    /// ```
573    pub fn or_default_values(&mut self) -> &mut Self {
574        self.default_values = Some(1);
575        self
576    }
577
578    /// Insert multiple rows with default values if columns and values are not supplied.
579    ///
580    /// # Examples
581    ///
582    /// ```
583    /// use sea_query::{tests_cfg::*, *};
584    ///
585    /// // Insert default
586    /// let query = Query::insert()
587    ///     .into_table(Glyph::Table)
588    ///     .or_default_values_many(3)
589    ///     .to_owned();
590    ///
591    /// assert_eq!(
592    ///     query.to_string(MysqlQueryBuilder),
593    ///     r#"INSERT INTO `glyph` VALUES (), (), ()"#
594    /// );
595    /// assert_eq!(
596    ///     query.to_string(PostgresQueryBuilder),
597    ///     r#"INSERT INTO "glyph" VALUES (DEFAULT), (DEFAULT), (DEFAULT)"#
598    /// );
599    /// assert_eq!(
600    ///     query.to_string(SqliteQueryBuilder),
601    ///     r#"INSERT INTO "glyph" DEFAULT VALUES"#
602    /// );
603    ///
604    /// // Ordinary insert as columns and values are supplied
605    /// let query = Query::insert()
606    ///     .into_table(Glyph::Table)
607    ///     .or_default_values_many(3)
608    ///     .columns([Glyph::Image])
609    ///     .values_panic(["ABC".into()])
610    ///     .to_owned();
611    ///
612    /// assert_eq!(
613    ///     query.to_string(MysqlQueryBuilder),
614    ///     r#"INSERT INTO `glyph` (`image`) VALUES ('ABC')"#
615    /// );
616    /// assert_eq!(
617    ///     query.to_string(PostgresQueryBuilder),
618    ///     r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
619    /// );
620    /// assert_eq!(
621    ///     query.to_string(SqliteQueryBuilder),
622    ///     r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
623    /// );
624    /// ```
625    pub fn or_default_values_many(&mut self, num_rows: u32) -> &mut Self {
626        self.default_values = Some(num_rows);
627        self
628    }
629}
630
631#[inherent]
632impl QueryStatementBuilder for InsertStatement {
633    pub fn build_collect_any_into(
634        &self,
635        query_builder: &dyn QueryBuilder,
636        sql: &mut dyn SqlWriter,
637    ) {
638        query_builder.prepare_insert_statement(self, sql);
639    }
640
641    pub fn into_sub_query_statement(self) -> SubQueryStatement {
642        SubQueryStatement::InsertStatement(self)
643    }
644
645    pub fn build_any(&self, query_builder: &dyn QueryBuilder) -> (String, Values);
646    pub fn build_collect_any(
647        &self,
648        query_builder: &dyn QueryBuilder,
649        sql: &mut dyn SqlWriter,
650    ) -> String;
651}
652
653#[inherent]
654impl QueryStatementWriter for InsertStatement {
655    pub fn build_collect_into<T: QueryBuilder>(&self, query_builder: T, sql: &mut dyn SqlWriter) {
656        query_builder.prepare_insert_statement(self, sql);
657    }
658
659    pub fn build_collect<T: QueryBuilder>(
660        &self,
661        query_builder: T,
662        sql: &mut dyn SqlWriter,
663    ) -> String;
664    pub fn build<T: QueryBuilder>(&self, query_builder: T) -> (String, Values);
665    pub fn to_string<T: QueryBuilder>(&self, query_builder: T) -> String;
666}