Skip to main content

sqlite3_parser/parser/ast/
fmt.rs

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