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 { expr, alias, with_offset } => {
368 self.write_keyword("UNNEST(");
369 self.gen_expr(expr);
370 self.write(")");
371 if let Some(alias) = alias {
372 self.write(" ");
373 self.write_keyword("AS ");
374 self.write(alias);
375 }
376 if *with_offset {
377 self.write(" ");
378 self.write_keyword("WITH OFFSET");
379 }
380 }
381 }
382 }
383
384 fn gen_table_ref(&mut self, table: &TableRef) {
385 if let Some(catalog) = &table.catalog {
386 self.write(catalog);
387 self.write(".");
388 }
389 if let Some(schema) = &table.schema {
390 self.write(schema);
391 self.write(".");
392 }
393 self.write_quoted(&table.name, table.name_quote_style);
394 if let Some(alias) = &table.alias {
395 self.write(" ");
396 self.write_keyword("AS ");
397 self.write(alias);
398 }
399 }
400
401 fn gen_join(&mut self, join: &JoinClause) {
402 let join_kw = match join.join_type {
403 JoinType::Inner => "INNER JOIN",
404 JoinType::Left => "LEFT JOIN",
405 JoinType::Right => "RIGHT JOIN",
406 JoinType::Full => "FULL JOIN",
407 JoinType::Cross => "CROSS JOIN",
408 JoinType::Natural => "NATURAL JOIN",
409 JoinType::Lateral => "LATERAL JOIN",
410 };
411 self.sep();
412 self.write_keyword(join_kw);
413 if self.pretty {
414 self.indent_up();
415 self.newline();
416 self.gen_table_source(&join.table);
417 } else {
418 self.write(" ");
419 self.gen_table_source(&join.table);
420 }
421 if let Some(on) = &join.on {
422 if self.pretty {
423 self.newline();
424 } else {
425 self.write(" ");
426 }
427 self.write_keyword("ON ");
428 self.gen_expr(on);
429 }
430 if !join.using.is_empty() {
431 if self.pretty {
432 self.newline();
433 } else {
434 self.write(" ");
435 }
436 self.write_keyword("USING (");
437 self.write(&join.using.join(", "));
438 self.write(")");
439 }
440 if self.pretty {
441 self.indent_down();
442 }
443 }
444
445 fn gen_order_by(&mut self, items: &[OrderByItem]) {
446 if items.is_empty() {
447 return;
448 }
449 self.sep();
450 self.write_keyword("ORDER BY");
451 if self.pretty {
452 self.indent_up();
453 self.newline();
454 } else {
455 self.write(" ");
456 }
457 for (i, item) in items.iter().enumerate() {
458 if i > 0 {
459 self.write(", ");
460 }
461 self.gen_expr(&item.expr);
462 if !item.ascending {
463 self.write(" ");
464 self.write_keyword("DESC");
465 }
466 if let Some(nulls_first) = item.nulls_first {
467 if nulls_first {
468 self.write(" ");
469 self.write_keyword("NULLS FIRST");
470 } else {
471 self.write(" ");
472 self.write_keyword("NULLS LAST");
473 }
474 }
475 }
476 if self.pretty {
477 self.indent_down();
478 }
479 }
480
481 fn gen_set_operation(&mut self, sop: &SetOperationStatement) {
484 self.gen_statement(&sop.left);
485 let op_kw = match sop.op {
486 SetOperationType::Union => "UNION",
487 SetOperationType::Intersect => "INTERSECT",
488 SetOperationType::Except => "EXCEPT",
489 };
490 self.sep();
491 self.write_keyword(op_kw);
492 if sop.all {
493 self.write(" ");
494 self.write_keyword("ALL");
495 }
496 self.sep();
497 self.gen_statement(&sop.right);
498
499 self.gen_order_by(&sop.order_by);
500
501 if let Some(limit) = &sop.limit {
502 self.sep();
503 self.write_keyword("LIMIT ");
504 self.gen_expr(limit);
505 }
506 if let Some(offset) = &sop.offset {
507 self.sep();
508 self.write_keyword("OFFSET ");
509 self.gen_expr(offset);
510 }
511 }
512
513 fn gen_insert(&mut self, ins: &InsertStatement) {
516 self.write_keyword("INSERT INTO ");
517 self.gen_table_ref(&ins.table);
518
519 if !ins.columns.is_empty() {
520 self.write(" (");
521 self.write(&ins.columns.join(", "));
522 self.write(")");
523 }
524
525 match &ins.source {
526 InsertSource::Values(rows) => {
527 self.sep();
528 self.write_keyword("VALUES");
529 if self.pretty {
530 self.indent_up();
531 for (i, row) in rows.iter().enumerate() {
532 self.newline();
533 self.write("(");
534 self.gen_expr_list(row);
535 self.write(")");
536 if i < rows.len() - 1 {
537 self.write(",");
538 }
539 }
540 self.indent_down();
541 } else {
542 self.write(" ");
543 for (i, row) in rows.iter().enumerate() {
544 if i > 0 {
545 self.write(", ");
546 }
547 self.write("(");
548 self.gen_expr_list(row);
549 self.write(")");
550 }
551 }
552 }
553 InsertSource::Query(query) => {
554 self.sep();
555 self.gen_statement(query);
556 }
557 InsertSource::Default => {
558 self.sep();
559 self.write_keyword("DEFAULT VALUES");
560 }
561 }
562
563 if let Some(on_conflict) = &ins.on_conflict {
564 self.sep();
565 self.write_keyword("ON CONFLICT");
566 if !on_conflict.columns.is_empty() {
567 self.write(" (");
568 self.write(&on_conflict.columns.join(", "));
569 self.write(")");
570 }
571 match &on_conflict.action {
572 ConflictAction::DoNothing => {
573 self.write(" ");
574 self.write_keyword("DO NOTHING");
575 }
576 ConflictAction::DoUpdate(assignments) => {
577 self.write(" ");
578 self.write_keyword("DO UPDATE SET ");
579 for (i, (col, val)) in assignments.iter().enumerate() {
580 if i > 0 {
581 self.write(", ");
582 }
583 self.write(col);
584 self.write(" = ");
585 self.gen_expr(val);
586 }
587 }
588 }
589 }
590
591 if !ins.returning.is_empty() {
592 self.sep();
593 self.write_keyword("RETURNING ");
594 for (i, item) in ins.returning.iter().enumerate() {
595 if i > 0 {
596 self.write(", ");
597 }
598 self.gen_select_item(item);
599 }
600 }
601 }
602
603 fn gen_update(&mut self, upd: &UpdateStatement) {
606 self.write_keyword("UPDATE ");
607 self.gen_table_ref(&upd.table);
608 self.sep();
609 self.write_keyword("SET");
610
611 if self.pretty {
612 self.indent_up();
613 for (i, (col, val)) in upd.assignments.iter().enumerate() {
614 self.newline();
615 self.write(col);
616 self.write(" = ");
617 self.gen_expr(val);
618 if i < upd.assignments.len() - 1 {
619 self.write(",");
620 }
621 }
622 self.indent_down();
623 } else {
624 self.write(" ");
625 for (i, (col, val)) in upd.assignments.iter().enumerate() {
626 if i > 0 {
627 self.write(", ");
628 }
629 self.write(col);
630 self.write(" = ");
631 self.gen_expr(val);
632 }
633 }
634
635 if let Some(from) = &upd.from {
636 self.sep();
637 self.write_keyword("FROM ");
638 self.gen_table_source(&from.source);
639 }
640
641 if let Some(wh) = &upd.where_clause {
642 self.sep();
643 self.write_keyword("WHERE");
644 if self.pretty {
645 self.indent_up();
646 self.newline();
647 self.gen_expr(wh);
648 self.indent_down();
649 } else {
650 self.write(" ");
651 self.gen_expr(wh);
652 }
653 }
654
655 if !upd.returning.is_empty() {
656 self.sep();
657 self.write_keyword("RETURNING ");
658 for (i, item) in upd.returning.iter().enumerate() {
659 if i > 0 {
660 self.write(", ");
661 }
662 self.gen_select_item(item);
663 }
664 }
665 }
666
667 fn gen_delete(&mut self, del: &DeleteStatement) {
670 self.write_keyword("DELETE FROM ");
671 self.gen_table_ref(&del.table);
672
673 if let Some(using) = &del.using {
674 self.sep();
675 self.write_keyword("USING ");
676 self.gen_table_source(&using.source);
677 }
678
679 if let Some(wh) = &del.where_clause {
680 self.sep();
681 self.write_keyword("WHERE");
682 if self.pretty {
683 self.indent_up();
684 self.newline();
685 self.gen_expr(wh);
686 self.indent_down();
687 } else {
688 self.write(" ");
689 self.gen_expr(wh);
690 }
691 }
692
693 if !del.returning.is_empty() {
694 self.sep();
695 self.write_keyword("RETURNING ");
696 for (i, item) in del.returning.iter().enumerate() {
697 if i > 0 {
698 self.write(", ");
699 }
700 self.gen_select_item(item);
701 }
702 }
703 }
704
705 fn gen_create_table(&mut self, ct: &CreateTableStatement) {
708 self.write_keyword("CREATE ");
709 if ct.temporary {
710 self.write_keyword("TEMPORARY ");
711 }
712 self.write_keyword("TABLE ");
713 if ct.if_not_exists {
714 self.write_keyword("IF NOT EXISTS ");
715 }
716 self.gen_table_ref(&ct.table);
717
718 if let Some(as_select) = &ct.as_select {
719 self.write(" ");
720 self.write_keyword("AS ");
721 self.gen_statement(as_select);
722 return;
723 }
724
725 self.write(" (");
726
727 if self.pretty {
728 self.indent_up();
729 for (i, col) in ct.columns.iter().enumerate() {
730 self.newline();
731 self.gen_column_def(col);
732 if i < ct.columns.len() - 1 || !ct.constraints.is_empty() {
733 self.write(",");
734 }
735 }
736 for (i, constraint) in ct.constraints.iter().enumerate() {
737 self.newline();
738 self.gen_table_constraint(constraint);
739 if i < ct.constraints.len() - 1 {
740 self.write(",");
741 }
742 }
743 self.indent_down();
744 self.newline();
745 } else {
746 for (i, col) in ct.columns.iter().enumerate() {
747 if i > 0 {
748 self.write(", ");
749 }
750 self.gen_column_def(col);
751 }
752 for (i, constraint) in ct.constraints.iter().enumerate() {
753 if i + ct.columns.len() > 0 {
754 self.write(", ");
755 }
756 self.gen_table_constraint(constraint);
757 }
758 }
759
760 self.write(")");
761 }
762
763 fn gen_column_def(&mut self, col: &ColumnDef) {
764 self.write(&col.name);
765 self.write(" ");
766 self.gen_data_type(&col.data_type);
767
768 if col.primary_key {
769 self.write(" ");
770 self.write_keyword("PRIMARY KEY");
771 }
772 if col.unique {
773 self.write(" ");
774 self.write_keyword("UNIQUE");
775 }
776 if col.auto_increment {
777 self.write(" ");
778 self.write_keyword("AUTOINCREMENT");
779 }
780
781 match col.nullable {
782 Some(false) => {
783 self.write(" ");
784 self.write_keyword("NOT NULL");
785 }
786 Some(true) => {
787 self.write(" ");
788 self.write_keyword("NULL");
789 }
790 None => {}
791 }
792
793 if let Some(default) = &col.default {
794 self.write(" ");
795 self.write_keyword("DEFAULT ");
796 self.gen_expr(default);
797 }
798
799 if let Some(collation) = &col.collation {
800 self.write(" ");
801 self.write_keyword("COLLATE ");
802 self.write(collation);
803 }
804
805 if let Some(comment) = &col.comment {
806 self.write(" ");
807 self.write_keyword("COMMENT '");
808 self.write(&comment.replace('\'', "''"));
809 self.write("'");
810 }
811 }
812
813 fn gen_table_constraint(&mut self, constraint: &TableConstraint) {
814 match constraint {
815 TableConstraint::PrimaryKey { name, columns } => {
816 if let Some(name) = name {
817 self.write_keyword("CONSTRAINT ");
818 self.write(name);
819 self.write(" ");
820 }
821 self.write_keyword("PRIMARY KEY (");
822 self.write(&columns.join(", "));
823 self.write(")");
824 }
825 TableConstraint::Unique { name, columns } => {
826 if let Some(name) = name {
827 self.write_keyword("CONSTRAINT ");
828 self.write(name);
829 self.write(" ");
830 }
831 self.write_keyword("UNIQUE (");
832 self.write(&columns.join(", "));
833 self.write(")");
834 }
835 TableConstraint::ForeignKey {
836 name,
837 columns,
838 ref_table,
839 ref_columns,
840 on_delete,
841 on_update,
842 } => {
843 if let Some(name) = name {
844 self.write_keyword("CONSTRAINT ");
845 self.write(name);
846 self.write(" ");
847 }
848 self.write_keyword("FOREIGN KEY (");
849 self.write(&columns.join(", "));
850 self.write(") ");
851 self.write_keyword("REFERENCES ");
852 self.gen_table_ref(ref_table);
853 self.write(" (");
854 self.write(&ref_columns.join(", "));
855 self.write(")");
856 if let Some(action) = on_delete {
857 self.write(" ");
858 self.write_keyword("ON DELETE ");
859 self.gen_referential_action(action);
860 }
861 if let Some(action) = on_update {
862 self.write(" ");
863 self.write_keyword("ON UPDATE ");
864 self.gen_referential_action(action);
865 }
866 }
867 TableConstraint::Check { name, expr } => {
868 if let Some(name) = name {
869 self.write_keyword("CONSTRAINT ");
870 self.write(name);
871 self.write(" ");
872 }
873 self.write_keyword("CHECK (");
874 self.gen_expr(expr);
875 self.write(")");
876 }
877 }
878 }
879
880 fn gen_referential_action(&mut self, action: &ReferentialAction) {
881 match action {
882 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
883 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
884 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
885 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
886 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
887 }
888 }
889
890 fn gen_drop_table(&mut self, dt: &DropTableStatement) {
893 self.write_keyword("DROP TABLE ");
894 if dt.if_exists {
895 self.write_keyword("IF EXISTS ");
896 }
897 self.gen_table_ref(&dt.table);
898 if dt.cascade {
899 self.write(" ");
900 self.write_keyword("CASCADE");
901 }
902 }
903
904 fn gen_alter_table(&mut self, alt: &AlterTableStatement) {
907 self.write_keyword("ALTER TABLE ");
908 self.gen_table_ref(&alt.table);
909
910 for (i, action) in alt.actions.iter().enumerate() {
911 if i > 0 {
912 self.write(",");
913 }
914 self.write(" ");
915 match action {
916 AlterTableAction::AddColumn(col) => {
917 self.write_keyword("ADD COLUMN ");
918 self.gen_column_def(col);
919 }
920 AlterTableAction::DropColumn { name, if_exists } => {
921 self.write_keyword("DROP COLUMN ");
922 if *if_exists {
923 self.write_keyword("IF EXISTS ");
924 }
925 self.write(name);
926 }
927 AlterTableAction::RenameColumn { old_name, new_name } => {
928 self.write_keyword("RENAME COLUMN ");
929 self.write(old_name);
930 self.write(" ");
931 self.write_keyword("TO ");
932 self.write(new_name);
933 }
934 AlterTableAction::AlterColumnType { name, data_type } => {
935 self.write_keyword("ALTER COLUMN ");
936 self.write(name);
937 self.write(" ");
938 self.write_keyword("TYPE ");
939 self.gen_data_type(data_type);
940 }
941 AlterTableAction::AddConstraint(constraint) => {
942 self.write_keyword("ADD ");
943 self.gen_table_constraint(constraint);
944 }
945 AlterTableAction::DropConstraint { name } => {
946 self.write_keyword("DROP CONSTRAINT ");
947 self.write(name);
948 }
949 AlterTableAction::RenameTable { new_name } => {
950 self.write_keyword("RENAME TO ");
951 self.write(new_name);
952 }
953 }
954 }
955 }
956
957 fn gen_create_view(&mut self, cv: &CreateViewStatement) {
960 self.write_keyword("CREATE ");
961 if cv.or_replace {
962 self.write_keyword("OR REPLACE ");
963 }
964 if cv.materialized {
965 self.write_keyword("MATERIALIZED ");
966 }
967 self.write_keyword("VIEW ");
968 if cv.if_not_exists {
969 self.write_keyword("IF NOT EXISTS ");
970 }
971 self.gen_table_ref(&cv.name);
972
973 if !cv.columns.is_empty() {
974 self.write(" (");
975 self.write(&cv.columns.join(", "));
976 self.write(")");
977 }
978
979 self.write(" ");
980 self.write_keyword("AS ");
981 self.gen_statement(&cv.query);
982 }
983
984 fn gen_drop_view(&mut self, dv: &DropViewStatement) {
985 self.write_keyword("DROP ");
986 if dv.materialized {
987 self.write_keyword("MATERIALIZED ");
988 }
989 self.write_keyword("VIEW ");
990 if dv.if_exists {
991 self.write_keyword("IF EXISTS ");
992 }
993 self.gen_table_ref(&dv.name);
994 }
995
996 fn gen_truncate(&mut self, t: &TruncateStatement) {
999 self.write_keyword("TRUNCATE TABLE ");
1000 self.gen_table_ref(&t.table);
1001 }
1002
1003 fn gen_transaction(&mut self, t: &TransactionStatement) {
1006 match t {
1007 TransactionStatement::Begin => self.write_keyword("BEGIN"),
1008 TransactionStatement::Commit => self.write_keyword("COMMIT"),
1009 TransactionStatement::Rollback => self.write_keyword("ROLLBACK"),
1010 TransactionStatement::Savepoint(name) => {
1011 self.write_keyword("SAVEPOINT ");
1012 self.write(name);
1013 }
1014 TransactionStatement::ReleaseSavepoint(name) => {
1015 self.write_keyword("RELEASE SAVEPOINT ");
1016 self.write(name);
1017 }
1018 TransactionStatement::RollbackTo(name) => {
1019 self.write_keyword("ROLLBACK TO SAVEPOINT ");
1020 self.write(name);
1021 }
1022 }
1023 }
1024
1025 fn gen_explain(&mut self, e: &ExplainStatement) {
1028 self.write_keyword("EXPLAIN ");
1029 if e.analyze {
1030 self.write_keyword("ANALYZE ");
1031 }
1032 self.gen_statement(&e.statement);
1033 }
1034
1035 fn gen_use(&mut self, u: &UseStatement) {
1038 self.write_keyword("USE ");
1039 self.write(&u.name);
1040 }
1041
1042 fn gen_data_type(&mut self, dt: &DataType) {
1047 match dt {
1048 DataType::TinyInt => self.write("TINYINT"),
1049 DataType::SmallInt => self.write("SMALLINT"),
1050 DataType::Int => self.write("INT"),
1051 DataType::BigInt => self.write("BIGINT"),
1052 DataType::Float => self.write("FLOAT"),
1053 DataType::Double => self.write("DOUBLE"),
1054 DataType::Real => self.write("REAL"),
1055 DataType::Decimal { precision, scale } | DataType::Numeric { precision, scale } => {
1056 self.write(if matches!(dt, DataType::Numeric { .. }) { "NUMERIC" } else { "DECIMAL" });
1057 if let Some(p) = precision {
1058 self.write(&format!("({p}"));
1059 if let Some(s) = scale {
1060 self.write(&format!(", {s}"));
1061 }
1062 self.write(")");
1063 }
1064 }
1065 DataType::Varchar(len) => {
1066 self.write("VARCHAR");
1067 if let Some(n) = len {
1068 self.write(&format!("({n})"));
1069 }
1070 }
1071 DataType::Char(len) => {
1072 self.write("CHAR");
1073 if let Some(n) = len {
1074 self.write(&format!("({n})"));
1075 }
1076 }
1077 DataType::Text => self.write("TEXT"),
1078 DataType::String => self.write("STRING"),
1079 DataType::Binary(len) => {
1080 self.write("BINARY");
1081 if let Some(n) = len {
1082 self.write(&format!("({n})"));
1083 }
1084 }
1085 DataType::Varbinary(len) => {
1086 self.write("VARBINARY");
1087 if let Some(n) = len {
1088 self.write(&format!("({n})"));
1089 }
1090 }
1091 DataType::Boolean => self.write("BOOLEAN"),
1092 DataType::Date => self.write("DATE"),
1093 DataType::Time { precision } => {
1094 self.write("TIME");
1095 if let Some(p) = precision {
1096 self.write(&format!("({p})"));
1097 }
1098 }
1099 DataType::Timestamp { precision, with_tz } => {
1100 self.write("TIMESTAMP");
1101 if let Some(p) = precision {
1102 self.write(&format!("({p})"));
1103 }
1104 if *with_tz {
1105 self.write(" WITH TIME ZONE");
1106 }
1107 }
1108 DataType::Interval => self.write("INTERVAL"),
1109 DataType::DateTime => self.write("DATETIME"),
1110 DataType::Blob => self.write("BLOB"),
1111 DataType::Bytea => self.write("BYTEA"),
1112 DataType::Bytes => self.write("BYTES"),
1113 DataType::Json => self.write("JSON"),
1114 DataType::Jsonb => self.write("JSONB"),
1115 DataType::Uuid => self.write("UUID"),
1116 DataType::Array(inner) => {
1117 self.write("ARRAY");
1118 if let Some(inner) = inner {
1119 self.write("<");
1120 self.gen_data_type(inner);
1121 self.write(">");
1122 }
1123 }
1124 DataType::Map { key, value } => {
1125 self.write("MAP<");
1126 self.gen_data_type(key);
1127 self.write(", ");
1128 self.gen_data_type(value);
1129 self.write(">");
1130 }
1131 DataType::Struct(fields) => {
1132 self.write("STRUCT<");
1133 for (i, (name, dt)) in fields.iter().enumerate() {
1134 if i > 0 {
1135 self.write(", ");
1136 }
1137 self.write(name);
1138 self.write(" ");
1139 self.gen_data_type(dt);
1140 }
1141 self.write(">");
1142 }
1143 DataType::Tuple(types) => {
1144 self.write("TUPLE(");
1145 for (i, dt) in types.iter().enumerate() {
1146 if i > 0 {
1147 self.write(", ");
1148 }
1149 self.gen_data_type(dt);
1150 }
1151 self.write(")");
1152 }
1153 DataType::Null => self.write("NULL"),
1154 DataType::Variant => self.write("VARIANT"),
1155 DataType::Object => self.write("OBJECT"),
1156 DataType::Xml => self.write("XML"),
1157 DataType::Inet => self.write("INET"),
1158 DataType::Cidr => self.write("CIDR"),
1159 DataType::Macaddr => self.write("MACADDR"),
1160 DataType::Bit(len) => {
1161 self.write("BIT");
1162 if let Some(n) = len {
1163 self.write(&format!("({n})"));
1164 }
1165 }
1166 DataType::Money => self.write("MONEY"),
1167 DataType::Serial => self.write("SERIAL"),
1168 DataType::BigSerial => self.write("BIGSERIAL"),
1169 DataType::SmallSerial => self.write("SMALLSERIAL"),
1170 DataType::Regclass => self.write("REGCLASS"),
1171 DataType::Regtype => self.write("REGTYPE"),
1172 DataType::Hstore => self.write("HSTORE"),
1173 DataType::Geography => self.write("GEOGRAPHY"),
1174 DataType::Geometry => self.write("GEOMETRY"),
1175 DataType::Super => self.write("SUPER"),
1176 DataType::Unknown(name) => self.write(name),
1177 }
1178 }
1179
1180 fn gen_expr_list(&mut self, exprs: &[Expr]) {
1185 for (i, expr) in exprs.iter().enumerate() {
1186 if i > 0 {
1187 self.write(", ");
1188 }
1189 self.gen_expr(expr);
1190 }
1191 }
1192
1193 fn gen_expr(&mut self, expr: &Expr) {
1194 match expr {
1195 Expr::Column { table, name, quote_style, table_quote_style } => {
1196 if let Some(t) = table {
1197 self.write_quoted(t, *table_quote_style);
1198 self.write(".");
1199 }
1200 self.write_quoted(name, *quote_style);
1201 }
1202 Expr::Number(n) => self.write(n),
1203 Expr::StringLiteral(s) => {
1204 self.write("'");
1205 self.write(&s.replace('\'', "''"));
1206 self.write("'");
1207 }
1208 Expr::Boolean(b) => self.write(if *b { "TRUE" } else { "FALSE" }),
1209 Expr::Null => self.write("NULL"),
1210 Expr::Default => self.write_keyword("DEFAULT"),
1211 Expr::Wildcard | Expr::Star => self.write("*"),
1212
1213 Expr::BinaryOp { left, op, right } => {
1214 self.gen_expr(left);
1215 let op_str = match op {
1216 BinaryOperator::Plus => " + ",
1217 BinaryOperator::Minus => " - ",
1218 BinaryOperator::Multiply => " * ",
1219 BinaryOperator::Divide => " / ",
1220 BinaryOperator::Modulo => " % ",
1221 BinaryOperator::Eq => " = ",
1222 BinaryOperator::Neq => " <> ",
1223 BinaryOperator::Lt => " < ",
1224 BinaryOperator::Gt => " > ",
1225 BinaryOperator::LtEq => " <= ",
1226 BinaryOperator::GtEq => " >= ",
1227 BinaryOperator::And => " AND ",
1228 BinaryOperator::Or => " OR ",
1229 BinaryOperator::Xor => " XOR ",
1230 BinaryOperator::Concat => " || ",
1231 BinaryOperator::BitwiseAnd => " & ",
1232 BinaryOperator::BitwiseOr => " | ",
1233 BinaryOperator::BitwiseXor => " ^ ",
1234 BinaryOperator::ShiftLeft => " << ",
1235 BinaryOperator::ShiftRight => " >> ",
1236 BinaryOperator::Arrow => " -> ",
1237 BinaryOperator::DoubleArrow => " ->> ",
1238 };
1239 self.write(op_str);
1240 self.gen_expr(right);
1241 }
1242 Expr::UnaryOp { op, expr } => {
1243 let op_str = match op {
1244 UnaryOperator::Not => "NOT ",
1245 UnaryOperator::Minus => "-",
1246 UnaryOperator::Plus => "+",
1247 UnaryOperator::BitwiseNot => "~",
1248 };
1249 self.write(op_str);
1250 self.gen_expr(expr);
1251 }
1252 Expr::Function { name, args, distinct, filter, over } => {
1253 self.write(name);
1254 self.write("(");
1255 if *distinct {
1256 self.write_keyword("DISTINCT ");
1257 }
1258 self.gen_expr_list(args);
1259 self.write(")");
1260
1261 if let Some(filter_expr) = filter {
1262 self.write(" ");
1263 self.write_keyword("FILTER (WHERE ");
1264 self.gen_expr(filter_expr);
1265 self.write(")");
1266 }
1267 if let Some(spec) = over {
1268 self.write(" ");
1269 self.write_keyword("OVER ");
1270 if let Some(wref) = &spec.window_ref {
1271 if spec.partition_by.is_empty() && spec.order_by.is_empty() && spec.frame.is_none() {
1272 self.write(wref);
1273 } else {
1274 self.write("(");
1275 self.gen_window_spec(spec);
1276 self.write(")");
1277 }
1278 } else {
1279 self.write("(");
1280 self.gen_window_spec(spec);
1281 self.write(")");
1282 }
1283 }
1284 }
1285 Expr::Between { expr, low, high, negated } => {
1286 self.gen_expr(expr);
1287 if *negated {
1288 self.write(" ");
1289 self.write_keyword("NOT");
1290 }
1291 self.write(" ");
1292 self.write_keyword("BETWEEN ");
1293 self.gen_expr(low);
1294 self.write(" ");
1295 self.write_keyword("AND ");
1296 self.gen_expr(high);
1297 }
1298 Expr::InList { expr, list, negated } => {
1299 self.gen_expr(expr);
1300 if *negated {
1301 self.write(" ");
1302 self.write_keyword("NOT");
1303 }
1304 self.write(" ");
1305 self.write_keyword("IN (");
1306 self.gen_expr_list(list);
1307 self.write(")");
1308 }
1309 Expr::InSubquery { expr, subquery, negated } => {
1310 self.gen_expr(expr);
1311 if *negated {
1312 self.write(" ");
1313 self.write_keyword("NOT");
1314 }
1315 self.write(" ");
1316 self.write_keyword("IN (");
1317 self.gen_statement(subquery);
1318 self.write(")");
1319 }
1320 Expr::IsNull { expr, negated } => {
1321 self.gen_expr(expr);
1322 if *negated {
1323 self.write(" ");
1324 self.write_keyword("IS NOT NULL");
1325 } else {
1326 self.write(" ");
1327 self.write_keyword("IS NULL");
1328 }
1329 }
1330 Expr::IsBool { expr, value, negated } => {
1331 self.gen_expr(expr);
1332 self.write(" ");
1333 match (negated, value) {
1334 (false, true) => self.write_keyword("IS TRUE"),
1335 (false, false) => self.write_keyword("IS FALSE"),
1336 (true, true) => self.write_keyword("IS NOT TRUE"),
1337 (true, false) => self.write_keyword("IS NOT FALSE"),
1338 }
1339 }
1340 Expr::Like { expr, pattern, negated, escape } => {
1341 self.gen_expr(expr);
1342 if *negated {
1343 self.write(" ");
1344 self.write_keyword("NOT");
1345 }
1346 self.write(" ");
1347 self.write_keyword("LIKE ");
1348 self.gen_expr(pattern);
1349 if let Some(esc) = escape {
1350 self.write(" ");
1351 self.write_keyword("ESCAPE ");
1352 self.gen_expr(esc);
1353 }
1354 }
1355 Expr::ILike { expr, pattern, negated, escape } => {
1356 self.gen_expr(expr);
1357 if *negated {
1358 self.write(" ");
1359 self.write_keyword("NOT");
1360 }
1361 self.write(" ");
1362 self.write_keyword("ILIKE ");
1363 self.gen_expr(pattern);
1364 if let Some(esc) = escape {
1365 self.write(" ");
1366 self.write_keyword("ESCAPE ");
1367 self.gen_expr(esc);
1368 }
1369 }
1370 Expr::Case { operand, when_clauses, else_clause } => {
1371 self.write_keyword("CASE");
1372 if let Some(op) = operand {
1373 self.write(" ");
1374 self.gen_expr(op);
1375 }
1376 for (cond, result) in when_clauses {
1377 self.write(" ");
1378 self.write_keyword("WHEN ");
1379 self.gen_expr(cond);
1380 self.write(" ");
1381 self.write_keyword("THEN ");
1382 self.gen_expr(result);
1383 }
1384 if let Some(el) = else_clause {
1385 self.write(" ");
1386 self.write_keyword("ELSE ");
1387 self.gen_expr(el);
1388 }
1389 self.write(" ");
1390 self.write_keyword("END");
1391 }
1392 Expr::Nested(inner) => {
1393 self.write("(");
1394 self.gen_expr(inner);
1395 self.write(")");
1396 }
1397 Expr::Subquery(query) => {
1398 self.write("(");
1399 self.gen_statement(query);
1400 self.write(")");
1401 }
1402 Expr::Exists { subquery, negated } => {
1403 if *negated {
1404 self.write_keyword("NOT ");
1405 }
1406 self.write_keyword("EXISTS (");
1407 self.gen_statement(subquery);
1408 self.write(")");
1409 }
1410 Expr::Cast { expr, data_type } => {
1411 self.write_keyword("CAST(");
1412 self.gen_expr(expr);
1413 self.write(" ");
1414 self.write_keyword("AS ");
1415 self.gen_data_type(data_type);
1416 self.write(")");
1417 }
1418 Expr::TryCast { expr, data_type } => {
1419 self.write_keyword("TRY_CAST(");
1420 self.gen_expr(expr);
1421 self.write(" ");
1422 self.write_keyword("AS ");
1423 self.gen_data_type(data_type);
1424 self.write(")");
1425 }
1426 Expr::Extract { field, expr } => {
1427 self.write_keyword("EXTRACT(");
1428 self.gen_datetime_field(field);
1429 self.write(" ");
1430 self.write_keyword("FROM ");
1431 self.gen_expr(expr);
1432 self.write(")");
1433 }
1434 Expr::Interval { value, unit } => {
1435 self.write_keyword("INTERVAL ");
1436 self.gen_expr(value);
1437 if let Some(unit) = unit {
1438 self.write(" ");
1439 self.gen_datetime_field(unit);
1440 }
1441 }
1442 Expr::ArrayLiteral(items) => {
1443 self.write_keyword("ARRAY[");
1444 self.gen_expr_list(items);
1445 self.write("]");
1446 }
1447 Expr::Tuple(items) => {
1448 self.write("(");
1449 self.gen_expr_list(items);
1450 self.write(")");
1451 }
1452 Expr::Coalesce(items) => {
1453 self.write_keyword("COALESCE(");
1454 self.gen_expr_list(items);
1455 self.write(")");
1456 }
1457 Expr::If { condition, true_val, false_val } => {
1458 self.write_keyword("IF(");
1459 self.gen_expr(condition);
1460 self.write(", ");
1461 self.gen_expr(true_val);
1462 if let Some(fv) = false_val {
1463 self.write(", ");
1464 self.gen_expr(fv);
1465 }
1466 self.write(")");
1467 }
1468 Expr::NullIf { expr, r#else } => {
1469 self.write_keyword("NULLIF(");
1470 self.gen_expr(expr);
1471 self.write(", ");
1472 self.gen_expr(r#else);
1473 self.write(")");
1474 }
1475 Expr::Collate { expr, collation } => {
1476 self.gen_expr(expr);
1477 self.write(" ");
1478 self.write_keyword("COLLATE ");
1479 self.write(collation);
1480 }
1481 Expr::Parameter(p) => self.write(p),
1482 Expr::TypeExpr(dt) => self.gen_data_type(dt),
1483 Expr::QualifiedWildcard { table } => {
1484 self.write(table);
1485 self.write(".*");
1486 }
1487 Expr::Alias { expr, name } => {
1488 self.gen_expr(expr);
1489 self.write(" ");
1490 self.write_keyword("AS ");
1491 self.write(name);
1492 }
1493 Expr::ArrayIndex { expr, index } => {
1494 self.gen_expr(expr);
1495 self.write("[");
1496 self.gen_expr(index);
1497 self.write("]");
1498 }
1499 Expr::JsonAccess { expr, path, as_text } => {
1500 self.gen_expr(expr);
1501 if *as_text {
1502 self.write("->>");
1503 } else {
1504 self.write("->");
1505 }
1506 self.gen_expr(path);
1507 }
1508 Expr::Lambda { params, body } => {
1509 if params.len() == 1 {
1510 self.write(¶ms[0]);
1511 } else {
1512 self.write("(");
1513 self.write(¶ms.join(", "));
1514 self.write(")");
1515 }
1516 self.write(" -> ");
1517 self.gen_expr(body);
1518 }
1519 }
1520 }
1521
1522 fn gen_window_spec(&mut self, spec: &WindowSpec) {
1523 if let Some(wref) = &spec.window_ref {
1524 self.write(wref);
1525 if !spec.partition_by.is_empty() || !spec.order_by.is_empty() || spec.frame.is_some() {
1526 self.write(" ");
1527 }
1528 }
1529 if !spec.partition_by.is_empty() {
1530 self.write_keyword("PARTITION BY ");
1531 self.gen_expr_list(&spec.partition_by);
1532 }
1533 if !spec.order_by.is_empty() {
1534 if !spec.partition_by.is_empty() {
1535 self.write(" ");
1536 }
1537 self.write_keyword("ORDER BY ");
1538 for (i, item) in spec.order_by.iter().enumerate() {
1539 if i > 0 {
1540 self.write(", ");
1541 }
1542 self.gen_expr(&item.expr);
1543 if !item.ascending {
1544 self.write(" ");
1545 self.write_keyword("DESC");
1546 }
1547 if let Some(nulls_first) = item.nulls_first {
1548 if nulls_first {
1549 self.write(" ");
1550 self.write_keyword("NULLS FIRST");
1551 } else {
1552 self.write(" ");
1553 self.write_keyword("NULLS LAST");
1554 }
1555 }
1556 }
1557 }
1558 if let Some(frame) = &spec.frame {
1559 self.write(" ");
1560 self.gen_window_frame(frame);
1561 }
1562 }
1563
1564 fn gen_window_frame(&mut self, frame: &WindowFrame) {
1565 match frame.kind {
1566 WindowFrameKind::Rows => self.write_keyword("ROWS "),
1567 WindowFrameKind::Range => self.write_keyword("RANGE "),
1568 WindowFrameKind::Groups => self.write_keyword("GROUPS "),
1569 }
1570 if let Some(end) = &frame.end {
1571 self.write_keyword("BETWEEN ");
1572 self.gen_window_frame_bound(&frame.start);
1573 self.write(" ");
1574 self.write_keyword("AND ");
1575 self.gen_window_frame_bound(end);
1576 } else {
1577 self.gen_window_frame_bound(&frame.start);
1578 }
1579 }
1580
1581 fn gen_window_frame_bound(&mut self, bound: &WindowFrameBound) {
1582 match bound {
1583 WindowFrameBound::CurrentRow => self.write_keyword("CURRENT ROW"),
1584 WindowFrameBound::Preceding(None) => self.write_keyword("UNBOUNDED PRECEDING"),
1585 WindowFrameBound::Preceding(Some(n)) => {
1586 self.gen_expr(n);
1587 self.write(" ");
1588 self.write_keyword("PRECEDING");
1589 }
1590 WindowFrameBound::Following(None) => self.write_keyword("UNBOUNDED FOLLOWING"),
1591 WindowFrameBound::Following(Some(n)) => {
1592 self.gen_expr(n);
1593 self.write(" ");
1594 self.write_keyword("FOLLOWING");
1595 }
1596 }
1597 }
1598
1599 fn gen_datetime_field(&mut self, field: &DateTimeField) {
1600 let name = match field {
1601 DateTimeField::Year => "YEAR",
1602 DateTimeField::Quarter => "QUARTER",
1603 DateTimeField::Month => "MONTH",
1604 DateTimeField::Week => "WEEK",
1605 DateTimeField::Day => "DAY",
1606 DateTimeField::DayOfWeek => "DOW",
1607 DateTimeField::DayOfYear => "DOY",
1608 DateTimeField::Hour => "HOUR",
1609 DateTimeField::Minute => "MINUTE",
1610 DateTimeField::Second => "SECOND",
1611 DateTimeField::Millisecond => "MILLISECOND",
1612 DateTimeField::Microsecond => "MICROSECOND",
1613 DateTimeField::Nanosecond => "NANOSECOND",
1614 DateTimeField::Epoch => "EPOCH",
1615 DateTimeField::Timezone => "TIMEZONE",
1616 DateTimeField::TimezoneHour => "TIMEZONE_HOUR",
1617 DateTimeField::TimezoneMinute => "TIMEZONE_MINUTE",
1618 };
1619 self.write(name);
1620 }
1621}
1622
1623impl Default for Generator {
1624 fn default() -> Self {
1625 Self::new()
1626 }
1627}
1628
1629#[cfg(test)]
1630mod tests {
1631 use super::*;
1632 use crate::parser::Parser;
1633
1634 fn roundtrip(sql: &str) -> String {
1635 let stmt = Parser::new(sql).unwrap().parse_statement().unwrap();
1636 let mut g = Generator::new();
1637 g.generate(&stmt)
1638 }
1639
1640 #[test]
1641 fn test_select_roundtrip() {
1642 assert_eq!(roundtrip("SELECT a, b FROM t"), "SELECT a, b FROM t");
1643 }
1644
1645 #[test]
1646 fn test_select_where() {
1647 assert_eq!(
1648 roundtrip("SELECT x FROM t WHERE x > 10"),
1649 "SELECT x FROM t WHERE x > 10"
1650 );
1651 }
1652
1653 #[test]
1654 fn test_select_wildcard() {
1655 assert_eq!(roundtrip("SELECT * FROM users"), "SELECT * FROM users");
1656 }
1657
1658 #[test]
1659 fn test_insert_values() {
1660 assert_eq!(
1661 roundtrip("INSERT INTO t (a, b) VALUES (1, 'hello')"),
1662 "INSERT INTO t (a, b) VALUES (1, 'hello')"
1663 );
1664 }
1665
1666 #[test]
1667 fn test_delete() {
1668 assert_eq!(
1669 roundtrip("DELETE FROM users WHERE id = 1"),
1670 "DELETE FROM users WHERE id = 1"
1671 );
1672 }
1673
1674 #[test]
1675 fn test_join() {
1676 assert_eq!(
1677 roundtrip("SELECT a.id, b.name FROM a INNER JOIN b ON a.id = b.a_id"),
1678 "SELECT a.id, b.name FROM a INNER JOIN b ON a.id = b.a_id"
1679 );
1680 }
1681
1682 #[test]
1683 fn test_create_table() {
1684 assert_eq!(
1685 roundtrip("CREATE TABLE users (id INT NOT NULL, name VARCHAR(255), email TEXT)"),
1686 "CREATE TABLE users (id INT NOT NULL, name VARCHAR(255), email TEXT)"
1687 );
1688 }
1689
1690 #[test]
1691 fn test_cte_roundtrip() {
1692 let sql = "WITH cte AS (SELECT 1 AS x) SELECT x FROM cte";
1693 assert_eq!(roundtrip(sql), "WITH cte AS (SELECT 1 AS x) SELECT x FROM cte");
1694 }
1695
1696 #[test]
1697 fn test_union_roundtrip() {
1698 let sql = "SELECT 1 UNION ALL SELECT 2";
1699 assert_eq!(roundtrip(sql), "SELECT 1 UNION ALL SELECT 2");
1700 }
1701
1702 #[test]
1703 fn test_cast_roundtrip() {
1704 assert_eq!(
1705 roundtrip("SELECT CAST(x AS INT) FROM t"),
1706 "SELECT CAST(x AS INT) FROM t"
1707 );
1708 }
1709
1710 #[test]
1711 fn test_exists_roundtrip() {
1712 assert_eq!(
1713 roundtrip("SELECT * FROM t WHERE EXISTS (SELECT 1 FROM t2)"),
1714 "SELECT * FROM t WHERE EXISTS (SELECT 1 FROM t2)"
1715 );
1716 }
1717
1718 #[test]
1719 fn test_extract_roundtrip() {
1720 assert_eq!(
1721 roundtrip("SELECT EXTRACT(YEAR FROM created_at) FROM t"),
1722 "SELECT EXTRACT(YEAR FROM created_at) FROM t"
1723 );
1724 }
1725
1726 #[test]
1727 fn test_window_function_roundtrip() {
1728 assert_eq!(
1729 roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) FROM emp"),
1730 "SELECT ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) FROM emp"
1731 );
1732 }
1733
1734 #[test]
1735 fn test_subquery_from_roundtrip() {
1736 assert_eq!(
1737 roundtrip("SELECT * FROM (SELECT 1 AS x) AS sub"),
1738 "SELECT * FROM (SELECT 1 AS x) AS sub"
1739 );
1740 }
1741
1742 #[test]
1743 fn test_in_subquery_roundtrip() {
1744 assert_eq!(
1745 roundtrip("SELECT * FROM t WHERE id IN (SELECT id FROM t2)"),
1746 "SELECT * FROM t WHERE id IN (SELECT id FROM t2)"
1747 );
1748 }
1749
1750 fn pretty_print(sql: &str) -> String {
1755 let stmt = Parser::new(sql).unwrap().parse_statement().unwrap();
1756 let mut g = Generator::pretty();
1757 g.generate(&stmt)
1758 }
1759
1760 #[test]
1761 fn test_pretty_simple_select() {
1762 assert_eq!(
1763 pretty_print("SELECT a, b, c FROM t"),
1764 "SELECT\n a,\n b,\n c\nFROM\n t"
1765 );
1766 }
1767
1768 #[test]
1769 fn test_pretty_select_where() {
1770 assert_eq!(
1771 pretty_print("SELECT a FROM t WHERE a > 1"),
1772 "SELECT\n a\nFROM\n t\nWHERE\n a > 1"
1773 );
1774 }
1775
1776 #[test]
1777 fn test_pretty_select_group_by_having() {
1778 assert_eq!(
1779 pretty_print("SELECT a, COUNT(*) FROM t GROUP BY a HAVING COUNT(*) > 1"),
1780 "SELECT\n a,\n COUNT(*)\nFROM\n t\nGROUP BY\n a\nHAVING\n COUNT(*) > 1"
1781 );
1782 }
1783
1784 #[test]
1785 fn test_pretty_select_order_by_limit() {
1786 assert_eq!(
1787 pretty_print("SELECT a FROM t ORDER BY a DESC LIMIT 10"),
1788 "SELECT\n a\nFROM\n t\nORDER BY\n a DESC\nLIMIT 10"
1789 );
1790 }
1791
1792 #[test]
1793 fn test_pretty_join() {
1794 assert_eq!(
1795 pretty_print("SELECT a.id, b.name FROM a INNER JOIN b ON a.id = b.a_id"),
1796 "SELECT\n a.id,\n b.name\nFROM\n a\nINNER JOIN\n b\n ON a.id = b.a_id"
1797 );
1798 }
1799
1800 #[test]
1801 fn test_pretty_cte() {
1802 assert_eq!(
1803 pretty_print("WITH cte AS (SELECT 1 AS x) SELECT x FROM cte"),
1804 "WITH cte AS (\n SELECT\n 1 AS x\n)\nSELECT\n x\nFROM\n cte"
1805 );
1806 }
1807
1808 #[test]
1809 fn test_pretty_union() {
1810 assert_eq!(
1811 pretty_print("SELECT 1 UNION ALL SELECT 2"),
1812 "SELECT\n 1\nUNION ALL\nSELECT\n 2"
1813 );
1814 }
1815
1816 #[test]
1817 fn test_pretty_insert() {
1818 assert_eq!(
1819 pretty_print("INSERT INTO t (a, b) VALUES (1, 'hello'), (2, 'world')"),
1820 "INSERT INTO t (a, b)\nVALUES\n (1, 'hello'),\n (2, 'world')"
1821 );
1822 }
1823
1824 #[test]
1825 fn test_pretty_update() {
1826 assert_eq!(
1827 pretty_print("UPDATE t SET a = 1, b = 2 WHERE c = 3"),
1828 "UPDATE t\nSET\n a = 1,\n b = 2\nWHERE\n c = 3"
1829 );
1830 }
1831
1832 #[test]
1833 fn test_pretty_delete() {
1834 assert_eq!(
1835 pretty_print("DELETE FROM t WHERE id = 1"),
1836 "DELETE FROM t\nWHERE\n id = 1"
1837 );
1838 }
1839
1840 #[test]
1841 fn test_pretty_create_table() {
1842 assert_eq!(
1843 pretty_print("CREATE TABLE t (id INT NOT NULL, name VARCHAR(255), email TEXT)"),
1844 "CREATE TABLE t (\n id INT NOT NULL,\n name VARCHAR(255),\n email TEXT\n)"
1845 );
1846 }
1847
1848 #[test]
1849 fn test_pretty_complex_query() {
1850 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";
1851 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";
1852 assert_eq!(pretty_print(sql), expected);
1853 }
1854
1855 #[test]
1856 fn test_pretty_select_distinct() {
1857 assert_eq!(
1858 pretty_print("SELECT DISTINCT a, b FROM t"),
1859 "SELECT DISTINCT\n a,\n b\nFROM\n t"
1860 );
1861 }
1862}