Skip to main content

limbo_sqlite3_parser/parser/ast/
fmt.rs

1//! AST node format
2use std::fmt::{self, Display, Formatter, Write};
3
4use crate::ast::*;
5use crate::dialect::TokenType::*;
6
7struct FmtTokenStream<'a, 'b> {
8    f: &'a mut Formatter<'b>,
9    spaced: bool,
10}
11
12impl TokenStream for FmtTokenStream<'_, '_> {
13    type Error = fmt::Error;
14
15    fn append(&mut self, ty: TokenType, value: Option<&str>) -> fmt::Result {
16        if !self.spaced {
17            match ty {
18                TK_COMMA | TK_SEMI | TK_RP | TK_DOT => {}
19                _ => {
20                    self.f.write_char(' ')?;
21                    self.spaced = true;
22                }
23            };
24        }
25        if ty == TK_BLOB {
26            self.f.write_char('X')?;
27            self.f.write_char('\'')?;
28            if let Some(str) = value {
29                self.f.write_str(str)?;
30            }
31            return self.f.write_char('\'');
32        } else if let Some(str) = ty.as_str() {
33            self.f.write_str(str)?;
34            self.spaced = ty == TK_LP || ty == TK_DOT; // str should not be whitespace
35        }
36        if let Some(str) = value {
37            // trick for pretty-print
38            self.spaced = str.bytes().all(|b| b.is_ascii_whitespace());
39            /*if !self.spaced {
40                self.f.write_char(' ')?;
41            }*/
42            self.f.write_str(str)
43        } else {
44            Ok(())
45        }
46    }
47}
48
49struct WriteTokenStream<'a, T: fmt::Write> {
50    write: &'a mut T,
51    spaced: bool,
52}
53
54impl<T: fmt::Write> TokenStream for WriteTokenStream<'_, T> {
55    type Error = fmt::Error;
56
57    fn append(&mut self, ty: TokenType, value: Option<&str>) -> fmt::Result {
58        if !self.spaced {
59            match ty {
60                TK_COMMA | TK_SEMI | TK_RP | TK_DOT => {}
61                _ => {
62                    self.write.write_char(' ')?;
63                    self.spaced = true;
64                }
65            };
66        }
67        if ty == TK_BLOB {
68            self.write.write_char('X')?;
69            self.write.write_char('\'')?;
70            if let Some(str) = value {
71                self.write.write_str(str)?;
72            }
73            return self.write.write_char('\'');
74        } else if let Some(str) = ty.as_str() {
75            self.write.write_str(str)?;
76            self.spaced = ty == TK_LP || ty == TK_DOT; // str should not be whitespace
77        }
78        if let Some(str) = value {
79            // trick for pretty-print
80            self.spaced = str.bytes().all(|b| b.is_ascii_whitespace());
81            self.write.write_str(str)
82        } else {
83            Ok(())
84        }
85    }
86}
87
88/// Stream of token
89pub trait TokenStream {
90    /// Potential error raised
91    type Error;
92    /// Push token to this stream
93    fn append(&mut self, ty: TokenType, value: Option<&str>) -> Result<(), Self::Error>;
94}
95
96/// Generate token(s) from AST node
97pub trait ToTokens {
98    /// Send token(s) to the specified stream
99    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error>;
100    /// Format AST node
101    fn to_fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
102        let mut s = FmtTokenStream { f, spaced: true };
103        self.to_tokens(&mut s)
104    }
105    /// Format AST node to string
106    fn format(&self) -> Result<String, fmt::Error> {
107        let mut s = String::new();
108
109        let mut w = WriteTokenStream {
110            write: &mut s,
111            spaced: true,
112        };
113
114        self.to_tokens(&mut w)?;
115
116        Ok(s)
117    }
118}
119
120impl<T: ?Sized + ToTokens> ToTokens for &T {
121    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
122        ToTokens::to_tokens(&**self, s)
123    }
124}
125
126impl ToTokens for String {
127    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
128        s.append(TK_ANY, Some(self.as_ref()))
129    }
130}
131
132impl ToTokens for Cmd {
133    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
134        match self {
135            Self::Explain(stmt) => {
136                s.append(TK_EXPLAIN, None)?;
137                stmt.to_tokens(s)?;
138            }
139            Self::ExplainQueryPlan(stmt) => {
140                s.append(TK_EXPLAIN, None)?;
141                s.append(TK_QUERY, None)?;
142                s.append(TK_PLAN, None)?;
143                stmt.to_tokens(s)?;
144            }
145            Self::Stmt(stmt) => {
146                stmt.to_tokens(s)?;
147            }
148        }
149        s.append(TK_SEMI, None)
150    }
151}
152
153impl Display for Cmd {
154    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
155        self.to_fmt(f)
156    }
157}
158
159impl ToTokens for Stmt {
160    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
161        match self {
162            Self::AlterTable(alter_table) => {
163                let (tbl_name, body) = &**alter_table;
164                s.append(TK_ALTER, None)?;
165                s.append(TK_TABLE, None)?;
166                tbl_name.to_tokens(s)?;
167                body.to_tokens(s)
168            }
169            Self::Analyze(obj_name) => {
170                s.append(TK_ANALYZE, None)?;
171                if let Some(obj_name) = obj_name {
172                    obj_name.to_tokens(s)?;
173                }
174                Ok(())
175            }
176            Self::Attach { expr, db_name, key } => {
177                s.append(TK_ATTACH, None)?;
178                expr.to_tokens(s)?;
179                s.append(TK_AS, None)?;
180                db_name.to_tokens(s)?;
181                if let Some(key) = key {
182                    s.append(TK_KEY, None)?;
183                    key.to_tokens(s)?;
184                }
185                Ok(())
186            }
187            Self::Begin(tx_type, tx_name) => {
188                s.append(TK_BEGIN, None)?;
189                if let Some(tx_type) = tx_type {
190                    tx_type.to_tokens(s)?;
191                }
192                if let Some(tx_name) = tx_name {
193                    s.append(TK_TRANSACTION, None)?;
194                    tx_name.to_tokens(s)?;
195                }
196                Ok(())
197            }
198            Self::Commit(tx_name) => {
199                s.append(TK_COMMIT, None)?;
200                if let Some(tx_name) = tx_name {
201                    s.append(TK_TRANSACTION, None)?;
202                    tx_name.to_tokens(s)?;
203                }
204                Ok(())
205            }
206            Self::CreateIndex {
207                unique,
208                if_not_exists,
209                idx_name,
210                tbl_name,
211                columns,
212                where_clause,
213            } => {
214                s.append(TK_CREATE, None)?;
215                if *unique {
216                    s.append(TK_UNIQUE, None)?;
217                }
218                s.append(TK_INDEX, None)?;
219                if *if_not_exists {
220                    s.append(TK_IF, None)?;
221                    s.append(TK_NOT, None)?;
222                    s.append(TK_EXISTS, None)?;
223                }
224                idx_name.to_tokens(s)?;
225                s.append(TK_ON, None)?;
226                tbl_name.to_tokens(s)?;
227                s.append(TK_LP, None)?;
228                comma(columns, s)?;
229                s.append(TK_RP, None)?;
230                if let Some(where_clause) = where_clause {
231                    s.append(TK_WHERE, None)?;
232                    where_clause.to_tokens(s)?;
233                }
234                Ok(())
235            }
236            Self::CreateTable {
237                temporary,
238                if_not_exists,
239                tbl_name,
240                body,
241            } => {
242                s.append(TK_CREATE, None)?;
243                if *temporary {
244                    s.append(TK_TEMP, None)?;
245                }
246                s.append(TK_TABLE, None)?;
247                if *if_not_exists {
248                    s.append(TK_IF, None)?;
249                    s.append(TK_NOT, None)?;
250                    s.append(TK_EXISTS, None)?;
251                }
252                tbl_name.to_tokens(s)?;
253                body.to_tokens(s)
254            }
255            Self::CreateTrigger(trigger) => {
256                let CreateTrigger {
257                    temporary,
258                    if_not_exists,
259                    trigger_name,
260                    time,
261                    event,
262                    tbl_name,
263                    for_each_row,
264                    when_clause,
265                    commands,
266                } = &**trigger;
267                s.append(TK_CREATE, None)?;
268                if *temporary {
269                    s.append(TK_TEMP, None)?;
270                }
271                s.append(TK_TRIGGER, None)?;
272                if *if_not_exists {
273                    s.append(TK_IF, None)?;
274                    s.append(TK_NOT, None)?;
275                    s.append(TK_EXISTS, None)?;
276                }
277                trigger_name.to_tokens(s)?;
278                if let Some(time) = time {
279                    time.to_tokens(s)?;
280                }
281                event.to_tokens(s)?;
282                s.append(TK_ON, None)?;
283                tbl_name.to_tokens(s)?;
284                if *for_each_row {
285                    s.append(TK_FOR, None)?;
286                    s.append(TK_EACH, None)?;
287                    s.append(TK_ROW, None)?;
288                }
289                if let Some(when_clause) = when_clause {
290                    s.append(TK_WHEN, None)?;
291                    when_clause.to_tokens(s)?;
292                }
293                s.append(TK_BEGIN, Some("\n"))?;
294                for command in commands {
295                    command.to_tokens(s)?;
296                    s.append(TK_SEMI, Some("\n"))?;
297                }
298                s.append(TK_END, None)
299            }
300            Self::CreateView {
301                temporary,
302                if_not_exists,
303                view_name,
304                columns,
305                select,
306            } => {
307                s.append(TK_CREATE, None)?;
308                if *temporary {
309                    s.append(TK_TEMP, None)?;
310                }
311                s.append(TK_VIEW, None)?;
312                if *if_not_exists {
313                    s.append(TK_IF, None)?;
314                    s.append(TK_NOT, None)?;
315                    s.append(TK_EXISTS, None)?;
316                }
317                view_name.to_tokens(s)?;
318                if let Some(columns) = columns {
319                    s.append(TK_LP, None)?;
320                    comma(columns, s)?;
321                    s.append(TK_RP, None)?;
322                }
323                s.append(TK_AS, None)?;
324                select.to_tokens(s)
325            }
326            Self::CreateVirtualTable(create_virtual_table) => {
327                let CreateVirtualTable {
328                    if_not_exists,
329                    tbl_name,
330                    module_name,
331                    args,
332                } = &**create_virtual_table;
333                s.append(TK_CREATE, None)?;
334                s.append(TK_VIRTUAL, None)?;
335                s.append(TK_TABLE, None)?;
336                if *if_not_exists {
337                    s.append(TK_IF, None)?;
338                    s.append(TK_NOT, None)?;
339                    s.append(TK_EXISTS, None)?;
340                }
341                tbl_name.to_tokens(s)?;
342                s.append(TK_USING, None)?;
343                module_name.to_tokens(s)?;
344                s.append(TK_LP, None)?;
345                if let Some(args) = args {
346                    comma(args, s)?;
347                }
348                s.append(TK_RP, None)
349            }
350            Self::Delete(delete) => {
351                let Delete {
352                    with,
353                    tbl_name,
354                    indexed,
355                    where_clause,
356                    returning,
357                    order_by,
358                    limit,
359                } = &**delete;
360                if let Some(with) = with {
361                    with.to_tokens(s)?;
362                }
363                s.append(TK_DELETE, None)?;
364                s.append(TK_FROM, None)?;
365                tbl_name.to_tokens(s)?;
366                if let Some(indexed) = indexed {
367                    indexed.to_tokens(s)?;
368                }
369                if let Some(where_clause) = where_clause {
370                    s.append(TK_WHERE, None)?;
371                    where_clause.to_tokens(s)?;
372                }
373                if let Some(returning) = returning {
374                    s.append(TK_RETURNING, None)?;
375                    comma(returning, s)?;
376                }
377                if let Some(order_by) = order_by {
378                    s.append(TK_ORDER, None)?;
379                    s.append(TK_BY, None)?;
380                    comma(order_by, s)?;
381                }
382                if let Some(limit) = limit {
383                    limit.to_tokens(s)?;
384                }
385                Ok(())
386            }
387            Self::Detach(expr) => {
388                s.append(TK_DETACH, None)?;
389                expr.to_tokens(s)
390            }
391            Self::DropIndex {
392                if_exists,
393                idx_name,
394            } => {
395                s.append(TK_DROP, None)?;
396                s.append(TK_INDEX, None)?;
397                if *if_exists {
398                    s.append(TK_IF, None)?;
399                    s.append(TK_EXISTS, None)?;
400                }
401                idx_name.to_tokens(s)
402            }
403            Self::DropTable {
404                if_exists,
405                tbl_name,
406            } => {
407                s.append(TK_DROP, None)?;
408                s.append(TK_TABLE, None)?;
409                if *if_exists {
410                    s.append(TK_IF, None)?;
411                    s.append(TK_EXISTS, None)?;
412                }
413                tbl_name.to_tokens(s)
414            }
415            Self::DropTrigger {
416                if_exists,
417                trigger_name,
418            } => {
419                s.append(TK_DROP, None)?;
420                s.append(TK_TRIGGER, None)?;
421                if *if_exists {
422                    s.append(TK_IF, None)?;
423                    s.append(TK_EXISTS, None)?;
424                }
425                trigger_name.to_tokens(s)
426            }
427            Self::DropView {
428                if_exists,
429                view_name,
430            } => {
431                s.append(TK_DROP, None)?;
432                s.append(TK_VIEW, None)?;
433                if *if_exists {
434                    s.append(TK_IF, None)?;
435                    s.append(TK_EXISTS, None)?;
436                }
437                view_name.to_tokens(s)
438            }
439            Self::Insert(insert) => {
440                let Insert {
441                    with,
442                    or_conflict,
443                    tbl_name,
444                    columns,
445                    body,
446                    returning,
447                } = &**insert;
448                if let Some(with) = with {
449                    with.to_tokens(s)?;
450                }
451                if let Some(ResolveType::Replace) = or_conflict {
452                    s.append(TK_REPLACE, None)?;
453                } else {
454                    s.append(TK_INSERT, None)?;
455                    if let Some(or_conflict) = or_conflict {
456                        s.append(TK_OR, None)?;
457                        or_conflict.to_tokens(s)?;
458                    }
459                }
460                s.append(TK_INTO, None)?;
461                tbl_name.to_tokens(s)?;
462                if let Some(columns) = columns {
463                    s.append(TK_LP, None)?;
464                    comma(columns.deref(), s)?;
465                    s.append(TK_RP, None)?;
466                }
467                body.to_tokens(s)?;
468                if let Some(returning) = returning {
469                    s.append(TK_RETURNING, None)?;
470                    comma(returning, s)?;
471                }
472                Ok(())
473            }
474            Self::Pragma(name, value) => {
475                s.append(TK_PRAGMA, None)?;
476                name.to_tokens(s)?;
477                if let Some(value) = value {
478                    value.to_tokens(s)?;
479                }
480                Ok(())
481            }
482            Self::Reindex { obj_name } => {
483                s.append(TK_REINDEX, None)?;
484                if let Some(obj_name) = obj_name {
485                    obj_name.to_tokens(s)?;
486                }
487                Ok(())
488            }
489            Self::Release(name) => {
490                s.append(TK_RELEASE, None)?;
491                name.to_tokens(s)
492            }
493            Self::Rollback {
494                tx_name,
495                savepoint_name,
496            } => {
497                s.append(TK_ROLLBACK, None)?;
498                if let Some(tx_name) = tx_name {
499                    s.append(TK_TRANSACTION, None)?;
500                    tx_name.to_tokens(s)?;
501                }
502                if let Some(savepoint_name) = savepoint_name {
503                    s.append(TK_TO, None)?;
504                    savepoint_name.to_tokens(s)?;
505                }
506                Ok(())
507            }
508            Self::Savepoint(name) => {
509                s.append(TK_SAVEPOINT, None)?;
510                name.to_tokens(s)
511            }
512            Self::Select(select) => select.to_tokens(s),
513            Self::Update(update) => {
514                let Update {
515                    with,
516                    or_conflict,
517                    tbl_name,
518                    indexed,
519                    sets,
520                    from,
521                    where_clause,
522                    returning,
523                    order_by,
524                    limit,
525                } = &**update;
526                if let Some(with) = with {
527                    with.to_tokens(s)?;
528                }
529                s.append(TK_UPDATE, None)?;
530                if let Some(or_conflict) = or_conflict {
531                    s.append(TK_OR, None)?;
532                    or_conflict.to_tokens(s)?;
533                }
534                tbl_name.to_tokens(s)?;
535                if let Some(indexed) = indexed {
536                    indexed.to_tokens(s)?;
537                }
538                s.append(TK_SET, None)?;
539                comma(sets, s)?;
540                if let Some(from) = from {
541                    s.append(TK_FROM, None)?;
542                    from.to_tokens(s)?;
543                }
544                if let Some(where_clause) = where_clause {
545                    s.append(TK_WHERE, None)?;
546                    where_clause.to_tokens(s)?;
547                }
548                if let Some(returning) = returning {
549                    s.append(TK_RETURNING, None)?;
550                    comma(returning, s)?;
551                }
552                if let Some(order_by) = order_by {
553                    s.append(TK_ORDER, None)?;
554                    s.append(TK_BY, None)?;
555                    comma(order_by, s)?;
556                }
557                if let Some(limit) = limit {
558                    limit.to_tokens(s)?;
559                }
560                Ok(())
561            }
562            Self::Vacuum(name, expr) => {
563                s.append(TK_VACUUM, None)?;
564                if let Some(ref name) = name {
565                    name.to_tokens(s)?;
566                }
567                if let Some(ref expr) = expr {
568                    s.append(TK_INTO, None)?;
569                    expr.to_tokens(s)?;
570                }
571                Ok(())
572            }
573        }
574    }
575}
576
577impl ToTokens for Expr {
578    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
579        match self {
580            Self::Between {
581                lhs,
582                not,
583                start,
584                end,
585            } => {
586                lhs.to_tokens(s)?;
587                if *not {
588                    s.append(TK_NOT, None)?;
589                }
590                s.append(TK_BETWEEN, None)?;
591                start.to_tokens(s)?;
592                s.append(TK_AND, None)?;
593                end.to_tokens(s)
594            }
595            Self::Binary(lhs, op, rhs) => {
596                lhs.to_tokens(s)?;
597                op.to_tokens(s)?;
598                rhs.to_tokens(s)
599            }
600            Self::Case {
601                base,
602                when_then_pairs,
603                else_expr,
604            } => {
605                s.append(TK_CASE, None)?;
606                if let Some(ref base) = base {
607                    base.to_tokens(s)?;
608                }
609                for (when, then) in when_then_pairs {
610                    s.append(TK_WHEN, None)?;
611                    when.to_tokens(s)?;
612                    s.append(TK_THEN, None)?;
613                    then.to_tokens(s)?;
614                }
615                if let Some(ref else_expr) = else_expr {
616                    s.append(TK_ELSE, None)?;
617                    else_expr.to_tokens(s)?;
618                }
619                s.append(TK_END, None)
620            }
621            Self::Cast { expr, type_name } => {
622                s.append(TK_CAST, None)?;
623                s.append(TK_LP, None)?;
624                expr.to_tokens(s)?;
625                s.append(TK_AS, None)?;
626                if let Some(ref type_name) = type_name {
627                    type_name.to_tokens(s)?;
628                }
629                s.append(TK_RP, None)
630            }
631            Self::Collate(expr, collation) => {
632                expr.to_tokens(s)?;
633                s.append(TK_COLLATE, None)?;
634                double_quote(collation, s)
635            }
636            Self::DoublyQualified(db_name, tbl_name, col_name) => {
637                db_name.to_tokens(s)?;
638                s.append(TK_DOT, None)?;
639                tbl_name.to_tokens(s)?;
640                s.append(TK_DOT, None)?;
641                col_name.to_tokens(s)
642            }
643            Self::Exists(subquery) => {
644                s.append(TK_EXISTS, None)?;
645                s.append(TK_LP, None)?;
646                subquery.to_tokens(s)?;
647                s.append(TK_RP, None)
648            }
649            Self::FunctionCall {
650                name,
651                distinctness,
652                args,
653                order_by,
654                filter_over,
655            } => {
656                name.to_tokens(s)?;
657                s.append(TK_LP, None)?;
658                if let Some(distinctness) = distinctness {
659                    distinctness.to_tokens(s)?;
660                }
661                if let Some(args) = args {
662                    comma(args, s)?;
663                }
664                if let Some(order_by) = order_by {
665                    s.append(TK_ORDER, None)?;
666                    s.append(TK_BY, None)?;
667                    comma(order_by, s)?;
668                }
669                s.append(TK_RP, None)?;
670                if let Some(filter_over) = filter_over {
671                    filter_over.to_tokens(s)?;
672                }
673                Ok(())
674            }
675            Self::FunctionCallStar { name, filter_over } => {
676                name.to_tokens(s)?;
677                s.append(TK_LP, None)?;
678                s.append(TK_STAR, None)?;
679                s.append(TK_RP, None)?;
680                if let Some(filter_over) = filter_over {
681                    filter_over.to_tokens(s)?;
682                }
683                Ok(())
684            }
685            Self::Id(id) => id.to_tokens(s),
686            Self::Column { .. } => Ok(()),
687            Self::InList { lhs, not, rhs } => {
688                lhs.to_tokens(s)?;
689                if *not {
690                    s.append(TK_NOT, None)?;
691                }
692                s.append(TK_IN, None)?;
693                s.append(TK_LP, None)?;
694                if let Some(rhs) = rhs {
695                    comma(rhs, s)?;
696                }
697                s.append(TK_RP, None)
698            }
699            Self::InSelect { lhs, not, rhs } => {
700                lhs.to_tokens(s)?;
701                if *not {
702                    s.append(TK_NOT, None)?;
703                }
704                s.append(TK_IN, None)?;
705                s.append(TK_LP, None)?;
706                rhs.to_tokens(s)?;
707                s.append(TK_RP, None)
708            }
709            Self::InTable {
710                lhs,
711                not,
712                rhs,
713                args,
714            } => {
715                lhs.to_tokens(s)?;
716                if *not {
717                    s.append(TK_NOT, None)?;
718                }
719                s.append(TK_IN, None)?;
720                rhs.to_tokens(s)?;
721                if let Some(args) = args {
722                    s.append(TK_LP, None)?;
723                    comma(args, s)?;
724                    s.append(TK_RP, None)?;
725                }
726                Ok(())
727            }
728            Self::IsNull(sub_expr) => {
729                sub_expr.to_tokens(s)?;
730                s.append(TK_ISNULL, None)
731            }
732            Self::Like {
733                lhs,
734                not,
735                op,
736                rhs,
737                escape,
738            } => {
739                lhs.to_tokens(s)?;
740                if *not {
741                    s.append(TK_NOT, None)?;
742                }
743                op.to_tokens(s)?;
744                rhs.to_tokens(s)?;
745                if let Some(escape) = escape {
746                    s.append(TK_ESCAPE, None)?;
747                    escape.to_tokens(s)?;
748                }
749                Ok(())
750            }
751            Self::Literal(lit) => lit.to_tokens(s),
752            Self::Name(name) => name.to_tokens(s),
753            Self::NotNull(sub_expr) => {
754                sub_expr.to_tokens(s)?;
755                s.append(TK_NOTNULL, None)
756            }
757            Self::Parenthesized(exprs) => {
758                s.append(TK_LP, None)?;
759                comma(exprs, s)?;
760                s.append(TK_RP, None)
761            }
762            Self::Qualified(qualifier, qualified) => {
763                qualifier.to_tokens(s)?;
764                s.append(TK_DOT, None)?;
765                qualified.to_tokens(s)
766            }
767            Self::Raise(rt, err) => {
768                s.append(TK_RAISE, None)?;
769                s.append(TK_LP, None)?;
770                rt.to_tokens(s)?;
771                if let Some(err) = err {
772                    s.append(TK_COMMA, None)?;
773                    err.to_tokens(s)?;
774                }
775                s.append(TK_RP, None)
776            }
777            Self::RowId { .. } => Ok(()),
778            Self::Subquery(query) => {
779                s.append(TK_LP, None)?;
780                query.to_tokens(s)?;
781                s.append(TK_RP, None)
782            }
783            Self::Unary(op, sub_expr) => {
784                op.to_tokens(s)?;
785                sub_expr.to_tokens(s)
786            }
787            Self::Variable(var) => match var.chars().next() {
788                Some(c) if c == '$' || c == '@' || c == '#' || c == ':' => {
789                    s.append(TK_VARIABLE, Some(var))
790                }
791                Some(_) => s.append(TK_VARIABLE, Some(&("?".to_owned() + var))),
792                None => s.append(TK_VARIABLE, Some("?")),
793            },
794        }
795    }
796}
797
798impl Display for Expr {
799    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
800        self.to_fmt(f)
801    }
802}
803
804impl ToTokens for Literal {
805    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
806        match self {
807            Self::Numeric(ref num) => s.append(TK_FLOAT, Some(num)), // TODO Validate TK_FLOAT
808            Self::String(ref str) => s.append(TK_STRING, Some(str)),
809            Self::Blob(ref blob) => s.append(TK_BLOB, Some(blob)),
810            Self::Keyword(ref str) => s.append(TK_ID, Some(str)), // TODO Validate TK_ID
811            Self::Null => s.append(TK_NULL, None),
812            Self::CurrentDate => s.append(TK_CTIME_KW, Some("CURRENT_DATE")),
813            Self::CurrentTime => s.append(TK_CTIME_KW, Some("CURRENT_TIME")),
814            Self::CurrentTimestamp => s.append(TK_CTIME_KW, Some("CURRENT_TIMESTAMP")),
815        }
816    }
817}
818
819impl ToTokens for LikeOperator {
820    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
821        s.append(
822            TK_LIKE_KW,
823            Some(match self {
824                Self::Glob => "GLOB",
825                Self::Like => "LIKE",
826                Self::Match => "MATCH",
827                Self::Regexp => "REGEXP",
828            }),
829        )
830    }
831}
832
833impl ToTokens for Operator {
834    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
835        match self {
836            Self::Add => s.append(TK_PLUS, None),
837            Self::And => s.append(TK_AND, None),
838            Self::ArrowRight => s.append(TK_PTR, Some("->")),
839            Self::ArrowRightShift => s.append(TK_PTR, Some("->>")),
840            Self::BitwiseAnd => s.append(TK_BITAND, None),
841            Self::BitwiseOr => s.append(TK_BITOR, None),
842            Self::BitwiseNot => s.append(TK_BITNOT, None),
843            Self::Concat => s.append(TK_CONCAT, None),
844            Self::Equals => s.append(TK_EQ, None),
845            Self::Divide => s.append(TK_SLASH, None),
846            Self::Greater => s.append(TK_GT, None),
847            Self::GreaterEquals => s.append(TK_GE, None),
848            Self::Is => s.append(TK_IS, None),
849            Self::IsNot => {
850                s.append(TK_IS, None)?;
851                s.append(TK_NOT, None)
852            }
853            Self::LeftShift => s.append(TK_LSHIFT, None),
854            Self::Less => s.append(TK_LT, None),
855            Self::LessEquals => s.append(TK_LE, None),
856            Self::Modulus => s.append(TK_REM, None),
857            Self::Multiply => s.append(TK_STAR, None),
858            Self::NotEquals => s.append(TK_NE, None),
859            Self::Or => s.append(TK_OR, None),
860            Self::RightShift => s.append(TK_RSHIFT, None),
861            Self::Subtract => s.append(TK_MINUS, None),
862        }
863    }
864}
865
866impl ToTokens for UnaryOperator {
867    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
868        s.append(
869            match self {
870                Self::BitwiseNot => TK_BITNOT,
871                Self::Negative => TK_MINUS,
872                Self::Not => TK_NOT,
873                Self::Positive => TK_PLUS,
874            },
875            None,
876        )
877    }
878}
879
880impl ToTokens for Select {
881    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
882        if let Some(ref with) = self.with {
883            with.to_tokens(s)?;
884        }
885        self.body.to_tokens(s)?;
886        if let Some(ref order_by) = self.order_by {
887            s.append(TK_ORDER, None)?;
888            s.append(TK_BY, None)?;
889            comma(order_by, s)?;
890        }
891        if let Some(ref limit) = self.limit {
892            limit.to_tokens(s)?;
893        }
894        Ok(())
895    }
896}
897
898impl ToTokens for SelectBody {
899    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
900        self.select.to_tokens(s)?;
901        if let Some(ref compounds) = self.compounds {
902            for compound in compounds {
903                compound.to_tokens(s)?;
904            }
905        }
906        Ok(())
907    }
908}
909
910impl ToTokens for CompoundSelect {
911    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
912        self.operator.to_tokens(s)?;
913        self.select.to_tokens(s)
914    }
915}
916
917impl ToTokens for CompoundOperator {
918    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
919        match self {
920            Self::Union => s.append(TK_UNION, None),
921            Self::UnionAll => {
922                s.append(TK_UNION, None)?;
923                s.append(TK_ALL, None)
924            }
925            Self::Except => s.append(TK_EXCEPT, None),
926            Self::Intersect => s.append(TK_INTERSECT, None),
927        }
928    }
929}
930
931impl Display for CompoundOperator {
932    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
933        self.to_fmt(f)
934    }
935}
936
937impl ToTokens for OneSelect {
938    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
939        match self {
940            Self::Select(select) => {
941                let SelectInner {
942                    distinctness,
943                    columns,
944                    from,
945                    where_clause,
946                    group_by,
947                    window_clause,
948                } = &**select;
949                s.append(TK_SELECT, None)?;
950                if let Some(ref distinctness) = distinctness {
951                    distinctness.to_tokens(s)?;
952                }
953                comma(columns, s)?;
954                if let Some(ref from) = from {
955                    s.append(TK_FROM, None)?;
956                    from.to_tokens(s)?;
957                }
958                if let Some(ref where_clause) = where_clause {
959                    s.append(TK_WHERE, None)?;
960                    where_clause.to_tokens(s)?;
961                }
962                if let Some(ref group_by) = group_by {
963                    group_by.to_tokens(s)?;
964                }
965                if let Some(ref window_clause) = window_clause {
966                    s.append(TK_WINDOW, None)?;
967                    comma(window_clause, s)?;
968                }
969                Ok(())
970            }
971            Self::Values(values) => {
972                for (i, vals) in values.iter().enumerate() {
973                    if i == 0 {
974                        s.append(TK_VALUES, None)?;
975                    } else {
976                        s.append(TK_COMMA, None)?;
977                    }
978                    s.append(TK_LP, None)?;
979                    comma(vals, s)?;
980                    s.append(TK_RP, None)?;
981                }
982                Ok(())
983            }
984        }
985    }
986}
987
988impl ToTokens for FromClause {
989    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
990        self.select
991            .as_ref()
992            .expect("FromClause select is mandatory per AST invariant")
993            .to_tokens(s)?;
994        if let Some(ref joins) = self.joins {
995            for join in joins {
996                join.to_tokens(s)?;
997            }
998        }
999        Ok(())
1000    }
1001}
1002
1003impl ToTokens for Distinctness {
1004    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1005        s.append(
1006            match self {
1007                Self::Distinct => TK_DISTINCT,
1008                Self::All => TK_ALL,
1009            },
1010            None,
1011        )
1012    }
1013}
1014
1015impl ToTokens for ResultColumn {
1016    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1017        match self {
1018            Self::Expr(expr, alias) => {
1019                expr.to_tokens(s)?;
1020                if let Some(alias) = alias {
1021                    alias.to_tokens(s)?;
1022                }
1023                Ok(())
1024            }
1025            Self::Star => s.append(TK_STAR, None),
1026            Self::TableStar(tbl_name) => {
1027                tbl_name.to_tokens(s)?;
1028                s.append(TK_DOT, None)?;
1029                s.append(TK_STAR, None)
1030            }
1031        }
1032    }
1033}
1034
1035impl ToTokens for As {
1036    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1037        match self {
1038            Self::As(ref name) => {
1039                s.append(TK_AS, None)?;
1040                name.to_tokens(s)
1041            }
1042            Self::Elided(ref name) => name.to_tokens(s),
1043        }
1044    }
1045}
1046
1047impl ToTokens for JoinedSelectTable {
1048    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1049        self.operator.to_tokens(s)?;
1050        self.table.to_tokens(s)?;
1051        if let Some(ref constraint) = self.constraint {
1052            constraint.to_tokens(s)?;
1053        }
1054        Ok(())
1055    }
1056}
1057
1058impl ToTokens for SelectTable {
1059    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1060        match self {
1061            Self::Table(name, alias, indexed) => {
1062                name.to_tokens(s)?;
1063                if let Some(alias) = alias {
1064                    alias.to_tokens(s)?;
1065                }
1066                if let Some(indexed) = indexed {
1067                    indexed.to_tokens(s)?;
1068                }
1069                Ok(())
1070            }
1071            Self::TableCall(name, exprs, alias) => {
1072                name.to_tokens(s)?;
1073                s.append(TK_LP, None)?;
1074                if let Some(exprs) = exprs {
1075                    comma(exprs, s)?;
1076                }
1077                s.append(TK_RP, None)?;
1078                if let Some(alias) = alias {
1079                    alias.to_tokens(s)?;
1080                }
1081                Ok(())
1082            }
1083            Self::Select(select, alias) => {
1084                s.append(TK_LP, None)?;
1085                select.to_tokens(s)?;
1086                s.append(TK_RP, None)?;
1087                if let Some(alias) = alias {
1088                    alias.to_tokens(s)?;
1089                }
1090                Ok(())
1091            }
1092            Self::Sub(from, alias) => {
1093                s.append(TK_LP, None)?;
1094                from.to_tokens(s)?;
1095                s.append(TK_RP, None)?;
1096                if let Some(alias) = alias {
1097                    alias.to_tokens(s)?;
1098                }
1099                Ok(())
1100            }
1101        }
1102    }
1103}
1104
1105impl ToTokens for JoinOperator {
1106    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1107        match self {
1108            Self::Comma => s.append(TK_COMMA, None),
1109            Self::TypedJoin(join_type) => {
1110                if let Some(ref join_type) = join_type {
1111                    join_type.to_tokens(s)?;
1112                }
1113                s.append(TK_JOIN, None)
1114            }
1115        }
1116    }
1117}
1118
1119impl ToTokens for JoinType {
1120    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1121        if self.contains(Self::NATURAL) {
1122            s.append(TK_JOIN_KW, Some("NATURAL"))?;
1123        }
1124        if self.contains(Self::INNER) {
1125            if self.contains(Self::CROSS) {
1126                s.append(TK_JOIN_KW, Some("CROSS"))?;
1127            }
1128            s.append(TK_JOIN_KW, Some("INNER"))?;
1129        } else {
1130            if self.contains(Self::LEFT) {
1131                if self.contains(Self::RIGHT) {
1132                    s.append(TK_JOIN_KW, Some("FULL"))?;
1133                } else {
1134                    s.append(TK_JOIN_KW, Some("LEFT"))?;
1135                }
1136            } else if self.contains(Self::RIGHT) {
1137                s.append(TK_JOIN_KW, Some("RIGHT"))?;
1138            }
1139            if self.contains(Self::OUTER) {
1140                s.append(TK_JOIN_KW, Some("OUTER"))?;
1141            }
1142        }
1143        Ok(())
1144    }
1145}
1146
1147impl ToTokens for JoinConstraint {
1148    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1149        match self {
1150            Self::On(expr) => {
1151                s.append(TK_ON, None)?;
1152                expr.to_tokens(s)
1153            }
1154            Self::Using(col_names) => {
1155                s.append(TK_USING, None)?;
1156                s.append(TK_LP, None)?;
1157                comma(col_names.deref(), s)?;
1158                s.append(TK_RP, None)
1159            }
1160        }
1161    }
1162}
1163
1164impl ToTokens for GroupBy {
1165    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1166        s.append(TK_GROUP, None)?;
1167        s.append(TK_BY, None)?;
1168        comma(&self.exprs, s)?;
1169        if let Some(ref having) = self.having {
1170            s.append(TK_HAVING, None)?;
1171            having.to_tokens(s)?;
1172        }
1173        Ok(())
1174    }
1175}
1176
1177impl ToTokens for Id {
1178    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1179        double_quote(&self.0, s)
1180    }
1181}
1182
1183impl ToTokens for Name {
1184    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1185        double_quote(self.0.as_str(), s)
1186    }
1187}
1188
1189impl Display for Name {
1190    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1191        self.to_fmt(f)
1192    }
1193}
1194
1195impl ToTokens for QualifiedName {
1196    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1197        if let Some(ref db_name) = self.db_name {
1198            db_name.to_tokens(s)?;
1199            s.append(TK_DOT, None)?;
1200        }
1201        self.name.to_tokens(s)?;
1202        if let Some(ref alias) = self.alias {
1203            s.append(TK_AS, None)?;
1204            alias.to_tokens(s)?;
1205        }
1206        Ok(())
1207    }
1208}
1209
1210impl ToTokens for AlterTableBody {
1211    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1212        match self {
1213            Self::RenameTo(name) => {
1214                s.append(TK_RENAME, None)?;
1215                s.append(TK_TO, None)?;
1216                name.to_tokens(s)
1217            }
1218            Self::AddColumn(def) => {
1219                s.append(TK_ADD, None)?;
1220                s.append(TK_COLUMNKW, None)?;
1221                def.to_tokens(s)
1222            }
1223            Self::RenameColumn { old, new } => {
1224                s.append(TK_RENAME, None)?;
1225                old.to_tokens(s)?;
1226                s.append(TK_TO, None)?;
1227                new.to_tokens(s)
1228            }
1229            Self::DropColumn(name) => {
1230                s.append(TK_DROP, None)?;
1231                s.append(TK_COLUMNKW, None)?;
1232                name.to_tokens(s)
1233            }
1234        }
1235    }
1236}
1237
1238impl ToTokens for CreateTableBody {
1239    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1240        match self {
1241            Self::ColumnsAndConstraints {
1242                columns,
1243                constraints,
1244                options,
1245            } => {
1246                s.append(TK_LP, None)?;
1247                comma(columns.values(), s)?;
1248                if let Some(constraints) = constraints {
1249                    s.append(TK_COMMA, None)?;
1250                    comma(constraints, s)?;
1251                }
1252                s.append(TK_RP, None)?;
1253                if options.contains(TableOptions::WITHOUT_ROWID) {
1254                    s.append(TK_WITHOUT, None)?;
1255                    s.append(TK_ID, Some("ROWID"))?;
1256                }
1257                if options.contains(TableOptions::STRICT) {
1258                    s.append(TK_ID, Some("STRICT"))?;
1259                }
1260                Ok(())
1261            }
1262            Self::AsSelect(select) => {
1263                s.append(TK_AS, None)?;
1264                select.to_tokens(s)
1265            }
1266        }
1267    }
1268}
1269
1270impl ToTokens for ColumnDefinition {
1271    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1272        self.col_name.to_tokens(s)?;
1273        if let Some(ref col_type) = self.col_type {
1274            col_type.to_tokens(s)?;
1275        }
1276        for constraint in &self.constraints {
1277            constraint.to_tokens(s)?;
1278        }
1279        Ok(())
1280    }
1281}
1282
1283impl ToTokens for NamedColumnConstraint {
1284    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1285        if let Some(ref name) = self.name {
1286            s.append(TK_CONSTRAINT, None)?;
1287            name.to_tokens(s)?;
1288        }
1289        self.constraint.to_tokens(s)
1290    }
1291}
1292
1293impl ToTokens for ColumnConstraint {
1294    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1295        match self {
1296            Self::PrimaryKey {
1297                order,
1298                conflict_clause,
1299                auto_increment,
1300            } => {
1301                s.append(TK_PRIMARY, None)?;
1302                s.append(TK_KEY, None)?;
1303                if let Some(order) = order {
1304                    order.to_tokens(s)?;
1305                }
1306                if let Some(conflict_clause) = conflict_clause {
1307                    s.append(TK_ON, None)?;
1308                    s.append(TK_CONFLICT, None)?;
1309                    conflict_clause.to_tokens(s)?;
1310                }
1311                if *auto_increment {
1312                    s.append(TK_AUTOINCR, None)?;
1313                }
1314                Ok(())
1315            }
1316            Self::NotNull {
1317                nullable,
1318                conflict_clause,
1319            } => {
1320                if !nullable {
1321                    s.append(TK_NOT, None)?;
1322                }
1323                s.append(TK_NULL, None)?;
1324                if let Some(conflict_clause) = conflict_clause {
1325                    s.append(TK_ON, None)?;
1326                    s.append(TK_CONFLICT, None)?;
1327                    conflict_clause.to_tokens(s)?;
1328                }
1329                Ok(())
1330            }
1331            Self::Unique(conflict_clause) => {
1332                s.append(TK_UNIQUE, None)?;
1333                if let Some(conflict_clause) = conflict_clause {
1334                    s.append(TK_ON, None)?;
1335                    s.append(TK_CONFLICT, None)?;
1336                    conflict_clause.to_tokens(s)?;
1337                }
1338                Ok(())
1339            }
1340            Self::Check(expr) => {
1341                s.append(TK_CHECK, None)?;
1342                s.append(TK_LP, None)?;
1343                expr.to_tokens(s)?;
1344                s.append(TK_RP, None)
1345            }
1346            Self::Default(expr) => {
1347                s.append(TK_DEFAULT, None)?;
1348                expr.to_tokens(s)
1349            }
1350            Self::Defer(deref_clause) => deref_clause.to_tokens(s),
1351            Self::Collate { collation_name } => {
1352                s.append(TK_COLLATE, None)?;
1353                collation_name.to_tokens(s)
1354            }
1355            Self::ForeignKey {
1356                clause,
1357                deref_clause,
1358            } => {
1359                s.append(TK_REFERENCES, None)?;
1360                clause.to_tokens(s)?;
1361                if let Some(deref_clause) = deref_clause {
1362                    deref_clause.to_tokens(s)?;
1363                }
1364                Ok(())
1365            }
1366            Self::Generated { expr, typ } => {
1367                s.append(TK_AS, None)?;
1368                s.append(TK_LP, None)?;
1369                expr.to_tokens(s)?;
1370                s.append(TK_RP, None)?;
1371                if let Some(typ) = typ {
1372                    typ.to_tokens(s)?;
1373                }
1374                Ok(())
1375            }
1376        }
1377    }
1378}
1379
1380impl ToTokens for NamedTableConstraint {
1381    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1382        if let Some(ref name) = self.name {
1383            s.append(TK_CONSTRAINT, None)?;
1384            name.to_tokens(s)?;
1385        }
1386        self.constraint.to_tokens(s)
1387    }
1388}
1389
1390impl ToTokens for TableConstraint {
1391    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1392        match self {
1393            Self::PrimaryKey {
1394                columns,
1395                auto_increment,
1396                conflict_clause,
1397            } => {
1398                s.append(TK_PRIMARY, None)?;
1399                s.append(TK_KEY, None)?;
1400                s.append(TK_LP, None)?;
1401                comma(columns, s)?;
1402                if *auto_increment {
1403                    s.append(TK_AUTOINCR, None)?;
1404                }
1405                s.append(TK_RP, None)?;
1406                if let Some(conflict_clause) = conflict_clause {
1407                    s.append(TK_ON, None)?;
1408                    s.append(TK_CONFLICT, None)?;
1409                    conflict_clause.to_tokens(s)?;
1410                }
1411                Ok(())
1412            }
1413            Self::Unique {
1414                columns,
1415                conflict_clause,
1416            } => {
1417                s.append(TK_UNIQUE, None)?;
1418                s.append(TK_LP, None)?;
1419                comma(columns, s)?;
1420                s.append(TK_RP, None)?;
1421                if let Some(conflict_clause) = conflict_clause {
1422                    s.append(TK_ON, None)?;
1423                    s.append(TK_CONFLICT, None)?;
1424                    conflict_clause.to_tokens(s)?;
1425                }
1426                Ok(())
1427            }
1428            Self::Check(expr) => {
1429                s.append(TK_CHECK, None)?;
1430                s.append(TK_LP, None)?;
1431                expr.to_tokens(s)?;
1432                s.append(TK_RP, None)
1433            }
1434            Self::ForeignKey {
1435                columns,
1436                clause,
1437                deref_clause,
1438            } => {
1439                s.append(TK_FOREIGN, None)?;
1440                s.append(TK_KEY, None)?;
1441                s.append(TK_LP, None)?;
1442                comma(columns, s)?;
1443                s.append(TK_RP, None)?;
1444                s.append(TK_REFERENCES, None)?;
1445                clause.to_tokens(s)?;
1446                if let Some(deref_clause) = deref_clause {
1447                    deref_clause.to_tokens(s)?;
1448                }
1449                Ok(())
1450            }
1451        }
1452    }
1453}
1454
1455impl ToTokens for SortOrder {
1456    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1457        s.append(
1458            match self {
1459                Self::Asc => TK_ASC,
1460                Self::Desc => TK_DESC,
1461            },
1462            None,
1463        )
1464    }
1465}
1466
1467impl ToTokens for NullsOrder {
1468    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1469        s.append(TK_NULLS, None)?;
1470        s.append(
1471            match self {
1472                Self::First => TK_FIRST,
1473                Self::Last => TK_LAST,
1474            },
1475            None,
1476        )
1477    }
1478}
1479
1480impl ToTokens for ForeignKeyClause {
1481    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1482        self.tbl_name.to_tokens(s)?;
1483        if let Some(ref columns) = self.columns {
1484            s.append(TK_LP, None)?;
1485            comma(columns, s)?;
1486            s.append(TK_RP, None)?;
1487        }
1488        for arg in &self.args {
1489            arg.to_tokens(s)?;
1490        }
1491        Ok(())
1492    }
1493}
1494
1495impl ToTokens for RefArg {
1496    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1497        match self {
1498            Self::OnDelete(ref action) => {
1499                s.append(TK_ON, None)?;
1500                s.append(TK_DELETE, None)?;
1501                action.to_tokens(s)
1502            }
1503            Self::OnInsert(ref action) => {
1504                s.append(TK_ON, None)?;
1505                s.append(TK_INSERT, None)?;
1506                action.to_tokens(s)
1507            }
1508            Self::OnUpdate(ref action) => {
1509                s.append(TK_ON, None)?;
1510                s.append(TK_UPDATE, None)?;
1511                action.to_tokens(s)
1512            }
1513            Self::Match(ref name) => {
1514                s.append(TK_MATCH, None)?;
1515                name.to_tokens(s)
1516            }
1517        }
1518    }
1519}
1520
1521impl ToTokens for RefAct {
1522    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1523        match self {
1524            Self::SetNull => {
1525                s.append(TK_SET, None)?;
1526                s.append(TK_NULL, None)
1527            }
1528            Self::SetDefault => {
1529                s.append(TK_SET, None)?;
1530                s.append(TK_DEFAULT, None)
1531            }
1532            Self::Cascade => s.append(TK_CASCADE, None),
1533            Self::Restrict => s.append(TK_RESTRICT, None),
1534            Self::NoAction => {
1535                s.append(TK_NO, None)?;
1536                s.append(TK_ACTION, None)
1537            }
1538        }
1539    }
1540}
1541
1542impl ToTokens for DeferSubclause {
1543    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1544        if !self.deferrable {
1545            s.append(TK_NOT, None)?;
1546        }
1547        s.append(TK_DEFERRABLE, None)?;
1548        if let Some(init_deferred) = self.init_deferred {
1549            init_deferred.to_tokens(s)?;
1550        }
1551        Ok(())
1552    }
1553}
1554
1555impl ToTokens for InitDeferredPred {
1556    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1557        s.append(TK_INITIALLY, None)?;
1558        s.append(
1559            match self {
1560                Self::InitiallyDeferred => TK_DEFERRED,
1561                Self::InitiallyImmediate => TK_IMMEDIATE,
1562            },
1563            None,
1564        )
1565    }
1566}
1567
1568impl ToTokens for IndexedColumn {
1569    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1570        self.col_name.to_tokens(s)?;
1571        if let Some(ref collation_name) = self.collation_name {
1572            s.append(TK_COLLATE, None)?;
1573            collation_name.to_tokens(s)?;
1574        }
1575        if let Some(order) = self.order {
1576            order.to_tokens(s)?;
1577        }
1578        Ok(())
1579    }
1580}
1581
1582impl ToTokens for Indexed {
1583    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1584        match self {
1585            Self::IndexedBy(ref name) => {
1586                s.append(TK_INDEXED, None)?;
1587                s.append(TK_BY, None)?;
1588                name.to_tokens(s)
1589            }
1590            Self::NotIndexed => {
1591                s.append(TK_NOT, None)?;
1592                s.append(TK_INDEXED, None)
1593            }
1594        }
1595    }
1596}
1597
1598impl ToTokens for SortedColumn {
1599    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1600        self.expr.to_tokens(s)?;
1601        if let Some(ref order) = self.order {
1602            order.to_tokens(s)?;
1603        }
1604        if let Some(ref nulls) = self.nulls {
1605            nulls.to_tokens(s)?;
1606        }
1607        Ok(())
1608    }
1609}
1610
1611impl ToTokens for Limit {
1612    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1613        s.append(TK_LIMIT, None)?;
1614        self.expr.to_tokens(s)?;
1615        if let Some(ref offset) = self.offset {
1616            s.append(TK_OFFSET, None)?;
1617            offset.to_tokens(s)?;
1618        }
1619        Ok(())
1620    }
1621}
1622
1623impl ToTokens for InsertBody {
1624    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1625        match self {
1626            Self::Select(select, upsert) => {
1627                select.to_tokens(s)?;
1628                if let Some(upsert) = upsert {
1629                    upsert.to_tokens(s)?;
1630                }
1631                Ok(())
1632            }
1633            Self::DefaultValues => {
1634                s.append(TK_DEFAULT, None)?;
1635                s.append(TK_VALUES, None)
1636            }
1637        }
1638    }
1639}
1640
1641impl ToTokens for Set {
1642    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1643        if self.col_names.len() == 1 {
1644            comma(self.col_names.deref(), s)?;
1645        } else {
1646            s.append(TK_LP, None)?;
1647            comma(self.col_names.deref(), s)?;
1648            s.append(TK_RP, None)?;
1649        }
1650        s.append(TK_EQ, None)?;
1651        self.expr.to_tokens(s)
1652    }
1653}
1654
1655impl ToTokens for PragmaBody {
1656    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1657        match self {
1658            Self::Equals(value) => {
1659                s.append(TK_EQ, None)?;
1660                value.to_tokens(s)
1661            }
1662            Self::Call(value) => {
1663                s.append(TK_LP, None)?;
1664                value.to_tokens(s)?;
1665                s.append(TK_RP, None)
1666            }
1667        }
1668    }
1669}
1670
1671impl ToTokens for TriggerTime {
1672    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1673        match self {
1674            Self::Before => s.append(TK_BEFORE, None),
1675            Self::After => s.append(TK_AFTER, None),
1676            Self::InsteadOf => {
1677                s.append(TK_INSTEAD, None)?;
1678                s.append(TK_OF, None)
1679            }
1680        }
1681    }
1682}
1683
1684impl ToTokens for TriggerEvent {
1685    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1686        match self {
1687            Self::Delete => s.append(TK_DELETE, None),
1688            Self::Insert => s.append(TK_INSERT, None),
1689            Self::Update => s.append(TK_UPDATE, None),
1690            Self::UpdateOf(ref col_names) => {
1691                s.append(TK_UPDATE, None)?;
1692                s.append(TK_OF, None)?;
1693                comma(col_names.deref(), s)
1694            }
1695        }
1696    }
1697}
1698
1699impl ToTokens for TriggerCmd {
1700    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1701        match self {
1702            Self::Update(update) => {
1703                let TriggerCmdUpdate {
1704                    or_conflict,
1705                    tbl_name,
1706                    sets,
1707                    from,
1708                    where_clause,
1709                } = &**update;
1710                s.append(TK_UPDATE, None)?;
1711                if let Some(or_conflict) = or_conflict {
1712                    s.append(TK_OR, None)?;
1713                    or_conflict.to_tokens(s)?;
1714                }
1715                tbl_name.to_tokens(s)?;
1716                s.append(TK_SET, None)?;
1717                comma(sets, s)?;
1718                if let Some(from) = from {
1719                    s.append(TK_FROM, None)?;
1720                    from.to_tokens(s)?;
1721                }
1722                if let Some(where_clause) = where_clause {
1723                    s.append(TK_WHERE, None)?;
1724                    where_clause.to_tokens(s)?;
1725                }
1726                Ok(())
1727            }
1728            Self::Insert(insert) => {
1729                let TriggerCmdInsert {
1730                    or_conflict,
1731                    tbl_name,
1732                    col_names,
1733                    select,
1734                    upsert,
1735                    returning,
1736                } = &**insert;
1737                if let Some(ResolveType::Replace) = or_conflict {
1738                    s.append(TK_REPLACE, None)?;
1739                } else {
1740                    s.append(TK_INSERT, None)?;
1741                    if let Some(or_conflict) = or_conflict {
1742                        s.append(TK_OR, None)?;
1743                        or_conflict.to_tokens(s)?;
1744                    }
1745                }
1746                s.append(TK_INTO, None)?;
1747                tbl_name.to_tokens(s)?;
1748                if let Some(col_names) = col_names {
1749                    s.append(TK_LP, None)?;
1750                    comma(col_names.deref(), s)?;
1751                    s.append(TK_RP, None)?;
1752                }
1753                select.to_tokens(s)?;
1754                if let Some(upsert) = upsert {
1755                    upsert.to_tokens(s)?;
1756                }
1757                if let Some(returning) = returning {
1758                    s.append(TK_RETURNING, None)?;
1759                    comma(returning, s)?;
1760                }
1761                Ok(())
1762            }
1763            Self::Delete(delete) => {
1764                s.append(TK_DELETE, None)?;
1765                s.append(TK_FROM, None)?;
1766                delete.tbl_name.to_tokens(s)?;
1767                if let Some(where_clause) = &delete.where_clause {
1768                    s.append(TK_WHERE, None)?;
1769                    where_clause.to_tokens(s)?;
1770                }
1771                Ok(())
1772            }
1773            Self::Select(select) => select.to_tokens(s),
1774        }
1775    }
1776}
1777
1778impl ToTokens for ResolveType {
1779    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1780        s.append(
1781            match self {
1782                Self::Rollback => TK_ROLLBACK,
1783                Self::Abort => TK_ABORT,
1784                Self::Fail => TK_FAIL,
1785                Self::Ignore => TK_IGNORE,
1786                Self::Replace => TK_REPLACE,
1787            },
1788            None,
1789        )
1790    }
1791}
1792
1793impl ToTokens for With {
1794    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1795        s.append(TK_WITH, None)?;
1796        if self.recursive {
1797            s.append(TK_RECURSIVE, None)?;
1798        }
1799        comma(&self.ctes, s)
1800    }
1801}
1802
1803impl ToTokens for CommonTableExpr {
1804    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1805        self.tbl_name.to_tokens(s)?;
1806        if let Some(ref columns) = self.columns {
1807            s.append(TK_LP, None)?;
1808            comma(columns, s)?;
1809            s.append(TK_RP, None)?;
1810        }
1811        s.append(TK_AS, None)?;
1812        match self.materialized {
1813            Materialized::Any => {}
1814            Materialized::Yes => {
1815                s.append(TK_MATERIALIZED, None)?;
1816            }
1817            Materialized::No => {
1818                s.append(TK_NOT, None)?;
1819                s.append(TK_MATERIALIZED, None)?;
1820            }
1821        };
1822        s.append(TK_LP, None)?;
1823        self.select.to_tokens(s)?;
1824        s.append(TK_RP, None)
1825    }
1826}
1827
1828impl ToTokens for Type {
1829    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1830        match self.size {
1831            None => s.append(TK_ID, Some(&self.name)),
1832            Some(ref size) => {
1833                s.append(TK_ID, Some(&self.name))?; // TODO check there is no forbidden chars
1834                s.append(TK_LP, None)?;
1835                size.to_tokens(s)?;
1836                s.append(TK_RP, None)
1837            }
1838        }
1839    }
1840}
1841
1842impl ToTokens for TypeSize {
1843    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1844        match self {
1845            Self::MaxSize(size) => size.to_tokens(s),
1846            Self::TypeSize(size1, size2) => {
1847                size1.to_tokens(s)?;
1848                s.append(TK_COMMA, None)?;
1849                size2.to_tokens(s)
1850            }
1851        }
1852    }
1853}
1854
1855impl ToTokens for TransactionType {
1856    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1857        s.append(
1858            match self {
1859                Self::Deferred => TK_DEFERRED,
1860                Self::Immediate => TK_IMMEDIATE,
1861                Self::Exclusive => TK_EXCLUSIVE,
1862            },
1863            None,
1864        )
1865    }
1866}
1867
1868impl ToTokens for Upsert {
1869    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1870        s.append(TK_ON, None)?;
1871        s.append(TK_CONFLICT, None)?;
1872        if let Some(ref index) = self.index {
1873            index.to_tokens(s)?;
1874        }
1875        self.do_clause.to_tokens(s)?;
1876        if let Some(ref next) = self.next {
1877            next.to_tokens(s)?;
1878        }
1879        Ok(())
1880    }
1881}
1882
1883impl ToTokens for UpsertIndex {
1884    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1885        s.append(TK_LP, None)?;
1886        comma(&self.targets, s)?;
1887        s.append(TK_RP, None)?;
1888        if let Some(ref where_clause) = self.where_clause {
1889            s.append(TK_WHERE, None)?;
1890            where_clause.to_tokens(s)?;
1891        }
1892        Ok(())
1893    }
1894}
1895
1896impl ToTokens for UpsertDo {
1897    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1898        match self {
1899            Self::Set { sets, where_clause } => {
1900                s.append(TK_DO, None)?;
1901                s.append(TK_UPDATE, None)?;
1902                s.append(TK_SET, None)?;
1903                comma(sets, s)?;
1904                if let Some(where_clause) = where_clause {
1905                    s.append(TK_WHERE, None)?;
1906                    where_clause.to_tokens(s)?;
1907                }
1908                Ok(())
1909            }
1910            Self::Nothing => {
1911                s.append(TK_DO, None)?;
1912                s.append(TK_NOTHING, None)
1913            }
1914        }
1915    }
1916}
1917
1918impl ToTokens for FunctionTail {
1919    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1920        if let Some(ref filter_clause) = self.filter_clause {
1921            s.append(TK_FILTER, None)?;
1922            s.append(TK_LP, None)?;
1923            s.append(TK_WHERE, None)?;
1924            filter_clause.to_tokens(s)?;
1925            s.append(TK_RP, None)?;
1926        }
1927        if let Some(ref over_clause) = self.over_clause {
1928            s.append(TK_OVER, None)?;
1929            over_clause.to_tokens(s)?;
1930        }
1931        Ok(())
1932    }
1933}
1934
1935impl ToTokens for Over {
1936    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1937        match self {
1938            Self::Window(ref window) => window.to_tokens(s),
1939            Self::Name(ref name) => name.to_tokens(s),
1940        }
1941    }
1942}
1943
1944impl ToTokens for WindowDef {
1945    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1946        self.name.to_tokens(s)?;
1947        s.append(TK_AS, None)?;
1948        self.window.to_tokens(s)
1949    }
1950}
1951
1952impl ToTokens for Window {
1953    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1954        s.append(TK_LP, None)?;
1955        if let Some(ref base) = self.base {
1956            base.to_tokens(s)?;
1957        }
1958        if let Some(ref partition_by) = self.partition_by {
1959            s.append(TK_PARTITION, None)?;
1960            s.append(TK_BY, None)?;
1961            comma(partition_by, s)?;
1962        }
1963        if let Some(ref order_by) = self.order_by {
1964            s.append(TK_ORDER, None)?;
1965            s.append(TK_BY, None)?;
1966            comma(order_by, s)?;
1967        }
1968        if let Some(ref frame_clause) = self.frame_clause {
1969            frame_clause.to_tokens(s)?;
1970        }
1971        s.append(TK_RP, None)
1972    }
1973}
1974
1975impl ToTokens for FrameClause {
1976    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1977        self.mode.to_tokens(s)?;
1978        if let Some(ref end) = self.end {
1979            s.append(TK_BETWEEN, None)?;
1980            self.start.to_tokens(s)?;
1981            s.append(TK_AND, None)?;
1982            end.to_tokens(s)?;
1983        } else {
1984            self.start.to_tokens(s)?;
1985        }
1986        if let Some(ref exclude) = self.exclude {
1987            s.append(TK_EXCLUDE, None)?;
1988            exclude.to_tokens(s)?;
1989        }
1990        Ok(())
1991    }
1992}
1993
1994impl ToTokens for FrameMode {
1995    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
1996        s.append(
1997            match self {
1998                Self::Groups => TK_GROUPS,
1999                Self::Range => TK_RANGE,
2000                Self::Rows => TK_ROWS,
2001            },
2002            None,
2003        )
2004    }
2005}
2006
2007impl ToTokens for FrameBound {
2008    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2009        match self {
2010            Self::CurrentRow => {
2011                s.append(TK_CURRENT, None)?;
2012                s.append(TK_ROW, None)
2013            }
2014            Self::Following(value) => {
2015                value.to_tokens(s)?;
2016                s.append(TK_FOLLOWING, None)
2017            }
2018            Self::Preceding(value) => {
2019                value.to_tokens(s)?;
2020                s.append(TK_PRECEDING, None)
2021            }
2022            Self::UnboundedFollowing => {
2023                s.append(TK_UNBOUNDED, None)?;
2024                s.append(TK_FOLLOWING, None)
2025            }
2026            Self::UnboundedPreceding => {
2027                s.append(TK_UNBOUNDED, None)?;
2028                s.append(TK_PRECEDING, None)
2029            }
2030        }
2031    }
2032}
2033
2034impl ToTokens for FrameExclude {
2035    fn to_tokens<S: TokenStream>(&self, s: &mut S) -> Result<(), S::Error> {
2036        match self {
2037            Self::NoOthers => {
2038                s.append(TK_NO, None)?;
2039                s.append(TK_OTHERS, None)
2040            }
2041            Self::CurrentRow => {
2042                s.append(TK_CURRENT, None)?;
2043                s.append(TK_ROW, None)
2044            }
2045            Self::Group => s.append(TK_GROUP, None),
2046            Self::Ties => s.append(TK_TIES, None),
2047        }
2048    }
2049}
2050
2051fn comma<I, S: TokenStream>(items: I, s: &mut S) -> Result<(), S::Error>
2052where
2053    I: IntoIterator,
2054    I::Item: ToTokens,
2055{
2056    let iter = items.into_iter();
2057    for (i, item) in iter.enumerate() {
2058        if i != 0 {
2059            s.append(TK_COMMA, None)?;
2060        }
2061        item.to_tokens(s)?;
2062    }
2063    Ok(())
2064}
2065
2066// TK_ID: [...] / `...` / "..." / some keywords / non keywords
2067fn double_quote<S: TokenStream>(name: &str, s: &mut S) -> Result<(), S::Error> {
2068    if name.is_empty() {
2069        return s.append(TK_ID, Some("\"\""));
2070    }
2071    if is_identifier(name) {
2072        // identifier must be quoted when they match a keyword...
2073        /*if is_keyword(name) {
2074            f.write_char('`')?;
2075            f.write_str(name)?;
2076            return f.write_char('`');
2077        }*/
2078        return s.append(TK_ID, Some(name));
2079    }
2080    /*f.write_char('"')?;
2081    for c in name.chars() {
2082        if c == '"' {
2083            f.write_char(c)?;
2084        }
2085        f.write_char(c)?;
2086    }
2087    f.write_char('"')*/
2088    s.append(TK_ID, Some(name))
2089}