sea_query/query/
insert.rs

1use crate::{
2    Expr, OnConflict, QueryStatement, QueryStatementBuilder, QueryStatementWriter, ReturningClause,
3    SelectStatement, SubQueryStatement, Values, WithClause, WithQuery, backend::QueryBuilder,
4    error::*, prepare::*, types::*,
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<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    /// use sea_query::{audit::*, tests_cfg::*, *};
201    /// let query = Query::insert()
202    ///     .into_table(Glyph::Table)
203    ///     .columns([Glyph::Image])
204    ///     .select_from(
205    ///         Query::select()
206    ///             .expr(Font::Name)
207    ///             .from(Font::Table)
208    ///             .take(),
209    ///     )
210    ///     .unwrap()
211    ///     .take();
212    ///
213    /// assert_eq!(
214    ///     query.to_string(SqliteQueryBuilder),
215    ///     r#"INSERT INTO "glyph" ("image") SELECT "name" FROM "font""#
216    /// );
217    /// assert_eq!(
218    ///     query.audit().unwrap().selected_tables(),
219    ///     [Font::Table.into_iden()]
220    /// );
221    /// assert_eq!(
222    ///     query.audit().unwrap().inserted_tables(),
223    ///     [Glyph::Table.into_iden()]
224    /// );
225    /// ```
226    pub fn select_from<S>(&mut self, select: S) -> Result<&mut Self>
227    where
228        S: Into<SelectStatement>,
229    {
230        let statement = select.into();
231
232        if self.columns.len() != statement.selects.len() {
233            return Err(Error::ColValNumMismatch {
234                col_len: self.columns.len(),
235                val_len: statement.selects.len(),
236            });
237        }
238
239        self.source = Some(InsertValueSource::Select(Box::new(statement)));
240        Ok(self)
241    }
242
243    /// Specify a row of values to be inserted.
244    /// Return error when number of values not matching number of columns.
245    ///
246    /// # Examples
247    ///
248    /// ```
249    /// use sea_query::{tests_cfg::*, *};
250    ///
251    /// let query = Query::insert()
252    ///     .into_table(Glyph::Table)
253    ///     .columns([Glyph::Aspect, Glyph::Image])
254    ///     .values([
255    ///         2.into(),
256    ///         Func::cast_as("2020-02-02 00:00:00", "DATE").into(),
257    ///     ])
258    ///     .unwrap()
259    ///     .take();
260    ///
261    /// assert_eq!(
262    ///     query.to_string(MysqlQueryBuilder),
263    ///     r#"INSERT INTO `glyph` (`aspect`, `image`) VALUES (2, CAST('2020-02-02 00:00:00' AS DATE))"#
264    /// );
265    /// assert_eq!(
266    ///     query.to_string(PostgresQueryBuilder),
267    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2, CAST('2020-02-02 00:00:00' AS DATE))"#
268    /// );
269    /// assert_eq!(
270    ///     query.to_string(SqliteQueryBuilder),
271    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2, CAST('2020-02-02 00:00:00' AS DATE))"#
272    /// );
273    ///
274    /// assert!(
275    ///     Query::insert()
276    ///         .into_table(Glyph::Table)
277    ///         .columns([Glyph::Aspect, Glyph::Image])
278    ///         .values([1.into()])
279    ///         .is_err()
280    /// );
281    /// ```
282    pub fn values<I>(&mut self, values: I) -> Result<&mut Self>
283    where
284        I: IntoIterator<Item = Expr>,
285    {
286        let values = values.into_iter().collect::<Vec<Expr>>();
287        if self.columns.len() != values.len() {
288            return Err(Error::ColValNumMismatch {
289                col_len: self.columns.len(),
290                val_len: values.len(),
291            });
292        }
293        if !values.is_empty() {
294            let values_source = if let Some(InsertValueSource::Values(values)) = &mut self.source {
295                values
296            } else {
297                self.source = Some(InsertValueSource::Values(Default::default()));
298                if let Some(InsertValueSource::Values(values)) = &mut self.source {
299                    values
300                } else {
301                    unreachable!();
302                }
303            };
304            values_source.push(values);
305        }
306        Ok(self)
307    }
308
309    /// Specify a row of values to be inserted, variation of [`InsertStatement::values`].
310    ///
311    /// # Examples
312    ///
313    /// ```
314    /// use sea_query::{tests_cfg::*, *};
315    ///
316    /// let query = Query::insert()
317    ///     .into_table(Glyph::Table)
318    ///     .columns([Glyph::Aspect, Glyph::Image])
319    ///     .values_panic([2.1345.into(), "24B".into()])
320    ///     .values_panic([5.15.into(), "12A".into()])
321    ///     .take();
322    ///
323    /// assert_eq!(
324    ///     query.to_string(MysqlQueryBuilder),
325    ///     r#"INSERT INTO `glyph` (`aspect`, `image`) VALUES (2.1345, '24B'), (5.15, '12A')"#
326    /// );
327    /// assert_eq!(
328    ///     query.to_string(PostgresQueryBuilder),
329    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
330    /// );
331    /// assert_eq!(
332    ///     query.to_string(SqliteQueryBuilder),
333    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
334    /// );
335    /// ```
336    ///
337    /// The same query can be constructed using the `raw_query!` macro.
338    ///
339    /// ```
340    /// use sea_query::Values;
341    ///
342    /// let values = vec![(2.1345, "24B"), (5.15, "12A")];
343    /// let query = sea_query::raw_query!(
344    ///     PostgresQueryBuilder,
345    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES {..(values.0:1),}"#
346    /// );
347    ///
348    /// assert_eq!(
349    ///     query.sql,
350    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES ($1, $2), ($3, $4)"#
351    /// );
352    /// assert_eq!(
353    ///     query.values,
354    ///     Values(vec![2.1345.into(), "24B".into(), 5.15.into(), "12A".into()])
355    /// );
356    ///
357    /// // same as above but with named fields:
358    ///
359    /// struct Item<'a> {
360    ///     aspect: f64,
361    ///     image: &'a str,
362    /// };
363    ///
364    /// let values = vec![
365    ///     Item {
366    ///         aspect: 2.1345,
367    ///         image: "24B",
368    ///     },
369    ///     Item {
370    ///         aspect: 5.15,
371    ///         image: "12A",
372    ///     },
373    /// ];
374    ///
375    /// let new_query = sea_query::raw_query!(
376    ///     PostgresQueryBuilder,
377    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES {..(values.aspect, values.image),}"#
378    /// );
379    ///
380    /// assert_eq!(query.sql, new_query.sql);
381    /// assert_eq!(query.values, new_query.values);
382    /// ```
383    pub fn values_panic<I>(&mut self, values: I) -> &mut Self
384    where
385        I: IntoIterator<Item = Expr>,
386    {
387        self.values(values).unwrap()
388    }
389
390    /// Add rows to be inserted from an iterator, variation of [`InsertStatement::values_panic`].
391    ///
392    /// # Examples
393    ///
394    /// ```
395    /// use sea_query::{audit::*, tests_cfg::*, *};
396    ///
397    /// let rows = vec![[2.1345.into(), "24B".into()], [5.15.into(), "12A".into()]];
398    ///
399    /// let query = Query::insert()
400    ///     .into_table(Glyph::Table)
401    ///     .columns([Glyph::Aspect, Glyph::Image])
402    ///     .values_from_panic(rows)
403    ///     .take();
404    ///
405    /// assert_eq!(
406    ///     query.to_string(MysqlQueryBuilder),
407    ///     r#"INSERT INTO `glyph` (`aspect`, `image`) VALUES (2.1345, '24B'), (5.15, '12A')"#
408    /// );
409    /// assert_eq!(
410    ///     query.to_string(PostgresQueryBuilder),
411    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
412    /// );
413    /// assert_eq!(
414    ///     query.to_string(SqliteQueryBuilder),
415    ///     r#"INSERT INTO "glyph" ("aspect", "image") VALUES (2.1345, '24B'), (5.15, '12A')"#
416    /// );
417    /// assert_eq!(
418    ///     query.audit().unwrap().inserted_tables(),
419    ///     [Glyph::Table.into_iden()]
420    /// );
421    /// ```
422    pub fn values_from_panic<I, J>(&mut self, values_iter: J) -> &mut Self
423    where
424        I: IntoIterator<Item = Expr>,
425        J: IntoIterator<Item = I>,
426    {
427        values_iter.into_iter().for_each(|values| {
428            self.values_panic(values);
429        });
430        self
431    }
432
433    /// ON CONFLICT expression
434    ///
435    /// # Examples
436    ///
437    /// - [`OnConflict::update_columns`]: Update column value of existing row with inserting value
438    /// - [`OnConflict::update_values`]: Update column value of existing row with value
439    /// - [`OnConflict::update_exprs`]: Update column value of existing row with expression
440    pub fn on_conflict(&mut self, on_conflict: OnConflict) -> &mut Self {
441        self.on_conflict = Some(on_conflict);
442        self
443    }
444
445    /// RETURNING expressions.
446    ///
447    /// # Examples
448    ///
449    /// ```
450    /// use sea_query::{tests_cfg::*, *};
451    ///
452    /// let query = Query::insert()
453    ///     .into_table(Glyph::Table)
454    ///     .columns([Glyph::Image])
455    ///     .values_panic(["12A".into()])
456    ///     .returning(Query::returning().columns([Glyph::Id]))
457    ///     .take();
458    ///
459    /// assert_eq!(
460    ///     query.to_string(MysqlQueryBuilder),
461    ///     "INSERT INTO `glyph` (`image`) VALUES ('12A')"
462    /// );
463    /// assert_eq!(
464    ///     query.to_string(PostgresQueryBuilder),
465    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
466    /// );
467    /// assert_eq!(
468    ///     query.to_string(SqliteQueryBuilder),
469    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
470    /// );
471    /// ```
472    pub fn returning(&mut self, returning: ReturningClause) -> &mut Self {
473        self.returning = Some(returning);
474        self
475    }
476
477    /// RETURNING expressions for a column.
478    ///
479    /// # Examples
480    ///
481    /// ```
482    /// use sea_query::{tests_cfg::*, *};
483    ///
484    /// let query = Query::insert()
485    ///     .into_table(Glyph::Table)
486    ///     .columns([Glyph::Image])
487    ///     .values_panic(["12A".into()])
488    ///     .returning_col(Glyph::Id)
489    ///     .take();
490    ///
491    /// assert_eq!(
492    ///     query.to_string(MysqlQueryBuilder),
493    ///     "INSERT INTO `glyph` (`image`) VALUES ('12A')"
494    /// );
495    /// assert_eq!(
496    ///     query.to_string(PostgresQueryBuilder),
497    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
498    /// );
499    /// assert_eq!(
500    ///     query.to_string(SqliteQueryBuilder),
501    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING "id""#
502    /// );
503    /// ```
504    pub fn returning_col<C>(&mut self, col: C) -> &mut Self
505    where
506        C: IntoColumnRef,
507    {
508        self.returning(ReturningClause::Columns(vec![col.into_column_ref()]))
509    }
510
511    /// RETURNING expressions all columns.
512    ///
513    /// # Examples
514    ///
515    /// ```
516    /// use sea_query::{tests_cfg::*, *};
517    ///
518    /// let query = Query::insert()
519    ///     .into_table(Glyph::Table)
520    ///     .columns([Glyph::Image])
521    ///     .values_panic(["12A".into()])
522    ///     .returning_all()
523    ///     .take();
524    ///
525    /// assert_eq!(
526    ///     query.to_string(MysqlQueryBuilder),
527    ///     "INSERT INTO `glyph` (`image`) VALUES ('12A')"
528    /// );
529    /// assert_eq!(
530    ///     query.to_string(PostgresQueryBuilder),
531    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING *"#
532    /// );
533    /// assert_eq!(
534    ///     query.to_string(SqliteQueryBuilder),
535    ///     r#"INSERT INTO "glyph" ("image") VALUES ('12A') RETURNING *"#
536    /// );
537    /// ```
538    pub fn returning_all(&mut self) -> &mut Self {
539        self.returning(ReturningClause::All)
540    }
541
542    /// Create a [WithQuery] by specifying a [WithClause] to execute this query with.
543    ///
544    /// # Examples
545    ///
546    /// ```
547    /// use sea_query::{*, IntoCondition, IntoIden, tests_cfg::*};
548    ///
549    /// let select = SelectStatement::new()
550    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
551    ///         .from(Glyph::Table)
552    ///         .take();
553    ///     let cte = CommonTableExpression::new()
554    ///         .query(select)
555    ///         .column(Glyph::Id)
556    ///         .column(Glyph::Image)
557    ///         .column(Glyph::Aspect)
558    ///         .table_name("cte")
559    ///         .to_owned();
560    ///     let with_clause = WithClause::new().cte(cte).to_owned();
561    ///     let select = SelectStatement::new()
562    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
563    ///         .from("cte")
564    ///         .take();
565    ///     let mut insert = Query::insert();
566    ///     insert
567    ///         .into_table(Glyph::Table)
568    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
569    ///         .select_from(select)
570    ///         .unwrap();
571    ///     let query = insert.with(with_clause);
572    ///
573    /// assert_eq!(
574    ///     query.to_string(MysqlQueryBuilder),
575    ///     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`"#
576    /// );
577    /// assert_eq!(
578    ///     query.to_string(PostgresQueryBuilder),
579    ///     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""#
580    /// );
581    /// assert_eq!(
582    ///     query.to_string(SqliteQueryBuilder),
583    ///     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""#
584    /// );
585    /// ```
586    pub fn with(self, clause: WithClause) -> WithQuery {
587        clause.query(self)
588    }
589
590    /// Create a Common Table Expression by specifying a [CommonTableExpression] or [WithClause] to execute this query with.
591    ///
592    /// # Examples
593    ///
594    /// ```
595    /// use sea_query::{*, IntoCondition, IntoIden, tests_cfg::*};
596    ///
597    /// let select = SelectStatement::new()
598    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
599    ///         .from(Glyph::Table)
600    ///         .take();
601    ///     let cte = CommonTableExpression::new()
602    ///         .query(select)
603    ///         .column(Glyph::Id)
604    ///         .column(Glyph::Image)
605    ///         .column(Glyph::Aspect)
606    ///         .table_name("cte")
607    ///         .to_owned();
608    ///     let with_clause = WithClause::new().cte(cte).to_owned();
609    ///     let select = SelectStatement::new()
610    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
611    ///         .from("cte")
612    ///         .take();
613    ///     let mut query = Query::insert();
614    ///     query
615    ///         .with_cte(with_clause)
616    ///         .into_table(Glyph::Table)
617    ///         .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
618    ///         .select_from(select)
619    ///         .unwrap();
620    ///
621    /// assert_eq!(
622    ///     query.to_string(MysqlQueryBuilder),
623    ///     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`"#
624    /// );
625    /// assert_eq!(
626    ///     query.to_string(PostgresQueryBuilder),
627    ///     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""#
628    /// );
629    /// assert_eq!(
630    ///     query.to_string(SqliteQueryBuilder),
631    ///     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""#
632    /// );
633    /// ```
634    pub fn with_cte<C: Into<WithClause>>(&mut self, clause: C) -> &mut Self {
635        self.with = Some(clause.into());
636        self
637    }
638
639    /// Insert with default values if columns and values are not supplied.
640    ///
641    /// # Examples
642    ///
643    /// ```
644    /// use sea_query::{tests_cfg::*, *};
645    ///
646    /// // Insert default
647    /// let query = Query::insert()
648    ///     .into_table(Glyph::Table)
649    ///     .or_default_values()
650    ///     .take();
651    ///
652    /// assert_eq!(
653    ///     query.to_string(MysqlQueryBuilder),
654    ///     r#"INSERT INTO `glyph` VALUES ()"#
655    /// );
656    /// assert_eq!(
657    ///     query.to_string(PostgresQueryBuilder),
658    ///     r#"INSERT INTO "glyph" VALUES (DEFAULT)"#
659    /// );
660    /// assert_eq!(
661    ///     query.to_string(SqliteQueryBuilder),
662    ///     r#"INSERT INTO "glyph" DEFAULT VALUES"#
663    /// );
664    ///
665    /// // Ordinary insert as columns and values are supplied
666    /// let query = Query::insert()
667    ///     .into_table(Glyph::Table)
668    ///     .or_default_values()
669    ///     .columns([Glyph::Image])
670    ///     .values_panic(["ABC".into()])
671    ///     .take();
672    ///
673    /// assert_eq!(
674    ///     query.to_string(MysqlQueryBuilder),
675    ///     r#"INSERT INTO `glyph` (`image`) VALUES ('ABC')"#
676    /// );
677    /// assert_eq!(
678    ///     query.to_string(PostgresQueryBuilder),
679    ///     r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
680    /// );
681    /// assert_eq!(
682    ///     query.to_string(SqliteQueryBuilder),
683    ///     r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
684    /// );
685    /// ```
686    pub fn or_default_values(&mut self) -> &mut Self {
687        self.default_values = Some(1);
688        self
689    }
690
691    /// Insert multiple rows with default values if columns and values are not supplied.
692    ///
693    /// # Examples
694    ///
695    /// ```
696    /// use sea_query::{tests_cfg::*, *};
697    ///
698    /// // Insert default
699    /// let query = Query::insert()
700    ///     .into_table(Glyph::Table)
701    ///     .or_default_values_many(3)
702    ///     .take();
703    ///
704    /// assert_eq!(
705    ///     query.to_string(MysqlQueryBuilder),
706    ///     r#"INSERT INTO `glyph` VALUES (), (), ()"#
707    /// );
708    /// assert_eq!(
709    ///     query.to_string(PostgresQueryBuilder),
710    ///     r#"INSERT INTO "glyph" VALUES (DEFAULT), (DEFAULT), (DEFAULT)"#
711    /// );
712    /// assert_eq!(
713    ///     query.to_string(SqliteQueryBuilder),
714    ///     r#"INSERT INTO "glyph" DEFAULT VALUES"#
715    /// );
716    ///
717    /// // Ordinary insert as columns and values are supplied
718    /// let query = Query::insert()
719    ///     .into_table(Glyph::Table)
720    ///     .or_default_values_many(3)
721    ///     .columns([Glyph::Image])
722    ///     .values_panic(["ABC".into()])
723    ///     .take();
724    ///
725    /// assert_eq!(
726    ///     query.to_string(MysqlQueryBuilder),
727    ///     r#"INSERT INTO `glyph` (`image`) VALUES ('ABC')"#
728    /// );
729    /// assert_eq!(
730    ///     query.to_string(PostgresQueryBuilder),
731    ///     r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
732    /// );
733    /// assert_eq!(
734    ///     query.to_string(SqliteQueryBuilder),
735    ///     r#"INSERT INTO "glyph" ("image") VALUES ('ABC')"#
736    /// );
737    /// ```
738    pub fn or_default_values_many(&mut self, num_rows: u32) -> &mut Self {
739        self.default_values = Some(num_rows);
740        self
741    }
742}
743
744#[inherent]
745impl QueryStatementBuilder for InsertStatement {
746    pub fn build_collect_any_into(
747        &self,
748        query_builder: &dyn QueryBuilder,
749        sql: &mut dyn SqlWriter,
750    ) {
751        query_builder.prepare_insert_statement(self, sql);
752    }
753
754    pub fn build_any(&self, query_builder: &dyn QueryBuilder) -> (String, Values);
755    pub fn build_collect_any(
756        &self,
757        query_builder: &dyn QueryBuilder,
758        sql: &mut dyn SqlWriter,
759    ) -> String;
760}
761
762impl From<InsertStatement> for QueryStatement {
763    fn from(s: InsertStatement) -> Self {
764        Self::Insert(s)
765    }
766}
767
768impl From<InsertStatement> for SubQueryStatement {
769    fn from(s: InsertStatement) -> Self {
770        Self::InsertStatement(s)
771    }
772}
773
774#[inherent]
775impl QueryStatementWriter for InsertStatement {
776    pub fn build_collect_into<T: QueryBuilder>(&self, query_builder: T, sql: &mut dyn SqlWriter) {
777        query_builder.prepare_insert_statement(self, sql);
778    }
779
780    pub fn build_collect<T: QueryBuilder>(
781        &self,
782        query_builder: T,
783        sql: &mut dyn SqlWriter,
784    ) -> String;
785    pub fn build<T: QueryBuilder>(&self, query_builder: T) -> (String, Values);
786    pub fn to_string<T: QueryBuilder>(&self, query_builder: T) -> String;
787}