1use crate::ast::*;
2
3pub struct Generator {
9 output: String,
10 pretty: bool,
12 indent: usize,
13}
14
15impl Generator {
16 #[must_use]
17 pub fn new() -> Self {
18 Self {
19 output: String::new(),
20 pretty: false,
21 indent: 0,
22 }
23 }
24
25 #[must_use]
27 pub fn pretty() -> Self {
28 Self {
29 output: String::new(),
30 pretty: true,
31 indent: 0,
32 }
33 }
34
35 #[must_use]
37 pub fn generate(&mut self, statement: &Statement) -> String {
38 self.output.clear();
39 self.gen_statement(statement);
40 self.output.clone()
41 }
42
43 #[must_use]
45 pub fn expr_to_sql(expr: &Expr) -> String {
46 let mut g = Self::new();
47 g.gen_expr(expr);
48 g.output
49 }
50
51 fn write(&mut self, s: &str) {
52 self.output.push_str(s);
53 }
54
55 fn newline(&mut self) {
57 if self.pretty {
58 self.output.push('\n');
59 for _ in 0..self.indent {
60 self.output.push_str(" ");
61 }
62 }
63 }
64
65 fn sep(&mut self) {
67 if self.pretty {
68 self.newline();
69 } else {
70 self.output.push(' ');
71 }
72 }
73
74 fn indent_up(&mut self) {
75 self.indent += 1;
76 }
77
78 fn indent_down(&mut self) {
79 self.indent = self.indent.saturating_sub(1);
80 }
81
82 fn write_keyword(&mut self, s: &str) {
83 self.write(s);
84 }
85
86 fn write_quoted(&mut self, name: &str, style: QuoteStyle) {
88 match style {
89 QuoteStyle::None => self.write(name),
90 QuoteStyle::DoubleQuote => {
91 self.write("\"");
92 self.write(&name.replace('"', "\"\""));
93 self.write("\"");
94 }
95 QuoteStyle::Backtick => {
96 self.write("`");
97 self.write(&name.replace('`', "``"));
98 self.write("`");
99 }
100 QuoteStyle::Bracket => {
101 self.write("[");
102 self.write(&name.replace(']', "]]"));
103 self.write("]");
104 }
105 }
106 }
107
108 fn gen_statement(&mut self, statement: &Statement) {
113 match statement {
114 Statement::Select(s) => self.gen_select(s),
115 Statement::Insert(s) => self.gen_insert(s),
116 Statement::Update(s) => self.gen_update(s),
117 Statement::Delete(s) => self.gen_delete(s),
118 Statement::CreateTable(s) => self.gen_create_table(s),
119 Statement::DropTable(s) => self.gen_drop_table(s),
120 Statement::SetOperation(s) => self.gen_set_operation(s),
121 Statement::AlterTable(s) => self.gen_alter_table(s),
122 Statement::CreateView(s) => self.gen_create_view(s),
123 Statement::DropView(s) => self.gen_drop_view(s),
124 Statement::Truncate(s) => self.gen_truncate(s),
125 Statement::Transaction(s) => self.gen_transaction(s),
126 Statement::Explain(s) => self.gen_explain(s),
127 Statement::Use(s) => self.gen_use(s),
128 Statement::Expression(e) => self.gen_expr(e),
129 }
130 }
131
132 fn gen_select(&mut self, sel: &SelectStatement) {
135 if !sel.ctes.is_empty() {
137 self.gen_ctes(&sel.ctes);
138 self.sep();
139 }
140
141 self.write_keyword("SELECT");
142 if sel.distinct {
143 self.write(" ");
144 self.write_keyword("DISTINCT");
145 }
146 if let Some(top) = &sel.top {
147 self.write(" ");
148 self.write_keyword("TOP ");
149 self.gen_expr(top);
150 }
151
152 if self.pretty {
154 self.indent_up();
155 for (i, item) in sel.columns.iter().enumerate() {
156 self.newline();
157 self.gen_select_item(item);
158 if i < sel.columns.len() - 1 {
159 self.write(",");
160 }
161 }
162 self.indent_down();
163 } else {
164 self.write(" ");
165 for (i, item) in sel.columns.iter().enumerate() {
166 if i > 0 {
167 self.write(", ");
168 }
169 self.gen_select_item(item);
170 }
171 }
172
173 if let Some(from) = &sel.from {
174 self.sep();
175 self.write_keyword("FROM");
176 if self.pretty {
177 self.indent_up();
178 self.newline();
179 self.gen_table_source(&from.source);
180 self.indent_down();
181 } else {
182 self.write(" ");
183 self.gen_table_source(&from.source);
184 }
185 }
186
187 for join in &sel.joins {
188 self.gen_join(join);
189 }
190
191 if let Some(wh) = &sel.where_clause {
192 self.sep();
193 self.write_keyword("WHERE");
194 if self.pretty {
195 self.indent_up();
196 self.newline();
197 self.gen_expr(wh);
198 self.indent_down();
199 } else {
200 self.write(" ");
201 self.gen_expr(wh);
202 }
203 }
204
205 if !sel.group_by.is_empty() {
206 self.sep();
207 self.write_keyword("GROUP BY");
208 if self.pretty {
209 self.indent_up();
210 self.newline();
211 self.gen_expr_list(&sel.group_by);
212 self.indent_down();
213 } else {
214 self.write(" ");
215 self.gen_expr_list(&sel.group_by);
216 }
217 }
218
219 if let Some(having) = &sel.having {
220 self.sep();
221 self.write_keyword("HAVING");
222 if self.pretty {
223 self.indent_up();
224 self.newline();
225 self.gen_expr(having);
226 self.indent_down();
227 } else {
228 self.write(" ");
229 self.gen_expr(having);
230 }
231 }
232
233 if let Some(qualify) = &sel.qualify {
234 self.sep();
235 self.write_keyword("QUALIFY");
236 if self.pretty {
237 self.indent_up();
238 self.newline();
239 self.gen_expr(qualify);
240 self.indent_down();
241 } else {
242 self.write(" ");
243 self.gen_expr(qualify);
244 }
245 }
246
247 if !sel.window_definitions.is_empty() {
248 self.sep();
249 self.write_keyword("WINDOW ");
250 for (i, wd) in sel.window_definitions.iter().enumerate() {
251 if i > 0 {
252 self.write(", ");
253 }
254 self.write(&wd.name);
255 self.write(" AS (");
256 self.gen_window_spec(&wd.spec);
257 self.write(")");
258 }
259 }
260
261 self.gen_order_by(&sel.order_by);
262
263 if let Some(limit) = &sel.limit {
264 self.sep();
265 self.write_keyword("LIMIT ");
266 self.gen_expr(limit);
267 }
268
269 if let Some(offset) = &sel.offset {
270 self.sep();
271 self.write_keyword("OFFSET ");
272 self.gen_expr(offset);
273 }
274
275 if let Some(fetch) = &sel.fetch_first {
276 self.sep();
277 self.write_keyword("FETCH FIRST ");
278 self.gen_expr(fetch);
279 self.write(" ");
280 self.write_keyword("ROWS ONLY");
281 }
282 }
283
284 fn gen_ctes(&mut self, ctes: &[Cte]) {
285 self.write_keyword("WITH ");
286 if ctes.iter().any(|c| c.recursive) {
287 self.write_keyword("RECURSIVE ");
288 }
289 for (i, cte) in ctes.iter().enumerate() {
290 if i > 0 {
291 self.write(",");
292 self.sep();
293 }
294 self.write(&cte.name);
295 if !cte.columns.is_empty() {
296 self.write("(");
297 self.write(&cte.columns.join(", "));
298 self.write(")");
299 }
300 self.write(" ");
301 self.write_keyword("AS ");
302 if let Some(true) = cte.materialized {
303 self.write_keyword("MATERIALIZED ");
304 } else if let Some(false) = cte.materialized {
305 self.write_keyword("NOT MATERIALIZED ");
306 }
307 self.write("(");
308 if self.pretty {
309 self.indent_up();
310 self.newline();
311 self.gen_statement(&cte.query);
312 self.indent_down();
313 self.newline();
314 } else {
315 self.gen_statement(&cte.query);
316 }
317 self.write(")");
318 }
319 }
320
321 fn gen_select_item(&mut self, item: &SelectItem) {
322 match item {
323 SelectItem::Wildcard => self.write("*"),
324 SelectItem::QualifiedWildcard { table } => {
325 self.write(table);
326 self.write(".*");
327 }
328 SelectItem::Expr { expr, alias } => {
329 self.gen_expr(expr);
330 if let Some(alias) = alias {
331 self.write(" ");
332 self.write_keyword("AS ");
333 self.write(alias);
334 }
335 }
336 }
337 }
338
339 fn gen_table_source(&mut self, source: &TableSource) {
340 match source {
341 TableSource::Table(table_ref) => self.gen_table_ref(table_ref),
342 TableSource::Subquery { query, alias } => {
343 self.write("(");
344 self.gen_statement(query);
345 self.write(")");
346 if let Some(alias) = alias {
347 self.write(" ");
348 self.write_keyword("AS ");
349 self.write(alias);
350 }
351 }
352 TableSource::TableFunction { name, args, alias } => {
353 self.write(name);
354 self.write("(");
355 self.gen_expr_list(args);
356 self.write(")");
357 if let Some(alias) = alias {
358 self.write(" ");
359 self.write_keyword("AS ");
360 self.write(alias);
361 }
362 }
363 TableSource::Lateral { source } => {
364 self.write_keyword("LATERAL ");
365 self.gen_table_source(source);
366 }
367 TableSource::Unnest {
368 expr,
369 alias,
370 with_offset,
371 } => {
372 self.write_keyword("UNNEST(");
373 self.gen_expr(expr);
374 self.write(")");
375 if let Some(alias) = alias {
376 self.write(" ");
377 self.write_keyword("AS ");
378 self.write(alias);
379 }
380 if *with_offset {
381 self.write(" ");
382 self.write_keyword("WITH OFFSET");
383 }
384 }
385 }
386 }
387
388 fn gen_table_ref(&mut self, table: &TableRef) {
389 if let Some(catalog) = &table.catalog {
390 self.write(catalog);
391 self.write(".");
392 }
393 if let Some(schema) = &table.schema {
394 self.write(schema);
395 self.write(".");
396 }
397 self.write_quoted(&table.name, table.name_quote_style);
398 if let Some(alias) = &table.alias {
399 self.write(" ");
400 self.write_keyword("AS ");
401 self.write(alias);
402 }
403 }
404
405 fn gen_join(&mut self, join: &JoinClause) {
406 let join_kw = match join.join_type {
407 JoinType::Inner => "INNER JOIN",
408 JoinType::Left => "LEFT JOIN",
409 JoinType::Right => "RIGHT JOIN",
410 JoinType::Full => "FULL JOIN",
411 JoinType::Cross => "CROSS JOIN",
412 JoinType::Natural => "NATURAL JOIN",
413 JoinType::Lateral => "LATERAL JOIN",
414 };
415 self.sep();
416 self.write_keyword(join_kw);
417 if self.pretty {
418 self.indent_up();
419 self.newline();
420 self.gen_table_source(&join.table);
421 } else {
422 self.write(" ");
423 self.gen_table_source(&join.table);
424 }
425 if let Some(on) = &join.on {
426 if self.pretty {
427 self.newline();
428 } else {
429 self.write(" ");
430 }
431 self.write_keyword("ON ");
432 self.gen_expr(on);
433 }
434 if !join.using.is_empty() {
435 if self.pretty {
436 self.newline();
437 } else {
438 self.write(" ");
439 }
440 self.write_keyword("USING (");
441 self.write(&join.using.join(", "));
442 self.write(")");
443 }
444 if self.pretty {
445 self.indent_down();
446 }
447 }
448
449 fn gen_order_by(&mut self, items: &[OrderByItem]) {
450 if items.is_empty() {
451 return;
452 }
453 self.sep();
454 self.write_keyword("ORDER BY");
455 if self.pretty {
456 self.indent_up();
457 self.newline();
458 } else {
459 self.write(" ");
460 }
461 for (i, item) in items.iter().enumerate() {
462 if i > 0 {
463 self.write(", ");
464 }
465 self.gen_expr(&item.expr);
466 if !item.ascending {
467 self.write(" ");
468 self.write_keyword("DESC");
469 }
470 if let Some(nulls_first) = item.nulls_first {
471 if nulls_first {
472 self.write(" ");
473 self.write_keyword("NULLS FIRST");
474 } else {
475 self.write(" ");
476 self.write_keyword("NULLS LAST");
477 }
478 }
479 }
480 if self.pretty {
481 self.indent_down();
482 }
483 }
484
485 fn gen_set_operation(&mut self, sop: &SetOperationStatement) {
488 self.gen_statement(&sop.left);
489 let op_kw = match sop.op {
490 SetOperationType::Union => "UNION",
491 SetOperationType::Intersect => "INTERSECT",
492 SetOperationType::Except => "EXCEPT",
493 };
494 self.sep();
495 self.write_keyword(op_kw);
496 if sop.all {
497 self.write(" ");
498 self.write_keyword("ALL");
499 }
500 self.sep();
501 self.gen_statement(&sop.right);
502
503 self.gen_order_by(&sop.order_by);
504
505 if let Some(limit) = &sop.limit {
506 self.sep();
507 self.write_keyword("LIMIT ");
508 self.gen_expr(limit);
509 }
510 if let Some(offset) = &sop.offset {
511 self.sep();
512 self.write_keyword("OFFSET ");
513 self.gen_expr(offset);
514 }
515 }
516
517 fn gen_insert(&mut self, ins: &InsertStatement) {
520 self.write_keyword("INSERT INTO ");
521 self.gen_table_ref(&ins.table);
522
523 if !ins.columns.is_empty() {
524 self.write(" (");
525 self.write(&ins.columns.join(", "));
526 self.write(")");
527 }
528
529 match &ins.source {
530 InsertSource::Values(rows) => {
531 self.sep();
532 self.write_keyword("VALUES");
533 if self.pretty {
534 self.indent_up();
535 for (i, row) in rows.iter().enumerate() {
536 self.newline();
537 self.write("(");
538 self.gen_expr_list(row);
539 self.write(")");
540 if i < rows.len() - 1 {
541 self.write(",");
542 }
543 }
544 self.indent_down();
545 } else {
546 self.write(" ");
547 for (i, row) in rows.iter().enumerate() {
548 if i > 0 {
549 self.write(", ");
550 }
551 self.write("(");
552 self.gen_expr_list(row);
553 self.write(")");
554 }
555 }
556 }
557 InsertSource::Query(query) => {
558 self.sep();
559 self.gen_statement(query);
560 }
561 InsertSource::Default => {
562 self.sep();
563 self.write_keyword("DEFAULT VALUES");
564 }
565 }
566
567 if let Some(on_conflict) = &ins.on_conflict {
568 self.sep();
569 self.write_keyword("ON CONFLICT");
570 if !on_conflict.columns.is_empty() {
571 self.write(" (");
572 self.write(&on_conflict.columns.join(", "));
573 self.write(")");
574 }
575 match &on_conflict.action {
576 ConflictAction::DoNothing => {
577 self.write(" ");
578 self.write_keyword("DO NOTHING");
579 }
580 ConflictAction::DoUpdate(assignments) => {
581 self.write(" ");
582 self.write_keyword("DO UPDATE SET ");
583 for (i, (col, val)) in assignments.iter().enumerate() {
584 if i > 0 {
585 self.write(", ");
586 }
587 self.write(col);
588 self.write(" = ");
589 self.gen_expr(val);
590 }
591 }
592 }
593 }
594
595 if !ins.returning.is_empty() {
596 self.sep();
597 self.write_keyword("RETURNING ");
598 for (i, item) in ins.returning.iter().enumerate() {
599 if i > 0 {
600 self.write(", ");
601 }
602 self.gen_select_item(item);
603 }
604 }
605 }
606
607 fn gen_update(&mut self, upd: &UpdateStatement) {
610 self.write_keyword("UPDATE ");
611 self.gen_table_ref(&upd.table);
612 self.sep();
613 self.write_keyword("SET");
614
615 if self.pretty {
616 self.indent_up();
617 for (i, (col, val)) in upd.assignments.iter().enumerate() {
618 self.newline();
619 self.write(col);
620 self.write(" = ");
621 self.gen_expr(val);
622 if i < upd.assignments.len() - 1 {
623 self.write(",");
624 }
625 }
626 self.indent_down();
627 } else {
628 self.write(" ");
629 for (i, (col, val)) in upd.assignments.iter().enumerate() {
630 if i > 0 {
631 self.write(", ");
632 }
633 self.write(col);
634 self.write(" = ");
635 self.gen_expr(val);
636 }
637 }
638
639 if let Some(from) = &upd.from {
640 self.sep();
641 self.write_keyword("FROM ");
642 self.gen_table_source(&from.source);
643 }
644
645 if let Some(wh) = &upd.where_clause {
646 self.sep();
647 self.write_keyword("WHERE");
648 if self.pretty {
649 self.indent_up();
650 self.newline();
651 self.gen_expr(wh);
652 self.indent_down();
653 } else {
654 self.write(" ");
655 self.gen_expr(wh);
656 }
657 }
658
659 if !upd.returning.is_empty() {
660 self.sep();
661 self.write_keyword("RETURNING ");
662 for (i, item) in upd.returning.iter().enumerate() {
663 if i > 0 {
664 self.write(", ");
665 }
666 self.gen_select_item(item);
667 }
668 }
669 }
670
671 fn gen_delete(&mut self, del: &DeleteStatement) {
674 self.write_keyword("DELETE FROM ");
675 self.gen_table_ref(&del.table);
676
677 if let Some(using) = &del.using {
678 self.sep();
679 self.write_keyword("USING ");
680 self.gen_table_source(&using.source);
681 }
682
683 if let Some(wh) = &del.where_clause {
684 self.sep();
685 self.write_keyword("WHERE");
686 if self.pretty {
687 self.indent_up();
688 self.newline();
689 self.gen_expr(wh);
690 self.indent_down();
691 } else {
692 self.write(" ");
693 self.gen_expr(wh);
694 }
695 }
696
697 if !del.returning.is_empty() {
698 self.sep();
699 self.write_keyword("RETURNING ");
700 for (i, item) in del.returning.iter().enumerate() {
701 if i > 0 {
702 self.write(", ");
703 }
704 self.gen_select_item(item);
705 }
706 }
707 }
708
709 fn gen_create_table(&mut self, ct: &CreateTableStatement) {
712 self.write_keyword("CREATE ");
713 if ct.temporary {
714 self.write_keyword("TEMPORARY ");
715 }
716 self.write_keyword("TABLE ");
717 if ct.if_not_exists {
718 self.write_keyword("IF NOT EXISTS ");
719 }
720 self.gen_table_ref(&ct.table);
721
722 if let Some(as_select) = &ct.as_select {
723 self.write(" ");
724 self.write_keyword("AS ");
725 self.gen_statement(as_select);
726 return;
727 }
728
729 self.write(" (");
730
731 if self.pretty {
732 self.indent_up();
733 for (i, col) in ct.columns.iter().enumerate() {
734 self.newline();
735 self.gen_column_def(col);
736 if i < ct.columns.len() - 1 || !ct.constraints.is_empty() {
737 self.write(",");
738 }
739 }
740 for (i, constraint) in ct.constraints.iter().enumerate() {
741 self.newline();
742 self.gen_table_constraint(constraint);
743 if i < ct.constraints.len() - 1 {
744 self.write(",");
745 }
746 }
747 self.indent_down();
748 self.newline();
749 } else {
750 for (i, col) in ct.columns.iter().enumerate() {
751 if i > 0 {
752 self.write(", ");
753 }
754 self.gen_column_def(col);
755 }
756 for (i, constraint) in ct.constraints.iter().enumerate() {
757 if i + ct.columns.len() > 0 {
758 self.write(", ");
759 }
760 self.gen_table_constraint(constraint);
761 }
762 }
763
764 self.write(")");
765 }
766
767 fn gen_column_def(&mut self, col: &ColumnDef) {
768 self.write(&col.name);
769 self.write(" ");
770 self.gen_data_type(&col.data_type);
771
772 if col.primary_key {
773 self.write(" ");
774 self.write_keyword("PRIMARY KEY");
775 }
776 if col.unique {
777 self.write(" ");
778 self.write_keyword("UNIQUE");
779 }
780 if col.auto_increment {
781 self.write(" ");
782 self.write_keyword("AUTOINCREMENT");
783 }
784
785 match col.nullable {
786 Some(false) => {
787 self.write(" ");
788 self.write_keyword("NOT NULL");
789 }
790 Some(true) => {
791 self.write(" ");
792 self.write_keyword("NULL");
793 }
794 None => {}
795 }
796
797 if let Some(default) = &col.default {
798 self.write(" ");
799 self.write_keyword("DEFAULT ");
800 self.gen_expr(default);
801 }
802
803 if let Some(collation) = &col.collation {
804 self.write(" ");
805 self.write_keyword("COLLATE ");
806 self.write(collation);
807 }
808
809 if let Some(comment) = &col.comment {
810 self.write(" ");
811 self.write_keyword("COMMENT '");
812 self.write(&comment.replace('\'', "''"));
813 self.write("'");
814 }
815 }
816
817 fn gen_table_constraint(&mut self, constraint: &TableConstraint) {
818 match constraint {
819 TableConstraint::PrimaryKey { name, columns } => {
820 if let Some(name) = name {
821 self.write_keyword("CONSTRAINT ");
822 self.write(name);
823 self.write(" ");
824 }
825 self.write_keyword("PRIMARY KEY (");
826 self.write(&columns.join(", "));
827 self.write(")");
828 }
829 TableConstraint::Unique { name, columns } => {
830 if let Some(name) = name {
831 self.write_keyword("CONSTRAINT ");
832 self.write(name);
833 self.write(" ");
834 }
835 self.write_keyword("UNIQUE (");
836 self.write(&columns.join(", "));
837 self.write(")");
838 }
839 TableConstraint::ForeignKey {
840 name,
841 columns,
842 ref_table,
843 ref_columns,
844 on_delete,
845 on_update,
846 } => {
847 if let Some(name) = name {
848 self.write_keyword("CONSTRAINT ");
849 self.write(name);
850 self.write(" ");
851 }
852 self.write_keyword("FOREIGN KEY (");
853 self.write(&columns.join(", "));
854 self.write(") ");
855 self.write_keyword("REFERENCES ");
856 self.gen_table_ref(ref_table);
857 self.write(" (");
858 self.write(&ref_columns.join(", "));
859 self.write(")");
860 if let Some(action) = on_delete {
861 self.write(" ");
862 self.write_keyword("ON DELETE ");
863 self.gen_referential_action(action);
864 }
865 if let Some(action) = on_update {
866 self.write(" ");
867 self.write_keyword("ON UPDATE ");
868 self.gen_referential_action(action);
869 }
870 }
871 TableConstraint::Check { name, expr } => {
872 if let Some(name) = name {
873 self.write_keyword("CONSTRAINT ");
874 self.write(name);
875 self.write(" ");
876 }
877 self.write_keyword("CHECK (");
878 self.gen_expr(expr);
879 self.write(")");
880 }
881 }
882 }
883
884 fn gen_referential_action(&mut self, action: &ReferentialAction) {
885 match action {
886 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
887 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
888 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
889 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
890 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
891 }
892 }
893
894 fn gen_drop_table(&mut self, dt: &DropTableStatement) {
897 self.write_keyword("DROP TABLE ");
898 if dt.if_exists {
899 self.write_keyword("IF EXISTS ");
900 }
901 self.gen_table_ref(&dt.table);
902 if dt.cascade {
903 self.write(" ");
904 self.write_keyword("CASCADE");
905 }
906 }
907
908 fn gen_alter_table(&mut self, alt: &AlterTableStatement) {
911 self.write_keyword("ALTER TABLE ");
912 self.gen_table_ref(&alt.table);
913
914 for (i, action) in alt.actions.iter().enumerate() {
915 if i > 0 {
916 self.write(",");
917 }
918 self.write(" ");
919 match action {
920 AlterTableAction::AddColumn(col) => {
921 self.write_keyword("ADD COLUMN ");
922 self.gen_column_def(col);
923 }
924 AlterTableAction::DropColumn { name, if_exists } => {
925 self.write_keyword("DROP COLUMN ");
926 if *if_exists {
927 self.write_keyword("IF EXISTS ");
928 }
929 self.write(name);
930 }
931 AlterTableAction::RenameColumn { old_name, new_name } => {
932 self.write_keyword("RENAME COLUMN ");
933 self.write(old_name);
934 self.write(" ");
935 self.write_keyword("TO ");
936 self.write(new_name);
937 }
938 AlterTableAction::AlterColumnType { name, data_type } => {
939 self.write_keyword("ALTER COLUMN ");
940 self.write(name);
941 self.write(" ");
942 self.write_keyword("TYPE ");
943 self.gen_data_type(data_type);
944 }
945 AlterTableAction::AddConstraint(constraint) => {
946 self.write_keyword("ADD ");
947 self.gen_table_constraint(constraint);
948 }
949 AlterTableAction::DropConstraint { name } => {
950 self.write_keyword("DROP CONSTRAINT ");
951 self.write(name);
952 }
953 AlterTableAction::RenameTable { new_name } => {
954 self.write_keyword("RENAME TO ");
955 self.write(new_name);
956 }
957 }
958 }
959 }
960
961 fn gen_create_view(&mut self, cv: &CreateViewStatement) {
964 self.write_keyword("CREATE ");
965 if cv.or_replace {
966 self.write_keyword("OR REPLACE ");
967 }
968 if cv.materialized {
969 self.write_keyword("MATERIALIZED ");
970 }
971 self.write_keyword("VIEW ");
972 if cv.if_not_exists {
973 self.write_keyword("IF NOT EXISTS ");
974 }
975 self.gen_table_ref(&cv.name);
976
977 if !cv.columns.is_empty() {
978 self.write(" (");
979 self.write(&cv.columns.join(", "));
980 self.write(")");
981 }
982
983 self.write(" ");
984 self.write_keyword("AS ");
985 self.gen_statement(&cv.query);
986 }
987
988 fn gen_drop_view(&mut self, dv: &DropViewStatement) {
989 self.write_keyword("DROP ");
990 if dv.materialized {
991 self.write_keyword("MATERIALIZED ");
992 }
993 self.write_keyword("VIEW ");
994 if dv.if_exists {
995 self.write_keyword("IF EXISTS ");
996 }
997 self.gen_table_ref(&dv.name);
998 }
999
1000 fn gen_truncate(&mut self, t: &TruncateStatement) {
1003 self.write_keyword("TRUNCATE TABLE ");
1004 self.gen_table_ref(&t.table);
1005 }
1006
1007 fn gen_transaction(&mut self, t: &TransactionStatement) {
1010 match t {
1011 TransactionStatement::Begin => self.write_keyword("BEGIN"),
1012 TransactionStatement::Commit => self.write_keyword("COMMIT"),
1013 TransactionStatement::Rollback => self.write_keyword("ROLLBACK"),
1014 TransactionStatement::Savepoint(name) => {
1015 self.write_keyword("SAVEPOINT ");
1016 self.write(name);
1017 }
1018 TransactionStatement::ReleaseSavepoint(name) => {
1019 self.write_keyword("RELEASE SAVEPOINT ");
1020 self.write(name);
1021 }
1022 TransactionStatement::RollbackTo(name) => {
1023 self.write_keyword("ROLLBACK TO SAVEPOINT ");
1024 self.write(name);
1025 }
1026 }
1027 }
1028
1029 fn gen_explain(&mut self, e: &ExplainStatement) {
1032 self.write_keyword("EXPLAIN ");
1033 if e.analyze {
1034 self.write_keyword("ANALYZE ");
1035 }
1036 self.gen_statement(&e.statement);
1037 }
1038
1039 fn gen_use(&mut self, u: &UseStatement) {
1042 self.write_keyword("USE ");
1043 self.write(&u.name);
1044 }
1045
1046 fn gen_data_type(&mut self, dt: &DataType) {
1051 match dt {
1052 DataType::TinyInt => self.write("TINYINT"),
1053 DataType::SmallInt => self.write("SMALLINT"),
1054 DataType::Int => self.write("INT"),
1055 DataType::BigInt => self.write("BIGINT"),
1056 DataType::Float => self.write("FLOAT"),
1057 DataType::Double => self.write("DOUBLE"),
1058 DataType::Real => self.write("REAL"),
1059 DataType::Decimal { precision, scale } | DataType::Numeric { precision, scale } => {
1060 self.write(if matches!(dt, DataType::Numeric { .. }) {
1061 "NUMERIC"
1062 } else {
1063 "DECIMAL"
1064 });
1065 if let Some(p) = precision {
1066 self.write(&format!("({p}"));
1067 if let Some(s) = scale {
1068 self.write(&format!(", {s}"));
1069 }
1070 self.write(")");
1071 }
1072 }
1073 DataType::Varchar(len) => {
1074 self.write("VARCHAR");
1075 if let Some(n) = len {
1076 self.write(&format!("({n})"));
1077 }
1078 }
1079 DataType::Char(len) => {
1080 self.write("CHAR");
1081 if let Some(n) = len {
1082 self.write(&format!("({n})"));
1083 }
1084 }
1085 DataType::Text => self.write("TEXT"),
1086 DataType::String => self.write("STRING"),
1087 DataType::Binary(len) => {
1088 self.write("BINARY");
1089 if let Some(n) = len {
1090 self.write(&format!("({n})"));
1091 }
1092 }
1093 DataType::Varbinary(len) => {
1094 self.write("VARBINARY");
1095 if let Some(n) = len {
1096 self.write(&format!("({n})"));
1097 }
1098 }
1099 DataType::Boolean => self.write("BOOLEAN"),
1100 DataType::Date => self.write("DATE"),
1101 DataType::Time { precision } => {
1102 self.write("TIME");
1103 if let Some(p) = precision {
1104 self.write(&format!("({p})"));
1105 }
1106 }
1107 DataType::Timestamp { precision, with_tz } => {
1108 self.write("TIMESTAMP");
1109 if let Some(p) = precision {
1110 self.write(&format!("({p})"));
1111 }
1112 if *with_tz {
1113 self.write(" WITH TIME ZONE");
1114 }
1115 }
1116 DataType::Interval => self.write("INTERVAL"),
1117 DataType::DateTime => self.write("DATETIME"),
1118 DataType::Blob => self.write("BLOB"),
1119 DataType::Bytea => self.write("BYTEA"),
1120 DataType::Bytes => self.write("BYTES"),
1121 DataType::Json => self.write("JSON"),
1122 DataType::Jsonb => self.write("JSONB"),
1123 DataType::Uuid => self.write("UUID"),
1124 DataType::Array(inner) => {
1125 self.write("ARRAY");
1126 if let Some(inner) = inner {
1127 self.write("<");
1128 self.gen_data_type(inner);
1129 self.write(">");
1130 }
1131 }
1132 DataType::Map { key, value } => {
1133 self.write("MAP<");
1134 self.gen_data_type(key);
1135 self.write(", ");
1136 self.gen_data_type(value);
1137 self.write(">");
1138 }
1139 DataType::Struct(fields) => {
1140 self.write("STRUCT<");
1141 for (i, (name, dt)) in fields.iter().enumerate() {
1142 if i > 0 {
1143 self.write(", ");
1144 }
1145 self.write(name);
1146 self.write(" ");
1147 self.gen_data_type(dt);
1148 }
1149 self.write(">");
1150 }
1151 DataType::Tuple(types) => {
1152 self.write("TUPLE(");
1153 for (i, dt) in types.iter().enumerate() {
1154 if i > 0 {
1155 self.write(", ");
1156 }
1157 self.gen_data_type(dt);
1158 }
1159 self.write(")");
1160 }
1161 DataType::Null => self.write("NULL"),
1162 DataType::Variant => self.write("VARIANT"),
1163 DataType::Object => self.write("OBJECT"),
1164 DataType::Xml => self.write("XML"),
1165 DataType::Inet => self.write("INET"),
1166 DataType::Cidr => self.write("CIDR"),
1167 DataType::Macaddr => self.write("MACADDR"),
1168 DataType::Bit(len) => {
1169 self.write("BIT");
1170 if let Some(n) = len {
1171 self.write(&format!("({n})"));
1172 }
1173 }
1174 DataType::Money => self.write("MONEY"),
1175 DataType::Serial => self.write("SERIAL"),
1176 DataType::BigSerial => self.write("BIGSERIAL"),
1177 DataType::SmallSerial => self.write("SMALLSERIAL"),
1178 DataType::Regclass => self.write("REGCLASS"),
1179 DataType::Regtype => self.write("REGTYPE"),
1180 DataType::Hstore => self.write("HSTORE"),
1181 DataType::Geography => self.write("GEOGRAPHY"),
1182 DataType::Geometry => self.write("GEOMETRY"),
1183 DataType::Super => self.write("SUPER"),
1184 DataType::Unknown(name) => self.write(name),
1185 }
1186 }
1187
1188 fn binary_op_str(op: &BinaryOperator) -> &'static str {
1193 match op {
1194 BinaryOperator::Plus => " + ",
1195 BinaryOperator::Minus => " - ",
1196 BinaryOperator::Multiply => " * ",
1197 BinaryOperator::Divide => " / ",
1198 BinaryOperator::Modulo => " % ",
1199 BinaryOperator::Eq => " = ",
1200 BinaryOperator::Neq => " <> ",
1201 BinaryOperator::Lt => " < ",
1202 BinaryOperator::Gt => " > ",
1203 BinaryOperator::LtEq => " <= ",
1204 BinaryOperator::GtEq => " >= ",
1205 BinaryOperator::And => " AND ",
1206 BinaryOperator::Or => " OR ",
1207 BinaryOperator::Xor => " XOR ",
1208 BinaryOperator::Concat => " || ",
1209 BinaryOperator::BitwiseAnd => " & ",
1210 BinaryOperator::BitwiseOr => " | ",
1211 BinaryOperator::BitwiseXor => " ^ ",
1212 BinaryOperator::ShiftLeft => " << ",
1213 BinaryOperator::ShiftRight => " >> ",
1214 BinaryOperator::Arrow => " -> ",
1215 BinaryOperator::DoubleArrow => " ->> ",
1216 }
1217 }
1218
1219 fn gen_expr_list(&mut self, exprs: &[Expr]) {
1220 for (i, expr) in exprs.iter().enumerate() {
1221 if i > 0 {
1222 self.write(", ");
1223 }
1224 self.gen_expr(expr);
1225 }
1226 }
1227
1228 fn gen_expr(&mut self, expr: &Expr) {
1229 match expr {
1230 Expr::Column {
1231 table,
1232 name,
1233 quote_style,
1234 table_quote_style,
1235 } => {
1236 if let Some(t) = table {
1237 self.write_quoted(t, *table_quote_style);
1238 self.write(".");
1239 }
1240 self.write_quoted(name, *quote_style);
1241 }
1242 Expr::Number(n) => self.write(n),
1243 Expr::StringLiteral(s) => {
1244 self.write("'");
1245 self.write(&s.replace('\'', "''"));
1246 self.write("'");
1247 }
1248 Expr::Boolean(b) => self.write(if *b { "TRUE" } else { "FALSE" }),
1249 Expr::Null => self.write("NULL"),
1250 Expr::Default => self.write_keyword("DEFAULT"),
1251 Expr::Wildcard | Expr::Star => self.write("*"),
1252
1253 Expr::BinaryOp { left, op, right } => {
1254 self.gen_expr(left);
1255 self.write(Self::binary_op_str(op));
1256 self.gen_expr(right);
1257 }
1258 Expr::AnyOp { expr, op, right } => {
1259 self.gen_expr(expr);
1260 self.write(Self::binary_op_str(op));
1261 self.write_keyword("ANY");
1262 self.write("(");
1263 if let Expr::Subquery(query) = right.as_ref() {
1264 self.gen_statement(query);
1265 } else {
1266 self.gen_expr(right);
1267 }
1268 self.write(")");
1269 }
1270 Expr::AllOp { expr, op, right } => {
1271 self.gen_expr(expr);
1272 self.write(Self::binary_op_str(op));
1273 self.write_keyword("ALL");
1274 self.write("(");
1275 if let Expr::Subquery(query) = right.as_ref() {
1276 self.gen_statement(query);
1277 } else {
1278 self.gen_expr(right);
1279 }
1280 self.write(")");
1281 }
1282 Expr::UnaryOp { op, expr } => {
1283 let op_str = match op {
1284 UnaryOperator::Not => "NOT ",
1285 UnaryOperator::Minus => "-",
1286 UnaryOperator::Plus => "+",
1287 UnaryOperator::BitwiseNot => "~",
1288 };
1289 self.write(op_str);
1290 self.gen_expr(expr);
1291 }
1292 Expr::Function {
1293 name,
1294 args,
1295 distinct,
1296 filter,
1297 over,
1298 } => {
1299 self.write(name);
1300 self.write("(");
1301 if *distinct {
1302 self.write_keyword("DISTINCT ");
1303 }
1304 self.gen_expr_list(args);
1305 self.write(")");
1306
1307 if let Some(filter_expr) = filter {
1308 self.write(" ");
1309 self.write_keyword("FILTER (WHERE ");
1310 self.gen_expr(filter_expr);
1311 self.write(")");
1312 }
1313 if let Some(spec) = over {
1314 self.write(" ");
1315 self.write_keyword("OVER ");
1316 if let Some(wref) = &spec.window_ref {
1317 if spec.partition_by.is_empty()
1318 && spec.order_by.is_empty()
1319 && spec.frame.is_none()
1320 {
1321 self.write(wref);
1322 } else {
1323 self.write("(");
1324 self.gen_window_spec(spec);
1325 self.write(")");
1326 }
1327 } else {
1328 self.write("(");
1329 self.gen_window_spec(spec);
1330 self.write(")");
1331 }
1332 }
1333 }
1334 Expr::Between {
1335 expr,
1336 low,
1337 high,
1338 negated,
1339 } => {
1340 self.gen_expr(expr);
1341 if *negated {
1342 self.write(" ");
1343 self.write_keyword("NOT");
1344 }
1345 self.write(" ");
1346 self.write_keyword("BETWEEN ");
1347 self.gen_expr(low);
1348 self.write(" ");
1349 self.write_keyword("AND ");
1350 self.gen_expr(high);
1351 }
1352 Expr::InList {
1353 expr,
1354 list,
1355 negated,
1356 } => {
1357 self.gen_expr(expr);
1358 if *negated {
1359 self.write(" ");
1360 self.write_keyword("NOT");
1361 }
1362 self.write(" ");
1363 self.write_keyword("IN (");
1364 self.gen_expr_list(list);
1365 self.write(")");
1366 }
1367 Expr::InSubquery {
1368 expr,
1369 subquery,
1370 negated,
1371 } => {
1372 self.gen_expr(expr);
1373 if *negated {
1374 self.write(" ");
1375 self.write_keyword("NOT");
1376 }
1377 self.write(" ");
1378 self.write_keyword("IN (");
1379 self.gen_statement(subquery);
1380 self.write(")");
1381 }
1382 Expr::IsNull { expr, negated } => {
1383 self.gen_expr(expr);
1384 if *negated {
1385 self.write(" ");
1386 self.write_keyword("IS NOT NULL");
1387 } else {
1388 self.write(" ");
1389 self.write_keyword("IS NULL");
1390 }
1391 }
1392 Expr::IsBool {
1393 expr,
1394 value,
1395 negated,
1396 } => {
1397 self.gen_expr(expr);
1398 self.write(" ");
1399 match (negated, value) {
1400 (false, true) => self.write_keyword("IS TRUE"),
1401 (false, false) => self.write_keyword("IS FALSE"),
1402 (true, true) => self.write_keyword("IS NOT TRUE"),
1403 (true, false) => self.write_keyword("IS NOT FALSE"),
1404 }
1405 }
1406 Expr::Like {
1407 expr,
1408 pattern,
1409 negated,
1410 escape,
1411 } => {
1412 self.gen_expr(expr);
1413 if *negated {
1414 self.write(" ");
1415 self.write_keyword("NOT");
1416 }
1417 self.write(" ");
1418 self.write_keyword("LIKE ");
1419 self.gen_expr(pattern);
1420 if let Some(esc) = escape {
1421 self.write(" ");
1422 self.write_keyword("ESCAPE ");
1423 self.gen_expr(esc);
1424 }
1425 }
1426 Expr::ILike {
1427 expr,
1428 pattern,
1429 negated,
1430 escape,
1431 } => {
1432 self.gen_expr(expr);
1433 if *negated {
1434 self.write(" ");
1435 self.write_keyword("NOT");
1436 }
1437 self.write(" ");
1438 self.write_keyword("ILIKE ");
1439 self.gen_expr(pattern);
1440 if let Some(esc) = escape {
1441 self.write(" ");
1442 self.write_keyword("ESCAPE ");
1443 self.gen_expr(esc);
1444 }
1445 }
1446 Expr::Case {
1447 operand,
1448 when_clauses,
1449 else_clause,
1450 } => {
1451 self.write_keyword("CASE");
1452 if let Some(op) = operand {
1453 self.write(" ");
1454 self.gen_expr(op);
1455 }
1456 for (cond, result) in when_clauses {
1457 self.write(" ");
1458 self.write_keyword("WHEN ");
1459 self.gen_expr(cond);
1460 self.write(" ");
1461 self.write_keyword("THEN ");
1462 self.gen_expr(result);
1463 }
1464 if let Some(el) = else_clause {
1465 self.write(" ");
1466 self.write_keyword("ELSE ");
1467 self.gen_expr(el);
1468 }
1469 self.write(" ");
1470 self.write_keyword("END");
1471 }
1472 Expr::Nested(inner) => {
1473 self.write("(");
1474 self.gen_expr(inner);
1475 self.write(")");
1476 }
1477 Expr::Subquery(query) => {
1478 self.write("(");
1479 self.gen_statement(query);
1480 self.write(")");
1481 }
1482 Expr::Exists { subquery, negated } => {
1483 if *negated {
1484 self.write_keyword("NOT ");
1485 }
1486 self.write_keyword("EXISTS (");
1487 self.gen_statement(subquery);
1488 self.write(")");
1489 }
1490 Expr::Cast { expr, data_type } => {
1491 self.write_keyword("CAST(");
1492 self.gen_expr(expr);
1493 self.write(" ");
1494 self.write_keyword("AS ");
1495 self.gen_data_type(data_type);
1496 self.write(")");
1497 }
1498 Expr::TryCast { expr, data_type } => {
1499 self.write_keyword("TRY_CAST(");
1500 self.gen_expr(expr);
1501 self.write(" ");
1502 self.write_keyword("AS ");
1503 self.gen_data_type(data_type);
1504 self.write(")");
1505 }
1506 Expr::Extract { field, expr } => {
1507 self.write_keyword("EXTRACT(");
1508 self.gen_datetime_field(field);
1509 self.write(" ");
1510 self.write_keyword("FROM ");
1511 self.gen_expr(expr);
1512 self.write(")");
1513 }
1514 Expr::Interval { value, unit } => {
1515 self.write_keyword("INTERVAL ");
1516 self.gen_expr(value);
1517 if let Some(unit) = unit {
1518 self.write(" ");
1519 self.gen_datetime_field(unit);
1520 }
1521 }
1522 Expr::ArrayLiteral(items) => {
1523 self.write_keyword("ARRAY[");
1524 self.gen_expr_list(items);
1525 self.write("]");
1526 }
1527 Expr::Tuple(items) => {
1528 self.write("(");
1529 self.gen_expr_list(items);
1530 self.write(")");
1531 }
1532 Expr::Coalesce(items) => {
1533 self.write_keyword("COALESCE(");
1534 self.gen_expr_list(items);
1535 self.write(")");
1536 }
1537 Expr::If {
1538 condition,
1539 true_val,
1540 false_val,
1541 } => {
1542 self.write_keyword("IF(");
1543 self.gen_expr(condition);
1544 self.write(", ");
1545 self.gen_expr(true_val);
1546 if let Some(fv) = false_val {
1547 self.write(", ");
1548 self.gen_expr(fv);
1549 }
1550 self.write(")");
1551 }
1552 Expr::NullIf { expr, r#else } => {
1553 self.write_keyword("NULLIF(");
1554 self.gen_expr(expr);
1555 self.write(", ");
1556 self.gen_expr(r#else);
1557 self.write(")");
1558 }
1559 Expr::Collate { expr, collation } => {
1560 self.gen_expr(expr);
1561 self.write(" ");
1562 self.write_keyword("COLLATE ");
1563 self.write(collation);
1564 }
1565 Expr::Parameter(p) => self.write(p),
1566 Expr::TypeExpr(dt) => self.gen_data_type(dt),
1567 Expr::QualifiedWildcard { table } => {
1568 self.write(table);
1569 self.write(".*");
1570 }
1571 Expr::Alias { expr, name } => {
1572 self.gen_expr(expr);
1573 self.write(" ");
1574 self.write_keyword("AS ");
1575 self.write(name);
1576 }
1577 Expr::ArrayIndex { expr, index } => {
1578 self.gen_expr(expr);
1579 self.write("[");
1580 self.gen_expr(index);
1581 self.write("]");
1582 }
1583 Expr::JsonAccess {
1584 expr,
1585 path,
1586 as_text,
1587 } => {
1588 self.gen_expr(expr);
1589 if *as_text {
1590 self.write("->>");
1591 } else {
1592 self.write("->");
1593 }
1594 self.gen_expr(path);
1595 }
1596 Expr::Lambda { params, body } => {
1597 if params.len() == 1 {
1598 self.write(¶ms[0]);
1599 } else {
1600 self.write("(");
1601 self.write(¶ms.join(", "));
1602 self.write(")");
1603 }
1604 self.write(" -> ");
1605 self.gen_expr(body);
1606 }
1607 }
1608 }
1609
1610 fn gen_window_spec(&mut self, spec: &WindowSpec) {
1611 if let Some(wref) = &spec.window_ref {
1612 self.write(wref);
1613 if !spec.partition_by.is_empty() || !spec.order_by.is_empty() || spec.frame.is_some() {
1614 self.write(" ");
1615 }
1616 }
1617 if !spec.partition_by.is_empty() {
1618 self.write_keyword("PARTITION BY ");
1619 self.gen_expr_list(&spec.partition_by);
1620 }
1621 if !spec.order_by.is_empty() {
1622 if !spec.partition_by.is_empty() {
1623 self.write(" ");
1624 }
1625 self.write_keyword("ORDER BY ");
1626 for (i, item) in spec.order_by.iter().enumerate() {
1627 if i > 0 {
1628 self.write(", ");
1629 }
1630 self.gen_expr(&item.expr);
1631 if !item.ascending {
1632 self.write(" ");
1633 self.write_keyword("DESC");
1634 }
1635 if let Some(nulls_first) = item.nulls_first {
1636 if nulls_first {
1637 self.write(" ");
1638 self.write_keyword("NULLS FIRST");
1639 } else {
1640 self.write(" ");
1641 self.write_keyword("NULLS LAST");
1642 }
1643 }
1644 }
1645 }
1646 if let Some(frame) = &spec.frame {
1647 self.write(" ");
1648 self.gen_window_frame(frame);
1649 }
1650 }
1651
1652 fn gen_window_frame(&mut self, frame: &WindowFrame) {
1653 match frame.kind {
1654 WindowFrameKind::Rows => self.write_keyword("ROWS "),
1655 WindowFrameKind::Range => self.write_keyword("RANGE "),
1656 WindowFrameKind::Groups => self.write_keyword("GROUPS "),
1657 }
1658 if let Some(end) = &frame.end {
1659 self.write_keyword("BETWEEN ");
1660 self.gen_window_frame_bound(&frame.start);
1661 self.write(" ");
1662 self.write_keyword("AND ");
1663 self.gen_window_frame_bound(end);
1664 } else {
1665 self.gen_window_frame_bound(&frame.start);
1666 }
1667 }
1668
1669 fn gen_window_frame_bound(&mut self, bound: &WindowFrameBound) {
1670 match bound {
1671 WindowFrameBound::CurrentRow => self.write_keyword("CURRENT ROW"),
1672 WindowFrameBound::Preceding(None) => self.write_keyword("UNBOUNDED PRECEDING"),
1673 WindowFrameBound::Preceding(Some(n)) => {
1674 self.gen_expr(n);
1675 self.write(" ");
1676 self.write_keyword("PRECEDING");
1677 }
1678 WindowFrameBound::Following(None) => self.write_keyword("UNBOUNDED FOLLOWING"),
1679 WindowFrameBound::Following(Some(n)) => {
1680 self.gen_expr(n);
1681 self.write(" ");
1682 self.write_keyword("FOLLOWING");
1683 }
1684 }
1685 }
1686
1687 fn gen_datetime_field(&mut self, field: &DateTimeField) {
1688 let name = match field {
1689 DateTimeField::Year => "YEAR",
1690 DateTimeField::Quarter => "QUARTER",
1691 DateTimeField::Month => "MONTH",
1692 DateTimeField::Week => "WEEK",
1693 DateTimeField::Day => "DAY",
1694 DateTimeField::DayOfWeek => "DOW",
1695 DateTimeField::DayOfYear => "DOY",
1696 DateTimeField::Hour => "HOUR",
1697 DateTimeField::Minute => "MINUTE",
1698 DateTimeField::Second => "SECOND",
1699 DateTimeField::Millisecond => "MILLISECOND",
1700 DateTimeField::Microsecond => "MICROSECOND",
1701 DateTimeField::Nanosecond => "NANOSECOND",
1702 DateTimeField::Epoch => "EPOCH",
1703 DateTimeField::Timezone => "TIMEZONE",
1704 DateTimeField::TimezoneHour => "TIMEZONE_HOUR",
1705 DateTimeField::TimezoneMinute => "TIMEZONE_MINUTE",
1706 };
1707 self.write(name);
1708 }
1709}
1710
1711impl Default for Generator {
1712 fn default() -> Self {
1713 Self::new()
1714 }
1715}
1716
1717#[cfg(test)]
1718mod tests {
1719 use super::*;
1720 use crate::parser::Parser;
1721
1722 fn roundtrip(sql: &str) -> String {
1723 let stmt = Parser::new(sql).unwrap().parse_statement().unwrap();
1724 let mut g = Generator::new();
1725 g.generate(&stmt)
1726 }
1727
1728 #[test]
1729 fn test_select_roundtrip() {
1730 assert_eq!(roundtrip("SELECT a, b FROM t"), "SELECT a, b FROM t");
1731 }
1732
1733 #[test]
1734 fn test_select_where() {
1735 assert_eq!(
1736 roundtrip("SELECT x FROM t WHERE x > 10"),
1737 "SELECT x FROM t WHERE x > 10"
1738 );
1739 }
1740
1741 #[test]
1742 fn test_select_wildcard() {
1743 assert_eq!(roundtrip("SELECT * FROM users"), "SELECT * FROM users");
1744 }
1745
1746 #[test]
1747 fn test_insert_values() {
1748 assert_eq!(
1749 roundtrip("INSERT INTO t (a, b) VALUES (1, 'hello')"),
1750 "INSERT INTO t (a, b) VALUES (1, 'hello')"
1751 );
1752 }
1753
1754 #[test]
1755 fn test_delete() {
1756 assert_eq!(
1757 roundtrip("DELETE FROM users WHERE id = 1"),
1758 "DELETE FROM users WHERE id = 1"
1759 );
1760 }
1761
1762 #[test]
1763 fn test_join() {
1764 assert_eq!(
1765 roundtrip("SELECT a.id, b.name FROM a INNER JOIN b ON a.id = b.a_id"),
1766 "SELECT a.id, b.name FROM a INNER JOIN b ON a.id = b.a_id"
1767 );
1768 }
1769
1770 #[test]
1771 fn test_create_table() {
1772 assert_eq!(
1773 roundtrip("CREATE TABLE users (id INT NOT NULL, name VARCHAR(255), email TEXT)"),
1774 "CREATE TABLE users (id INT NOT NULL, name VARCHAR(255), email TEXT)"
1775 );
1776 }
1777
1778 #[test]
1779 fn test_cte_roundtrip() {
1780 let sql = "WITH cte AS (SELECT 1 AS x) SELECT x FROM cte";
1781 assert_eq!(
1782 roundtrip(sql),
1783 "WITH cte AS (SELECT 1 AS x) SELECT x FROM cte"
1784 );
1785 }
1786
1787 #[test]
1788 fn test_union_roundtrip() {
1789 let sql = "SELECT 1 UNION ALL SELECT 2";
1790 assert_eq!(roundtrip(sql), "SELECT 1 UNION ALL SELECT 2");
1791 }
1792
1793 #[test]
1794 fn test_cast_roundtrip() {
1795 assert_eq!(
1796 roundtrip("SELECT CAST(x AS INT) FROM t"),
1797 "SELECT CAST(x AS INT) FROM t"
1798 );
1799 }
1800
1801 #[test]
1802 fn test_exists_roundtrip() {
1803 assert_eq!(
1804 roundtrip("SELECT * FROM t WHERE EXISTS (SELECT 1 FROM t2)"),
1805 "SELECT * FROM t WHERE EXISTS (SELECT 1 FROM t2)"
1806 );
1807 }
1808
1809 #[test]
1810 fn test_extract_roundtrip() {
1811 assert_eq!(
1812 roundtrip("SELECT EXTRACT(YEAR FROM created_at) FROM t"),
1813 "SELECT EXTRACT(YEAR FROM created_at) FROM t"
1814 );
1815 }
1816
1817 #[test]
1818 fn test_window_function_roundtrip() {
1819 assert_eq!(
1820 roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) FROM emp"),
1821 "SELECT ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) FROM emp"
1822 );
1823 }
1824
1825 #[test]
1826 fn test_subquery_from_roundtrip() {
1827 assert_eq!(
1828 roundtrip("SELECT * FROM (SELECT 1 AS x) AS sub"),
1829 "SELECT * FROM (SELECT 1 AS x) AS sub"
1830 );
1831 }
1832
1833 #[test]
1834 fn test_in_subquery_roundtrip() {
1835 assert_eq!(
1836 roundtrip("SELECT * FROM t WHERE id IN (SELECT id FROM t2)"),
1837 "SELECT * FROM t WHERE id IN (SELECT id FROM t2)"
1838 );
1839 }
1840
1841 fn pretty_print(sql: &str) -> String {
1846 let stmt = Parser::new(sql).unwrap().parse_statement().unwrap();
1847 let mut g = Generator::pretty();
1848 g.generate(&stmt)
1849 }
1850
1851 #[test]
1852 fn test_pretty_simple_select() {
1853 assert_eq!(
1854 pretty_print("SELECT a, b, c FROM t"),
1855 "SELECT\n a,\n b,\n c\nFROM\n t"
1856 );
1857 }
1858
1859 #[test]
1860 fn test_pretty_select_where() {
1861 assert_eq!(
1862 pretty_print("SELECT a FROM t WHERE a > 1"),
1863 "SELECT\n a\nFROM\n t\nWHERE\n a > 1"
1864 );
1865 }
1866
1867 #[test]
1868 fn test_pretty_select_group_by_having() {
1869 assert_eq!(
1870 pretty_print("SELECT a, COUNT(*) FROM t GROUP BY a HAVING COUNT(*) > 1"),
1871 "SELECT\n a,\n COUNT(*)\nFROM\n t\nGROUP BY\n a\nHAVING\n COUNT(*) > 1"
1872 );
1873 }
1874
1875 #[test]
1876 fn test_pretty_select_order_by_limit() {
1877 assert_eq!(
1878 pretty_print("SELECT a FROM t ORDER BY a DESC LIMIT 10"),
1879 "SELECT\n a\nFROM\n t\nORDER BY\n a DESC\nLIMIT 10"
1880 );
1881 }
1882
1883 #[test]
1884 fn test_pretty_join() {
1885 assert_eq!(
1886 pretty_print("SELECT a.id, b.name FROM a INNER JOIN b ON a.id = b.a_id"),
1887 "SELECT\n a.id,\n b.name\nFROM\n a\nINNER JOIN\n b\n ON a.id = b.a_id"
1888 );
1889 }
1890
1891 #[test]
1892 fn test_pretty_cte() {
1893 assert_eq!(
1894 pretty_print("WITH cte AS (SELECT 1 AS x) SELECT x FROM cte"),
1895 "WITH cte AS (\n SELECT\n 1 AS x\n)\nSELECT\n x\nFROM\n cte"
1896 );
1897 }
1898
1899 #[test]
1900 fn test_pretty_union() {
1901 assert_eq!(
1902 pretty_print("SELECT 1 UNION ALL SELECT 2"),
1903 "SELECT\n 1\nUNION ALL\nSELECT\n 2"
1904 );
1905 }
1906
1907 #[test]
1908 fn test_pretty_insert() {
1909 assert_eq!(
1910 pretty_print("INSERT INTO t (a, b) VALUES (1, 'hello'), (2, 'world')"),
1911 "INSERT INTO t (a, b)\nVALUES\n (1, 'hello'),\n (2, 'world')"
1912 );
1913 }
1914
1915 #[test]
1916 fn test_pretty_update() {
1917 assert_eq!(
1918 pretty_print("UPDATE t SET a = 1, b = 2 WHERE c = 3"),
1919 "UPDATE t\nSET\n a = 1,\n b = 2\nWHERE\n c = 3"
1920 );
1921 }
1922
1923 #[test]
1924 fn test_pretty_delete() {
1925 assert_eq!(
1926 pretty_print("DELETE FROM t WHERE id = 1"),
1927 "DELETE FROM t\nWHERE\n id = 1"
1928 );
1929 }
1930
1931 #[test]
1932 fn test_pretty_create_table() {
1933 assert_eq!(
1934 pretty_print("CREATE TABLE t (id INT NOT NULL, name VARCHAR(255), email TEXT)"),
1935 "CREATE TABLE t (\n id INT NOT NULL,\n name VARCHAR(255),\n email TEXT\n)"
1936 );
1937 }
1938
1939 #[test]
1940 fn test_pretty_complex_query() {
1941 let sql = "SELECT a, SUM(b) FROM t1 INNER JOIN t2 ON t1.id = t2.id WHERE t1.x > 1 GROUP BY a HAVING SUM(b) > 10 ORDER BY a LIMIT 100";
1942 let expected = "SELECT\n a,\n SUM(b)\nFROM\n t1\nINNER JOIN\n t2\n ON t1.id = t2.id\nWHERE\n t1.x > 1\nGROUP BY\n a\nHAVING\n SUM(b) > 10\nORDER BY\n a\nLIMIT 100";
1943 assert_eq!(pretty_print(sql), expected);
1944 }
1945
1946 #[test]
1947 fn test_pretty_select_distinct() {
1948 assert_eq!(
1949 pretty_print("SELECT DISTINCT a, b FROM t"),
1950 "SELECT DISTINCT\n a,\n b\nFROM\n t"
1951 );
1952 }
1953}