sea_query/query/
insert.rs

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