1use crate::ast::*;
6use crate::dialect::is_identifier;
7use crate::dialect::TokenType::*;
8use std::ops::Deref;
9
10use super::functions::{ToTokens, TokenStream};
11
12impl ToTokens for PragmaBody {
13 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
14 match self {
15 Self::Equals(value) => {
16 s.append(TK_EQ, None)?;
17 value.to_tokens(s)
18 }
19 Self::Call(value) => {
20 s.append(TK_LP, None)?;
21 value.to_tokens(s)?;
22 s.append(TK_RP, None)
23 }
24 }
25 }
26}
27
28impl ToTokens for TriggerTime {
29 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
30 match self {
31 Self::Before => s.append(TK_BEFORE, None),
32 Self::After => s.append(TK_AFTER, None),
33 Self::InsteadOf => {
34 s.append(TK_INSTEAD, None)?;
35 s.append(TK_OF, None)
36 }
37 }
38 }
39}
40
41impl ToTokens for TriggerEvent {
42 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
43 match self {
44 Self::Delete => s.append(TK_DELETE, None),
45 Self::Insert => s.append(TK_INSERT, None),
46 Self::Update => s.append(TK_UPDATE, None),
47 Self::UpdateOf(ref col_names) => {
48 s.append(TK_UPDATE, None)?;
49 s.append(TK_OF, None)?;
50 comma(col_names.deref(), s)
51 }
52 }
53 }
54}
55
56impl ToTokens for TriggerCmd {
57 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
58 match self {
59 Self::Update(update) => {
60 let TriggerCmdUpdate {
61 or_conflict,
62 tbl_name,
63 sets,
64 from,
65 where_clause,
66 } = &**update;
67 s.append(TK_UPDATE, None)?;
68 if let Some(or_conflict) = or_conflict {
69 s.append(TK_OR, None)?;
70 or_conflict.to_tokens(s)?;
71 }
72 tbl_name.to_tokens(s)?;
73 s.append(TK_SET, None)?;
74 comma(sets, s)?;
75 if let Some(from) = from {
76 s.append(TK_FROM, None)?;
77 from.to_tokens(s)?;
78 }
79 if let Some(where_clause) = where_clause {
80 s.append(TK_WHERE, None)?;
81 where_clause.to_tokens(s)?;
82 }
83 Ok(())
84 }
85 Self::Insert(insert) => {
86 let TriggerCmdInsert {
87 or_conflict,
88 tbl_name,
89 col_names,
90 select,
91 upsert,
92 returning,
93 } = &**insert;
94 if let Some(ResolveType::Replace) = or_conflict {
95 s.append(TK_REPLACE, None)?;
96 } else {
97 s.append(TK_INSERT, None)?;
98 if let Some(or_conflict) = or_conflict {
99 s.append(TK_OR, None)?;
100 or_conflict.to_tokens(s)?;
101 }
102 }
103 s.append(TK_INTO, None)?;
104 tbl_name.to_tokens(s)?;
105 if let Some(col_names) = col_names {
106 s.append(TK_LP, None)?;
107 comma(col_names.deref(), s)?;
108 s.append(TK_RP, None)?;
109 }
110 select.to_tokens(s)?;
111 if let Some(upsert) = upsert {
112 upsert.to_tokens(s)?;
113 }
114 if let Some(returning) = returning {
115 s.append(TK_RETURNING, None)?;
116 comma(returning, s)?;
117 }
118 Ok(())
119 }
120 Self::Delete(delete) => {
121 s.append(TK_DELETE, None)?;
122 s.append(TK_FROM, None)?;
123 delete.tbl_name.to_tokens(s)?;
124 if let Some(where_clause) = &delete.where_clause {
125 s.append(TK_WHERE, None)?;
126 where_clause.to_tokens(s)?;
127 }
128 Ok(())
129 }
130 Self::Select(select) => select.to_tokens(s),
131 }
132 }
133}
134
135impl ToTokens for ResolveType {
136 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
137 s.append(
138 match self {
139 Self::Rollback => TK_ROLLBACK,
140 Self::Abort => TK_ABORT,
141 Self::Fail => TK_FAIL,
142 Self::Ignore => TK_IGNORE,
143 Self::Replace => TK_REPLACE,
144 },
145 None,
146 )
147 }
148}
149
150impl ToTokens for With {
151 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
152 s.append(TK_WITH, None)?;
153 if self.recursive {
154 s.append(TK_RECURSIVE, None)?;
155 }
156 comma(&self.ctes, s)
157 }
158}
159
160impl ToTokens for CommonTableExpr {
161 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
162 self.tbl_name.to_tokens(s)?;
163 if let Some(ref columns) = self.columns {
164 s.append(TK_LP, None)?;
165 comma(columns, s)?;
166 s.append(TK_RP, None)?;
167 }
168 s.append(TK_AS, None)?;
169 match self.materialized {
170 Materialized::Any => {}
171 Materialized::Yes => {
172 s.append(TK_MATERIALIZED, None)?;
173 }
174 Materialized::No => {
175 s.append(TK_NOT, None)?;
176 s.append(TK_MATERIALIZED, None)?;
177 }
178 };
179 s.append(TK_LP, None)?;
180 self.select.to_tokens(s)?;
181 s.append(TK_RP, None)
182 }
183}
184
185impl ToTokens for Type {
186 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
187 match self.size {
188 None => s.append(TK_ID, Some(&self.name)),
189 Some(ref size) => {
190 s.append(TK_ID, Some(&self.name))?; s.append(TK_LP, None)?;
192 size.to_tokens(s)?;
193 s.append(TK_RP, None)
194 }
195 }
196 }
197}
198
199impl ToTokens for TypeSize {
200 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
201 match self {
202 Self::MaxSize(size) => size.to_tokens(s),
203 Self::TypeSize(size1, size2) => {
204 size1.to_tokens(s)?;
205 s.append(TK_COMMA, None)?;
206 size2.to_tokens(s)
207 }
208 }
209 }
210}
211
212impl ToTokens for TransactionType {
213 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
214 s.append(
215 match self {
216 Self::Deferred => TK_DEFERRED,
217 Self::Immediate => TK_IMMEDIATE,
218 Self::Exclusive => TK_EXCLUSIVE,
219 },
220 None,
221 )
222 }
223}
224
225impl ToTokens for Upsert {
226 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
227 s.append(TK_ON, None)?;
228 s.append(TK_CONFLICT, None)?;
229 if let Some(ref index) = self.index {
230 index.to_tokens(s)?;
231 }
232 self.do_clause.to_tokens(s)?;
233 if let Some(ref next) = self.next {
234 next.to_tokens(s)?;
235 }
236 Ok(())
237 }
238}
239
240impl ToTokens for UpsertIndex {
241 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
242 s.append(TK_LP, None)?;
243 comma(&self.targets, s)?;
244 s.append(TK_RP, None)?;
245 if let Some(ref where_clause) = self.where_clause {
246 s.append(TK_WHERE, None)?;
247 where_clause.to_tokens(s)?;
248 }
249 Ok(())
250 }
251}
252
253impl ToTokens for UpsertDo {
254 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
255 match self {
256 Self::Set { sets, where_clause } => {
257 s.append(TK_DO, None)?;
258 s.append(TK_UPDATE, None)?;
259 s.append(TK_SET, None)?;
260 comma(sets, s)?;
261 if let Some(where_clause) = where_clause {
262 s.append(TK_WHERE, None)?;
263 where_clause.to_tokens(s)?;
264 }
265 Ok(())
266 }
267 Self::Nothing => {
268 s.append(TK_DO, None)?;
269 s.append(TK_NOTHING, None)
270 }
271 }
272 }
273}
274
275impl ToTokens for FunctionTail {
276 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
277 if let Some(ref filter_clause) = self.filter_clause {
278 s.append(TK_FILTER, None)?;
279 s.append(TK_LP, None)?;
280 s.append(TK_WHERE, None)?;
281 filter_clause.to_tokens(s)?;
282 s.append(TK_RP, None)?;
283 }
284 if let Some(ref over_clause) = self.over_clause {
285 s.append(TK_OVER, None)?;
286 over_clause.to_tokens(s)?;
287 }
288 Ok(())
289 }
290}
291
292impl ToTokens for Over {
293 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
294 match self {
295 Self::Window(ref window) => window.to_tokens(s),
296 Self::Name(ref name) => name.to_tokens(s),
297 }
298 }
299}
300
301impl ToTokens for WindowDef {
302 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
303 self.name.to_tokens(s)?;
304 s.append(TK_AS, None)?;
305 self.window.to_tokens(s)
306 }
307}
308
309impl ToTokens for Window {
310 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
311 s.append(TK_LP, None)?;
312 if let Some(ref base) = self.base {
313 base.to_tokens(s)?;
314 }
315 if let Some(ref partition_by) = self.partition_by {
316 s.append(TK_PARTITION, None)?;
317 s.append(TK_BY, None)?;
318 comma(partition_by, s)?;
319 }
320 if let Some(ref order_by) = self.order_by {
321 s.append(TK_ORDER, None)?;
322 s.append(TK_BY, None)?;
323 comma(order_by, s)?;
324 }
325 if let Some(ref frame_clause) = self.frame_clause {
326 frame_clause.to_tokens(s)?;
327 }
328 s.append(TK_RP, None)
329 }
330}
331
332impl ToTokens for FrameClause {
333 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
334 self.mode.to_tokens(s)?;
335 if let Some(ref end) = self.end {
336 s.append(TK_BETWEEN, None)?;
337 self.start.to_tokens(s)?;
338 s.append(TK_AND, None)?;
339 end.to_tokens(s)?;
340 } else {
341 self.start.to_tokens(s)?;
342 }
343 if let Some(ref exclude) = self.exclude {
344 s.append(TK_EXCLUDE, None)?;
345 exclude.to_tokens(s)?;
346 }
347 Ok(())
348 }
349}
350
351impl ToTokens for FrameMode {
352 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
353 s.append(
354 match self {
355 Self::Groups => TK_GROUPS,
356 Self::Range => TK_RANGE,
357 Self::Rows => TK_ROWS,
358 },
359 None,
360 )
361 }
362}
363
364impl ToTokens for FrameBound {
365 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
366 match self {
367 Self::CurrentRow => {
368 s.append(TK_CURRENT, None)?;
369 s.append(TK_ROW, None)
370 }
371 Self::Following(value) => {
372 value.to_tokens(s)?;
373 s.append(TK_FOLLOWING, None)
374 }
375 Self::Preceding(value) => {
376 value.to_tokens(s)?;
377 s.append(TK_PRECEDING, None)
378 }
379 Self::UnboundedFollowing => {
380 s.append(TK_UNBOUNDED, None)?;
381 s.append(TK_FOLLOWING, None)
382 }
383 Self::UnboundedPreceding => {
384 s.append(TK_UNBOUNDED, None)?;
385 s.append(TK_PRECEDING, None)
386 }
387 }
388 }
389}
390
391impl ToTokens for FrameExclude {
392 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
393 match self {
394 Self::NoOthers => {
395 s.append(TK_NO, None)?;
396 s.append(TK_OTHERS, None)
397 }
398 Self::CurrentRow => {
399 s.append(TK_CURRENT, None)?;
400 s.append(TK_ROW, None)
401 }
402 Self::Group => s.append(TK_GROUP, None),
403 Self::Ties => s.append(TK_TIES, None),
404 }
405 }
406}
407
408pub(super) fn comma<I, S: TokenStream>(items: I, s: &mut S) -> Result<(), S::Error>
409where
410 I: IntoIterator,
411 I::Item: ToTokens,
412{
413 let iter = items.into_iter();
414 for (i, item) in iter.enumerate() {
415 if i != 0 {
416 s.append(TK_COMMA, None)?;
417 }
418 item.to_tokens(s)?;
419 }
420 Ok(())
421}
422
423pub(super) fn double_quote<S: TokenStream>(name: &str, s: &mut S) -> Result<(), S::Error> {
424 if name.is_empty() {
425 return s.append(TK_ID, Some("\"\""));
426 }
427 if is_identifier(name) {
428 return s.append(TK_ID, Some(name));
435 }
436 s.append(TK_ID, Some(name))
445}