Skip to main content

sea_query/query/
insert.rs

1use crate::{
2    DynIden, Expr, IntoColumnRef, IntoIden, IntoTableRef, OnConflict, QueryBuilder, QueryStatement,
3    QueryStatementBuilder, QueryStatementWriter, ReturningClause, SelectStatement, SqlWriter,
4    SubQueryStatement, TableRef, Values, WithClause, WithQuery,
5    error::{Error, Result},
6};
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<Expr>>),
15    Select(Box<SelectStatement>),
16}
17
18/// Insert any new rows into an existing table
19///
20/// # Examples
21///
22/// ```
23/// use sea_query::{audit::*, 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///     .take();
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/// assert_eq!(
45///     query.audit().unwrap().inserted_tables(),
46///     [Glyph::Table.into_iden()]
47/// );
48/// ```
49#[derive(Debug, Default, Clone, PartialEq)]
50pub struct InsertStatement {
51    pub(crate) replace: bool,
52    pub(crate) table: Option<Box<TableRef>>,
53    pub(crate) columns: Vec<DynIden>,
54    pub(crate) source: Option<InsertValueSource>,
55    pub(crate) on_conflict: Option<OnConflict>,
56    pub(crate) returning: Option<ReturningClause>,
57    pub(crate) default_values: Option<u32>,
58    pub(crate) with: Option<WithClause>,
59}
60
61impl InsertStatement {
62    /// Construct a new [`InsertStatement`]
63    pub fn new() -> Self {
64        Self::default()
65    }
66
67    /// Take the ownership of data in the current [`SelectStatement`]
68    pub fn take(&mut self) -> Self {
69        Self {
70            replace: self.replace,
71            table: self.table.take(),
72            columns: std::mem::take(&mut self.columns),
73            source: self.source.take(),
74            on_conflict: self.on_conflict.take(),
75            returning: self.returning.take(),
76            default_values: self.default_values.take(),
77            with: self.with.take(),
78        }
79    }
80
81    /// Use REPLACE instead of INSERT
82    ///
83    /// # Examples
84    ///
85    /// ```
86    /// use sea_query::{tests_cfg::*, *};
87    ///
88    /// let query = Query::insert()
89    ///     .replace()
90    ///     .into_table(Glyph::Table)
91    ///     .columns([Glyph::Aspect, Glyph::Image])
92    ///     .values_panic([5.15.into(), "12A".into()])
93    ///     .take();
94    ///
95    /// assert_eq!(
96    ///     query.to_string(MysqlQueryBuilder),
97    ///     r#"REPLACE INTO `glyph` (`aspect`, `image`) VALUES (5.15, '12A')"#
98    /// );
99    /// assert_eq!(
100    ///     query.to_string(SqliteQueryBuilder),
101    ///     r#"REPLACE INTO "glyph" ("aspect", "image") VALUES (5.15, '12A')"#
102    /// );
103    /// ```
104    #[cfg(any(feature = "backend-sqlite", feature = "backend-mysql"))]
105    pub fn replace(&mut self) -> &mut Self {
106        self.replace = true;
107        self
108    }
109
110    /// Specify which table to insert into.
111    ///
112    /// # Examples
113    ///
114    /// See [`InsertStatement::values`]
115    pub fn into_table<T>(&mut self, tbl_ref: T) -> &mut Self
116    where
117        T: IntoTableRef,
118    {
119        self.table = Some(Box::new(tbl_ref.into_table_ref()));
120        self
121    }
122
123    /// Specify what columns to insert.
124    ///
125    /// # Examples
126    ///
127    /// See [`InsertStatement::values`]
128    pub fn columns<C, I>(&mut self, columns: I) -> &mut Self
129    where
130        C: IntoIden,
131        I: IntoIterator<Item = C>,
132    {
133        self.columns = columns.into_iter().map(|c| c.into_iden()).collect();
134        self
135    }
136
137    /// Specify a select query whose values to be inserted.
138    ///
139    /// # Examples
140    ///
141    /// ```
142    /// use sea_query::{audit::*, tests_cfg::*, *};
143    ///
144    /// let query = Query::insert()
145    ///     .into_table(Glyph::Table)
146    ///     .columns([Glyph::Aspect, Glyph::Image])
147    ///     .select_from(Query::select()
148    ///         .column(Glyph::Aspect)
149    ///         .column(Glyph::Image)
150    ///         .from(Glyph::Table)
151    ///         .and_where(Expr::col(Glyph::Image).like("0%"))
152    ///         .take()
153    ///     )
154    ///     .unwrap()
155    ///     .take();
156    ///
157    /// assert_eq!(
158    ///     query.to_string(MysqlQueryBuilder),
159    ///     r#"INSERT INTO `glyph` (`aspect`, `image`) SELECT `aspect`, `image` FROM `glyph` WHERE `image` LIKE '0%'"#
160    /// );
161    /// assert_eq!(
162    ///     query.to_string(PostgresQueryBuilder),
163    ///     r#"INSERT INTO "glyph" ("aspect", "image") SELECT "aspect", "image" FROM "glyph" WHERE "image" LIKE '0%'"#
164    /// );
165    /// assert_eq!(
166    ///     query.to_string(SqliteQueryBuilder),
167    ///     r#"INSERT INTO "glyph" ("aspect", "image") SELECT "aspect", "image" FROM "glyph" WHERE "image" LIKE '0%'"#
168    /// );
169    /// assert_eq!(
170    ///     query.audit().unwrap().selected_tables(),
171    ///     [Glyph::Table.into_iden()]
172    /// );
173    /// assert_eq!(
174    ///     query.audit().unwrap().inserted_tables(),
175    ///     [Glyph::Table.into_iden()]
176    /// );
177    /// ```
178    ///
179    /// ```
180    /// use sea_query::{tests_cfg::*, *};
181    /// let query = Query::insert()
182    ///     .into_table(Glyph::Table)
183    ///     .columns([Glyph::Image])
184    ///     .select_from(
185    ///         Query::select()
186    ///             .expr(Expr::val("hello"))
187    ///             .cond_where(Cond::all().not().add(Expr::exists(
188    ///                 Query::select().expr(Expr::val("world")).take(),
189    ///             )))
190    ///             .take(),
191    ///     )
192    ///     .unwrap()
193    ///     .take();
194    ///
195    /// assert_eq!(
196    ///     query.to_string(SqliteQueryBuilder),
197    ///     r#"INSERT INTO "glyph" ("image") SELECT 'hello' WHERE NOT EXISTS(SELECT 'world')"#
198    /// );
199    /// ```
200    ///
201    /// ```
202    /// use sea_query::{audit::*, tests_cfg::*, *};
203    /// let query = Query::insert()
204    ///     .into_table(Glyph::Table)
205    ///     .columns([Glyph::Image])
206    ///     .select_from(
207    ///         Query::select()
208    ///             .expr(Expr::col(Font::Name))
209    ///             .from(Font::Table)
210    ///             .take(),
211    ///     )
212    ///     .unwrap()
213    ///     .take();
214    ///
215    /// assert_eq!(
216    ///     query.to_string(SqliteQueryBuilder),
217    ///     r#"INSERT INTO "glyph" ("image") SELECT "name" FROM "font""#
218    /// );
219    /// assert_eq!(
220    ///     query.audit().unwrap().selected_tables(),
221    ///     [Font::Table.into_iden()]
222    /// );
223    /// assert_eq!(
224    ///     query.audit().unwrap().inserted_tables(),
225    ///     [Glyph::Table.into_iden()]
226    /// );
227    /// ```
228    pub fn select_from<S>(&mut self, select: S) -> Result<&mut Self>
229    where
230        S: Into<SelectStatement>,
231    {
232        let statement = select.into();
233
234        if self.columns.len() != statement.selects.len() {
235            return Err(Error::ColValNumMismatch {
236                col_len: self.columns.len(),
237                val_len: statement.selects.len(),
238            });
239        }
240
241        self.source = Some(InsertValueSource::Select(Box::new(statement)));
242        Ok(self)
243    }
244
245    /// Specify a row of values to be inserted.
246    ///
247    /// Return error when number of values not matching number of columns.
248    ///
249    /// # Examples
250    ///
251    /// ```
252    /// use sea_query::{tests_cfg::*, *};
253    ///
254    /// let query = Query::insert()
255    ///     .into_table(Glyph::Table)
256    ///     .columns([Glyph::Aspect, Glyph::Image])
257    ///     .values([
258    ///         2.into(),
259    ///         Func::cast_as("2020-02-02 00:00:00", "DATE").into(),
260    ///     ])
261    ///     .unwrap()
262    ///     .take();
263    ///
264    /// assert_eq!(
265    ///     query.to_string(MysqlQueryBuilder),
266    ///     r#"INSERT INTO `glyph` (`aspect`, `image`) VALUES (2, CAST('2020-02-02 00:00:00' AS DATE))"#
267    /// );
268    /// assert_eq!(
269    ///     query.to_string(PostgresQueryBuilder),
270    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2, CAST('2020-02-02 00:00:00' AS DATE))"#
271    /// );
272    /// assert_eq!(
273    ///     query.to_string(SqliteQueryBuilder),
274    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2, CAST('2020-02-02 00:00:00' AS DATE))"#
275    /// );
276    ///
277    /// assert!(
278    ///     Query::insert()
279    ///         .into_table(Glyph::Table)
280    ///         .columns([Glyph::Aspect, Glyph::Image])
281    ///         .values([1.into()])
282    ///         .is_err()
283    /// );
284    /// ```
285    pub fn values<I>(&mut self, values: I) -> Result<&mut Self>
286    where
287        I: IntoIterator<Item = Expr>,
288    {
289        let values = values.into_iter().collect::<Vec<Expr>>();
290        if self.columns.len() != values.len() {
291            return Err(Error::ColValNumMismatch {
292                col_len: self.columns.len(),
293                val_len: values.len(),
294            });
295        }
296        if !values.is_empty() {
297            let values_source = if let Some(InsertValueSource::Values(values)) = &mut self.source {
298                values
299            } else {
300                self.source = Some(InsertValueSource::Values(Default::default()));
301                if let Some(InsertValueSource::Values(values)) = &mut self.source {
302                    values
303                } else {
304                    unreachable!();
305                }
306            };
307            values_source.push(values);
308        }
309        Ok(self)
310    }
311
312    /// Specify a row of values to be inserted, variation of [`InsertStatement::values`].
313    ///
314    /// # Panics
315    ///
316    /// Panics when number of values not matching number of columns.
317    /// The equivalent `insert_many` method in SeaORM does not panic, it can construct the column list from active models.
318    ///
319    /// # Examples
320    ///
321    /// ```
322    /// use sea_query::{tests_cfg::*, *};
323    ///
324    /// let query = Query::insert()
325    ///     .into_table(Glyph::Table)
326    ///     .columns([Glyph::Aspect, Glyph::Image])
327    ///     .values_panic([2.1345.into(), "24B".into()])
328    ///     .values_panic([5.15.into(), "12A".into()])
329    ///     .take();
330    ///
331    /// assert_eq!(
332    ///     query.to_string(MysqlQueryBuilder),
333    ///     r#"INSERT INTO `glyph` (`aspect`, `image`) VALUES (2.1345, '24B'), (5.15, '12A')"#
334    /// );
335    /// assert_eq!(
336    ///     query.to_string(PostgresQueryBuilder),
337    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
338    /// );
339    /// assert_eq!(
340    ///     query.to_string(SqliteQueryBuilder),
341    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
342    /// );
343    /// ```
344    ///
345    /// ```should_panic
346    /// # use sea_query::{tests_cfg::*, *};
347    /// let query = Query::insert()
348    ///     .into_table(Glyph::Table)
349    ///     .columns([Glyph::Aspect])
350    ///     .values_panic([2.1345.into(), "24B".into()])
351    ///     .take();
352    /// ```
353    ///
354    /// The same query can be constructed using the `raw_query!` macro.
355    ///
356    /// ```
357    /// use sea_query::Values;
358    ///
359    /// let values = vec![(2.1345, "24B"), (5.15, "12A")];
360    /// let query = sea_query::raw_query!(
361    ///     PostgresQueryBuilder,
362    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES {..(values.0:1),}"#
363    /// );
364    ///
365    /// assert_eq!(
366    ///     query.sql,
367    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES ($1, $2), ($3, $4)"#
368    /// );
369    /// assert_eq!(
370    ///     query.values,
371    ///     Values(vec![2.1345.into(), "24B".into(), 5.15.into(), "12A".into()])
372    /// );
373    ///
374    /// // same as above but with named fields:
375    ///
376    /// struct Item<'a> {
377    ///     aspect: f64,
378    ///     image: &'a str,
379    /// };
380    ///
381    /// let values = vec![
382    ///     Item {
383    ///         aspect: 2.1345,
384    ///         image: "24B",
385    ///     },
386    ///     Item {
387    ///         aspect: 5.15,
388    ///         image: "12A",
389    ///     },
390    /// ];
391    ///
392    /// let new_query = sea_query::raw_query!(
393    ///     PostgresQueryBuilder,
394    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES {..(values.aspect, values.image),}"#
395    /// );
396    ///
397    /// assert_eq!(query.sql, new_query.sql);
398    /// assert_eq!(query.values, new_query.values);
399    /// ```
400    pub fn values_panic<I>(&mut self, values: I) -> &mut Self
401    where
402        I: IntoIterator<Item = Expr>,
403    {
404        self.values(values).unwrap()
405    }
406
407    /// Add rows to be inserted from an iterator, variation of [`InsertStatement::values_panic`].
408    ///
409    /// # Examples
410    ///
411    /// ```
412    /// use sea_query::{audit::*, tests_cfg::*, *};
413    ///
414    /// let rows = vec![[2.1345.into(), "24B".into()], [5.15.into(), "12A".into()]];
415    ///
416    /// let query = Query::insert()
417    ///     .into_table(Glyph::Table)
418    ///     .columns([Glyph::Aspect, Glyph::Image])
419    ///     .values_from_panic(rows)
420    ///     .take();
421    ///
422    /// assert_eq!(
423    ///     query.to_string(MysqlQueryBuilder),
424    ///     r#"INSERT INTO `glyph` (`aspect`, `image`) VALUES (2.1345, '24B'), (5.15, '12A')"#
425    /// );
426    /// assert_eq!(
427    ///     query.to_string(PostgresQueryBuilder),
428    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
429    /// );
430    /// assert_eq!(
431    ///     query.to_string(SqliteQueryBuilder),
432    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
433    /// );
434    /// assert_eq!(
435    ///     query.audit().unwrap().inserted_tables(),
436    ///     [Glyph::Table.into_iden()]
437    /// );
438    /// ```
439    pub fn values_from_panic<I, J>(&mut self, values_iter: J) -> &mut Self
440    where
441        I: IntoIterator<Item = Expr>,
442        J: IntoIterator<Item = I>,
443    {
444        values_iter.into_iter().for_each(|values| {
445            self.values_panic(values);
446        });
447        self
448    }
449
450    /// ON CONFLICT expression
451    ///
452    /// # Examples
453    ///
454    /// - [`OnConflict::update_columns`]: Update column value of existing row with inserting value
455    pub fn on_conflict(&mut self, on_conflict: OnConflict) -> &mut Self {
456        self.on_conflict = Some(on_conflict);
457        self
458    }
459
460    /// RETURNING expressions.
461    ///
462    /// # Examples
463    ///
464    /// ```
465    /// use sea_query::{tests_cfg::*, *};
466    ///
467    /// let query = Query::insert()
468    ///     .into_table(Glyph::Table)
469    ///     .columns([Glyph::Image])
470    ///     .values_panic(["12A".into()])
471    ///     .returning(Query::returning().columns([Glyph::Id]))
472    ///     .take();
473    ///
474    /// assert_eq!(
475    ///     query.to_string(MysqlQueryBuilder),
476    ///     "INSERT INTO `glyph` (`image`) VALUES ('12A')"
477    /// );
478    /// assert_eq!(
479    ///     query.to_string(PostgresQueryBuilder),
480    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
481    /// );
482    /// assert_eq!(
483    ///     query.to_string(SqliteQueryBuilder),
484    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
485    /// );
486    /// ```
487    pub fn returning(&mut self, returning: ReturningClause) -> &mut Self {
488        self.returning = Some(returning);
489        self
490    }
491
492    /// RETURNING expressions for a column.
493    ///
494    /// # Examples
495    ///
496    /// ```
497    /// use sea_query::{tests_cfg::*, *};
498    ///
499    /// let query = Query::insert()
500    ///     .into_table(Glyph::Table)
501    ///     .columns([Glyph::Image])
502    ///     .values_panic(["12A".into()])
503    ///     .returning_col(Glyph::Id)
504    ///     .take();
505    ///
506    /// assert_eq!(
507    ///     query.to_string(MysqlQueryBuilder),
508    ///     "INSERT INTO `glyph` (`image`) VALUES ('12A')"
509    /// );
510    /// assert_eq!(
511    ///     query.to_string(PostgresQueryBuilder),
512    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
513    /// );
514    /// assert_eq!(
515    ///     query.to_string(SqliteQueryBuilder),
516    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
517    /// );
518    /// ```
519    pub fn returning_col<C>(&mut self, col: C) -> &mut Self
520    where
521        C: IntoColumnRef,
522    {
523        self.returning(ReturningClause::Columns(vec![col.into_column_ref()]))
524    }
525
526    /// RETURNING expressions all columns.
527    ///
528    /// # Examples
529    ///
530    /// ```
531    /// use sea_query::{tests_cfg::*, *};
532    ///
533    /// let query = Query::insert()
534    ///     .into_table(Glyph::Table)
535    ///     .columns([Glyph::Image])
536    ///     .values_panic(["12A".into()])
537    ///     .returning_all()
538    ///     .take();
539    ///
540    /// assert_eq!(
541    ///     query.to_string(MysqlQueryBuilder),
542    ///     "INSERT INTO `glyph` (`image`) VALUES ('12A')"
543    /// );
544    /// assert_eq!(
545    ///     query.to_string(PostgresQueryBuilder),
546    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING *"#
547    /// );
548    /// assert_eq!(
549    ///     query.to_string(SqliteQueryBuilder),
550    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING *"#
551    /// );
552    /// ```
553    pub fn returning_all(&mut self) -> &mut Self {
554        self.returning(ReturningClause::All)
555    }
556
557    /// Create a [WithQuery] by specifying a [WithClause] to execute this query with.
558    ///
559    /// # Examples
560    ///
561    /// ```
562    /// use sea_query::{*, IntoCondition, IntoIden, tests_cfg::*};
563    ///
564    /// let select = SelectStatement::new()
565    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
566    ///         .from(Glyph::Table)
567    ///         .take();
568    ///     let cte = CommonTableExpression::new()
569    ///         .query(select)
570    ///         .column(Glyph::Id)
571    ///         .column(Glyph::Image)
572    ///         .column(Glyph::Aspect)
573    ///         .table_name("cte")
574    ///         .to_owned();
575    ///     let with_clause = WithClause::new().cte(cte).to_owned();
576    ///     let select = SelectStatement::new()
577    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
578    ///         .from("cte")
579    ///         .take();
580    ///     let mut insert = Query::insert();
581    ///     insert
582    ///         .into_table(Glyph::Table)
583    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
584    ///         .select_from(select)
585    ///         .unwrap();
586    ///     let query = insert.with(with_clause);
587    ///
588    /// assert_eq!(
589    ///     query.to_string(MysqlQueryBuilder),
590    ///     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`"#
591    /// );
592    /// assert_eq!(
593    ///     query.to_string(PostgresQueryBuilder),
594    ///     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""#
595    /// );
596    /// assert_eq!(
597    ///     query.to_string(SqliteQueryBuilder),
598    ///     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""#
599    /// );
600    /// ```
601    pub fn with(self, clause: WithClause) -> WithQuery {
602        clause.query(self)
603    }
604
605    /// Create a Common Table Expression by specifying a [CommonTableExpression][crate::CommonTableExpression]
606    /// or [WithClause] to execute this query with.
607    ///
608    /// # Examples
609    ///
610    /// ```
611    /// use sea_query::{*, IntoCondition, IntoIden, tests_cfg::*};
612    ///
613    /// let select = SelectStatement::new()
614    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
615    ///         .from(Glyph::Table)
616    ///         .take();
617    ///     let cte = CommonTableExpression::new()
618    ///         .query(select)
619    ///         .column(Glyph::Id)
620    ///         .column(Glyph::Image)
621    ///         .column(Glyph::Aspect)
622    ///         .table_name("cte")
623    ///         .to_owned();
624    ///     let with_clause = WithClause::new().cte(cte).to_owned();
625    ///     let select = SelectStatement::new()
626    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
627    ///         .from("cte")
628    ///         .take();
629    ///     let mut query = Query::insert();
630    ///     query
631    ///         .with_cte(with_clause)
632    ///         .into_table(Glyph::Table)
633    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
634    ///         .select_from(select)
635    ///         .unwrap();
636    ///
637    /// assert_eq!(
638    ///     query.to_string(MysqlQueryBuilder),
639    ///     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`"#
640    /// );
641    /// assert_eq!(
642    ///     query.to_string(PostgresQueryBuilder),
643    ///     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""#
644    /// );
645    /// assert_eq!(
646    ///     query.to_string(SqliteQueryBuilder),
647    ///     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""#
648    /// );
649    /// ```
650    pub fn with_cte<C: Into<WithClause>>(&mut self, clause: C) -> &mut Self {
651        self.with = Some(clause.into());
652        self
653    }
654
655    /// Insert with default values if columns and values are not supplied.
656    ///
657    /// # Examples
658    ///
659    /// ```
660    /// use sea_query::{tests_cfg::*, *};
661    ///
662    /// // Insert default
663    /// let query = Query::insert()
664    ///     .into_table(Glyph::Table)
665    ///     .or_default_values()
666    ///     .take();
667    ///
668    /// assert_eq!(
669    ///     query.to_string(MysqlQueryBuilder),
670    ///     r#"INSERT INTO `glyph` VALUES ()"#
671    /// );
672    /// assert_eq!(
673    ///     query.to_string(PostgresQueryBuilder),
674    ///     r#"INSERT INTO "glyph" VALUES (DEFAULT)"#
675    /// );
676    /// assert_eq!(
677    ///     query.to_string(SqliteQueryBuilder),
678    ///     r#"INSERT INTO "glyph" DEFAULT VALUES"#
679    /// );
680    ///
681    /// // Ordinary insert as columns and values are supplied
682    /// let query = Query::insert()
683    ///     .into_table(Glyph::Table)
684    ///     .or_default_values()
685    ///     .columns([Glyph::Image])
686    ///     .values_panic(["ABC".into()])
687    ///     .take();
688    ///
689    /// assert_eq!(
690    ///     query.to_string(MysqlQueryBuilder),
691    ///     r#"INSERT INTO `glyph` (`image`) VALUES ('ABC')"#
692    /// );
693    /// assert_eq!(
694    ///     query.to_string(PostgresQueryBuilder),
695    ///     r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
696    /// );
697    /// assert_eq!(
698    ///     query.to_string(SqliteQueryBuilder),
699    ///     r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
700    /// );
701    /// ```
702    pub fn or_default_values(&mut self) -> &mut Self {
703        self.default_values = Some(1);
704        self
705    }
706
707    /// Insert multiple rows with default values if columns and values are not supplied.
708    ///
709    /// # Examples
710    ///
711    /// ```
712    /// use sea_query::{tests_cfg::*, *};
713    ///
714    /// // Insert default
715    /// let query = Query::insert()
716    ///     .into_table(Glyph::Table)
717    ///     .or_default_values_many(3)
718    ///     .take();
719    ///
720    /// assert_eq!(
721    ///     query.to_string(MysqlQueryBuilder),
722    ///     r#"INSERT INTO `glyph` VALUES (), (), ()"#
723    /// );
724    /// assert_eq!(
725    ///     query.to_string(PostgresQueryBuilder),
726    ///     r#"INSERT INTO "glyph" VALUES (DEFAULT), (DEFAULT), (DEFAULT)"#
727    /// );
728    /// assert_eq!(
729    ///     query.to_string(SqliteQueryBuilder),
730    ///     r#"INSERT INTO "glyph" DEFAULT VALUES"#
731    /// );
732    ///
733    /// // Ordinary insert as columns and values are supplied
734    /// let query = Query::insert()
735    ///     .into_table(Glyph::Table)
736    ///     .or_default_values_many(3)
737    ///     .columns([Glyph::Image])
738    ///     .values_panic(["ABC".into()])
739    ///     .take();
740    ///
741    /// assert_eq!(
742    ///     query.to_string(MysqlQueryBuilder),
743    ///     r#"INSERT INTO `glyph` (`image`) VALUES ('ABC')"#
744    /// );
745    /// assert_eq!(
746    ///     query.to_string(PostgresQueryBuilder),
747    ///     r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
748    /// );
749    /// assert_eq!(
750    ///     query.to_string(SqliteQueryBuilder),
751    ///     r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
752    /// );
753    /// ```
754    pub fn or_default_values_many(&mut self, num_rows: u32) -> &mut Self {
755        self.default_values = Some(num_rows);
756        self
757    }
758}
759
760impl QueryStatementBuilder for InsertStatement {
761    fn build_collect_any_into(&self, query_builder: &impl QueryBuilder, sql: &mut impl SqlWriter) {
762        query_builder.prepare_insert_statement(self, sql);
763    }
764}
765
766impl InsertStatement {
767    pub fn build_any(&self, query_builder: &impl QueryBuilder) -> (String, Values) {
768        <Self as QueryStatementBuilder>::build_any(self, query_builder)
769    }
770
771    pub fn build_collect_any(
772        &self,
773        query_builder: &impl QueryBuilder,
774        sql: &mut impl SqlWriter,
775    ) -> String {
776        <Self as QueryStatementBuilder>::build_collect_any(self, query_builder, sql)
777    }
778
779    pub fn build_collect_any_into(
780        &self,
781        query_builder: &impl QueryBuilder,
782        sql: &mut impl SqlWriter,
783    ) {
784        <Self as QueryStatementBuilder>::build_collect_any_into(self, query_builder, sql)
785    }
786}
787
788impl From<InsertStatement> for QueryStatement {
789    fn from(s: InsertStatement) -> Self {
790        Self::Insert(s)
791    }
792}
793
794impl From<InsertStatement> for SubQueryStatement {
795    fn from(s: InsertStatement) -> Self {
796        Self::InsertStatement(s)
797    }
798}
799
800impl QueryStatementWriter for InsertStatement {
801    fn build_collect_into<T: QueryBuilder>(&self, query_builder: T, sql: &mut impl SqlWriter) {
802        query_builder.prepare_insert_statement(self, sql);
803    }
804}
805
806impl InsertStatement {
807    pub fn to_string<T: QueryBuilder>(&self, query_builder: T) -> String {
808        <Self as QueryStatementWriter>::to_string(self, query_builder)
809    }
810
811    pub fn build<T: QueryBuilder>(&self, query_builder: T) -> (String, Values) {
812        <Self as QueryStatementWriter>::build(self, query_builder)
813    }
814
815    pub fn build_collect<T: QueryBuilder>(
816        &self,
817        query_builder: T,
818        sql: &mut impl SqlWriter,
819    ) -> String {
820        <Self as QueryStatementWriter>::build_collect(self, query_builder, sql)
821    }
822
823    pub fn build_collect_into<T: QueryBuilder>(&self, query_builder: T, sql: &mut impl SqlWriter) {
824        <Self as QueryStatementWriter>::build_collect_into(self, query_builder, sql);
825    }
826}