Skip to main content

turso_parser/ast/
fmt.rs

1//! AST node format
2use std::fmt::{self, Display, Formatter, Write};
3
4use crate::ast::*;
5use crate::token::TokenType;
6use crate::token::TokenType::*;
7use crate::Result;
8
9use crate::ast::TableInternalId;
10
11/// Context to be used in ToSqlString
12pub trait ToSqlContext {
13    /// Given an id, get the table name
14    /// First Option indicates whether the table exists
15    ///
16    /// Currently not considering aliases
17    fn get_table_name(&self, _id: TableInternalId) -> Option<&str> {
18        None
19    }
20
21    /// Given a table id and a column index, get the column name
22    /// First Option indicates whether the column exists
23    /// Second Option indicates whether the column has a name
24    fn get_column_name(&self, _table_id: TableInternalId, _col_idx: usize) -> Option<Option<&str>> {
25        None
26    }
27
28    // help function to handle missing table/column names
29    fn get_table_and_column_names(
30        &self,
31        table_id: TableInternalId,
32        col_idx: usize,
33    ) -> (String, String) {
34        let table_name = self
35            .get_table_name(table_id)
36            .map(|s| s.to_owned())
37            .unwrap_or_else(|| format!("t{}", table_id.0));
38
39        let column_name = self
40            .get_column_name(table_id, col_idx)
41            .map(|opt| {
42                opt.map(|s| s.to_owned())
43                    .unwrap_or_else(|| format!("c{col_idx}"))
44            })
45            .unwrap_or_else(|| format!("c{col_idx}"));
46
47        (table_name, column_name)
48    }
49}
50
51pub struct WriteTokenStream<'a, T: Write> {
52    write: &'a mut T,
53    spaced: bool,
54}
55
56impl<'a, T: Write> WriteTokenStream<'a, T> {
57    /// Create a new token stream writing to the specified writer
58    pub fn new(write: &'a mut T) -> Self {
59        Self {
60            write,
61            spaced: true,
62        }
63    }
64}
65
66impl<T: Write> TokenStream for WriteTokenStream<'_, T> {
67    type Error = fmt::Error;
68
69    fn append(&mut self, ty: TokenType, value: Option<&str>) -> fmt::Result {
70        if !self.spaced {
71            match ty {
72                TK_COMMA | TK_SEMI | TK_RP | TK_DOT | TK_LBRACKET | TK_RBRACKET => {}
73                _ => {
74                    self.write.write_char(' ')?;
75                    self.spaced = true;
76                }
77            };
78        }
79
80        match (ty, ty.as_str(), value) {
81            (TK_BLOB, None, value) => {
82                self.write.write_char('X')?;
83                self.write.write_char('\'')?;
84                if let Some(str) = value {
85                    self.write.write_str(str)?;
86                }
87                self.write.write_char('\'')?;
88                Ok(())
89            }
90            (_, ty_str, value) => {
91                if let Some(str) = ty_str {
92                    self.write.write_str(str)?;
93                    self.spaced = ty == TK_LP || ty == TK_DOT || ty == TK_LBRACKET;
94                    // str should not be whitespace
95                }
96
97                if let Some(str) = value {
98                    // trick for pretty-print
99                    self.spaced = str.bytes().all(|b| b.is_ascii_whitespace());
100                    self.write.write_str(str)?;
101                }
102
103                Ok(())
104            }
105        }
106    }
107}
108
109pub struct BlankContext;
110
111impl ToSqlContext for BlankContext {}
112
113/// Stream of token
114pub trait TokenStream {
115    /// Potential error raised
116    type Error;
117
118    /// Push token to this stream
119    fn append(&mut self, ty: TokenType, value: Option<&str>) -> Result<(), Self::Error>;
120
121    /// Interspace iterator with commas
122    fn comma<I, C: ToSqlContext>(&mut self, items: I, context: &C) -> Result<(), Self::Error>
123    where
124        I: IntoIterator,
125        I::Item: ToTokens,
126    {
127        let iter = items.into_iter();
128        for (i, item) in iter.enumerate() {
129            if i != 0 {
130                self.append(TK_COMMA, None)?;
131            }
132            item.to_tokens(self, context)?;
133        }
134        Ok(())
135    }
136}
137
138pub struct SqlDisplayer<'a, 'b, C: ToSqlContext, T: ToTokens> {
139    ctx: &'a C,
140    start_node: &'b T,
141}
142
143impl<'a, 'b, C: ToSqlContext, T: ToTokens> SqlDisplayer<'a, 'b, C, T> {
144    /// Create a new displayer with the specified context and AST node
145    pub fn new(ctx: &'a C, start_node: &'b T) -> Self {
146        Self { ctx, start_node }
147    }
148}
149
150impl<'a, 'b, C: ToSqlContext, T: ToTokens> Display for SqlDisplayer<'a, 'b, C, T> {
151    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
152        let mut stream = WriteTokenStream::new(f);
153        self.start_node.to_tokens(&mut stream, self.ctx)
154    }
155}
156
157/// Generate token(s) from AST node
158/// Also implements Display to make sure devs won't forget Display
159pub trait ToTokens: Display {
160    /// Send token(s) to the specified stream with context
161    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
162        &self,
163        s: &mut S,
164        context: &C,
165    ) -> Result<(), S::Error>;
166
167    // Return displayer representation with context
168    fn displayer<'a, 'b, C: ToSqlContext>(&'b self, ctx: &'a C) -> SqlDisplayer<'a, 'b, C, Self>
169    where
170        Self: Sized,
171    {
172        SqlDisplayer::new(ctx, self)
173    }
174}
175
176macro_rules! impl_display_for_to_tokens {
177    ($struct:ty) => {
178        impl Display for $struct {
179            fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
180                self.displayer(&BlankContext).fmt(f)
181            }
182        }
183    };
184}
185
186impl<T: ?Sized + ToTokens> ToTokens for &T {
187    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
188        &self,
189        s: &mut S,
190        context: &C,
191    ) -> Result<(), S::Error> {
192        ToTokens::to_tokens(&**self, s, context)
193    }
194}
195
196impl<T: ?Sized + ToTokens> ToTokens for Box<T> {
197    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
198        &self,
199        s: &mut S,
200        context: &C,
201    ) -> Result<(), S::Error> {
202        ToTokens::to_tokens(self.as_ref(), s, context)
203    }
204}
205
206impl ToTokens for String {
207    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
208        &self,
209        s: &mut S,
210        _: &C,
211    ) -> Result<(), S::Error> {
212        s.append(TK_ANY, Some(self.as_ref()))
213    }
214}
215
216impl_display_for_to_tokens!(Cmd);
217impl ToTokens for Cmd {
218    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
219        &self,
220        s: &mut S,
221        context: &C,
222    ) -> Result<(), S::Error> {
223        match self {
224            Self::Explain(stmt) => {
225                s.append(TK_EXPLAIN, None)?;
226                stmt.to_tokens(s, context)?;
227            }
228            Self::ExplainQueryPlan(stmt) => {
229                s.append(TK_EXPLAIN, None)?;
230                s.append(TK_QUERY, None)?;
231                s.append(TK_PLAN, None)?;
232                stmt.to_tokens(s, context)?;
233            }
234            Self::Stmt(stmt) => {
235                stmt.to_tokens(s, context)?;
236            }
237        }
238        s.append(TK_SEMI, None)
239    }
240}
241
242impl_display_for_to_tokens!(Stmt);
243impl ToTokens for Stmt {
244    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
245        &self,
246        s: &mut S,
247        context: &C,
248    ) -> Result<(), S::Error> {
249        match self {
250            Self::AlterTable(AlterTable { name, body }) => {
251                s.append(TK_ALTER, None)?;
252                s.append(TK_TABLE, None)?;
253                name.to_tokens(s, context)?;
254                body.to_tokens(s, context)
255            }
256            Self::Analyze { name } => {
257                s.append(TK_ANALYZE, None)?;
258                if let Some(name) = name {
259                    name.to_tokens(s, context)?;
260                }
261                Ok(())
262            }
263            Self::Attach { expr, db_name, key } => {
264                s.append(TK_ATTACH, None)?;
265                expr.to_tokens(s, context)?;
266                s.append(TK_AS, None)?;
267                db_name.to_tokens(s, context)?;
268                if let Some(key) = key {
269                    s.append(TK_KEY, None)?;
270                    key.to_tokens(s, context)?;
271                }
272                Ok(())
273            }
274            Self::Begin { typ, name } => {
275                s.append(TK_BEGIN, None)?;
276                if let Some(typ) = typ {
277                    typ.to_tokens(s, context)?;
278                }
279                if let Some(name) = name {
280                    s.append(TK_TRANSACTION, None)?;
281                    name.to_tokens(s, context)?;
282                }
283                Ok(())
284            }
285            Self::Commit { name } => {
286                s.append(TK_COMMIT, None)?;
287                if let Some(name) = name {
288                    s.append(TK_TRANSACTION, None)?;
289                    name.to_tokens(s, context)?;
290                }
291                Ok(())
292            }
293            Self::CreateIndex {
294                unique,
295                if_not_exists,
296                idx_name,
297                tbl_name,
298                using,
299                columns,
300                with_clause,
301                where_clause,
302            } => {
303                s.append(TK_CREATE, None)?;
304                if *unique {
305                    s.append(TK_UNIQUE, None)?;
306                }
307                s.append(TK_INDEX, None)?;
308                if *if_not_exists {
309                    s.append(TK_IF, None)?;
310                    s.append(TK_NOT, None)?;
311                    s.append(TK_EXISTS, None)?;
312                }
313                idx_name.to_tokens(s, context)?;
314                s.append(TK_ON, None)?;
315                tbl_name.to_tokens(s, context)?;
316                if let Some(using) = using {
317                    s.append(TK_USING, None)?;
318                    using.to_tokens(s, context)?;
319                }
320                s.append(TK_LP, None)?;
321                comma(columns, s, context)?;
322                s.append(TK_RP, None)?;
323                if !with_clause.is_empty() {
324                    s.append(TK_WITH, None)?;
325                    s.append(TK_LP, None)?;
326                    let mut first = true;
327                    for (name, value) in with_clause.iter() {
328                        if !first {
329                            s.append(TK_COMMA, None)?;
330                        }
331                        first = false;
332                        name.to_tokens(s, context)?;
333                        s.append(TK_EQ, None)?;
334                        value.to_tokens(s, context)?;
335                    }
336                    s.append(TK_RP, None)?;
337                }
338                if let Some(where_clause) = where_clause {
339                    s.append(TK_WHERE, None)?;
340                    where_clause.to_tokens(s, context)?;
341                }
342                Ok(())
343            }
344            Self::CreateTable {
345                temporary,
346                if_not_exists,
347                tbl_name,
348                body,
349            } => {
350                s.append(TK_CREATE, None)?;
351                if *temporary {
352                    s.append(TK_TEMP, None)?;
353                }
354                s.append(TK_TABLE, None)?;
355                if *if_not_exists {
356                    s.append(TK_IF, None)?;
357                    s.append(TK_NOT, None)?;
358                    s.append(TK_EXISTS, None)?;
359                }
360                tbl_name.to_tokens(s, context)?;
361                body.to_tokens(s, context)
362            }
363            Self::CreateTrigger {
364                temporary,
365                if_not_exists,
366                trigger_name,
367                time,
368                event,
369                tbl_name,
370                for_each_row,
371                when_clause,
372                commands,
373            } => {
374                s.append(TK_CREATE, None)?;
375                if *temporary {
376                    s.append(TK_TEMP, None)?;
377                }
378                s.append(TK_TRIGGER, None)?;
379                if *if_not_exists {
380                    s.append(TK_IF, None)?;
381                    s.append(TK_NOT, None)?;
382                    s.append(TK_EXISTS, None)?;
383                }
384                trigger_name.to_tokens(s, context)?;
385                if let Some(time) = time {
386                    time.to_tokens(s, context)?;
387                }
388                event.to_tokens(s, context)?;
389                s.append(TK_ON, None)?;
390                tbl_name.to_tokens(s, context)?;
391                if *for_each_row {
392                    s.append(TK_FOR, None)?;
393                    s.append(TK_EACH, None)?;
394                    s.append(TK_ROW, None)?;
395                }
396                if let Some(when_clause) = when_clause {
397                    s.append(TK_WHEN, None)?;
398                    when_clause.to_tokens(s, context)?;
399                }
400                s.append(TK_BEGIN, Some("\n"))?;
401                for command in commands {
402                    command.to_tokens(s, context)?;
403                    s.append(TK_SEMI, Some("\n"))?;
404                }
405                s.append(TK_END, None)
406            }
407            Self::CreateView {
408                temporary,
409                if_not_exists,
410                view_name,
411                columns,
412                select,
413            } => {
414                s.append(TK_CREATE, None)?;
415                if *temporary {
416                    s.append(TK_TEMP, None)?;
417                }
418                s.append(TK_VIEW, None)?;
419                if *if_not_exists {
420                    s.append(TK_IF, None)?;
421                    s.append(TK_NOT, None)?;
422                    s.append(TK_EXISTS, None)?;
423                }
424                view_name.to_tokens(s, context)?;
425                if !columns.is_empty() {
426                    s.append(TK_LP, None)?;
427                    comma(columns, s, context)?;
428                    s.append(TK_RP, None)?;
429                }
430                s.append(TK_AS, None)?;
431                select.to_tokens(s, context)
432            }
433            Self::CreateMaterializedView {
434                if_not_exists,
435                view_name,
436                columns,
437                select,
438            } => {
439                s.append(TK_CREATE, None)?;
440                s.append(TK_MATERIALIZED, None)?;
441                s.append(TK_VIEW, None)?;
442                if *if_not_exists {
443                    s.append(TK_IF, None)?;
444                    s.append(TK_NOT, None)?;
445                    s.append(TK_EXISTS, None)?;
446                }
447                view_name.to_tokens(s, context)?;
448                if !columns.is_empty() {
449                    s.append(TK_LP, None)?;
450                    comma(columns, s, context)?;
451                    s.append(TK_RP, None)?;
452                }
453                s.append(TK_AS, None)?;
454                select.to_tokens(s, context)
455            }
456            Self::CreateVirtualTable(CreateVirtualTable {
457                if_not_exists,
458                tbl_name,
459                module_name,
460                args,
461            }) => {
462                s.append(TK_CREATE, None)?;
463                s.append(TK_VIRTUAL, None)?;
464                s.append(TK_TABLE, None)?;
465                if *if_not_exists {
466                    s.append(TK_IF, None)?;
467                    s.append(TK_NOT, None)?;
468                    s.append(TK_EXISTS, None)?;
469                }
470                tbl_name.to_tokens(s, context)?;
471                s.append(TK_USING, None)?;
472                module_name.to_tokens(s, context)?;
473                s.append(TK_LP, None)?;
474                if !args.is_empty() {
475                    comma(args, s, context)?;
476                }
477                s.append(TK_RP, None)
478            }
479            Self::Delete {
480                with,
481                tbl_name,
482                indexed,
483                where_clause,
484                returning,
485                order_by,
486                limit,
487            } => {
488                if let Some(with) = with {
489                    with.to_tokens(s, context)?;
490                }
491                s.append(TK_DELETE, None)?;
492                s.append(TK_FROM, None)?;
493                tbl_name.to_tokens(s, context)?;
494                if let Some(indexed) = indexed {
495                    indexed.to_tokens(s, context)?;
496                }
497                if let Some(where_clause) = where_clause {
498                    s.append(TK_WHERE, None)?;
499                    where_clause.to_tokens(s, context)?;
500                }
501                if !returning.is_empty() {
502                    s.append(TK_RETURNING, None)?;
503                    comma(returning, s, context)?;
504                }
505                if !order_by.is_empty() {
506                    s.append(TK_ORDER, None)?;
507                    s.append(TK_BY, None)?;
508                    comma(order_by, s, context)?;
509                }
510                if let Some(limit) = limit {
511                    limit.to_tokens(s, context)?;
512                }
513                Ok(())
514            }
515            Self::Detach { name } => {
516                s.append(TK_DETACH, None)?;
517                name.to_tokens(s, context)
518            }
519            Self::DropIndex {
520                if_exists,
521                idx_name,
522            } => {
523                s.append(TK_DROP, None)?;
524                s.append(TK_INDEX, None)?;
525                if *if_exists {
526                    s.append(TK_IF, None)?;
527                    s.append(TK_EXISTS, None)?;
528                }
529                idx_name.to_tokens(s, context)
530            }
531            Self::DropTable {
532                if_exists,
533                tbl_name,
534            } => {
535                s.append(TK_DROP, None)?;
536                s.append(TK_TABLE, None)?;
537                if *if_exists {
538                    s.append(TK_IF, None)?;
539                    s.append(TK_EXISTS, None)?;
540                }
541                tbl_name.to_tokens(s, context)
542            }
543            Self::DropTrigger {
544                if_exists,
545                trigger_name,
546            } => {
547                s.append(TK_DROP, None)?;
548                s.append(TK_TRIGGER, None)?;
549                if *if_exists {
550                    s.append(TK_IF, None)?;
551                    s.append(TK_EXISTS, None)?;
552                }
553                trigger_name.to_tokens(s, context)
554            }
555            Self::DropView {
556                if_exists,
557                view_name,
558            } => {
559                s.append(TK_DROP, None)?;
560                s.append(TK_VIEW, None)?;
561                if *if_exists {
562                    s.append(TK_IF, None)?;
563                    s.append(TK_EXISTS, None)?;
564                }
565                view_name.to_tokens(s, context)
566            }
567            Self::Insert {
568                with,
569                or_conflict,
570                tbl_name,
571                columns,
572                body,
573                returning,
574            } => {
575                if let Some(with) = with {
576                    with.to_tokens(s, context)?;
577                }
578                if let Some(ResolveType::Replace) = or_conflict {
579                    s.append(TK_REPLACE, None)?;
580                } else {
581                    s.append(TK_INSERT, None)?;
582                    if let Some(or_conflict) = or_conflict {
583                        s.append(TK_OR, None)?;
584                        or_conflict.to_tokens(s, context)?;
585                    }
586                }
587                s.append(TK_INTO, None)?;
588                tbl_name.to_tokens(s, context)?;
589                if !columns.is_empty() {
590                    s.append(TK_LP, None)?;
591                    comma(columns, s, context)?;
592                    s.append(TK_RP, None)?;
593                }
594                body.to_tokens(s, context)?;
595                if !returning.is_empty() {
596                    s.append(TK_RETURNING, None)?;
597                    comma(returning, s, context)?;
598                }
599                Ok(())
600            }
601            Self::Pragma { name, body } => {
602                s.append(TK_PRAGMA, None)?;
603                name.to_tokens(s, context)?;
604                if let Some(body) = body {
605                    body.to_tokens(s, context)?;
606                }
607                Ok(())
608            }
609            Self::Reindex { name } => {
610                s.append(TK_REINDEX, None)?;
611                if let Some(name) = name {
612                    name.to_tokens(s, context)?;
613                }
614                Ok(())
615            }
616            Self::Optimize { idx_name } => {
617                s.append(TK_OPTIMIZE, None)?;
618                s.append(TK_INDEX, None)?;
619                if let Some(name) = idx_name {
620                    name.to_tokens(s, context)?;
621                }
622                Ok(())
623            }
624            Self::Release { name } => {
625                s.append(TK_RELEASE, None)?;
626                name.to_tokens(s, context)
627            }
628            Self::Rollback {
629                tx_name,
630                savepoint_name,
631            } => {
632                s.append(TK_ROLLBACK, None)?;
633                if let Some(tx_name) = tx_name {
634                    s.append(TK_TRANSACTION, None)?;
635                    tx_name.to_tokens(s, context)?;
636                }
637                if let Some(savepoint_name) = savepoint_name {
638                    s.append(TK_TO, None)?;
639                    savepoint_name.to_tokens(s, context)?;
640                }
641                Ok(())
642            }
643            Self::Savepoint { name } => {
644                s.append(TK_SAVEPOINT, None)?;
645                name.to_tokens(s, context)
646            }
647            Self::Select(select) => select.to_tokens(s, context),
648            Self::Update(Update {
649                with,
650                or_conflict,
651                tbl_name,
652                indexed,
653                sets,
654                from,
655                where_clause,
656                returning,
657                order_by,
658                limit,
659            }) => {
660                if let Some(with) = with {
661                    with.to_tokens(s, context)?;
662                }
663                s.append(TK_UPDATE, None)?;
664                if let Some(or_conflict) = or_conflict {
665                    s.append(TK_OR, None)?;
666                    or_conflict.to_tokens(s, context)?;
667                }
668                tbl_name.to_tokens(s, context)?;
669                if let Some(indexed) = indexed {
670                    indexed.to_tokens(s, context)?;
671                }
672                s.append(TK_SET, None)?;
673                comma(sets, s, context)?;
674                if let Some(from) = from {
675                    s.append(TK_FROM, None)?;
676                    from.to_tokens(s, context)?;
677                }
678                if let Some(where_clause) = where_clause {
679                    s.append(TK_WHERE, None)?;
680                    where_clause.to_tokens(s, context)?;
681                }
682                if !returning.is_empty() {
683                    s.append(TK_RETURNING, None)?;
684                    comma(returning, s, context)?;
685                }
686                if !order_by.is_empty() {
687                    s.append(TK_ORDER, None)?;
688                    s.append(TK_BY, None)?;
689                    comma(order_by, s, context)?;
690                }
691                if let Some(limit) = limit {
692                    limit.to_tokens(s, context)?;
693                }
694                Ok(())
695            }
696            Self::Vacuum { name, into } => {
697                s.append(TK_VACUUM, None)?;
698                if let Some(ref name) = name {
699                    name.to_tokens(s, context)?;
700                }
701                if let Some(ref into) = into {
702                    s.append(TK_INTO, None)?;
703                    into.to_tokens(s, context)?;
704                }
705                Ok(())
706            }
707            Self::CreateType {
708                if_not_exists,
709                type_name,
710                body,
711            } => {
712                s.append(TK_CREATE, None)?;
713                s.append(TK_TYPE, None)?;
714                if *if_not_exists {
715                    s.append(TK_IF, None)?;
716                    s.append(TK_NOT, None)?;
717                    s.append(TK_EXISTS, None)?;
718                }
719                s.append(TK_ID, Some(type_name))?;
720                match body {
721                    CreateTypeBody::Struct(fields) => {
722                        s.append(TK_AS, None)?;
723                        s.append(TK_ID, Some("STRUCT"))?;
724                        type_fields_to_tokens(fields, s, context)?;
725                    }
726                    CreateTypeBody::Union(fields) => {
727                        s.append(TK_AS, None)?;
728                        s.append(TK_ID, Some("UNION"))?;
729                        type_fields_to_tokens(fields, s, context)?;
730                    }
731                    CreateTypeBody::CustomType {
732                        params,
733                        base,
734                        encode,
735                        decode,
736                        operators,
737                        default,
738                    } => {
739                        // Parameters
740                        if !params.is_empty() {
741                            s.append(TK_LP, None)?;
742                            for (i, param) in params.iter().enumerate() {
743                                if i > 0 {
744                                    s.append(TK_COMMA, None)?;
745                                }
746                                s.append(TK_ID, Some(&param.name))?;
747                                if let Some(ref ty) = param.ty {
748                                    s.append(TK_ID, Some(ty))?;
749                                }
750                            }
751                            s.append(TK_RP, None)?;
752                        }
753                        // BASE
754                        s.append(TK_ID, Some("BASE"))?;
755                        s.append(TK_ID, Some(base))?;
756                        // ENCODE
757                        if let Some(ref encode) = encode {
758                            s.append(TK_ID, Some("ENCODE"))?;
759                            encode.to_tokens(s, context)?;
760                        }
761                        // DECODE
762                        if let Some(ref decode) = decode {
763                            s.append(TK_ID, Some("DECODE"))?;
764                            decode.to_tokens(s, context)?;
765                        }
766                        // DEFAULT
767                        if let Some(ref default) = default {
768                            s.append(TK_ID, Some("DEFAULT"))?;
769                            default.to_tokens(s, context)?;
770                        }
771                        // OPERATOR clauses
772                        for op in operators {
773                            s.append(TK_ID, Some("OPERATOR"))?;
774                            s.append(TK_STRING, Some(&format!("'{}'", op.op)))?;
775                            if let Some(ref func_name) = op.func_name {
776                                s.append(TK_ID, Some(func_name))?;
777                            }
778                        }
779                    }
780                }
781                Ok(())
782            }
783            Self::CreateDomain {
784                if_not_exists,
785                domain_name,
786                base_type,
787                default,
788                not_null,
789                constraints,
790            } => {
791                s.append(TK_CREATE, None)?;
792                s.append(TK_ID, Some("DOMAIN"))?;
793                if *if_not_exists {
794                    s.append(TK_IF, None)?;
795                    s.append(TK_NOT, None)?;
796                    s.append(TK_EXISTS, None)?;
797                }
798                s.append(TK_ID, Some(domain_name))?;
799                s.append(TK_AS, None)?;
800                s.append(TK_ID, Some(base_type))?;
801                if let Some(ref def) = default {
802                    s.append(TK_DEFAULT, None)?;
803                    def.to_tokens(s, context)?;
804                }
805                if *not_null {
806                    s.append(TK_NOT, None)?;
807                    s.append(TK_NULL, None)?;
808                }
809                for c in constraints {
810                    if let Some(ref name) = c.name {
811                        s.append(TK_CONSTRAINT, None)?;
812                        s.append(TK_ID, Some(name))?;
813                    }
814                    s.append(TK_CHECK, None)?;
815                    s.append(TK_LP, None)?;
816                    c.check.to_tokens(s, context)?;
817                    s.append(TK_RP, None)?;
818                }
819                Ok(())
820            }
821            Self::DropType {
822                if_exists,
823                type_name,
824            } => {
825                s.append(TK_DROP, None)?;
826                s.append(TK_TYPE, None)?;
827                if *if_exists {
828                    s.append(TK_IF, None)?;
829                    s.append(TK_EXISTS, None)?;
830                }
831                s.append(TK_ID, Some(type_name))?;
832                Ok(())
833            }
834            Self::CreateSequence {
835                if_not_exists,
836                seq_name,
837                start,
838                increment,
839                min_value,
840                max_value,
841                cycle,
842            } => {
843                s.append(TK_CREATE, None)?;
844                s.append(TK_ID, Some("SEQUENCE"))?;
845                if *if_not_exists {
846                    s.append(TK_IF, None)?;
847                    s.append(TK_NOT, None)?;
848                    s.append(TK_EXISTS, None)?;
849                }
850                seq_name.to_tokens(s, context)?;
851                if let Some(v) = start {
852                    s.append(TK_ID, Some("START"))?;
853                    s.append(TK_ID, Some("WITH"))?;
854                    s.append(TK_ID, Some(&v.to_string()))?;
855                }
856                if let Some(v) = increment {
857                    s.append(TK_ID, Some("INCREMENT"))?;
858                    s.append(TK_ID, Some("BY"))?;
859                    s.append(TK_ID, Some(&v.to_string()))?;
860                }
861                if let Some(v) = min_value {
862                    s.append(TK_ID, Some("MINVALUE"))?;
863                    s.append(TK_ID, Some(&v.to_string()))?;
864                }
865                if let Some(v) = max_value {
866                    s.append(TK_ID, Some("MAXVALUE"))?;
867                    s.append(TK_ID, Some(&v.to_string()))?;
868                }
869                if *cycle {
870                    s.append(TK_ID, Some("CYCLE"))?;
871                }
872                Ok(())
873            }
874            Self::DropSequence {
875                if_exists,
876                seq_name,
877            } => {
878                s.append(TK_DROP, None)?;
879                s.append(TK_ID, Some("SEQUENCE"))?;
880                if *if_exists {
881                    s.append(TK_IF, None)?;
882                    s.append(TK_EXISTS, None)?;
883                }
884                seq_name.to_tokens(s, context)?;
885                Ok(())
886            }
887            Self::DropDomain {
888                if_exists,
889                domain_name,
890            } => {
891                s.append(TK_DROP, None)?;
892                s.append(TK_ID, Some("DOMAIN"))?;
893                if *if_exists {
894                    s.append(TK_IF, None)?;
895                    s.append(TK_EXISTS, None)?;
896                }
897                s.append(TK_ID, Some(domain_name))?;
898                Ok(())
899            }
900        }
901    }
902}
903
904impl_display_for_to_tokens!(Expr);
905impl ToTokens for Expr {
906    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
907        &self,
908        s: &mut S,
909        context: &C,
910    ) -> Result<(), S::Error> {
911        match self {
912            Self::SubqueryResult { .. } => {
913                // FIXME: what to put here? This is a highly "artificial" AST node that has no meaning when stringified.
914                Ok(())
915            }
916            Self::Between {
917                lhs,
918                not,
919                start,
920                end,
921            } => {
922                lhs.to_tokens(s, context)?;
923                if *not {
924                    s.append(TK_NOT, None)?;
925                }
926                s.append(TK_BETWEEN, None)?;
927                start.to_tokens(s, context)?;
928                s.append(TK_AND, None)?;
929                end.to_tokens(s, context)
930            }
931            Self::Binary(lhs, op, rhs) => {
932                lhs.to_tokens(s, context)?;
933                op.to_tokens(s, context)?;
934                rhs.to_tokens(s, context)
935            }
936            Self::Register(reg) => {
937                // This is for internal use only, not part of SQL syntax
938                // Use a special notation that won't conflict with SQL
939                s.append(TK_VARIABLE, Some(&format!("$r{reg}")))
940            }
941            Self::Case {
942                base,
943                when_then_pairs,
944                else_expr,
945            } => {
946                s.append(TK_CASE, None)?;
947                if let Some(ref base) = base {
948                    base.to_tokens(s, context)?;
949                }
950                for (when, then) in when_then_pairs {
951                    s.append(TK_WHEN, None)?;
952                    when.to_tokens(s, context)?;
953                    s.append(TK_THEN, None)?;
954                    then.to_tokens(s, context)?;
955                }
956                if let Some(ref else_expr) = else_expr {
957                    s.append(TK_ELSE, None)?;
958                    else_expr.to_tokens(s, context)?;
959                }
960                s.append(TK_END, None)
961            }
962            Self::Cast { expr, type_name } => {
963                s.append(TK_CAST, None)?;
964                s.append(TK_LP, None)?;
965                expr.to_tokens(s, context)?;
966                s.append(TK_AS, None)?;
967                if let Some(ref type_name) = type_name {
968                    type_name.to_tokens(s, context)?;
969                }
970                s.append(TK_RP, None)
971            }
972            Self::Collate(expr, collation) => {
973                expr.to_tokens(s, context)?;
974                s.append(TK_COLLATE, None)?;
975                s.append(TK_ID, Some(&collation.as_ident()))
976            }
977            Self::DoublyQualified(db_name, tbl_name, col_name) => {
978                db_name.to_tokens(s, context)?;
979                s.append(TK_DOT, None)?;
980                tbl_name.to_tokens(s, context)?;
981                s.append(TK_DOT, None)?;
982                col_name.to_tokens(s, context)
983            }
984            Self::Exists(subquery) => {
985                s.append(TK_EXISTS, None)?;
986                s.append(TK_LP, None)?;
987                subquery.to_tokens(s, context)?;
988                s.append(TK_RP, None)
989            }
990            Self::FunctionCall {
991                name,
992                distinctness,
993                args,
994                order_by,
995                within_group,
996                filter_over,
997            } => {
998                name.to_tokens(s, context)?;
999                s.append(TK_LP, None)?;
1000                if let Some(distinctness) = distinctness {
1001                    distinctness.to_tokens(s, context)?;
1002                }
1003                if !args.is_empty() {
1004                    comma(args, s, context)?;
1005                }
1006                if !order_by.is_empty() {
1007                    s.append(TK_ORDER, None)?;
1008                    s.append(TK_BY, None)?;
1009                    comma(order_by, s, context)?;
1010                }
1011                s.append(TK_RP, None)?;
1012                if !within_group.is_empty() {
1013                    s.append(TK_WITHIN, None)?;
1014                    s.append(TK_GROUP, None)?;
1015                    s.append(TK_LP, None)?;
1016                    s.append(TK_ORDER, None)?;
1017                    s.append(TK_BY, None)?;
1018                    comma(within_group, s, context)?;
1019                    s.append(TK_RP, None)?;
1020                }
1021                filter_over.to_tokens(s, context)?;
1022                Ok(())
1023            }
1024            Self::FunctionCallStar { name, filter_over } => {
1025                name.to_tokens(s, context)?;
1026                s.append(TK_LP, None)?;
1027                s.append(TK_STAR, None)?;
1028                s.append(TK_RP, None)?;
1029                filter_over.to_tokens(s, context)?;
1030                Ok(())
1031            }
1032            Self::Id(id) => id.to_tokens(s, context),
1033            Self::Column { table, column, .. } => {
1034                let (tbl_name, col_name) = context.get_table_and_column_names(*table, *column);
1035                s.append(TK_ID, Some(tbl_name.as_ref()))?;
1036                s.append(TK_DOT, None)?;
1037                s.append(TK_ID, Some(col_name.as_ref()))
1038            }
1039            Self::InList { lhs, not, rhs } => {
1040                lhs.to_tokens(s, context)?;
1041                if *not {
1042                    s.append(TK_NOT, None)?;
1043                }
1044                s.append(TK_IN, None)?;
1045                s.append(TK_LP, None)?;
1046                if !rhs.is_empty() {
1047                    comma(rhs, s, context)?;
1048                }
1049                s.append(TK_RP, None)
1050            }
1051            Self::InSelect { lhs, not, rhs } => {
1052                lhs.to_tokens(s, context)?;
1053                if *not {
1054                    s.append(TK_NOT, None)?;
1055                }
1056                s.append(TK_IN, None)?;
1057                s.append(TK_LP, None)?;
1058                rhs.to_tokens(s, context)?;
1059                s.append(TK_RP, None)
1060            }
1061            Self::InTable {
1062                lhs,
1063                not,
1064                rhs,
1065                args,
1066            } => {
1067                lhs.to_tokens(s, context)?;
1068                if *not {
1069                    s.append(TK_NOT, None)?;
1070                }
1071                s.append(TK_IN, None)?;
1072                rhs.to_tokens(s, context)?;
1073                if !args.is_empty() {
1074                    s.append(TK_LP, None)?;
1075                    comma(args, s, context)?;
1076                    s.append(TK_RP, None)?;
1077                }
1078                Ok(())
1079            }
1080            Self::IsNull(sub_expr) => {
1081                sub_expr.to_tokens(s, context)?;
1082                s.append(TK_ISNULL, None)
1083            }
1084            Self::Like {
1085                lhs,
1086                not,
1087                op,
1088                rhs,
1089                escape,
1090            } => {
1091                lhs.to_tokens(s, context)?;
1092                if *not {
1093                    s.append(TK_NOT, None)?;
1094                }
1095                op.to_tokens(s, context)?;
1096                rhs.to_tokens(s, context)?;
1097                if let Some(escape) = escape {
1098                    s.append(TK_ESCAPE, None)?;
1099                    escape.to_tokens(s, context)?;
1100                }
1101                Ok(())
1102            }
1103            Self::Literal(lit) => lit.to_tokens(s, context),
1104            Self::Name(name) => name.to_tokens(s, context),
1105            Self::NotNull(sub_expr) => {
1106                sub_expr.to_tokens(s, context)?;
1107                s.append(TK_NOTNULL, None)
1108            }
1109            Self::Parenthesized(exprs) => {
1110                s.append(TK_LP, None)?;
1111                comma(exprs, s, context)?;
1112                s.append(TK_RP, None)
1113            }
1114            Self::Qualified(qualifier, qualified) => {
1115                qualifier.to_tokens(s, context)?;
1116                s.append(TK_DOT, None)?;
1117                qualified.to_tokens(s, context)
1118            }
1119            Self::FieldAccess { base, field, .. } => {
1120                base.to_tokens(s, context)?;
1121                s.append(TK_DOT, None)?;
1122                field.to_tokens(s, context)
1123            }
1124            Self::Raise(rt, err) => {
1125                s.append(TK_RAISE, None)?;
1126                s.append(TK_LP, None)?;
1127                rt.to_tokens(s, context)?;
1128                if let Some(err) = err {
1129                    s.append(TK_COMMA, None)?;
1130                    err.to_tokens(s, context)?;
1131                }
1132                s.append(TK_RP, None)
1133            }
1134            Self::RowId { .. } => Ok(()),
1135            Self::Subquery(query) => {
1136                s.append(TK_LP, None)?;
1137                query.to_tokens(s, context)?;
1138                s.append(TK_RP, None)
1139            }
1140            Self::Unary(op, sub_expr) => {
1141                op.to_tokens(s, context)?;
1142                sub_expr.to_tokens(s, context)
1143            }
1144            Self::Variable(var) => {
1145                if let Some(name) = var.name.as_deref() {
1146                    return s.append(TK_VARIABLE, Some(name));
1147                }
1148
1149                let indexed = format!("?{}", var.index.get());
1150                s.append(TK_VARIABLE, Some(indexed.as_str()))
1151            }
1152            Self::Default => s.append(TK_DEFAULT, None),
1153            Self::Array { elements } => {
1154                s.append(TK_ID, Some("ARRAY"))?;
1155                s.append(TK_LBRACKET, None)?;
1156                comma(elements, s, context)?;
1157                s.append(TK_RBRACKET, None)
1158            }
1159            Self::Subscript { base, index } => {
1160                base.to_tokens(s, context)?;
1161                s.append(TK_LBRACKET, None)?;
1162                index.to_tokens(s, context)?;
1163                s.append(TK_RBRACKET, None)
1164            }
1165        }
1166    }
1167}
1168
1169impl_display_for_to_tokens!(Literal);
1170impl ToTokens for Literal {
1171    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1172        &self,
1173        s: &mut S,
1174        _: &C,
1175    ) -> Result<(), S::Error> {
1176        match self {
1177            Self::Numeric(ref num) => s.append(TK_FLOAT, Some(num)), // TODO Validate TK_FLOAT
1178            Self::String(ref str) => s.append(TK_STRING, Some(str)),
1179            Self::Blob(ref blob) => s.append(TK_BLOB, Some(blob)),
1180            Self::Keyword(ref str) => s.append(TK_ID, Some(str)), // TODO Validate TK_ID
1181            Self::Null => s.append(TK_NULL, None),
1182            Self::True => s.append(TK_ID, Some("TRUE")),
1183            Self::False => s.append(TK_ID, Some("FALSE")),
1184            Self::CurrentDate => s.append(TK_CTIME_KW, Some("CURRENT_DATE")),
1185            Self::CurrentTime => s.append(TK_CTIME_KW, Some("CURRENT_TIME")),
1186            Self::CurrentTimestamp => s.append(TK_CTIME_KW, Some("CURRENT_TIMESTAMP")),
1187        }
1188    }
1189}
1190
1191impl_display_for_to_tokens!(LikeOperator);
1192impl ToTokens for LikeOperator {
1193    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1194        &self,
1195        s: &mut S,
1196        _: &C,
1197    ) -> Result<(), S::Error> {
1198        s.append(
1199            TK_LIKE_KW,
1200            Some(match self {
1201                Self::Glob => "GLOB",
1202                Self::Like => "LIKE",
1203                Self::Match => "MATCH",
1204                Self::Regexp => "REGEXP",
1205            }),
1206        )
1207    }
1208}
1209
1210impl_display_for_to_tokens!(Operator);
1211impl ToTokens for Operator {
1212    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1213        &self,
1214        s: &mut S,
1215        _: &C,
1216    ) -> Result<(), S::Error> {
1217        match self {
1218            Self::Add => s.append(TK_PLUS, None),
1219            Self::And => s.append(TK_AND, None),
1220            Self::ArrowRight => s.append(TK_PTR, Some("->")),
1221            Self::ArrowRightShift => s.append(TK_PTR, Some("->>")),
1222            Self::BitwiseAnd => s.append(TK_BITAND, None),
1223            Self::BitwiseOr => s.append(TK_BITOR, None),
1224            Self::BitwiseNot => s.append(TK_BITNOT, None),
1225            Self::Concat => s.append(TK_CONCAT, None),
1226            Self::Equals => s.append(TK_EQ, None),
1227            Self::Divide => s.append(TK_SLASH, None),
1228            Self::Greater => s.append(TK_GT, None),
1229            Self::GreaterEquals => s.append(TK_GE, None),
1230            Self::Is => s.append(TK_IS, None),
1231            Self::IsNot => {
1232                s.append(TK_IS, None)?;
1233                s.append(TK_NOT, None)
1234            }
1235            Self::LeftShift => s.append(TK_LSHIFT, None),
1236            Self::Less => s.append(TK_LT, None),
1237            Self::LessEquals => s.append(TK_LE, None),
1238            Self::Modulus => s.append(TK_REM, None),
1239            Self::Multiply => s.append(TK_STAR, None),
1240            Self::NotEquals => s.append(TK_NE, None),
1241            Self::Or => s.append(TK_OR, None),
1242            Self::RightShift => s.append(TK_RSHIFT, None),
1243            Self::Subtract => s.append(TK_MINUS, None),
1244            Self::ArrayContains => s.append(TK_ARRAY_CONTAINS, None),
1245            Self::ArrayOverlap => s.append(TK_ARRAY_OVERLAP, None),
1246        }
1247    }
1248}
1249
1250impl_display_for_to_tokens!(UnaryOperator);
1251impl ToTokens for UnaryOperator {
1252    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1253        &self,
1254        s: &mut S,
1255        _: &C,
1256    ) -> Result<(), S::Error> {
1257        s.append(
1258            match self {
1259                Self::BitwiseNot => TK_BITNOT,
1260                Self::Negative => TK_MINUS,
1261                Self::Not => TK_NOT,
1262                Self::Positive => TK_PLUS,
1263            },
1264            None,
1265        )
1266    }
1267}
1268
1269impl_display_for_to_tokens!(Select);
1270impl ToTokens for Select {
1271    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1272        &self,
1273        s: &mut S,
1274        context: &C,
1275    ) -> Result<(), S::Error> {
1276        if let Some(ref with) = self.with {
1277            with.to_tokens(s, context)?;
1278        }
1279        self.body.to_tokens(s, context)?;
1280        if !self.order_by.is_empty() {
1281            s.append(TK_ORDER, None)?;
1282            s.append(TK_BY, None)?;
1283            comma(&self.order_by, s, context)?;
1284        }
1285        if let Some(ref limit) = self.limit {
1286            limit.to_tokens(s, context)?;
1287        }
1288        Ok(())
1289    }
1290}
1291
1292impl_display_for_to_tokens!(SelectBody);
1293impl ToTokens for SelectBody {
1294    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1295        &self,
1296        s: &mut S,
1297        context: &C,
1298    ) -> Result<(), S::Error> {
1299        self.select.to_tokens(s, context)?;
1300        for compound in &self.compounds {
1301            compound.to_tokens(s, context)?;
1302        }
1303        Ok(())
1304    }
1305}
1306
1307impl_display_for_to_tokens!(CompoundSelect);
1308impl ToTokens for CompoundSelect {
1309    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1310        &self,
1311        s: &mut S,
1312        context: &C,
1313    ) -> Result<(), S::Error> {
1314        self.operator.to_tokens(s, context)?;
1315        self.select.to_tokens(s, context)
1316    }
1317}
1318
1319impl_display_for_to_tokens!(CompoundOperator);
1320impl ToTokens for CompoundOperator {
1321    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1322        &self,
1323        s: &mut S,
1324        _: &C,
1325    ) -> Result<(), S::Error> {
1326        match self {
1327            Self::Union => s.append(TK_UNION, None),
1328            Self::UnionAll => {
1329                s.append(TK_UNION, None)?;
1330                s.append(TK_ALL, None)
1331            }
1332            Self::Except => s.append(TK_EXCEPT, None),
1333            Self::Intersect => s.append(TK_INTERSECT, None),
1334        }
1335    }
1336}
1337
1338impl_display_for_to_tokens!(OneSelect);
1339impl ToTokens for OneSelect {
1340    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1341        &self,
1342        s: &mut S,
1343        context: &C,
1344    ) -> Result<(), S::Error> {
1345        match self {
1346            Self::Select {
1347                distinctness,
1348                columns,
1349                from,
1350                where_clause,
1351                group_by,
1352                window_clause,
1353            } => {
1354                s.append(TK_SELECT, None)?;
1355                if let Some(ref distinctness) = distinctness {
1356                    distinctness.to_tokens(s, context)?;
1357                }
1358                comma(columns, s, context)?;
1359                if let Some(ref from) = from {
1360                    s.append(TK_FROM, None)?;
1361                    from.to_tokens(s, context)?;
1362                }
1363                if let Some(ref where_clause) = where_clause {
1364                    s.append(TK_WHERE, None)?;
1365                    where_clause.to_tokens(s, context)?;
1366                }
1367                if let Some(ref group_by) = group_by {
1368                    group_by.to_tokens(s, context)?;
1369                }
1370                if !window_clause.is_empty() {
1371                    s.append(TK_WINDOW, None)?;
1372                    comma(window_clause, s, context)?;
1373                }
1374                Ok(())
1375            }
1376            Self::Values(values) => {
1377                for (i, vals) in values.iter().enumerate() {
1378                    if i == 0 {
1379                        s.append(TK_VALUES, None)?;
1380                    } else {
1381                        s.append(TK_COMMA, None)?;
1382                    }
1383                    s.append(TK_LP, None)?;
1384                    comma(vals, s, context)?;
1385                    s.append(TK_RP, None)?;
1386                }
1387                Ok(())
1388            }
1389        }
1390    }
1391}
1392
1393impl_display_for_to_tokens!(FromClause);
1394impl ToTokens for FromClause {
1395    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1396        &self,
1397        s: &mut S,
1398        context: &C,
1399    ) -> Result<(), S::Error> {
1400        self.select.as_ref().to_tokens(s, context)?;
1401        for join in &self.joins {
1402            join.to_tokens(s, context)?;
1403        }
1404
1405        Ok(())
1406    }
1407}
1408
1409impl_display_for_to_tokens!(Distinctness);
1410impl ToTokens for Distinctness {
1411    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1412        &self,
1413        s: &mut S,
1414        _: &C,
1415    ) -> Result<(), S::Error> {
1416        s.append(
1417            match self {
1418                Self::Distinct => TK_DISTINCT,
1419                Self::All => TK_ALL,
1420            },
1421            None,
1422        )
1423    }
1424}
1425
1426impl_display_for_to_tokens!(ResultColumn);
1427impl ToTokens for ResultColumn {
1428    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1429        &self,
1430        s: &mut S,
1431        context: &C,
1432    ) -> Result<(), S::Error> {
1433        match self {
1434            Self::Expr(expr, alias) => {
1435                expr.to_tokens(s, context)?;
1436                if let Some(alias) = alias {
1437                    alias.to_tokens(s, context)?;
1438                }
1439                Ok(())
1440            }
1441            Self::Star => s.append(TK_STAR, None),
1442            Self::TableStar(tbl_name) => {
1443                tbl_name.to_tokens(s, context)?;
1444                s.append(TK_DOT, None)?;
1445                s.append(TK_STAR, None)
1446            }
1447        }
1448    }
1449}
1450
1451impl_display_for_to_tokens!(As);
1452impl ToTokens for As {
1453    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1454        &self,
1455        s: &mut S,
1456        context: &C,
1457    ) -> Result<(), S::Error> {
1458        match self {
1459            Self::As(ref name) => {
1460                s.append(TK_AS, None)?;
1461                name.to_tokens(s, context)
1462            }
1463            Self::Elided(ref name) => name.to_tokens(s, context),
1464            Self::ImplicitColumnName(_) => Ok(()),
1465        }
1466    }
1467}
1468
1469impl_display_for_to_tokens!(JoinedSelectTable);
1470impl ToTokens for JoinedSelectTable {
1471    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1472        &self,
1473        s: &mut S,
1474        context: &C,
1475    ) -> Result<(), S::Error> {
1476        self.operator.to_tokens(s, context)?;
1477        self.table.to_tokens(s, context)?;
1478        if let Some(ref constraint) = self.constraint {
1479            constraint.to_tokens(s, context)?;
1480        }
1481        Ok(())
1482    }
1483}
1484
1485impl_display_for_to_tokens!(SelectTable);
1486impl ToTokens for SelectTable {
1487    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1488        &self,
1489        s: &mut S,
1490        context: &C,
1491    ) -> Result<(), S::Error> {
1492        match self {
1493            Self::Table(name, alias, indexed) => {
1494                name.to_tokens(s, context)?;
1495                if let Some(alias) = alias {
1496                    alias.to_tokens(s, context)?;
1497                }
1498                if let Some(indexed) = indexed {
1499                    indexed.to_tokens(s, context)?;
1500                }
1501                Ok(())
1502            }
1503            Self::TableCall(name, exprs, alias) => {
1504                name.to_tokens(s, context)?;
1505                s.append(TK_LP, None)?;
1506                comma(exprs, s, context)?;
1507                s.append(TK_RP, None)?;
1508                if let Some(alias) = alias {
1509                    alias.to_tokens(s, context)?;
1510                }
1511                Ok(())
1512            }
1513            Self::Select(select, alias) => {
1514                s.append(TK_LP, None)?;
1515                select.to_tokens(s, context)?;
1516                s.append(TK_RP, None)?;
1517                if let Some(alias) = alias {
1518                    alias.to_tokens(s, context)?;
1519                }
1520                Ok(())
1521            }
1522            Self::Sub(from, alias) => {
1523                s.append(TK_LP, None)?;
1524                from.to_tokens(s, context)?;
1525                s.append(TK_RP, None)?;
1526                if let Some(alias) = alias {
1527                    alias.to_tokens(s, context)?;
1528                }
1529                Ok(())
1530            }
1531        }
1532    }
1533}
1534
1535impl_display_for_to_tokens!(JoinOperator);
1536impl ToTokens for JoinOperator {
1537    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1538        &self,
1539        s: &mut S,
1540        context: &C,
1541    ) -> Result<(), S::Error> {
1542        match self {
1543            Self::Comma => s.append(TK_COMMA, None),
1544            Self::TypedJoin(join_type) => {
1545                if let Some(ref join_type) = join_type {
1546                    join_type.to_tokens(s, context)?;
1547                }
1548                s.append(TK_JOIN, None)
1549            }
1550        }
1551    }
1552}
1553
1554impl_display_for_to_tokens!(JoinType);
1555impl ToTokens for JoinType {
1556    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1557        &self,
1558        s: &mut S,
1559        _: &C,
1560    ) -> Result<(), S::Error> {
1561        if self.contains(Self::NATURAL) {
1562            s.append(TK_JOIN_KW, Some("NATURAL"))?;
1563        }
1564        if self.contains(Self::INNER) {
1565            if self.contains(Self::CROSS) {
1566                s.append(TK_JOIN_KW, Some("CROSS"))?;
1567            }
1568            s.append(TK_JOIN_KW, Some("INNER"))?;
1569        } else {
1570            if self.contains(Self::LEFT) {
1571                if self.contains(Self::RIGHT) {
1572                    s.append(TK_JOIN_KW, Some("FULL"))?;
1573                } else {
1574                    s.append(TK_JOIN_KW, Some("LEFT"))?;
1575                }
1576            } else if self.contains(Self::RIGHT) {
1577                s.append(TK_JOIN_KW, Some("RIGHT"))?;
1578            }
1579            if self.contains(Self::OUTER) {
1580                s.append(TK_JOIN_KW, Some("OUTER"))?;
1581            }
1582        }
1583        Ok(())
1584    }
1585}
1586
1587impl_display_for_to_tokens!(JoinConstraint);
1588impl ToTokens for JoinConstraint {
1589    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1590        &self,
1591        s: &mut S,
1592        context: &C,
1593    ) -> Result<(), S::Error> {
1594        match self {
1595            Self::On(expr) => {
1596                s.append(TK_ON, None)?;
1597                expr.to_tokens(s, context)
1598            }
1599            Self::Using(col_names) => {
1600                s.append(TK_USING, None)?;
1601                s.append(TK_LP, None)?;
1602                comma(col_names, s, context)?;
1603                s.append(TK_RP, None)
1604            }
1605        }
1606    }
1607}
1608
1609impl_display_for_to_tokens!(GroupBy);
1610impl ToTokens for GroupBy {
1611    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1612        &self,
1613        s: &mut S,
1614        context: &C,
1615    ) -> Result<(), S::Error> {
1616        if !self.exprs.is_empty() {
1617            s.append(TK_GROUP, None)?;
1618            s.append(TK_BY, None)?;
1619            comma(&self.exprs, s, context)?;
1620        }
1621        if let Some(ref having) = self.having {
1622            s.append(TK_HAVING, None)?;
1623            having.to_tokens(s, context)?;
1624        }
1625        Ok(())
1626    }
1627}
1628
1629impl_display_for_to_tokens!(Name);
1630impl ToTokens for Name {
1631    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1632        &self,
1633        s: &mut S,
1634        _: &C,
1635    ) -> Result<(), S::Error> {
1636        s.append(TK_ID, Some(&self.as_ident()))
1637    }
1638}
1639
1640impl_display_for_to_tokens!(QualifiedName);
1641impl ToTokens for QualifiedName {
1642    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1643        &self,
1644        s: &mut S,
1645        context: &C,
1646    ) -> Result<(), S::Error> {
1647        if let Some(ref db_name) = self.db_name {
1648            db_name.to_tokens(s, context)?;
1649            s.append(TK_DOT, None)?;
1650        }
1651        self.name.to_tokens(s, context)?;
1652        if let Some(ref alias) = self.alias {
1653            s.append(TK_AS, None)?;
1654            alias.to_tokens(s, context)?;
1655        }
1656        Ok(())
1657    }
1658}
1659
1660impl_display_for_to_tokens!(AlterTableBody);
1661impl ToTokens for AlterTableBody {
1662    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1663        &self,
1664        s: &mut S,
1665        context: &C,
1666    ) -> Result<(), S::Error> {
1667        match self {
1668            Self::RenameTo(name) => {
1669                s.append(TK_RENAME, None)?;
1670                s.append(TK_TO, None)?;
1671                name.to_tokens(s, context)
1672            }
1673            Self::AddColumn(def) => {
1674                s.append(TK_ADD, None)?;
1675                s.append(TK_COLUMNKW, None)?;
1676                def.to_tokens(s, context)
1677            }
1678            Self::AlterColumn { old, new } => {
1679                s.append(TK_ALTER, None)?;
1680                s.append(TK_COLUMNKW, None)?;
1681                old.to_tokens(s, context)?;
1682                s.append(TK_TO, None)?;
1683                new.to_tokens(s, context)
1684            }
1685            Self::RenameColumn { old, new } => {
1686                s.append(TK_RENAME, None)?;
1687                s.append(TK_COLUMNKW, None)?;
1688                old.to_tokens(s, context)?;
1689                s.append(TK_TO, None)?;
1690                new.to_tokens(s, context)
1691            }
1692            Self::DropColumn(name) => {
1693                s.append(TK_DROP, None)?;
1694                s.append(TK_COLUMNKW, None)?;
1695                name.to_tokens(s, context)
1696            }
1697        }
1698    }
1699}
1700
1701impl_display_for_to_tokens!(CreateTableBody);
1702impl ToTokens for CreateTableBody {
1703    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1704        &self,
1705        s: &mut S,
1706        context: &C,
1707    ) -> Result<(), S::Error> {
1708        match self {
1709            Self::ColumnsAndConstraints {
1710                columns,
1711                constraints,
1712                options,
1713            } => {
1714                s.append(TK_LP, None)?;
1715                comma(columns, s, context)?;
1716                if !constraints.is_empty() {
1717                    s.append(TK_COMMA, None)?;
1718                    comma(constraints, s, context)?;
1719                }
1720                s.append(TK_RP, None)?;
1721                // Use the original text if available
1722                if let Some(ref without_rowid) = options.without_rowid_text {
1723                    // Split "WITHOUT ROWID" back into tokens
1724                    let parts: Vec<&str> = without_rowid.split_whitespace().collect();
1725                    if parts.len() == 2 {
1726                        s.append(TK_WITHOUT, None)?;
1727                        s.append(TK_ID, Some(parts[1]))?;
1728                    }
1729                }
1730                if let Some(ref strict) = options.strict_text {
1731                    s.append(TK_ID, Some(strict))?;
1732                }
1733                Ok(())
1734            }
1735            Self::AsSelect(select) => {
1736                s.append(TK_AS, None)?;
1737                select.to_tokens(s, context)
1738            }
1739        }
1740    }
1741}
1742
1743impl_display_for_to_tokens!(ColumnDefinition);
1744impl ToTokens for ColumnDefinition {
1745    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1746        &self,
1747        s: &mut S,
1748        context: &C,
1749    ) -> Result<(), S::Error> {
1750        self.col_name.to_tokens(s, context)?;
1751        if let Some(ref col_type) = self.col_type {
1752            col_type.to_tokens(s, context)?;
1753        }
1754        for constraint in &self.constraints {
1755            constraint.to_tokens(s, context)?;
1756        }
1757        Ok(())
1758    }
1759}
1760
1761impl_display_for_to_tokens!(NamedColumnConstraint);
1762impl ToTokens for NamedColumnConstraint {
1763    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1764        &self,
1765        s: &mut S,
1766        context: &C,
1767    ) -> Result<(), S::Error> {
1768        if let Some(ref name) = self.name {
1769            s.append(TK_CONSTRAINT, None)?;
1770            name.to_tokens(s, context)?;
1771        }
1772        self.constraint.to_tokens(s, context)
1773    }
1774}
1775
1776impl_display_for_to_tokens!(ColumnConstraint);
1777impl ToTokens for ColumnConstraint {
1778    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1779        &self,
1780        s: &mut S,
1781        context: &C,
1782    ) -> Result<(), S::Error> {
1783        match self {
1784            Self::PrimaryKey {
1785                order,
1786                conflict_clause,
1787                auto_increment,
1788            } => {
1789                s.append(TK_PRIMARY, None)?;
1790                s.append(TK_KEY, None)?;
1791                if let Some(order) = order {
1792                    order.to_tokens(s, context)?;
1793                }
1794                if let Some(conflict_clause) = conflict_clause {
1795                    s.append(TK_ON, None)?;
1796                    s.append(TK_CONFLICT, None)?;
1797                    conflict_clause.to_tokens(s, context)?;
1798                }
1799                if *auto_increment {
1800                    s.append(TK_AUTOINCR, None)?;
1801                }
1802                Ok(())
1803            }
1804            Self::NotNull {
1805                nullable,
1806                conflict_clause,
1807            } => {
1808                if !nullable {
1809                    s.append(TK_NOT, None)?;
1810                }
1811                s.append(TK_NULL, None)?;
1812                if let Some(conflict_clause) = conflict_clause {
1813                    s.append(TK_ON, None)?;
1814                    s.append(TK_CONFLICT, None)?;
1815                    conflict_clause.to_tokens(s, context)?;
1816                }
1817                Ok(())
1818            }
1819            Self::Unique(conflict_clause) => {
1820                s.append(TK_UNIQUE, None)?;
1821                if let Some(conflict_clause) = conflict_clause {
1822                    s.append(TK_ON, None)?;
1823                    s.append(TK_CONFLICT, None)?;
1824                    conflict_clause.to_tokens(s, context)?;
1825                }
1826                Ok(())
1827            }
1828            Self::Check(expr) => {
1829                s.append(TK_CHECK, None)?;
1830                s.append(TK_LP, None)?;
1831                expr.to_tokens(s, context)?;
1832                s.append(TK_RP, None)
1833            }
1834            Self::Default(expr) => {
1835                s.append(TK_DEFAULT, None)?;
1836                expr.to_tokens(s, context)
1837            }
1838            Self::Collate { collation_name } => {
1839                s.append(TK_COLLATE, None)?;
1840                collation_name.to_tokens(s, context)
1841            }
1842            Self::ForeignKey {
1843                clause,
1844                defer_clause,
1845            } => {
1846                s.append(TK_REFERENCES, None)?;
1847                clause.to_tokens(s, context)?;
1848                if let Some(defer_clause) = defer_clause {
1849                    defer_clause.to_tokens(s, context)?;
1850                }
1851                Ok(())
1852            }
1853            Self::Generated { expr, typ } => {
1854                s.append(TK_AS, None)?;
1855                s.append(TK_LP, None)?;
1856                expr.to_tokens(s, context)?;
1857                s.append(TK_RP, None)?;
1858                if let Some(typ) = typ {
1859                    match typ {
1860                        GeneratedColumnType::Virtual => s.append(TK_VIRTUAL, None)?,
1861                        GeneratedColumnType::Stored => s.append(TK_ID, Some("STORED"))?,
1862                    }
1863                }
1864                Ok(())
1865            }
1866        }
1867    }
1868}
1869
1870impl_display_for_to_tokens!(NamedTableConstraint);
1871impl ToTokens for NamedTableConstraint {
1872    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1873        &self,
1874        s: &mut S,
1875        context: &C,
1876    ) -> Result<(), S::Error> {
1877        if let Some(ref name) = self.name {
1878            s.append(TK_CONSTRAINT, None)?;
1879            name.to_tokens(s, context)?;
1880        }
1881        self.constraint.to_tokens(s, context)
1882    }
1883}
1884
1885impl_display_for_to_tokens!(TableConstraint);
1886impl ToTokens for TableConstraint {
1887    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1888        &self,
1889        s: &mut S,
1890        context: &C,
1891    ) -> Result<(), S::Error> {
1892        match self {
1893            Self::PrimaryKey {
1894                columns,
1895                auto_increment,
1896                conflict_clause,
1897            } => {
1898                s.append(TK_PRIMARY, None)?;
1899                s.append(TK_KEY, None)?;
1900                s.append(TK_LP, None)?;
1901                comma(columns, s, context)?;
1902                if *auto_increment {
1903                    s.append(TK_AUTOINCR, None)?;
1904                }
1905                s.append(TK_RP, None)?;
1906                if let Some(conflict_clause) = conflict_clause {
1907                    s.append(TK_ON, None)?;
1908                    s.append(TK_CONFLICT, None)?;
1909                    conflict_clause.to_tokens(s, context)?;
1910                }
1911                Ok(())
1912            }
1913            Self::Unique {
1914                columns,
1915                conflict_clause,
1916            } => {
1917                s.append(TK_UNIQUE, None)?;
1918                s.append(TK_LP, None)?;
1919                comma(columns, s, context)?;
1920                s.append(TK_RP, None)?;
1921                if let Some(conflict_clause) = conflict_clause {
1922                    s.append(TK_ON, None)?;
1923                    s.append(TK_CONFLICT, None)?;
1924                    conflict_clause.to_tokens(s, context)?;
1925                }
1926                Ok(())
1927            }
1928            Self::Check(expr) => {
1929                s.append(TK_CHECK, None)?;
1930                s.append(TK_LP, None)?;
1931                expr.to_tokens(s, context)?;
1932                s.append(TK_RP, None)
1933            }
1934            Self::ForeignKey {
1935                columns,
1936                clause,
1937                defer_clause,
1938            } => {
1939                s.append(TK_FOREIGN, None)?;
1940                s.append(TK_KEY, None)?;
1941                s.append(TK_LP, None)?;
1942                comma(columns, s, context)?;
1943                s.append(TK_RP, None)?;
1944                s.append(TK_REFERENCES, None)?;
1945                clause.to_tokens(s, context)?;
1946                if let Some(defer_clause) = defer_clause {
1947                    defer_clause.to_tokens(s, context)?;
1948                }
1949                Ok(())
1950            }
1951        }
1952    }
1953}
1954
1955impl_display_for_to_tokens!(SortOrder);
1956impl ToTokens for SortOrder {
1957    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1958        &self,
1959        s: &mut S,
1960        _: &C,
1961    ) -> Result<(), S::Error> {
1962        s.append(
1963            match self {
1964                Self::Asc => TK_ASC,
1965                Self::Desc => TK_DESC,
1966            },
1967            None,
1968        )
1969    }
1970}
1971
1972impl_display_for_to_tokens!(NullsOrder);
1973impl ToTokens for NullsOrder {
1974    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1975        &self,
1976        s: &mut S,
1977        _: &C,
1978    ) -> Result<(), S::Error> {
1979        s.append(TK_NULLS, None)?;
1980        s.append(
1981            match self {
1982                Self::First => TK_FIRST,
1983                Self::Last => TK_LAST,
1984            },
1985            None,
1986        )
1987    }
1988}
1989
1990impl_display_for_to_tokens!(ForeignKeyClause);
1991impl ToTokens for ForeignKeyClause {
1992    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
1993        &self,
1994        s: &mut S,
1995        context: &C,
1996    ) -> Result<(), S::Error> {
1997        self.tbl_name.to_tokens(s, context)?;
1998        if !self.columns.is_empty() {
1999            s.append(TK_LP, None)?;
2000            comma(&self.columns, s, context)?;
2001            s.append(TK_RP, None)?;
2002        }
2003        for arg in &self.args {
2004            arg.to_tokens(s, context)?;
2005        }
2006        Ok(())
2007    }
2008}
2009
2010impl_display_for_to_tokens!(RefArg);
2011impl ToTokens for RefArg {
2012    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2013        &self,
2014        s: &mut S,
2015        context: &C,
2016    ) -> Result<(), S::Error> {
2017        match self {
2018            Self::OnDelete(ref action) => {
2019                s.append(TK_ON, None)?;
2020                s.append(TK_DELETE, None)?;
2021                action.to_tokens(s, context)
2022            }
2023            Self::OnInsert(ref action) => {
2024                s.append(TK_ON, None)?;
2025                s.append(TK_INSERT, None)?;
2026                action.to_tokens(s, context)
2027            }
2028            Self::OnUpdate(ref action) => {
2029                s.append(TK_ON, None)?;
2030                s.append(TK_UPDATE, None)?;
2031                action.to_tokens(s, context)
2032            }
2033            Self::Match(ref name) => {
2034                s.append(TK_MATCH, None)?;
2035                name.to_tokens(s, context)
2036            }
2037        }
2038    }
2039}
2040
2041impl_display_for_to_tokens!(RefAct);
2042impl ToTokens for RefAct {
2043    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2044        &self,
2045        s: &mut S,
2046        _: &C,
2047    ) -> Result<(), S::Error> {
2048        match self {
2049            Self::SetNull => {
2050                s.append(TK_SET, None)?;
2051                s.append(TK_NULL, None)
2052            }
2053            Self::SetDefault => {
2054                s.append(TK_SET, None)?;
2055                s.append(TK_DEFAULT, None)
2056            }
2057            Self::Cascade => s.append(TK_CASCADE, None),
2058            Self::Restrict => s.append(TK_RESTRICT, None),
2059            Self::NoAction => {
2060                s.append(TK_NO, None)?;
2061                s.append(TK_ACTION, None)
2062            }
2063        }
2064    }
2065}
2066
2067impl_display_for_to_tokens!(DeferSubclause);
2068impl ToTokens for DeferSubclause {
2069    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2070        &self,
2071        s: &mut S,
2072        context: &C,
2073    ) -> Result<(), S::Error> {
2074        if !self.deferrable {
2075            s.append(TK_NOT, None)?;
2076        }
2077        s.append(TK_DEFERRABLE, None)?;
2078        if let Some(init_deferred) = self.init_deferred {
2079            init_deferred.to_tokens(s, context)?;
2080        }
2081        Ok(())
2082    }
2083}
2084
2085impl_display_for_to_tokens!(InitDeferredPred);
2086impl ToTokens for InitDeferredPred {
2087    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2088        &self,
2089        s: &mut S,
2090        _: &C,
2091    ) -> Result<(), S::Error> {
2092        s.append(TK_INITIALLY, None)?;
2093        s.append(
2094            match self {
2095                Self::InitiallyDeferred => TK_DEFERRED,
2096                Self::InitiallyImmediate => TK_IMMEDIATE,
2097            },
2098            None,
2099        )
2100    }
2101}
2102
2103impl_display_for_to_tokens!(IndexedColumn);
2104impl ToTokens for IndexedColumn {
2105    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2106        &self,
2107        s: &mut S,
2108        context: &C,
2109    ) -> Result<(), S::Error> {
2110        self.col_name.to_tokens(s, context)?;
2111        if let Some(ref collation_name) = self.collation_name {
2112            s.append(TK_COLLATE, None)?;
2113            collation_name.to_tokens(s, context)?;
2114        }
2115        if let Some(order) = self.order {
2116            order.to_tokens(s, context)?;
2117        }
2118        Ok(())
2119    }
2120}
2121
2122impl_display_for_to_tokens!(Indexed);
2123impl ToTokens for Indexed {
2124    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2125        &self,
2126        s: &mut S,
2127        context: &C,
2128    ) -> Result<(), S::Error> {
2129        match self {
2130            Self::IndexedBy(ref name) => {
2131                s.append(TK_INDEXED, None)?;
2132                s.append(TK_BY, None)?;
2133                name.to_tokens(s, context)
2134            }
2135            Self::NotIndexed => {
2136                s.append(TK_NOT, None)?;
2137                s.append(TK_INDEXED, None)
2138            }
2139        }
2140    }
2141}
2142
2143impl_display_for_to_tokens!(SortedColumn);
2144impl ToTokens for SortedColumn {
2145    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2146        &self,
2147        s: &mut S,
2148        context: &C,
2149    ) -> Result<(), S::Error> {
2150        self.expr.to_tokens(s, context)?;
2151        if let Some(ref order) = self.order {
2152            order.to_tokens(s, context)?;
2153        }
2154        if let Some(ref nulls) = self.nulls {
2155            nulls.to_tokens(s, context)?;
2156        }
2157        Ok(())
2158    }
2159}
2160
2161impl_display_for_to_tokens!(Limit);
2162impl ToTokens for Limit {
2163    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2164        &self,
2165        s: &mut S,
2166        context: &C,
2167    ) -> Result<(), S::Error> {
2168        s.append(TK_LIMIT, None)?;
2169        self.expr.to_tokens(s, context)?;
2170        if let Some(ref offset) = self.offset {
2171            s.append(TK_OFFSET, None)?;
2172            offset.to_tokens(s, context)?;
2173        }
2174        Ok(())
2175    }
2176}
2177
2178impl_display_for_to_tokens!(InsertBody);
2179impl ToTokens for InsertBody {
2180    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2181        &self,
2182        s: &mut S,
2183        context: &C,
2184    ) -> Result<(), S::Error> {
2185        match self {
2186            Self::Select(select, upsert) => {
2187                select.to_tokens(s, context)?;
2188                if let Some(upsert) = upsert {
2189                    upsert.to_tokens(s, context)?;
2190                }
2191                Ok(())
2192            }
2193            Self::DefaultValues => {
2194                s.append(TK_DEFAULT, None)?;
2195                s.append(TK_VALUES, None)
2196            }
2197        }
2198    }
2199}
2200
2201impl_display_for_to_tokens!(Set);
2202impl ToTokens for Set {
2203    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2204        &self,
2205        s: &mut S,
2206        context: &C,
2207    ) -> Result<(), S::Error> {
2208        if self.col_names.len() == 1 {
2209            comma(&self.col_names, s, context)?;
2210        } else {
2211            s.append(TK_LP, None)?;
2212            comma(&self.col_names, s, context)?;
2213            s.append(TK_RP, None)?;
2214        }
2215        s.append(TK_EQ, None)?;
2216        self.expr.to_tokens(s, context)
2217    }
2218}
2219
2220impl_display_for_to_tokens!(PragmaBody);
2221impl ToTokens for PragmaBody {
2222    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2223        &self,
2224        s: &mut S,
2225        context: &C,
2226    ) -> Result<(), S::Error> {
2227        match self {
2228            Self::Equals(value) => {
2229                s.append(TK_EQ, None)?;
2230                value.to_tokens(s, context)
2231            }
2232            Self::Call(value) => {
2233                s.append(TK_LP, None)?;
2234                value.to_tokens(s, context)?;
2235                s.append(TK_RP, None)
2236            }
2237        }
2238    }
2239}
2240
2241impl_display_for_to_tokens!(TriggerTime);
2242impl ToTokens for TriggerTime {
2243    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2244        &self,
2245        s: &mut S,
2246        _: &C,
2247    ) -> Result<(), S::Error> {
2248        match self {
2249            Self::Before => s.append(TK_BEFORE, None),
2250            Self::After => s.append(TK_AFTER, None),
2251            Self::InsteadOf => {
2252                s.append(TK_INSTEAD, None)?;
2253                s.append(TK_OF, None)
2254            }
2255        }
2256    }
2257}
2258
2259impl_display_for_to_tokens!(TriggerEvent);
2260impl ToTokens for TriggerEvent {
2261    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2262        &self,
2263        s: &mut S,
2264        context: &C,
2265    ) -> Result<(), S::Error> {
2266        match self {
2267            Self::Delete => s.append(TK_DELETE, None),
2268            Self::Insert => s.append(TK_INSERT, None),
2269            Self::Update => s.append(TK_UPDATE, None),
2270            Self::UpdateOf(ref col_names) => {
2271                s.append(TK_UPDATE, None)?;
2272                s.append(TK_OF, None)?;
2273                comma(col_names, s, context)
2274            }
2275        }
2276    }
2277}
2278
2279impl_display_for_to_tokens!(TriggerCmd);
2280impl ToTokens for TriggerCmd {
2281    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2282        &self,
2283        s: &mut S,
2284        context: &C,
2285    ) -> Result<(), S::Error> {
2286        match self {
2287            Self::Update {
2288                or_conflict,
2289                tbl_name,
2290                sets,
2291                from,
2292                where_clause,
2293            } => {
2294                s.append(TK_UPDATE, None)?;
2295                if let Some(or_conflict) = or_conflict {
2296                    s.append(TK_OR, None)?;
2297                    or_conflict.to_tokens(s, context)?;
2298                }
2299                tbl_name.to_tokens(s, context)?;
2300                s.append(TK_SET, None)?;
2301                comma(sets, s, context)?;
2302                if let Some(from) = from {
2303                    s.append(TK_FROM, None)?;
2304                    from.to_tokens(s, context)?;
2305                }
2306                if let Some(where_clause) = where_clause {
2307                    s.append(TK_WHERE, None)?;
2308                    where_clause.to_tokens(s, context)?;
2309                }
2310                Ok(())
2311            }
2312            Self::Insert {
2313                or_conflict,
2314                tbl_name,
2315                col_names,
2316                select,
2317                upsert,
2318                returning,
2319            } => {
2320                if let Some(ResolveType::Replace) = or_conflict {
2321                    s.append(TK_REPLACE, None)?;
2322                } else {
2323                    s.append(TK_INSERT, None)?;
2324                    if let Some(or_conflict) = or_conflict {
2325                        s.append(TK_OR, None)?;
2326                        or_conflict.to_tokens(s, context)?;
2327                    }
2328                }
2329                s.append(TK_INTO, None)?;
2330                tbl_name.to_tokens(s, context)?;
2331                if !col_names.is_empty() {
2332                    s.append(TK_LP, None)?;
2333                    comma(col_names, s, context)?;
2334                    s.append(TK_RP, None)?;
2335                }
2336                select.to_tokens(s, context)?;
2337                if let Some(upsert) = upsert {
2338                    upsert.to_tokens(s, context)?;
2339                }
2340                if !returning.is_empty() {
2341                    s.append(TK_RETURNING, None)?;
2342                    comma(returning, s, context)?;
2343                }
2344                Ok(())
2345            }
2346            Self::Delete {
2347                tbl_name,
2348                where_clause,
2349            } => {
2350                s.append(TK_DELETE, None)?;
2351                s.append(TK_FROM, None)?;
2352                tbl_name.to_tokens(s, context)?;
2353                if let Some(where_clause) = where_clause {
2354                    s.append(TK_WHERE, None)?;
2355                    where_clause.to_tokens(s, context)?;
2356                }
2357                Ok(())
2358            }
2359            Self::Select(select) => select.to_tokens(s, context),
2360        }
2361    }
2362}
2363
2364impl_display_for_to_tokens!(ResolveType);
2365impl ToTokens for ResolveType {
2366    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2367        &self,
2368        s: &mut S,
2369        _: &C,
2370    ) -> Result<(), S::Error> {
2371        s.append(
2372            match self {
2373                Self::Rollback => TK_ROLLBACK,
2374                Self::Abort => TK_ABORT,
2375                Self::Fail => TK_FAIL,
2376                Self::Ignore => TK_IGNORE,
2377                Self::Replace => TK_REPLACE,
2378            },
2379            None,
2380        )
2381    }
2382}
2383
2384impl_display_for_to_tokens!(With);
2385impl ToTokens for With {
2386    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2387        &self,
2388        s: &mut S,
2389        context: &C,
2390    ) -> Result<(), S::Error> {
2391        s.append(TK_WITH, None)?;
2392        if self.recursive {
2393            s.append(TK_RECURSIVE, None)?;
2394        }
2395        comma(&self.ctes, s, context)
2396    }
2397}
2398
2399impl_display_for_to_tokens!(CommonTableExpr);
2400impl ToTokens for CommonTableExpr {
2401    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2402        &self,
2403        s: &mut S,
2404        context: &C,
2405    ) -> Result<(), S::Error> {
2406        self.tbl_name.to_tokens(s, context)?;
2407        if !self.columns.is_empty() {
2408            s.append(TK_LP, None)?;
2409            comma(&self.columns, s, context)?;
2410            s.append(TK_RP, None)?;
2411        }
2412        s.append(TK_AS, None)?;
2413        match self.materialized {
2414            Materialized::Any => {}
2415            Materialized::Yes => {
2416                s.append(TK_MATERIALIZED, None)?;
2417            }
2418            Materialized::No => {
2419                s.append(TK_NOT, None)?;
2420                s.append(TK_MATERIALIZED, None)?;
2421            }
2422        };
2423        s.append(TK_LP, None)?;
2424        self.select.to_tokens(s, context)?;
2425        s.append(TK_RP, None)
2426    }
2427}
2428
2429impl_display_for_to_tokens!(Type);
2430impl ToTokens for Type {
2431    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2432        &self,
2433        s: &mut S,
2434        context: &C,
2435    ) -> Result<(), S::Error> {
2436        s.append(TK_ID, Some(&self.name))?;
2437        if let Some(ref size) = self.size {
2438            s.append(TK_LP, None)?;
2439            size.to_tokens(s, context)?;
2440            s.append(TK_RP, None)?;
2441        }
2442        for _ in 0..self.array_dimensions {
2443            s.append(TK_LBRACKET, None)?;
2444            s.append(TK_RBRACKET, None)?;
2445        }
2446        Ok(())
2447    }
2448}
2449
2450impl_display_for_to_tokens!(TypeSize);
2451impl ToTokens for TypeSize {
2452    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2453        &self,
2454        s: &mut S,
2455        context: &C,
2456    ) -> Result<(), S::Error> {
2457        match self {
2458            Self::MaxSize(size) => size.to_tokens(s, context),
2459            Self::TypeSize(size1, size2) => {
2460                size1.to_tokens(s, context)?;
2461                s.append(TK_COMMA, None)?;
2462                size2.to_tokens(s, context)
2463            }
2464        }
2465    }
2466}
2467
2468impl_display_for_to_tokens!(TransactionType);
2469impl ToTokens for TransactionType {
2470    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2471        &self,
2472        s: &mut S,
2473        _: &C,
2474    ) -> Result<(), S::Error> {
2475        s.append(
2476            match self {
2477                Self::Deferred => TK_DEFERRED,
2478                Self::Immediate => TK_IMMEDIATE,
2479                Self::Exclusive => TK_EXCLUSIVE,
2480                Self::Concurrent => TK_CONCURRENT,
2481            },
2482            None,
2483        )
2484    }
2485}
2486
2487impl_display_for_to_tokens!(Upsert);
2488impl ToTokens for Upsert {
2489    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2490        &self,
2491        s: &mut S,
2492        context: &C,
2493    ) -> Result<(), S::Error> {
2494        s.append(TK_ON, None)?;
2495        s.append(TK_CONFLICT, None)?;
2496        if let Some(ref index) = self.index {
2497            index.to_tokens(s, context)?;
2498        }
2499        self.do_clause.to_tokens(s, context)?;
2500        if let Some(ref next) = self.next {
2501            next.to_tokens(s, context)?;
2502        }
2503        Ok(())
2504    }
2505}
2506
2507impl_display_for_to_tokens!(UpsertIndex);
2508impl ToTokens for UpsertIndex {
2509    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2510        &self,
2511        s: &mut S,
2512        context: &C,
2513    ) -> Result<(), S::Error> {
2514        s.append(TK_LP, None)?;
2515        comma(&self.targets, s, context)?;
2516        s.append(TK_RP, None)?;
2517        if let Some(ref where_clause) = self.where_clause {
2518            s.append(TK_WHERE, None)?;
2519            where_clause.to_tokens(s, context)?;
2520        }
2521        Ok(())
2522    }
2523}
2524
2525impl_display_for_to_tokens!(UpsertDo);
2526impl ToTokens for UpsertDo {
2527    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2528        &self,
2529        s: &mut S,
2530        context: &C,
2531    ) -> Result<(), S::Error> {
2532        match self {
2533            Self::Set { sets, where_clause } => {
2534                s.append(TK_DO, None)?;
2535                s.append(TK_UPDATE, None)?;
2536                s.append(TK_SET, None)?;
2537                comma(sets, s, context)?;
2538                if let Some(where_clause) = where_clause {
2539                    s.append(TK_WHERE, None)?;
2540                    where_clause.to_tokens(s, context)?;
2541                }
2542                Ok(())
2543            }
2544            Self::Nothing => {
2545                s.append(TK_DO, None)?;
2546                s.append(TK_NOTHING, None)
2547            }
2548        }
2549    }
2550}
2551
2552impl_display_for_to_tokens!(FunctionTail);
2553impl ToTokens for FunctionTail {
2554    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2555        &self,
2556        s: &mut S,
2557        context: &C,
2558    ) -> Result<(), S::Error> {
2559        if let Some(ref filter_clause) = self.filter_clause {
2560            s.append(TK_FILTER, None)?;
2561            s.append(TK_LP, None)?;
2562            s.append(TK_WHERE, None)?;
2563            filter_clause.to_tokens(s, context)?;
2564            s.append(TK_RP, None)?;
2565        }
2566        if let Some(ref over_clause) = self.over_clause {
2567            s.append(TK_OVER, None)?;
2568            over_clause.to_tokens(s, context)?;
2569        }
2570        Ok(())
2571    }
2572}
2573
2574impl_display_for_to_tokens!(Over);
2575impl ToTokens for Over {
2576    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2577        &self,
2578        s: &mut S,
2579        context: &C,
2580    ) -> Result<(), S::Error> {
2581        match self {
2582            Self::Window(ref window) => window.to_tokens(s, context),
2583            Self::Name(ref name) => name.to_tokens(s, context),
2584        }
2585    }
2586}
2587
2588impl_display_for_to_tokens!(WindowDef);
2589impl ToTokens for WindowDef {
2590    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2591        &self,
2592        s: &mut S,
2593        context: &C,
2594    ) -> Result<(), S::Error> {
2595        self.name.to_tokens(s, context)?;
2596        s.append(TK_AS, None)?;
2597        self.window.to_tokens(s, context)
2598    }
2599}
2600
2601impl_display_for_to_tokens!(Window);
2602impl ToTokens for Window {
2603    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2604        &self,
2605        s: &mut S,
2606        context: &C,
2607    ) -> Result<(), S::Error> {
2608        s.append(TK_LP, None)?;
2609        if let Some(ref base) = self.base {
2610            base.to_tokens(s, context)?;
2611        }
2612        if !self.partition_by.is_empty() {
2613            s.append(TK_PARTITION, None)?;
2614            s.append(TK_BY, None)?;
2615            comma(&self.partition_by, s, context)?;
2616        }
2617        if !self.order_by.is_empty() {
2618            s.append(TK_ORDER, None)?;
2619            s.append(TK_BY, None)?;
2620            comma(&self.order_by, s, context)?;
2621        }
2622        if let Some(ref frame_clause) = self.frame_clause {
2623            frame_clause.to_tokens(s, context)?;
2624        }
2625        s.append(TK_RP, None)
2626    }
2627}
2628
2629impl_display_for_to_tokens!(FrameClause);
2630impl ToTokens for FrameClause {
2631    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2632        &self,
2633        s: &mut S,
2634        context: &C,
2635    ) -> Result<(), S::Error> {
2636        self.mode.to_tokens(s, context)?;
2637        if let Some(ref end) = self.end {
2638            s.append(TK_BETWEEN, None)?;
2639            self.start.to_tokens(s, context)?;
2640            s.append(TK_AND, None)?;
2641            end.to_tokens(s, context)?;
2642        } else {
2643            self.start.to_tokens(s, context)?;
2644        }
2645        if let Some(ref exclude) = self.exclude {
2646            s.append(TK_EXCLUDE, None)?;
2647            exclude.to_tokens(s, context)?;
2648        }
2649        Ok(())
2650    }
2651}
2652
2653impl_display_for_to_tokens!(FrameMode);
2654impl ToTokens for FrameMode {
2655    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2656        &self,
2657        s: &mut S,
2658        _: &C,
2659    ) -> Result<(), S::Error> {
2660        s.append(
2661            match self {
2662                Self::Groups => TK_GROUPS,
2663                Self::Range => TK_RANGE,
2664                Self::Rows => TK_ROWS,
2665            },
2666            None,
2667        )
2668    }
2669}
2670
2671impl_display_for_to_tokens!(FrameBound);
2672impl ToTokens for FrameBound {
2673    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2674        &self,
2675        s: &mut S,
2676        context: &C,
2677    ) -> Result<(), S::Error> {
2678        match self {
2679            Self::CurrentRow => {
2680                s.append(TK_CURRENT, None)?;
2681                s.append(TK_ROW, None)
2682            }
2683            Self::Following(value) => {
2684                value.to_tokens(s, context)?;
2685                s.append(TK_FOLLOWING, None)
2686            }
2687            Self::Preceding(value) => {
2688                value.to_tokens(s, context)?;
2689                s.append(TK_PRECEDING, None)
2690            }
2691            Self::UnboundedFollowing => {
2692                s.append(TK_UNBOUNDED, None)?;
2693                s.append(TK_FOLLOWING, None)
2694            }
2695            Self::UnboundedPreceding => {
2696                s.append(TK_UNBOUNDED, None)?;
2697                s.append(TK_PRECEDING, None)
2698            }
2699        }
2700    }
2701}
2702
2703impl_display_for_to_tokens!(FrameExclude);
2704impl ToTokens for FrameExclude {
2705    fn to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2706        &self,
2707        s: &mut S,
2708        _: &C,
2709    ) -> Result<(), S::Error> {
2710        match self {
2711            Self::NoOthers => {
2712                s.append(TK_NO, None)?;
2713                s.append(TK_OTHERS, None)
2714            }
2715            Self::CurrentRow => {
2716                s.append(TK_CURRENT, None)?;
2717                s.append(TK_ROW, None)
2718            }
2719            Self::Group => s.append(TK_GROUP, None),
2720            Self::Ties => s.append(TK_TIES, None),
2721        }
2722    }
2723}
2724
2725/// Emit a parenthesized, comma-separated list of `name Type` pairs.
2726fn type_fields_to_tokens<S: TokenStream + ?Sized, C: ToSqlContext>(
2727    fields: &[TypeField],
2728    s: &mut S,
2729    context: &C,
2730) -> Result<(), S::Error> {
2731    s.append(TK_LP, None)?;
2732    for (i, field) in fields.iter().enumerate() {
2733        if i > 0 {
2734            s.append(TK_COMMA, None)?;
2735        }
2736        field.name.to_tokens(s, context)?;
2737        field.field_type.to_tokens(s, context)?;
2738    }
2739    s.append(TK_RP, None)
2740}
2741
2742fn comma<I, S: TokenStream + ?Sized, C: ToSqlContext>(
2743    items: I,
2744    s: &mut S,
2745    context: &C,
2746) -> Result<(), S::Error>
2747where
2748    I: IntoIterator,
2749    I::Item: ToTokens,
2750{
2751    s.comma(items, context)
2752}