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 binary_op_str(op: &BinaryOperator) -> &'static str {
1185 match op {
1186 BinaryOperator::Plus => " + ",
1187 BinaryOperator::Minus => " - ",
1188 BinaryOperator::Multiply => " * ",
1189 BinaryOperator::Divide => " / ",
1190 BinaryOperator::Modulo => " % ",
1191 BinaryOperator::Eq => " = ",
1192 BinaryOperator::Neq => " <> ",
1193 BinaryOperator::Lt => " < ",
1194 BinaryOperator::Gt => " > ",
1195 BinaryOperator::LtEq => " <= ",
1196 BinaryOperator::GtEq => " >= ",
1197 BinaryOperator::And => " AND ",
1198 BinaryOperator::Or => " OR ",
1199 BinaryOperator::Xor => " XOR ",
1200 BinaryOperator::Concat => " || ",
1201 BinaryOperator::BitwiseAnd => " & ",
1202 BinaryOperator::BitwiseOr => " | ",
1203 BinaryOperator::BitwiseXor => " ^ ",
1204 BinaryOperator::ShiftLeft => " << ",
1205 BinaryOperator::ShiftRight => " >> ",
1206 BinaryOperator::Arrow => " -> ",
1207 BinaryOperator::DoubleArrow => " ->> ",
1208 }
1209 }
1210
1211 fn gen_expr_list(&mut self, exprs: &[Expr]) {
1212 for (i, expr) in exprs.iter().enumerate() {
1213 if i > 0 {
1214 self.write(", ");
1215 }
1216 self.gen_expr(expr);
1217 }
1218 }
1219
1220 fn gen_expr(&mut self, expr: &Expr) {
1221 match expr {
1222 Expr::Column { table, name, quote_style, table_quote_style } => {
1223 if let Some(t) = table {
1224 self.write_quoted(t, *table_quote_style);
1225 self.write(".");
1226 }
1227 self.write_quoted(name, *quote_style);
1228 }
1229 Expr::Number(n) => self.write(n),
1230 Expr::StringLiteral(s) => {
1231 self.write("'");
1232 self.write(&s.replace('\'', "''"));
1233 self.write("'");
1234 }
1235 Expr::Boolean(b) => self.write(if *b { "TRUE" } else { "FALSE" }),
1236 Expr::Null => self.write("NULL"),
1237 Expr::Default => self.write_keyword("DEFAULT"),
1238 Expr::Wildcard | Expr::Star => self.write("*"),
1239
1240 Expr::BinaryOp { left, op, right } => {
1241 self.gen_expr(left);
1242 self.write(Self::binary_op_str(op));
1243 self.gen_expr(right);
1244 }
1245 Expr::AnyOp { expr, op, right } => {
1246 self.gen_expr(expr);
1247 self.write(Self::binary_op_str(op));
1248 self.write_keyword("ANY");
1249 self.write("(");
1250 if let Expr::Subquery(query) = right.as_ref() {
1251 self.gen_statement(query);
1252 } else {
1253 self.gen_expr(right);
1254 }
1255 self.write(")");
1256 }
1257 Expr::AllOp { expr, op, right } => {
1258 self.gen_expr(expr);
1259 self.write(Self::binary_op_str(op));
1260 self.write_keyword("ALL");
1261 self.write("(");
1262 if let Expr::Subquery(query) = right.as_ref() {
1263 self.gen_statement(query);
1264 } else {
1265 self.gen_expr(right);
1266 }
1267 self.write(")");
1268 }
1269 Expr::UnaryOp { op, expr } => {
1270 let op_str = match op {
1271 UnaryOperator::Not => "NOT ",
1272 UnaryOperator::Minus => "-",
1273 UnaryOperator::Plus => "+",
1274 UnaryOperator::BitwiseNot => "~",
1275 };
1276 self.write(op_str);
1277 self.gen_expr(expr);
1278 }
1279 Expr::Function { name, args, distinct, filter, over } => {
1280 self.write(name);
1281 self.write("(");
1282 if *distinct {
1283 self.write_keyword("DISTINCT ");
1284 }
1285 self.gen_expr_list(args);
1286 self.write(")");
1287
1288 if let Some(filter_expr) = filter {
1289 self.write(" ");
1290 self.write_keyword("FILTER (WHERE ");
1291 self.gen_expr(filter_expr);
1292 self.write(")");
1293 }
1294 if let Some(spec) = over {
1295 self.write(" ");
1296 self.write_keyword("OVER ");
1297 if let Some(wref) = &spec.window_ref {
1298 if spec.partition_by.is_empty() && spec.order_by.is_empty() && spec.frame.is_none() {
1299 self.write(wref);
1300 } else {
1301 self.write("(");
1302 self.gen_window_spec(spec);
1303 self.write(")");
1304 }
1305 } else {
1306 self.write("(");
1307 self.gen_window_spec(spec);
1308 self.write(")");
1309 }
1310 }
1311 }
1312 Expr::Between { expr, low, high, negated } => {
1313 self.gen_expr(expr);
1314 if *negated {
1315 self.write(" ");
1316 self.write_keyword("NOT");
1317 }
1318 self.write(" ");
1319 self.write_keyword("BETWEEN ");
1320 self.gen_expr(low);
1321 self.write(" ");
1322 self.write_keyword("AND ");
1323 self.gen_expr(high);
1324 }
1325 Expr::InList { expr, list, negated } => {
1326 self.gen_expr(expr);
1327 if *negated {
1328 self.write(" ");
1329 self.write_keyword("NOT");
1330 }
1331 self.write(" ");
1332 self.write_keyword("IN (");
1333 self.gen_expr_list(list);
1334 self.write(")");
1335 }
1336 Expr::InSubquery { expr, subquery, negated } => {
1337 self.gen_expr(expr);
1338 if *negated {
1339 self.write(" ");
1340 self.write_keyword("NOT");
1341 }
1342 self.write(" ");
1343 self.write_keyword("IN (");
1344 self.gen_statement(subquery);
1345 self.write(")");
1346 }
1347 Expr::IsNull { expr, negated } => {
1348 self.gen_expr(expr);
1349 if *negated {
1350 self.write(" ");
1351 self.write_keyword("IS NOT NULL");
1352 } else {
1353 self.write(" ");
1354 self.write_keyword("IS NULL");
1355 }
1356 }
1357 Expr::IsBool { expr, value, negated } => {
1358 self.gen_expr(expr);
1359 self.write(" ");
1360 match (negated, value) {
1361 (false, true) => self.write_keyword("IS TRUE"),
1362 (false, false) => self.write_keyword("IS FALSE"),
1363 (true, true) => self.write_keyword("IS NOT TRUE"),
1364 (true, false) => self.write_keyword("IS NOT FALSE"),
1365 }
1366 }
1367 Expr::Like { expr, pattern, negated, escape } => {
1368 self.gen_expr(expr);
1369 if *negated {
1370 self.write(" ");
1371 self.write_keyword("NOT");
1372 }
1373 self.write(" ");
1374 self.write_keyword("LIKE ");
1375 self.gen_expr(pattern);
1376 if let Some(esc) = escape {
1377 self.write(" ");
1378 self.write_keyword("ESCAPE ");
1379 self.gen_expr(esc);
1380 }
1381 }
1382 Expr::ILike { expr, pattern, negated, escape } => {
1383 self.gen_expr(expr);
1384 if *negated {
1385 self.write(" ");
1386 self.write_keyword("NOT");
1387 }
1388 self.write(" ");
1389 self.write_keyword("ILIKE ");
1390 self.gen_expr(pattern);
1391 if let Some(esc) = escape {
1392 self.write(" ");
1393 self.write_keyword("ESCAPE ");
1394 self.gen_expr(esc);
1395 }
1396 }
1397 Expr::Case { operand, when_clauses, else_clause } => {
1398 self.write_keyword("CASE");
1399 if let Some(op) = operand {
1400 self.write(" ");
1401 self.gen_expr(op);
1402 }
1403 for (cond, result) in when_clauses {
1404 self.write(" ");
1405 self.write_keyword("WHEN ");
1406 self.gen_expr(cond);
1407 self.write(" ");
1408 self.write_keyword("THEN ");
1409 self.gen_expr(result);
1410 }
1411 if let Some(el) = else_clause {
1412 self.write(" ");
1413 self.write_keyword("ELSE ");
1414 self.gen_expr(el);
1415 }
1416 self.write(" ");
1417 self.write_keyword("END");
1418 }
1419 Expr::Nested(inner) => {
1420 self.write("(");
1421 self.gen_expr(inner);
1422 self.write(")");
1423 }
1424 Expr::Subquery(query) => {
1425 self.write("(");
1426 self.gen_statement(query);
1427 self.write(")");
1428 }
1429 Expr::Exists { subquery, negated } => {
1430 if *negated {
1431 self.write_keyword("NOT ");
1432 }
1433 self.write_keyword("EXISTS (");
1434 self.gen_statement(subquery);
1435 self.write(")");
1436 }
1437 Expr::Cast { expr, data_type } => {
1438 self.write_keyword("CAST(");
1439 self.gen_expr(expr);
1440 self.write(" ");
1441 self.write_keyword("AS ");
1442 self.gen_data_type(data_type);
1443 self.write(")");
1444 }
1445 Expr::TryCast { expr, data_type } => {
1446 self.write_keyword("TRY_CAST(");
1447 self.gen_expr(expr);
1448 self.write(" ");
1449 self.write_keyword("AS ");
1450 self.gen_data_type(data_type);
1451 self.write(")");
1452 }
1453 Expr::Extract { field, expr } => {
1454 self.write_keyword("EXTRACT(");
1455 self.gen_datetime_field(field);
1456 self.write(" ");
1457 self.write_keyword("FROM ");
1458 self.gen_expr(expr);
1459 self.write(")");
1460 }
1461 Expr::Interval { value, unit } => {
1462 self.write_keyword("INTERVAL ");
1463 self.gen_expr(value);
1464 if let Some(unit) = unit {
1465 self.write(" ");
1466 self.gen_datetime_field(unit);
1467 }
1468 }
1469 Expr::ArrayLiteral(items) => {
1470 self.write_keyword("ARRAY[");
1471 self.gen_expr_list(items);
1472 self.write("]");
1473 }
1474 Expr::Tuple(items) => {
1475 self.write("(");
1476 self.gen_expr_list(items);
1477 self.write(")");
1478 }
1479 Expr::Coalesce(items) => {
1480 self.write_keyword("COALESCE(");
1481 self.gen_expr_list(items);
1482 self.write(")");
1483 }
1484 Expr::If { condition, true_val, false_val } => {
1485 self.write_keyword("IF(");
1486 self.gen_expr(condition);
1487 self.write(", ");
1488 self.gen_expr(true_val);
1489 if let Some(fv) = false_val {
1490 self.write(", ");
1491 self.gen_expr(fv);
1492 }
1493 self.write(")");
1494 }
1495 Expr::NullIf { expr, r#else } => {
1496 self.write_keyword("NULLIF(");
1497 self.gen_expr(expr);
1498 self.write(", ");
1499 self.gen_expr(r#else);
1500 self.write(")");
1501 }
1502 Expr::Collate { expr, collation } => {
1503 self.gen_expr(expr);
1504 self.write(" ");
1505 self.write_keyword("COLLATE ");
1506 self.write(collation);
1507 }
1508 Expr::Parameter(p) => self.write(p),
1509 Expr::TypeExpr(dt) => self.gen_data_type(dt),
1510 Expr::QualifiedWildcard { table } => {
1511 self.write(table);
1512 self.write(".*");
1513 }
1514 Expr::Alias { expr, name } => {
1515 self.gen_expr(expr);
1516 self.write(" ");
1517 self.write_keyword("AS ");
1518 self.write(name);
1519 }
1520 Expr::ArrayIndex { expr, index } => {
1521 self.gen_expr(expr);
1522 self.write("[");
1523 self.gen_expr(index);
1524 self.write("]");
1525 }
1526 Expr::JsonAccess { expr, path, as_text } => {
1527 self.gen_expr(expr);
1528 if *as_text {
1529 self.write("->>");
1530 } else {
1531 self.write("->");
1532 }
1533 self.gen_expr(path);
1534 }
1535 Expr::Lambda { params, body } => {
1536 if params.len() == 1 {
1537 self.write(¶ms[0]);
1538 } else {
1539 self.write("(");
1540 self.write(¶ms.join(", "));
1541 self.write(")");
1542 }
1543 self.write(" -> ");
1544 self.gen_expr(body);
1545 }
1546 }
1547 }
1548
1549 fn gen_window_spec(&mut self, spec: &WindowSpec) {
1550 if let Some(wref) = &spec.window_ref {
1551 self.write(wref);
1552 if !spec.partition_by.is_empty() || !spec.order_by.is_empty() || spec.frame.is_some() {
1553 self.write(" ");
1554 }
1555 }
1556 if !spec.partition_by.is_empty() {
1557 self.write_keyword("PARTITION BY ");
1558 self.gen_expr_list(&spec.partition_by);
1559 }
1560 if !spec.order_by.is_empty() {
1561 if !spec.partition_by.is_empty() {
1562 self.write(" ");
1563 }
1564 self.write_keyword("ORDER BY ");
1565 for (i, item) in spec.order_by.iter().enumerate() {
1566 if i > 0 {
1567 self.write(", ");
1568 }
1569 self.gen_expr(&item.expr);
1570 if !item.ascending {
1571 self.write(" ");
1572 self.write_keyword("DESC");
1573 }
1574 if let Some(nulls_first) = item.nulls_first {
1575 if nulls_first {
1576 self.write(" ");
1577 self.write_keyword("NULLS FIRST");
1578 } else {
1579 self.write(" ");
1580 self.write_keyword("NULLS LAST");
1581 }
1582 }
1583 }
1584 }
1585 if let Some(frame) = &spec.frame {
1586 self.write(" ");
1587 self.gen_window_frame(frame);
1588 }
1589 }
1590
1591 fn gen_window_frame(&mut self, frame: &WindowFrame) {
1592 match frame.kind {
1593 WindowFrameKind::Rows => self.write_keyword("ROWS "),
1594 WindowFrameKind::Range => self.write_keyword("RANGE "),
1595 WindowFrameKind::Groups => self.write_keyword("GROUPS "),
1596 }
1597 if let Some(end) = &frame.end {
1598 self.write_keyword("BETWEEN ");
1599 self.gen_window_frame_bound(&frame.start);
1600 self.write(" ");
1601 self.write_keyword("AND ");
1602 self.gen_window_frame_bound(end);
1603 } else {
1604 self.gen_window_frame_bound(&frame.start);
1605 }
1606 }
1607
1608 fn gen_window_frame_bound(&mut self, bound: &WindowFrameBound) {
1609 match bound {
1610 WindowFrameBound::CurrentRow => self.write_keyword("CURRENT ROW"),
1611 WindowFrameBound::Preceding(None) => self.write_keyword("UNBOUNDED PRECEDING"),
1612 WindowFrameBound::Preceding(Some(n)) => {
1613 self.gen_expr(n);
1614 self.write(" ");
1615 self.write_keyword("PRECEDING");
1616 }
1617 WindowFrameBound::Following(None) => self.write_keyword("UNBOUNDED FOLLOWING"),
1618 WindowFrameBound::Following(Some(n)) => {
1619 self.gen_expr(n);
1620 self.write(" ");
1621 self.write_keyword("FOLLOWING");
1622 }
1623 }
1624 }
1625
1626 fn gen_datetime_field(&mut self, field: &DateTimeField) {
1627 let name = match field {
1628 DateTimeField::Year => "YEAR",
1629 DateTimeField::Quarter => "QUARTER",
1630 DateTimeField::Month => "MONTH",
1631 DateTimeField::Week => "WEEK",
1632 DateTimeField::Day => "DAY",
1633 DateTimeField::DayOfWeek => "DOW",
1634 DateTimeField::DayOfYear => "DOY",
1635 DateTimeField::Hour => "HOUR",
1636 DateTimeField::Minute => "MINUTE",
1637 DateTimeField::Second => "SECOND",
1638 DateTimeField::Millisecond => "MILLISECOND",
1639 DateTimeField::Microsecond => "MICROSECOND",
1640 DateTimeField::Nanosecond => "NANOSECOND",
1641 DateTimeField::Epoch => "EPOCH",
1642 DateTimeField::Timezone => "TIMEZONE",
1643 DateTimeField::TimezoneHour => "TIMEZONE_HOUR",
1644 DateTimeField::TimezoneMinute => "TIMEZONE_MINUTE",
1645 };
1646 self.write(name);
1647 }
1648}
1649
1650impl Default for Generator {
1651 fn default() -> Self {
1652 Self::new()
1653 }
1654}
1655
1656#[cfg(test)]
1657mod tests {
1658 use super::*;
1659 use crate::parser::Parser;
1660
1661 fn roundtrip(sql: &str) -> String {
1662 let stmt = Parser::new(sql).unwrap().parse_statement().unwrap();
1663 let mut g = Generator::new();
1664 g.generate(&stmt)
1665 }
1666
1667 #[test]
1668 fn test_select_roundtrip() {
1669 assert_eq!(roundtrip("SELECT a, b FROM t"), "SELECT a, b FROM t");
1670 }
1671
1672 #[test]
1673 fn test_select_where() {
1674 assert_eq!(
1675 roundtrip("SELECT x FROM t WHERE x > 10"),
1676 "SELECT x FROM t WHERE x > 10"
1677 );
1678 }
1679
1680 #[test]
1681 fn test_select_wildcard() {
1682 assert_eq!(roundtrip("SELECT * FROM users"), "SELECT * FROM users");
1683 }
1684
1685 #[test]
1686 fn test_insert_values() {
1687 assert_eq!(
1688 roundtrip("INSERT INTO t (a, b) VALUES (1, 'hello')"),
1689 "INSERT INTO t (a, b) VALUES (1, 'hello')"
1690 );
1691 }
1692
1693 #[test]
1694 fn test_delete() {
1695 assert_eq!(
1696 roundtrip("DELETE FROM users WHERE id = 1"),
1697 "DELETE FROM users WHERE id = 1"
1698 );
1699 }
1700
1701 #[test]
1702 fn test_join() {
1703 assert_eq!(
1704 roundtrip("SELECT a.id, b.name FROM a INNER JOIN b ON a.id = b.a_id"),
1705 "SELECT a.id, b.name FROM a INNER JOIN b ON a.id = b.a_id"
1706 );
1707 }
1708
1709 #[test]
1710 fn test_create_table() {
1711 assert_eq!(
1712 roundtrip("CREATE TABLE users (id INT NOT NULL, name VARCHAR(255), email TEXT)"),
1713 "CREATE TABLE users (id INT NOT NULL, name VARCHAR(255), email TEXT)"
1714 );
1715 }
1716
1717 #[test]
1718 fn test_cte_roundtrip() {
1719 let sql = "WITH cte AS (SELECT 1 AS x) SELECT x FROM cte";
1720 assert_eq!(roundtrip(sql), "WITH cte AS (SELECT 1 AS x) SELECT x FROM cte");
1721 }
1722
1723 #[test]
1724 fn test_union_roundtrip() {
1725 let sql = "SELECT 1 UNION ALL SELECT 2";
1726 assert_eq!(roundtrip(sql), "SELECT 1 UNION ALL SELECT 2");
1727 }
1728
1729 #[test]
1730 fn test_cast_roundtrip() {
1731 assert_eq!(
1732 roundtrip("SELECT CAST(x AS INT) FROM t"),
1733 "SELECT CAST(x AS INT) FROM t"
1734 );
1735 }
1736
1737 #[test]
1738 fn test_exists_roundtrip() {
1739 assert_eq!(
1740 roundtrip("SELECT * FROM t WHERE EXISTS (SELECT 1 FROM t2)"),
1741 "SELECT * FROM t WHERE EXISTS (SELECT 1 FROM t2)"
1742 );
1743 }
1744
1745 #[test]
1746 fn test_extract_roundtrip() {
1747 assert_eq!(
1748 roundtrip("SELECT EXTRACT(YEAR FROM created_at) FROM t"),
1749 "SELECT EXTRACT(YEAR FROM created_at) FROM t"
1750 );
1751 }
1752
1753 #[test]
1754 fn test_window_function_roundtrip() {
1755 assert_eq!(
1756 roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) FROM emp"),
1757 "SELECT ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) FROM emp"
1758 );
1759 }
1760
1761 #[test]
1762 fn test_subquery_from_roundtrip() {
1763 assert_eq!(
1764 roundtrip("SELECT * FROM (SELECT 1 AS x) AS sub"),
1765 "SELECT * FROM (SELECT 1 AS x) AS sub"
1766 );
1767 }
1768
1769 #[test]
1770 fn test_in_subquery_roundtrip() {
1771 assert_eq!(
1772 roundtrip("SELECT * FROM t WHERE id IN (SELECT id FROM t2)"),
1773 "SELECT * FROM t WHERE id IN (SELECT id FROM t2)"
1774 );
1775 }
1776
1777 fn pretty_print(sql: &str) -> String {
1782 let stmt = Parser::new(sql).unwrap().parse_statement().unwrap();
1783 let mut g = Generator::pretty();
1784 g.generate(&stmt)
1785 }
1786
1787 #[test]
1788 fn test_pretty_simple_select() {
1789 assert_eq!(
1790 pretty_print("SELECT a, b, c FROM t"),
1791 "SELECT\n a,\n b,\n c\nFROM\n t"
1792 );
1793 }
1794
1795 #[test]
1796 fn test_pretty_select_where() {
1797 assert_eq!(
1798 pretty_print("SELECT a FROM t WHERE a > 1"),
1799 "SELECT\n a\nFROM\n t\nWHERE\n a > 1"
1800 );
1801 }
1802
1803 #[test]
1804 fn test_pretty_select_group_by_having() {
1805 assert_eq!(
1806 pretty_print("SELECT a, COUNT(*) FROM t GROUP BY a HAVING COUNT(*) > 1"),
1807 "SELECT\n a,\n COUNT(*)\nFROM\n t\nGROUP BY\n a\nHAVING\n COUNT(*) > 1"
1808 );
1809 }
1810
1811 #[test]
1812 fn test_pretty_select_order_by_limit() {
1813 assert_eq!(
1814 pretty_print("SELECT a FROM t ORDER BY a DESC LIMIT 10"),
1815 "SELECT\n a\nFROM\n t\nORDER BY\n a DESC\nLIMIT 10"
1816 );
1817 }
1818
1819 #[test]
1820 fn test_pretty_join() {
1821 assert_eq!(
1822 pretty_print("SELECT a.id, b.name FROM a INNER JOIN b ON a.id = b.a_id"),
1823 "SELECT\n a.id,\n b.name\nFROM\n a\nINNER JOIN\n b\n ON a.id = b.a_id"
1824 );
1825 }
1826
1827 #[test]
1828 fn test_pretty_cte() {
1829 assert_eq!(
1830 pretty_print("WITH cte AS (SELECT 1 AS x) SELECT x FROM cte"),
1831 "WITH cte AS (\n SELECT\n 1 AS x\n)\nSELECT\n x\nFROM\n cte"
1832 );
1833 }
1834
1835 #[test]
1836 fn test_pretty_union() {
1837 assert_eq!(
1838 pretty_print("SELECT 1 UNION ALL SELECT 2"),
1839 "SELECT\n 1\nUNION ALL\nSELECT\n 2"
1840 );
1841 }
1842
1843 #[test]
1844 fn test_pretty_insert() {
1845 assert_eq!(
1846 pretty_print("INSERT INTO t (a, b) VALUES (1, 'hello'), (2, 'world')"),
1847 "INSERT INTO t (a, b)\nVALUES\n (1, 'hello'),\n (2, 'world')"
1848 );
1849 }
1850
1851 #[test]
1852 fn test_pretty_update() {
1853 assert_eq!(
1854 pretty_print("UPDATE t SET a = 1, b = 2 WHERE c = 3"),
1855 "UPDATE t\nSET\n a = 1,\n b = 2\nWHERE\n c = 3"
1856 );
1857 }
1858
1859 #[test]
1860 fn test_pretty_delete() {
1861 assert_eq!(
1862 pretty_print("DELETE FROM t WHERE id = 1"),
1863 "DELETE FROM t\nWHERE\n id = 1"
1864 );
1865 }
1866
1867 #[test]
1868 fn test_pretty_create_table() {
1869 assert_eq!(
1870 pretty_print("CREATE TABLE t (id INT NOT NULL, name VARCHAR(255), email TEXT)"),
1871 "CREATE TABLE t (\n id INT NOT NULL,\n name VARCHAR(255),\n email TEXT\n)"
1872 );
1873 }
1874
1875 #[test]
1876 fn test_pretty_complex_query() {
1877 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";
1878 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";
1879 assert_eq!(pretty_print(sql), expected);
1880 }
1881
1882 #[test]
1883 fn test_pretty_select_distinct() {
1884 assert_eq!(
1885 pretty_print("SELECT DISTINCT a, b FROM t"),
1886 "SELECT DISTINCT\n a,\n b\nFROM\n t"
1887 );
1888 }
1889}