1#[cfg(not(feature = "std"))]
19use alloc::{boxed::Box, format, string::ToString, vec::Vec};
20
21use core::fmt::{self, Display};
22#[cfg(feature = "serde")]
23use serde::{Deserialize, Serialize};
24#[cfg(feature = "visitor")]
25use sqlparser_derive::{Visit, VisitMut};
26
27use crate::{
28 ast::display_separated,
29 display_utils::{indented_list, Indent, SpaceOrNewline},
30};
31
32use super::{
33 display_comma_separated, helpers::attached_token::AttachedToken, query::InputFormatClause,
34 Assignment, Expr, FromTable, Ident, InsertAliases, MysqlInsertPriority, ObjectName, OnInsert,
35 OptimizerHint, OrderByExpr, Query, SelectInto, SelectItem, Setting, SqliteOnConflict,
36 TableAliasWithoutColumns, TableFactor, TableObject, TableWithJoins, UpdateTableFromKind,
37 Values,
38};
39
40#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
42#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
43#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
44pub struct Insert {
45 pub insert_token: AttachedToken,
47 pub optimizer_hints: Vec<OptimizerHint>,
52 pub or: Option<SqliteOnConflict>,
54 pub ignore: bool,
56 pub into: bool,
58 pub table: TableObject,
60 pub table_alias: Option<TableAliasWithoutColumns>,
63 pub columns: Vec<ObjectName>,
65 pub overwrite: bool,
67 pub source: Option<Box<Query>>,
69 pub assignments: Vec<Assignment>,
72 pub partitioned: Option<Vec<Expr>>,
74 pub after_columns: Vec<Ident>,
76 pub has_table_keyword: bool,
78 pub on: Option<OnInsert>,
80 pub returning: Option<Vec<SelectItem>>,
82 pub output: Option<OutputClause>,
85 pub replace_into: bool,
87 pub priority: Option<MysqlInsertPriority>,
89 pub insert_alias: Option<InsertAliases>,
91 pub settings: Option<Vec<Setting>>,
97 pub format_clause: Option<InputFormatClause>,
104 pub multi_table_insert_type: Option<MultiTableInsertType>,
112 pub multi_table_into_clauses: Vec<MultiTableInsertIntoClause>,
118 pub multi_table_when_clauses: Vec<MultiTableInsertWhenClause>,
124 pub multi_table_else_clause: Option<Vec<MultiTableInsertIntoClause>>,
128}
129
130impl Display for Insert {
131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132 let table_name = if let Some(table_alias) = &self.table_alias {
134 format!(
135 "{table} {as_keyword}{alias}",
136 table = self.table,
137 as_keyword = if table_alias.explicit { "AS " } else { "" },
138 alias = table_alias.alias
139 )
140 } else {
141 self.table.to_string()
142 };
143
144 if let Some(on_conflict) = self.or {
145 f.write_str("INSERT")?;
146 for hint in &self.optimizer_hints {
147 write!(f, " {hint}")?;
148 }
149 write!(f, " {on_conflict} INTO {table_name} ")?;
150 } else {
151 write!(
152 f,
153 "{start}",
154 start = if self.replace_into {
155 "REPLACE"
156 } else {
157 "INSERT"
158 }
159 )?;
160 for hint in &self.optimizer_hints {
161 write!(f, " {hint}")?;
162 }
163 if let Some(priority) = self.priority {
164 write!(f, " {priority}")?;
165 }
166
167 if self.ignore {
168 write!(f, " IGNORE")?;
169 }
170
171 if self.overwrite {
172 write!(f, " OVERWRITE")?;
173 }
174
175 if let Some(insert_type) = &self.multi_table_insert_type {
176 write!(f, " {}", insert_type)?;
177 }
178
179 if self.into {
180 write!(f, " INTO")?;
181 }
182
183 if self.has_table_keyword {
184 write!(f, " TABLE")?;
185 }
186
187 if !table_name.is_empty() {
188 write!(f, " {table_name} ")?;
189 }
190 }
191
192 if !self.columns.is_empty() {
193 write!(f, "({})", display_comma_separated(&self.columns))?;
194 SpaceOrNewline.fmt(f)?;
195 }
196
197 if let Some(ref parts) = self.partitioned {
198 if !parts.is_empty() {
199 write!(f, "PARTITION ({})", display_comma_separated(parts))?;
200 SpaceOrNewline.fmt(f)?;
201 }
202 }
203
204 if !self.after_columns.is_empty() {
205 write!(f, "({})", display_comma_separated(&self.after_columns))?;
206 SpaceOrNewline.fmt(f)?;
207 }
208
209 if let Some(output) = &self.output {
210 write!(f, "{output}")?;
211 SpaceOrNewline.fmt(f)?;
212 }
213
214 if let Some(settings) = &self.settings {
215 write!(f, "SETTINGS {}", display_comma_separated(settings))?;
216 SpaceOrNewline.fmt(f)?;
217 }
218
219 for into_clause in &self.multi_table_into_clauses {
220 SpaceOrNewline.fmt(f)?;
221 write!(f, "{}", into_clause)?;
222 }
223
224 for when_clause in &self.multi_table_when_clauses {
225 SpaceOrNewline.fmt(f)?;
226 write!(f, "{}", when_clause)?;
227 }
228
229 if let Some(else_clauses) = &self.multi_table_else_clause {
230 SpaceOrNewline.fmt(f)?;
231 write!(f, "ELSE")?;
232 for into_clause in else_clauses {
233 SpaceOrNewline.fmt(f)?;
234 write!(f, "{}", into_clause)?;
235 }
236 }
237
238 if let Some(source) = &self.source {
239 if !self.multi_table_into_clauses.is_empty()
240 || !self.multi_table_when_clauses.is_empty()
241 {
242 SpaceOrNewline.fmt(f)?;
243 }
244 source.fmt(f)?;
245 } else if !self.assignments.is_empty() {
246 write!(f, "SET")?;
247 indented_list(f, &self.assignments)?;
248 } else if let Some(format_clause) = &self.format_clause {
249 format_clause.fmt(f)?;
250 } else if self.columns.is_empty() {
251 write!(f, "DEFAULT VALUES")?;
252 }
253
254 if let Some(insert_alias) = &self.insert_alias {
255 write!(f, " AS {0}", insert_alias.row_alias)?;
256
257 if let Some(col_aliases) = &insert_alias.col_aliases {
258 if !col_aliases.is_empty() {
259 write!(f, " ({})", display_comma_separated(col_aliases))?;
260 }
261 }
262 }
263
264 if let Some(on) = &self.on {
265 write!(f, "{on}")?;
266 }
267
268 if let Some(returning) = &self.returning {
269 SpaceOrNewline.fmt(f)?;
270 f.write_str("RETURNING")?;
271 indented_list(f, returning)?;
272 }
273
274 Ok(())
275 }
276}
277
278#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
280#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
281#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
282pub struct Delete {
283 pub delete_token: AttachedToken,
285 pub optimizer_hints: Vec<OptimizerHint>,
290 pub tables: Vec<ObjectName>,
292 pub from: FromTable,
294 pub using: Option<Vec<TableWithJoins>>,
296 pub selection: Option<Expr>,
298 pub returning: Option<Vec<SelectItem>>,
300 pub output: Option<OutputClause>,
303 pub order_by: Vec<OrderByExpr>,
305 pub limit: Option<Expr>,
307}
308
309impl Display for Delete {
310 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
311 f.write_str("DELETE")?;
312 for hint in &self.optimizer_hints {
313 f.write_str(" ")?;
314 hint.fmt(f)?;
315 }
316 if !self.tables.is_empty() {
317 indented_list(f, &self.tables)?;
318 }
319 match &self.from {
320 FromTable::WithFromKeyword(from) => {
321 f.write_str(" FROM")?;
322 indented_list(f, from)?;
323 }
324 FromTable::WithoutKeyword(from) => {
325 indented_list(f, from)?;
326 }
327 }
328 if let Some(output) = &self.output {
329 SpaceOrNewline.fmt(f)?;
330 write!(f, "{output}")?;
331 }
332 if let Some(using) = &self.using {
333 SpaceOrNewline.fmt(f)?;
334 f.write_str("USING")?;
335 indented_list(f, using)?;
336 }
337 if let Some(selection) = &self.selection {
338 SpaceOrNewline.fmt(f)?;
339 f.write_str("WHERE")?;
340 SpaceOrNewline.fmt(f)?;
341 Indent(selection).fmt(f)?;
342 }
343 if let Some(returning) = &self.returning {
344 SpaceOrNewline.fmt(f)?;
345 f.write_str("RETURNING")?;
346 indented_list(f, returning)?;
347 }
348 if !self.order_by.is_empty() {
349 SpaceOrNewline.fmt(f)?;
350 f.write_str("ORDER BY")?;
351 indented_list(f, &self.order_by)?;
352 }
353 if let Some(limit) = &self.limit {
354 SpaceOrNewline.fmt(f)?;
355 f.write_str("LIMIT")?;
356 SpaceOrNewline.fmt(f)?;
357 Indent(limit).fmt(f)?;
358 }
359 Ok(())
360 }
361}
362
363#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
365#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
366#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
367pub struct Update {
368 pub update_token: AttachedToken,
370 pub optimizer_hints: Vec<OptimizerHint>,
375 pub table: TableWithJoins,
377 pub assignments: Vec<Assignment>,
379 pub from: Option<UpdateTableFromKind>,
381 pub selection: Option<Expr>,
383 pub returning: Option<Vec<SelectItem>>,
385 pub output: Option<OutputClause>,
388 pub or: Option<SqliteOnConflict>,
390 pub order_by: Vec<OrderByExpr>,
393 pub limit: Option<Expr>,
395}
396
397impl Display for Update {
398 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
399 f.write_str("UPDATE")?;
400 for hint in &self.optimizer_hints {
401 f.write_str(" ")?;
402 hint.fmt(f)?;
403 }
404 f.write_str(" ")?;
405 if let Some(or) = &self.or {
406 or.fmt(f)?;
407 f.write_str(" ")?;
408 }
409 self.table.fmt(f)?;
410 if let Some(UpdateTableFromKind::BeforeSet(from)) = &self.from {
411 SpaceOrNewline.fmt(f)?;
412 f.write_str("FROM")?;
413 indented_list(f, from)?;
414 }
415 if !self.assignments.is_empty() {
416 SpaceOrNewline.fmt(f)?;
417 f.write_str("SET")?;
418 indented_list(f, &self.assignments)?;
419 }
420 if let Some(output) = &self.output {
421 SpaceOrNewline.fmt(f)?;
422 write!(f, "{output}")?;
423 }
424 if let Some(UpdateTableFromKind::AfterSet(from)) = &self.from {
425 SpaceOrNewline.fmt(f)?;
426 f.write_str("FROM")?;
427 indented_list(f, from)?;
428 }
429 if let Some(selection) = &self.selection {
430 SpaceOrNewline.fmt(f)?;
431 f.write_str("WHERE")?;
432 SpaceOrNewline.fmt(f)?;
433 Indent(selection).fmt(f)?;
434 }
435 if let Some(returning) = &self.returning {
436 SpaceOrNewline.fmt(f)?;
437 f.write_str("RETURNING")?;
438 indented_list(f, returning)?;
439 }
440 if !self.order_by.is_empty() {
441 SpaceOrNewline.fmt(f)?;
442 f.write_str("ORDER BY")?;
443 indented_list(f, &self.order_by)?;
444 }
445 if let Some(limit) = &self.limit {
446 SpaceOrNewline.fmt(f)?;
447 write!(f, "LIMIT {limit}")?;
448 }
449 Ok(())
450 }
451}
452
453#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
455#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
456#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
457pub struct Merge {
458 pub merge_token: AttachedToken,
460 pub optimizer_hints: Vec<OptimizerHint>,
464 pub into: bool,
466 pub table: TableFactor,
468 pub source: TableFactor,
470 pub on: Box<Expr>,
472 pub clauses: Vec<MergeClause>,
474 pub output: Option<OutputClause>,
476}
477
478impl Display for Merge {
479 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
480 f.write_str("MERGE")?;
481 for hint in &self.optimizer_hints {
482 write!(f, " {hint}")?;
483 }
484 if self.into {
485 write!(f, " INTO")?;
486 }
487 write!(
488 f,
489 " {table} USING {source} ",
490 table = self.table,
491 source = self.source
492 )?;
493 write!(f, "ON {on} ", on = self.on)?;
494 write!(f, "{}", display_separated(&self.clauses, " "))?;
495 if let Some(ref output) = self.output {
496 write!(f, " {output}")?;
497 }
498 Ok(())
499 }
500}
501
502#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
511#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
512#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
513pub struct MergeClause {
514 pub when_token: AttachedToken,
516 pub clause_kind: MergeClauseKind,
518 pub predicate: Option<Expr>,
520 pub action: MergeAction,
522}
523
524impl Display for MergeClause {
525 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
526 let MergeClause {
527 when_token: _,
528 clause_kind,
529 predicate,
530 action,
531 } = self;
532
533 write!(f, "WHEN {clause_kind}")?;
534 if let Some(pred) = predicate {
535 write!(f, " AND {pred}")?;
536 }
537 write!(f, " THEN {action}")
538 }
539}
540
541#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
550#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
551#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
552pub enum MergeClauseKind {
553 Matched,
555 NotMatched,
557 NotMatchedByTarget,
561 NotMatchedBySource,
565}
566
567impl Display for MergeClauseKind {
568 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
569 match self {
570 MergeClauseKind::Matched => write!(f, "MATCHED"),
571 MergeClauseKind::NotMatched => write!(f, "NOT MATCHED"),
572 MergeClauseKind::NotMatchedByTarget => write!(f, "NOT MATCHED BY TARGET"),
573 MergeClauseKind::NotMatchedBySource => write!(f, "NOT MATCHED BY SOURCE"),
574 }
575 }
576}
577
578#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
589#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
590#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
591pub enum MergeAction {
592 Insert(MergeInsertExpr),
599 Update(MergeUpdateExpr),
606 Delete {
608 delete_token: AttachedToken,
610 },
611}
612
613impl Display for MergeAction {
614 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
615 match self {
616 MergeAction::Insert(insert) => {
617 write!(f, "INSERT {insert}")
618 }
619 MergeAction::Update(update) => {
620 write!(f, "UPDATE {update}")
621 }
622 MergeAction::Delete { .. } => {
623 write!(f, "DELETE")
624 }
625 }
626 }
627}
628
629#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
634#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
635#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
636pub enum MergeInsertKind {
637 Values(Values),
644 Row,
652}
653
654impl Display for MergeInsertKind {
655 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
656 match self {
657 MergeInsertKind::Values(values) => {
658 write!(f, "{values}")
659 }
660 MergeInsertKind::Row => {
661 write!(f, "ROW")
662 }
663 }
664 }
665}
666
667#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
679#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
680#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
681pub struct MergeInsertExpr {
682 pub insert_token: AttachedToken,
684 pub columns: Vec<ObjectName>,
692 pub kind_token: AttachedToken,
694 pub kind: MergeInsertKind,
696 pub insert_predicate: Option<Expr>,
698}
699
700impl Display for MergeInsertExpr {
701 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
702 if !self.columns.is_empty() {
703 write!(f, "({}) ", display_comma_separated(self.columns.as_slice()))?;
704 }
705 write!(f, "{}", self.kind)?;
706 if let Some(predicate) = self.insert_predicate.as_ref() {
707 write!(f, " WHERE {}", predicate)?;
708 }
709 Ok(())
710 }
711}
712
713#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
724#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
725#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
726pub struct MergeUpdateExpr {
727 pub update_token: AttachedToken,
729 pub assignments: Vec<Assignment>,
731 pub update_predicate: Option<Expr>,
733 pub delete_predicate: Option<Expr>,
735}
736
737impl Display for MergeUpdateExpr {
738 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
739 write!(f, "SET {}", display_comma_separated(&self.assignments))?;
740 if let Some(predicate) = self.update_predicate.as_ref() {
741 write!(f, " WHERE {predicate}")?;
742 }
743 if let Some(predicate) = self.delete_predicate.as_ref() {
744 write!(f, " DELETE WHERE {predicate}")?;
745 }
746 Ok(())
747 }
748}
749
750#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
756#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
757#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
758pub enum OutputClause {
759 Output {
761 output_token: AttachedToken,
763 select_items: Vec<SelectItem>,
765 into_table: Option<SelectInto>,
767 },
768 Returning {
770 returning_token: AttachedToken,
772 select_items: Vec<SelectItem>,
774 },
775}
776
777impl fmt::Display for OutputClause {
778 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
779 match self {
780 OutputClause::Output {
781 output_token: _,
782 select_items,
783 into_table,
784 } => {
785 f.write_str("OUTPUT ")?;
786 display_comma_separated(select_items).fmt(f)?;
787 if let Some(into_table) = into_table {
788 f.write_str(" ")?;
789 into_table.fmt(f)?;
790 }
791 Ok(())
792 }
793 OutputClause::Returning {
794 returning_token: _,
795 select_items,
796 } => {
797 f.write_str("RETURNING ")?;
798 display_comma_separated(select_items).fmt(f)
799 }
800 }
801 }
802}
803
804#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
813#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
814#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
815pub struct MultiTableInsertWhenClause {
816 pub condition: Expr,
818 pub into_clauses: Vec<MultiTableInsertIntoClause>,
820}
821
822impl Display for MultiTableInsertWhenClause {
823 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
824 write!(f, "WHEN {} THEN", self.condition)?;
825 for into_clause in &self.into_clauses {
826 SpaceOrNewline.fmt(f)?;
827 write!(f, "{}", into_clause)?;
828 }
829 Ok(())
830 }
831}
832
833#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
840#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
841#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
842pub struct MultiTableInsertIntoClause {
843 pub table_name: ObjectName,
845 pub columns: Vec<Ident>,
847 pub values: Option<MultiTableInsertValues>,
849}
850
851impl Display for MultiTableInsertIntoClause {
852 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
853 write!(f, "INTO {}", self.table_name)?;
854 if !self.columns.is_empty() {
855 write!(f, " ({})", display_comma_separated(&self.columns))?;
856 }
857 if let Some(values) = &self.values {
858 write!(f, " VALUES ({})", display_comma_separated(&values.values))?;
859 }
860 Ok(())
861 }
862}
863
864#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
866#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
867#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
868pub struct MultiTableInsertValues {
869 pub values: Vec<MultiTableInsertValue>,
871}
872
873#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
875#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
876#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
877pub enum MultiTableInsertValue {
878 Expr(Expr),
880 Default,
882}
883
884impl Display for MultiTableInsertValue {
885 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
886 match self {
887 MultiTableInsertValue::Expr(expr) => write!(f, "{}", expr),
888 MultiTableInsertValue::Default => write!(f, "DEFAULT"),
889 }
890 }
891}
892
893#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
897#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
898#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
899pub enum MultiTableInsertType {
900 All,
902 First,
904}
905
906impl Display for MultiTableInsertType {
907 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
908 match self {
909 MultiTableInsertType::All => write!(f, "ALL"),
910 MultiTableInsertType::First => write!(f, "FIRST"),
911 }
912 }
913}