1use crate::ast::*;
6use crate::dialect::TokenType::*;
7use std::fmt::{self, Display, Formatter};
8use std::ops::Deref;
9
10use super::functions::{ToTokens, TokenStream};
11use super::functions_4::{comma, double_quote};
12
13impl ToTokens for JoinOperator {
14 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
15 match self {
16 Self::Comma => s.append(TK_COMMA, None),
17 Self::TypedJoin(join_type) => {
18 if let Some(ref join_type) = join_type {
19 join_type.to_tokens(s)?;
20 }
21 s.append(TK_JOIN, None)
22 }
23 }
24 }
25}
26
27impl ToTokens for JoinType {
28 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
29 if self.contains(Self::NATURAL) {
30 s.append(TK_JOIN_KW, Some("NATURAL"))?;
31 }
32 if self.contains(Self::INNER) {
33 if self.contains(Self::CROSS) {
34 s.append(TK_JOIN_KW, Some("CROSS"))?;
35 }
36 s.append(TK_JOIN_KW, Some("INNER"))?;
37 } else {
38 if self.contains(Self::LEFT) {
39 if self.contains(Self::RIGHT) {
40 s.append(TK_JOIN_KW, Some("FULL"))?;
41 } else {
42 s.append(TK_JOIN_KW, Some("LEFT"))?;
43 }
44 } else if self.contains(Self::RIGHT) {
45 s.append(TK_JOIN_KW, Some("RIGHT"))?;
46 }
47 if self.contains(Self::OUTER) {
48 s.append(TK_JOIN_KW, Some("OUTER"))?;
49 }
50 }
51 Ok(())
52 }
53}
54
55impl ToTokens for JoinConstraint {
56 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
57 match self {
58 Self::On(expr) => {
59 s.append(TK_ON, None)?;
60 expr.to_tokens(s)
61 }
62 Self::Using(col_names) => {
63 s.append(TK_USING, None)?;
64 s.append(TK_LP, None)?;
65 comma(col_names.deref(), s)?;
66 s.append(TK_RP, None)
67 }
68 }
69 }
70}
71
72impl ToTokens for GroupBy {
73 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
74 s.append(TK_GROUP, None)?;
75 s.append(TK_BY, None)?;
76 comma(&self.exprs, s)?;
77 if let Some(ref having) = self.having {
78 s.append(TK_HAVING, None)?;
79 having.to_tokens(s)?;
80 }
81 Ok(())
82 }
83}
84
85impl ToTokens for Id {
86 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
87 double_quote(&self.0, s)
88 }
89}
90
91impl ToTokens for Name {
92 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
93 double_quote(self.0.as_str(), s)
94 }
95}
96
97impl Display for Name {
98 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
99 self.to_fmt(f)
100 }
101}
102
103impl ToTokens for QualifiedName {
104 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
105 if let Some(ref db_name) = self.db_name {
106 db_name.to_tokens(s)?;
107 s.append(TK_DOT, None)?;
108 }
109 self.name.to_tokens(s)?;
110 if let Some(ref alias) = self.alias {
111 s.append(TK_AS, None)?;
112 alias.to_tokens(s)?;
113 }
114 Ok(())
115 }
116}
117
118impl ToTokens for AlterTableBody {
119 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
120 match self {
121 Self::RenameTo(name) => {
122 s.append(TK_RENAME, None)?;
123 s.append(TK_TO, None)?;
124 name.to_tokens(s)
125 }
126 Self::AddColumn(def) => {
127 s.append(TK_ADD, None)?;
128 s.append(TK_COLUMNKW, None)?;
129 def.to_tokens(s)
130 }
131 Self::RenameColumn { old, new } => {
132 s.append(TK_RENAME, None)?;
133 old.to_tokens(s)?;
134 s.append(TK_TO, None)?;
135 new.to_tokens(s)
136 }
137 Self::DropColumn(name) => {
138 s.append(TK_DROP, None)?;
139 s.append(TK_COLUMNKW, None)?;
140 name.to_tokens(s)
141 }
142 }
143 }
144}
145
146impl ToTokens for CreateTableBody {
147 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
148 match self {
149 Self::ColumnsAndConstraints {
150 columns,
151 constraints,
152 options,
153 } => {
154 s.append(TK_LP, None)?;
155 comma(columns.values(), s)?;
156 if let Some(constraints) = constraints {
157 s.append(TK_COMMA, None)?;
158 comma(constraints, s)?;
159 }
160 s.append(TK_RP, None)?;
161 if options.contains(TableOptions::WITHOUT_ROWID) {
162 s.append(TK_WITHOUT, None)?;
163 s.append(TK_ID, Some("ROWID"))?;
164 }
165 if options.contains(TableOptions::STRICT) {
166 s.append(TK_ID, Some("STRICT"))?;
167 }
168 Ok(())
169 }
170 Self::AsSelect(select) => {
171 s.append(TK_AS, None)?;
172 select.to_tokens(s)
173 }
174 }
175 }
176}
177
178impl ToTokens for ColumnDefinition {
179 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
180 self.col_name.to_tokens(s)?;
181 if let Some(ref col_type) = self.col_type {
182 col_type.to_tokens(s)?;
183 }
184 for constraint in &self.constraints {
185 constraint.to_tokens(s)?;
186 }
187 Ok(())
188 }
189}
190
191impl ToTokens for NamedColumnConstraint {
192 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
193 if let Some(ref name) = self.name {
194 s.append(TK_CONSTRAINT, None)?;
195 name.to_tokens(s)?;
196 }
197 self.constraint.to_tokens(s)
198 }
199}
200
201impl ToTokens for ColumnConstraint {
202 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
203 match self {
204 Self::PrimaryKey {
205 order,
206 conflict_clause,
207 auto_increment,
208 } => {
209 s.append(TK_PRIMARY, None)?;
210 s.append(TK_KEY, None)?;
211 if let Some(order) = order {
212 order.to_tokens(s)?;
213 }
214 if let Some(conflict_clause) = conflict_clause {
215 s.append(TK_ON, None)?;
216 s.append(TK_CONFLICT, None)?;
217 conflict_clause.to_tokens(s)?;
218 }
219 if *auto_increment {
220 s.append(TK_AUTOINCR, None)?;
221 }
222 Ok(())
223 }
224 Self::NotNull {
225 nullable,
226 conflict_clause,
227 } => {
228 if !nullable {
229 s.append(TK_NOT, None)?;
230 }
231 s.append(TK_NULL, None)?;
232 if let Some(conflict_clause) = conflict_clause {
233 s.append(TK_ON, None)?;
234 s.append(TK_CONFLICT, None)?;
235 conflict_clause.to_tokens(s)?;
236 }
237 Ok(())
238 }
239 Self::Unique(conflict_clause) => {
240 s.append(TK_UNIQUE, None)?;
241 if let Some(conflict_clause) = conflict_clause {
242 s.append(TK_ON, None)?;
243 s.append(TK_CONFLICT, None)?;
244 conflict_clause.to_tokens(s)?;
245 }
246 Ok(())
247 }
248 Self::Check(expr) => {
249 s.append(TK_CHECK, None)?;
250 s.append(TK_LP, None)?;
251 expr.to_tokens(s)?;
252 s.append(TK_RP, None)
253 }
254 Self::Default(expr) => {
255 s.append(TK_DEFAULT, None)?;
256 expr.to_tokens(s)
257 }
258 Self::Defer(deref_clause) => deref_clause.to_tokens(s),
259 Self::Collate { collation_name } => {
260 s.append(TK_COLLATE, None)?;
261 collation_name.to_tokens(s)
262 }
263 Self::ForeignKey {
264 clause,
265 deref_clause,
266 } => {
267 s.append(TK_REFERENCES, None)?;
268 clause.to_tokens(s)?;
269 if let Some(deref_clause) = deref_clause {
270 deref_clause.to_tokens(s)?;
271 }
272 Ok(())
273 }
274 Self::Generated { expr, typ } => {
275 s.append(TK_AS, None)?;
276 s.append(TK_LP, None)?;
277 expr.to_tokens(s)?;
278 s.append(TK_RP, None)?;
279 if let Some(typ) = typ {
280 typ.to_tokens(s)?;
281 }
282 Ok(())
283 }
284 }
285 }
286}
287
288impl ToTokens for NamedTableConstraint {
289 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
290 if let Some(ref name) = self.name {
291 s.append(TK_CONSTRAINT, None)?;
292 name.to_tokens(s)?;
293 }
294 self.constraint.to_tokens(s)
295 }
296}
297
298impl ToTokens for TableConstraint {
299 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
300 match self {
301 Self::PrimaryKey {
302 columns,
303 auto_increment,
304 conflict_clause,
305 } => {
306 s.append(TK_PRIMARY, None)?;
307 s.append(TK_KEY, None)?;
308 s.append(TK_LP, None)?;
309 comma(columns, s)?;
310 if *auto_increment {
311 s.append(TK_AUTOINCR, None)?;
312 }
313 s.append(TK_RP, None)?;
314 if let Some(conflict_clause) = conflict_clause {
315 s.append(TK_ON, None)?;
316 s.append(TK_CONFLICT, None)?;
317 conflict_clause.to_tokens(s)?;
318 }
319 Ok(())
320 }
321 Self::Unique {
322 columns,
323 conflict_clause,
324 } => {
325 s.append(TK_UNIQUE, None)?;
326 s.append(TK_LP, None)?;
327 comma(columns, s)?;
328 s.append(TK_RP, None)?;
329 if let Some(conflict_clause) = conflict_clause {
330 s.append(TK_ON, None)?;
331 s.append(TK_CONFLICT, None)?;
332 conflict_clause.to_tokens(s)?;
333 }
334 Ok(())
335 }
336 Self::Check(expr) => {
337 s.append(TK_CHECK, None)?;
338 s.append(TK_LP, None)?;
339 expr.to_tokens(s)?;
340 s.append(TK_RP, None)
341 }
342 Self::ForeignKey {
343 columns,
344 clause,
345 deref_clause,
346 } => {
347 s.append(TK_FOREIGN, None)?;
348 s.append(TK_KEY, None)?;
349 s.append(TK_LP, None)?;
350 comma(columns, s)?;
351 s.append(TK_RP, None)?;
352 s.append(TK_REFERENCES, None)?;
353 clause.to_tokens(s)?;
354 if let Some(deref_clause) = deref_clause {
355 deref_clause.to_tokens(s)?;
356 }
357 Ok(())
358 }
359 }
360 }
361}
362
363impl ToTokens for SortOrder {
364 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
365 s.append(
366 match self {
367 Self::Asc => TK_ASC,
368 Self::Desc => TK_DESC,
369 },
370 None,
371 )
372 }
373}
374
375impl ToTokens for NullsOrder {
376 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
377 s.append(TK_NULLS, None)?;
378 s.append(
379 match self {
380 Self::First => TK_FIRST,
381 Self::Last => TK_LAST,
382 },
383 None,
384 )
385 }
386}
387
388impl ToTokens for ForeignKeyClause {
389 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
390 self.tbl_name.to_tokens(s)?;
391 if let Some(ref columns) = self.columns {
392 s.append(TK_LP, None)?;
393 comma(columns, s)?;
394 s.append(TK_RP, None)?;
395 }
396 for arg in &self.args {
397 arg.to_tokens(s)?;
398 }
399 Ok(())
400 }
401}
402
403impl ToTokens for RefArg {
404 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
405 match self {
406 Self::OnDelete(ref action) => {
407 s.append(TK_ON, None)?;
408 s.append(TK_DELETE, None)?;
409 action.to_tokens(s)
410 }
411 Self::OnInsert(ref action) => {
412 s.append(TK_ON, None)?;
413 s.append(TK_INSERT, None)?;
414 action.to_tokens(s)
415 }
416 Self::OnUpdate(ref action) => {
417 s.append(TK_ON, None)?;
418 s.append(TK_UPDATE, None)?;
419 action.to_tokens(s)
420 }
421 Self::Match(ref name) => {
422 s.append(TK_MATCH, None)?;
423 name.to_tokens(s)
424 }
425 }
426 }
427}
428
429impl ToTokens for RefAct {
430 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
431 match self {
432 Self::SetNull => {
433 s.append(TK_SET, None)?;
434 s.append(TK_NULL, None)
435 }
436 Self::SetDefault => {
437 s.append(TK_SET, None)?;
438 s.append(TK_DEFAULT, None)
439 }
440 Self::Cascade => s.append(TK_CASCADE, None),
441 Self::Restrict => s.append(TK_RESTRICT, None),
442 Self::NoAction => {
443 s.append(TK_NO, None)?;
444 s.append(TK_ACTION, None)
445 }
446 }
447 }
448}
449
450impl ToTokens for DeferSubclause {
451 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
452 if !self.deferrable {
453 s.append(TK_NOT, None)?;
454 }
455 s.append(TK_DEFERRABLE, None)?;
456 if let Some(init_deferred) = self.init_deferred {
457 init_deferred.to_tokens(s)?;
458 }
459 Ok(())
460 }
461}
462
463impl ToTokens for InitDeferredPred {
464 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
465 s.append(TK_INITIALLY, None)?;
466 s.append(
467 match self {
468 Self::InitiallyDeferred => TK_DEFERRED,
469 Self::InitiallyImmediate => TK_IMMEDIATE,
470 },
471 None,
472 )
473 }
474}
475
476impl ToTokens for IndexedColumn {
477 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
478 self.col_name.to_tokens(s)?;
479 if let Some(ref collation_name) = self.collation_name {
480 s.append(TK_COLLATE, None)?;
481 collation_name.to_tokens(s)?;
482 }
483 if let Some(order) = self.order {
484 order.to_tokens(s)?;
485 }
486 Ok(())
487 }
488}
489
490impl ToTokens for Indexed {
491 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
492 match self {
493 Self::IndexedBy(ref name) => {
494 s.append(TK_INDEXED, None)?;
495 s.append(TK_BY, None)?;
496 name.to_tokens(s)
497 }
498 Self::NotIndexed => {
499 s.append(TK_NOT, None)?;
500 s.append(TK_INDEXED, None)
501 }
502 }
503 }
504}
505
506impl ToTokens for SortedColumn {
507 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
508 self.expr.to_tokens(s)?;
509 if let Some(ref order) = self.order {
510 order.to_tokens(s)?;
511 }
512 if let Some(ref nulls) = self.nulls {
513 nulls.to_tokens(s)?;
514 }
515 Ok(())
516 }
517}
518
519impl ToTokens for Limit {
520 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
521 s.append(TK_LIMIT, None)?;
522 self.expr.to_tokens(s)?;
523 if let Some(ref offset) = self.offset {
524 s.append(TK_OFFSET, None)?;
525 offset.to_tokens(s)?;
526 }
527 Ok(())
528 }
529}
530
531impl ToTokens for InsertBody {
532 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
533 match self {
534 Self::Select(select, upsert) => {
535 select.to_tokens(s)?;
536 if let Some(upsert) = upsert {
537 upsert.to_tokens(s)?;
538 }
539 Ok(())
540 }
541 Self::DefaultValues => {
542 s.append(TK_DEFAULT, None)?;
543 s.append(TK_VALUES, None)
544 }
545 }
546 }
547}
548
549impl ToTokens for Set {
550 fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
551 if self.col_names.len() == 1 {
552 comma(self.col_names.deref(), s)?;
553 } else {
554 s.append(TK_LP, None)?;
555 comma(self.col_names.deref(), s)?;
556 s.append(TK_RP, None)?;
557 }
558 s.append(TK_EQ, None)?;
559 self.expr.to_tokens(s)
560 }
561}