1#[cfg(not(feature = "std"))]
19use alloc::{
20 boxed::Box,
21 format,
22 string::{String, ToString},
23 vec::Vec,
24};
25
26use core::fmt::{self, Display};
27#[cfg(feature = "serde")]
28use serde::{Deserialize, Serialize};
29#[cfg(feature = "visitor")]
30use yachtsql_sqlparser_derive::{Visit, VisitMut};
31
32use crate::display_utils::{indented_list, Indent, SpaceOrNewline};
33
34use super::{
35 display_comma_separated, query::InputFormatClause, Assignment, Expr, FromTable, Ident,
36 InsertAliases, MysqlInsertPriority, ObjectName, OnInsert, OrderByExpr, Query, SelectItem,
37 Setting, SqliteOnConflict, TableObject, TableWithJoins,
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 or: Option<SqliteOnConflict>,
47 pub ignore: bool,
49 pub into: bool,
51 pub table: TableObject,
53 pub table_alias: Option<Ident>,
55 pub columns: Vec<Ident>,
57 pub overwrite: bool,
59 pub source: Option<Box<Query>>,
61 pub assignments: Vec<Assignment>,
64 pub partitioned: Option<Vec<Expr>>,
66 pub after_columns: Vec<Ident>,
68 pub has_table_keyword: bool,
70 pub on: Option<OnInsert>,
71 pub returning: Option<Vec<SelectItem>>,
73 pub replace_into: bool,
75 pub priority: Option<MysqlInsertPriority>,
77 pub insert_alias: Option<InsertAliases>,
79 pub settings: Option<Vec<Setting>>,
85 pub format_clause: Option<InputFormatClause>,
92}
93
94impl Display for Insert {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 let table_name = if let Some(alias) = &self.table_alias {
97 format!("{0} AS {alias}", self.table)
98 } else {
99 self.table.to_string()
100 };
101
102 if let Some(on_conflict) = self.or {
103 write!(f, "INSERT {on_conflict} INTO {table_name} ")?;
104 } else {
105 write!(
106 f,
107 "{start}",
108 start = if self.replace_into {
109 "REPLACE"
110 } else {
111 "INSERT"
112 },
113 )?;
114 if let Some(priority) = self.priority {
115 write!(f, " {priority}",)?;
116 }
117
118 write!(
119 f,
120 "{ignore}{over}{int}{tbl} {table_name} ",
121 table_name = table_name,
122 ignore = if self.ignore { " IGNORE" } else { "" },
123 over = if self.overwrite { " OVERWRITE" } else { "" },
124 int = if self.into { " INTO" } else { "" },
125 tbl = if self.has_table_keyword { " TABLE" } else { "" },
126 )?;
127 }
128 if !self.columns.is_empty() {
129 write!(f, "({})", display_comma_separated(&self.columns))?;
130 SpaceOrNewline.fmt(f)?;
131 }
132 if let Some(ref parts) = self.partitioned {
133 if !parts.is_empty() {
134 write!(f, "PARTITION ({})", display_comma_separated(parts))?;
135 SpaceOrNewline.fmt(f)?;
136 }
137 }
138 if !self.after_columns.is_empty() {
139 write!(f, "({})", display_comma_separated(&self.after_columns))?;
140 SpaceOrNewline.fmt(f)?;
141 }
142
143 if let Some(settings) = &self.settings {
144 write!(f, "SETTINGS {}", display_comma_separated(settings))?;
145 SpaceOrNewline.fmt(f)?;
146 }
147
148 if let Some(source) = &self.source {
149 source.fmt(f)?;
150 } else if !self.assignments.is_empty() {
151 write!(f, "SET")?;
152 indented_list(f, &self.assignments)?;
153 } else if let Some(format_clause) = &self.format_clause {
154 format_clause.fmt(f)?;
155 } else if self.columns.is_empty() {
156 write!(f, "DEFAULT VALUES")?;
157 }
158
159 if let Some(insert_alias) = &self.insert_alias {
160 write!(f, " AS {0}", insert_alias.row_alias)?;
161
162 if let Some(col_aliases) = &insert_alias.col_aliases {
163 if !col_aliases.is_empty() {
164 write!(f, " ({})", display_comma_separated(col_aliases))?;
165 }
166 }
167 }
168
169 if let Some(on) = &self.on {
170 write!(f, "{on}")?;
171 }
172
173 if let Some(returning) = &self.returning {
174 SpaceOrNewline.fmt(f)?;
175 f.write_str("RETURNING")?;
176 indented_list(f, returning)?;
177 }
178 Ok(())
179 }
180}
181
182#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
184#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
185#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
186pub struct Delete {
187 pub tables: Vec<ObjectName>,
189 pub from: FromTable,
191 pub using: Option<Vec<TableWithJoins>>,
193 pub selection: Option<Expr>,
195 pub returning: Option<Vec<SelectItem>>,
197 pub order_by: Vec<OrderByExpr>,
199 pub limit: Option<Expr>,
201}
202
203impl Display for Delete {
204 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
205 f.write_str("DELETE")?;
206 if !self.tables.is_empty() {
207 indented_list(f, &self.tables)?;
208 }
209 match &self.from {
210 FromTable::WithFromKeyword(from) => {
211 f.write_str(" FROM")?;
212 indented_list(f, from)?;
213 }
214 FromTable::WithoutKeyword(from) => {
215 indented_list(f, from)?;
216 }
217 }
218 if let Some(using) = &self.using {
219 SpaceOrNewline.fmt(f)?;
220 f.write_str("USING")?;
221 indented_list(f, using)?;
222 }
223 if let Some(selection) = &self.selection {
224 SpaceOrNewline.fmt(f)?;
225 f.write_str("WHERE")?;
226 SpaceOrNewline.fmt(f)?;
227 Indent(selection).fmt(f)?;
228 }
229 if let Some(returning) = &self.returning {
230 SpaceOrNewline.fmt(f)?;
231 f.write_str("RETURNING")?;
232 indented_list(f, returning)?;
233 }
234 if !self.order_by.is_empty() {
235 SpaceOrNewline.fmt(f)?;
236 f.write_str("ORDER BY")?;
237 indented_list(f, &self.order_by)?;
238 }
239 if let Some(limit) = &self.limit {
240 SpaceOrNewline.fmt(f)?;
241 f.write_str("LIMIT")?;
242 SpaceOrNewline.fmt(f)?;
243 Indent(limit).fmt(f)?;
244 }
245 Ok(())
246 }
247}