1use crate::error::Result;
14use crate::expressions::*;
15use crate::DialectType;
16
17pub struct Generator {
42 config: GeneratorConfig,
43 output: String,
44 indent_level: usize,
45 athena_hive_context: bool,
48 sqlite_inline_pk_columns: std::collections::HashSet<String>,
50 merge_strip_qualifiers: Vec<String>,
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Default)]
60pub enum NormalizeFunctions {
61 #[default]
63 Upper,
64 Lower,
66 None,
68}
69
70#[derive(Debug, Clone, Copy, PartialEq, Default)]
72pub enum LimitFetchStyle {
73 #[default]
75 Limit,
76 Top,
78 FetchFirst,
80}
81
82#[derive(Debug, Clone, Copy, PartialEq)]
84pub struct IdentifierQuoteStyle {
85 pub start: char,
87 pub end: char,
89}
90
91impl Default for IdentifierQuoteStyle {
92 fn default() -> Self {
93 Self { start: '"', end: '"' }
94 }
95}
96
97impl IdentifierQuoteStyle {
98 pub const DOUBLE_QUOTE: Self = Self { start: '"', end: '"' };
100 pub const BACKTICK: Self = Self { start: '`', end: '`' };
102 pub const BRACKET: Self = Self { start: '[', end: ']' };
104}
105
106#[derive(Debug, Clone)]
128pub struct GeneratorConfig {
129 pub pretty: bool,
132 pub indent: String,
134 pub max_text_width: usize,
136 pub identifier_quote: char,
138 pub identifier_quote_style: IdentifierQuoteStyle,
140 pub uppercase_keywords: bool,
142 pub normalize_identifiers: bool,
144 pub dialect: Option<crate::dialects::DialectType>,
146 pub normalize_functions: NormalizeFunctions,
148 pub string_escape: char,
150 pub case_sensitive_identifiers: bool,
152 pub identifiers_can_start_with_digit: bool,
154 pub always_quote_identifiers: bool,
157
158 pub null_ordering_supported: bool,
162 pub ignore_nulls_in_func: bool,
165 pub nvl2_supported: bool,
167
168 pub limit_fetch_style: LimitFetchStyle,
171 pub limit_is_top: bool,
173 pub limit_only_literals: bool,
175
176 pub single_string_interval: bool,
179 pub interval_allows_plural_form: bool,
181
182 pub cte_recursive_keyword_required: bool,
185
186 pub values_as_table: bool,
189 pub wrap_derived_values: bool,
191
192 pub tablesample_seed_keyword: &'static str,
195 pub tablesample_requires_parens: bool,
197 pub tablesample_size_is_rows: bool,
199 pub tablesample_keywords: &'static str,
201 pub tablesample_with_method: bool,
203 pub alias_post_tablesample: bool,
205
206 pub aggregate_filter_supported: bool,
209 pub multi_arg_distinct: bool,
211 pub quantified_no_paren_space: bool,
213 pub supports_median: bool,
215
216 pub supports_select_into: bool,
219 pub locking_reads_supported: bool,
221
222 pub rename_table_with_db: bool,
225 pub semi_anti_join_with_side: bool,
227 pub supports_table_alias_columns: bool,
229 pub join_hints: bool,
231 pub table_hints: bool,
233 pub query_hints: bool,
235 pub query_hint_sep: &'static str,
237 pub supports_column_join_marks: bool,
239
240 pub index_using_no_space: bool,
244 pub supports_unlogged_tables: bool,
246 pub supports_create_table_like: bool,
248 pub like_property_inside_schema: bool,
250 pub alter_table_include_column_keyword: bool,
252 pub supports_table_copy: bool,
254 pub alter_set_type: &'static str,
256 pub alter_set_wrapped: bool,
258
259 pub tz_to_with_time_zone: bool,
262 pub supports_convert_timezone: bool,
264
265 pub json_type_required_for_extraction: bool,
268 pub json_path_bracketed_key_supported: bool,
270 pub json_path_single_quote_escape: bool,
272 pub quote_json_path: bool,
274 pub json_key_value_pair_sep: &'static str,
276
277 pub copy_params_are_wrapped: bool,
280 pub copy_params_eq_required: bool,
282 pub copy_has_into_keyword: bool,
284
285 pub supports_window_exclude: bool,
288 pub unnest_with_ordinality: bool,
290 pub lowercase_window_frame_keywords: bool,
293 pub normalize_window_frame_between: bool,
296
297 pub array_concat_is_var_len: bool,
300 pub array_size_dim_required: Option<bool>,
303 pub can_implement_array_any: bool,
305 pub array_size_name: &'static str,
307
308 pub supports_between_flags: bool,
311
312 pub is_bool_allowed: bool,
315 pub ensure_bools: bool,
317
318 pub extract_allows_quotes: bool,
321 pub normalize_extract_date_parts: bool,
323
324 pub try_supported: bool,
327 pub supports_uescape: bool,
329 pub supports_to_number: bool,
331 pub supports_single_arg_concat: bool,
333 pub last_day_supports_date_part: bool,
335 pub supports_exploding_projections: bool,
337 pub supports_unix_seconds: bool,
339 pub supports_like_quantifiers: bool,
341 pub supports_decode_case: bool,
343 pub set_op_modifiers: bool,
345 pub update_statement_supports_from: bool,
347
348 pub collate_is_func: bool,
351
352 pub duplicate_key_update_with_set: bool,
355 pub insert_overwrite: &'static str,
357
358 pub returning_end: bool,
361
362 pub matched_by_source: bool,
365
366 pub create_function_return_as: bool,
369 pub parameter_default_equals: bool,
371
372 pub computed_column_with_type: bool,
375
376 pub unpivot_aliases_are_identifiers: bool,
379
380 pub star_except: &'static str,
383
384 pub hex_func: &'static str,
387
388 pub with_properties_prefix: &'static str,
391
392 pub pad_fill_pattern_is_required: bool,
395
396 pub index_on: &'static str,
399
400 pub groupings_sep: &'static str,
403
404 pub struct_delimiter: (&'static str, &'static str),
407 pub struct_curly_brace_notation: bool,
409 pub array_bracket_only: bool,
411 pub struct_field_sep: &'static str,
413
414 pub except_intersect_support_all_clause: bool,
417
418 pub parameter_token: &'static str,
421 pub named_placeholder_token: &'static str,
423
424 pub data_type_specifiers_allowed: bool,
427
428 pub schema_comment_with_eq: bool,
432}
433
434impl Default for GeneratorConfig {
435 fn default() -> Self {
436 Self {
437 pretty: false,
439 indent: " ".to_string(),
440 max_text_width: 80,
441 identifier_quote: '"',
442 identifier_quote_style: IdentifierQuoteStyle::DOUBLE_QUOTE,
443 uppercase_keywords: true,
444 normalize_identifiers: false,
445 dialect: None,
446 normalize_functions: NormalizeFunctions::Upper,
447 string_escape: '\'',
448 case_sensitive_identifiers: false,
449 identifiers_can_start_with_digit: false,
450 always_quote_identifiers: false,
451
452 null_ordering_supported: true,
454 ignore_nulls_in_func: false,
455 nvl2_supported: true,
456
457 limit_fetch_style: LimitFetchStyle::Limit,
459 limit_is_top: false,
460 limit_only_literals: false,
461
462 single_string_interval: false,
464 interval_allows_plural_form: true,
465
466 cte_recursive_keyword_required: true,
468
469 values_as_table: true,
471 wrap_derived_values: true,
472
473 tablesample_seed_keyword: "SEED",
475 tablesample_requires_parens: true,
476 tablesample_size_is_rows: true,
477 tablesample_keywords: "TABLESAMPLE",
478 tablesample_with_method: true,
479 alias_post_tablesample: false,
480
481 aggregate_filter_supported: true,
483 multi_arg_distinct: true,
484 quantified_no_paren_space: false,
485 supports_median: true,
486
487 supports_select_into: false,
489 locking_reads_supported: true,
490
491 rename_table_with_db: true,
493 semi_anti_join_with_side: true,
494 supports_table_alias_columns: true,
495 join_hints: true,
496 table_hints: true,
497 query_hints: true,
498 query_hint_sep: ", ",
499 supports_column_join_marks: false,
500
501 index_using_no_space: false,
503 supports_unlogged_tables: false,
504 supports_create_table_like: true,
505 like_property_inside_schema: false,
506 alter_table_include_column_keyword: true,
507 supports_table_copy: true,
508 alter_set_type: "SET DATA TYPE",
509 alter_set_wrapped: false,
510
511 tz_to_with_time_zone: false,
513 supports_convert_timezone: false,
514
515 json_type_required_for_extraction: false,
517 json_path_bracketed_key_supported: true,
518 json_path_single_quote_escape: false,
519 quote_json_path: true,
520 json_key_value_pair_sep: ":",
521
522 copy_params_are_wrapped: true,
524 copy_params_eq_required: false,
525 copy_has_into_keyword: true,
526
527 supports_window_exclude: false,
529 unnest_with_ordinality: true,
530 lowercase_window_frame_keywords: false,
531 normalize_window_frame_between: false,
532
533 array_concat_is_var_len: true,
535 array_size_dim_required: None,
536 can_implement_array_any: false,
537 array_size_name: "ARRAY_LENGTH",
538
539 supports_between_flags: false,
541
542 is_bool_allowed: true,
544 ensure_bools: false,
545
546 extract_allows_quotes: true,
548 normalize_extract_date_parts: false,
549
550 try_supported: true,
552 supports_uescape: true,
553 supports_to_number: true,
554 supports_single_arg_concat: true,
555 last_day_supports_date_part: true,
556 supports_exploding_projections: true,
557 supports_unix_seconds: false,
558 supports_like_quantifiers: true,
559 supports_decode_case: true,
560 set_op_modifiers: true,
561 update_statement_supports_from: true,
562
563 collate_is_func: false,
565
566 duplicate_key_update_with_set: true,
568 insert_overwrite: " OVERWRITE TABLE",
569
570 returning_end: true,
572
573 matched_by_source: true,
575
576 create_function_return_as: true,
578 parameter_default_equals: false,
579
580 computed_column_with_type: true,
582
583 unpivot_aliases_are_identifiers: true,
585
586 star_except: "EXCEPT",
588
589 hex_func: "HEX",
591
592 with_properties_prefix: "WITH",
594
595 pad_fill_pattern_is_required: false,
597
598 index_on: "ON",
600
601 groupings_sep: ",",
603
604 struct_delimiter: ("<", ">"),
606 struct_curly_brace_notation: false,
607 array_bracket_only: false,
608 struct_field_sep: " ",
609
610 except_intersect_support_all_clause: true,
612
613 parameter_token: "@",
615 named_placeholder_token: ":",
616
617 data_type_specifiers_allowed: false,
619
620 schema_comment_with_eq: true,
622 }
623 }
624}
625
626mod reserved_keywords {
629 use std::collections::HashSet;
630 use std::sync::LazyLock;
631
632 pub static SQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
634 [
635 "all", "alter", "and", "any", "array", "as", "asc", "at", "authorization",
636 "begin", "between", "both", "by",
637 "case", "cast", "check", "collate", "column", "commit", "constraint", "create", "cross", "cube", "current", "current_date", "current_time", "current_timestamp", "current_user",
638 "default", "delete", "desc", "distinct", "drop",
639 "else", "end", "escape", "except", "execute", "exists", "external",
640 "false", "fetch", "filter", "for", "foreign", "from", "full", "function",
641 "grant", "group", "grouping",
642 "having",
643 "if", "in", "index", "inner", "insert", "intersect", "interval", "into", "is",
644 "join",
645 "key",
646 "leading", "left", "like", "limit", "local", "localtime", "localtimestamp",
647 "match", "merge",
648 "natural", "no", "not", "null",
649 "of", "offset", "on", "only", "or", "order", "outer", "over",
650 "partition", "primary", "procedure",
651 "range", "references", "right", "rollback", "rollup", "row", "rows",
652 "select", "session_user", "set", "some",
653 "table", "tablesample", "then", "to", "trailing", "true", "truncate",
654 "union", "unique", "unknown", "update", "user", "using",
655 "values", "view",
656 "when", "where", "window", "with",
657 ].into_iter().collect()
658 });
659
660 pub static BIGQUERY_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
663 let mut set = SQL_RESERVED.clone();
664 set.extend([
665 "assert_rows_modified", "at", "contains", "cube", "current", "define", "enum",
666 "escape", "exclude", "following", "for", "groups", "hash", "ignore",
667 "lateral", "lookup", "new", "no", "nulls", "of", "over", "preceding",
668 "proto", "qualify", "recursive", "respect", "struct", "tablesample",
669 "treat", "unbounded", "unnest", "window", "within",
670 ]);
671 set.remove("grant");
673 set.remove("key");
674 set.remove("index");
675 set.remove("values");
676 set.remove("table");
677 set
678 });
679
680 pub static MYSQL_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
682 let mut set = SQL_RESERVED.clone();
683 set.extend([
684 "accessible", "add", "analyze", "asensitive", "before", "bigint", "binary",
685 "blob", "call", "cascade", "change", "char", "character", "condition",
686 "continue", "convert", "current_date", "current_time", "current_timestamp",
687 "current_user", "cursor", "database", "databases", "day_hour", "day_microsecond",
688 "day_minute", "day_second", "dec", "decimal", "declare", "delayed", "describe",
689 "deterministic", "distinctrow", "div", "double", "dual", "each", "elseif",
690 "enclosed", "escaped", "exit", "explain", "float", "float4", "float8", "force",
691 "get", "high_priority", "hour_microsecond", "hour_minute", "hour_second",
692 "ignore", "infile", "inout", "insensitive", "int", "int1", "int2", "int3",
693 "int4", "int8", "integer", "iterate", "keys", "kill", "leave", "linear",
694 "lines", "load", "lock", "long", "longblob", "longtext", "loop", "low_priority",
695 "master_ssl_verify_server_cert", "maxvalue", "mediumblob", "mediumint", "mediumtext",
696 "middleint", "minute_microsecond", "minute_second", "mod", "modifies", "no_write_to_binlog",
697 "numeric", "optimize", "option", "optionally", "out", "outfile", "precision",
698 "purge", "read", "reads", "real", "regexp", "release", "rename", "repeat",
699 "replace", "require", "resignal", "restrict", "return", "revoke", "rlike",
700 "schema", "schemas", "second_microsecond", "sensitive", "separator", "show",
701 "signal", "smallint", "spatial", "specific", "sql", "sql_big_result",
702 "sql_calc_found_rows", "sql_small_result", "sqlexception", "sqlstate", "sqlwarning",
703 "ssl", "starting", "straight_join", "terminated", "text", "tinyblob", "tinyint",
704 "tinytext", "trigger", "undo", "unlock", "unsigned", "usage", "utc_date",
705 "utc_time", "utc_timestamp", "varbinary", "varchar", "varcharacter", "varying",
706 "while", "write", "xor", "year_month", "zerofill",
707 ]);
708 set.remove("table");
709 set
710 });
711
712 pub static DORIS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
715 let mut set = MYSQL_RESERVED.clone();
716 set.extend([
717 "aggregate", "anti", "array", "backend", "backup", "begin", "bitmap",
718 "boolean", "broker", "buckets", "cached", "cancel", "cast", "catalog",
719 "charset", "cluster", "collation", "columns", "comment", "commit",
720 "config", "connection", "count", "current", "data", "date", "datetime",
721 "day", "deferred", "distributed", "dynamic", "enable", "end",
722 "events", "export", "external", "fields", "first", "follower", "format",
723 "free", "frontend", "full", "functions", "global", "grants", "hash",
724 "help", "hour", "install", "intermediate", "json", "label", "last",
725 "less", "level", "link", "local", "location", "max", "merge",
726 "min", "minute", "modify", "month", "name", "names", "negative",
727 "nulls", "observer", "offset", "only", "open", "overwrite", "password",
728 "path", "plan", "plugin", "plugins", "policy", "process", "properties",
729 "property", "query", "quota", "recover", "refresh", "repair", "replica",
730 "repository", "resource", "restore", "resume", "role", "roles",
731 "rollback", "rollup", "routine", "sample", "second", "semi", "session",
732 "signed", "snapshot", "start", "stats", "status", "stop", "stream",
733 "string", "sum", "tables", "tablet", "temporary", "text", "timestamp",
734 "transaction", "trash", "trim", "truncate", "type", "user", "value",
735 "variables", "verbose", "version", "view", "warnings", "week", "work",
736 "year",
737 ]);
738 set
739 });
740
741 pub static POSTGRES_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
743 let mut set = SQL_RESERVED.clone();
744 set.extend([
745 "analyse", "analyze", "asymmetric", "binary", "collation", "concurrently",
746 "current_catalog", "current_role", "current_schema", "deferrable", "do",
747 "freeze", "ilike", "initially", "isnull", "lateral", "notnull", "placing",
748 "returning", "similar", "symmetric", "variadic", "verbose",
749 ]);
750 set.remove("default");
752 set.remove("interval");
753 set.remove("match");
754 set.remove("offset");
755 set.remove("table");
756 set
757 });
758
759 pub static REDSHIFT_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
763 [
764 "aes128", "aes256", "all", "allowoverwrite", "analyse", "analyze", "and", "any",
765 "array", "as", "asc", "authorization", "az64", "backup", "between", "binary",
766 "blanksasnull", "both", "bytedict", "bzip2", "case", "cast", "check", "collate",
767 "column", "constraint", "create", "credentials", "cross", "current_date",
768 "current_time", "current_timestamp", "current_user", "current_user_id", "default",
769 "deferrable", "deflate", "defrag", "delta", "delta32k", "desc", "disable",
770 "distinct", "do", "else", "emptyasnull", "enable", "encode", "encrypt", "encryption",
771 "end", "except", "explicit", "false", "for", "foreign", "freeze", "from", "full",
772 "globaldict256", "globaldict64k", "grant", "group", "gzip", "having", "identity",
773 "ignore", "ilike", "in", "initially", "inner", "intersect", "interval", "into",
774 "is", "isnull", "join", "leading", "left", "like", "limit", "localtime",
775 "localtimestamp", "lun", "luns", "lzo", "lzop", "minus", "mostly16", "mostly32",
776 "mostly8", "natural", "new", "not", "notnull", "null", "nulls", "off", "offline",
777 "offset", "oid", "old", "on", "only", "open", "or", "order", "outer", "overlaps",
778 "parallel", "partition", "percent", "permissions", "pivot", "placing", "primary",
779 "raw", "readratio", "recover", "references", "rejectlog", "resort", "respect",
780 "restore", "right", "select", "session_user", "similar", "snapshot", "some",
781 "sysdate", "system", "table", "tag", "tdes", "text255", "text32k", "then",
782 "timestamp", "to", "top", "trailing", "true", "truncatecolumns", "type", "union",
783 "unique", "unnest", "unpivot", "user", "using", "verbose", "wallet", "when",
784 "where", "with", "without",
785 ].into_iter().collect()
786 });
787
788 pub static DUCKDB_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
790 let mut set = POSTGRES_RESERVED.clone();
791 set.extend([
792 "anti", "asof", "columns", "describe", "groups", "macro",
793 "pivot", "pivot_longer", "pivot_wider", "qualify", "replace",
794 "respect", "semi", "show", "table", "unpivot",
795 ]);
796 set.remove("at");
797 set.remove("row");
798 set
799 });
800
801 pub static TERADATA_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
803 let mut set = SQL_RESERVED.clone();
804 set.extend([
805 "abort", "abortsession", "account", "activity", "add", "after", "algorithm",
806 "all", "allocate", "alter", "amp", "analyse", "analyze", "and", "ansidate",
807 "any", "are", "array", "as", "asc", "at", "authorization", "avg", "before",
808 "begin", "between", "bigint", "binary", "blob", "both", "bt", "but", "by",
809 "byte", "byteint", "bytes", "call", "cascade", "case", "casespecific",
810 "cast", "cd", "char", "character", "characters", "character_length",
811 "chars", "check", "checkpoint", "class", "clob", "close", "cluster",
812 "cm", "coalesce", "collation", "collect", "column", "comment", "commit",
813 "compress", "connect", "constraint", "constructor", "consume", "contains",
814 "continue", "convert", "copy", "correlation", "cos", "count", "create",
815 "cross", "cs", "csum", "current", "current_date", "current_time",
816 "current_timestamp", "cursor", "cv", "cycle", "data", "database", "date",
817 "dateform", "day", "deallocate", "dec", "decimal", "declare", "default",
818 "deferred", "degrees", "del", "delete", "desc", "describe", "descriptor",
819 "deterministic", "diagnostic", "disabled", "distinct", "do", "domain",
820 "double", "drop", "dual", "dump", "dynamic", "each", "else", "elseif",
821 "enabled", "end", "eq", "error", "errorfiles", "errortables", "escape",
822 "et", "except", "exception", "exclusive", "exec", "execute", "exists",
823 "exit", "exp", "explain", "external", "extract", "fallback", "false",
824 "fastexport", "fetch", "first", "float", "for", "force", "foreign",
825 "format", "found", "freespace", "from", "full", "function", "ge", "get",
826 "give", "global", "go", "goto", "grant", "graphic", "group", "gt",
827 "handler", "hash", "hashamp", "hashbakamp", "hashbucket", "hashrow",
828 "having", "help", "hour", "identity", "if", "immediate", "in", "index",
829 "indicator", "initiate", "inner", "inout", "input", "ins", "insert",
830 "instead", "int", "integer", "integerdate", "intersect", "interval",
831 "into", "is", "iterate", "join", "journal", "key", "kurtosis", "language",
832 "large", "le", "leading", "leave", "left", "level", "like", "limit",
833 "ln", "loading", "local", "locator", "lock", "locking", "log", "logging",
834 "logon", "long", "loop", "lower", "lt", "macro", "map", "match", "mavg",
835 "max", "maximum", "mcharacters", "mdiff", "merge", "method", "min",
836 "minimum", "minus", "minute", "mlinreg", "mload", "mod", "mode", "modifies",
837 "modify", "monitor", "monresource", "monsession", "month", "msubstr",
838 "msum", "multiset", "named", "names", "national", "natural", "nchar",
839 "nclob", "ne", "new", "next", "no", "none", "not", "nowait", "null",
840 "nullif", "nullifzero", "number", "numeric", "object", "objects", "octet_length",
841 "of", "off", "old", "on", "only", "open", "option", "or", "order", "ordinality",
842 "out", "outer", "output", "over", "overlaps", "override", "parameter", "password",
843 "percent", "perm", "permanent", "position", "precision", "prepare", "preserve",
844 "primary", "privileges", "procedure", "profile", "proportional", "protection",
845 "public", "qualified", "qualify", "quantile", "queue", "radians", "random",
846 "range_n", "rank", "reads", "real", "recursive", "references", "referencing",
847 "regr_avgx", "regr_avgy", "regr_count", "regr_intercept", "regr_r2", "regr_slope",
848 "regr_sxx", "regr_sxy", "regr_syy", "relative", "release", "rename", "repeat",
849 "replace", "replication", "request", "resignal", "restart", "restore", "restrict",
850 "result", "resume", "retrieve", "return", "returns", "revert", "revoke", "right",
851 "rights", "role", "rollback", "rollforward", "rollup", "row", "row_number", "rowid",
852 "rows", "sample", "sampleid", "scroll", "second", "seconds", "sel", "select", "session",
853 "set", "setresrate", "sets", "setsessrate", "share", "show", "signal", "sin", "skew",
854 "smallint", "some", "source", "specific", "spool", "sql", "sqlexception", "sqlstate",
855 "sqltext", "sqlwarning", "sqrt", "ss", "start", "startup", "statement", "statistics",
856 "stddev_pop", "stddev_samp", "string", "subscriber", "subset", "substr", "substring",
857 "sum", "summary", "suspend", "system_user", "table", "tan", "then", "threshold",
858 "time", "timezone_hour", "timezone_minute", "title", "to", "top",
859 "trace", "trailing", "transaction", "translate", "translate_chk", "trigger", "trim",
860 "true", "type", "uc", "ud", "uescape", "undefined", "under", "undo", "union", "unique",
861 "until", "upd", "update", "upper", "upsert", "usage", "user", "using", "value", "values",
862 "var_pop", "var_samp", "varbyte", "varchar", "vargraphic", "varying", "view", "volatile",
863 "when", "where", "while", "width_bucket", "with", "without", "work", "write", "year",
864 "zeroifnull", "zone",
865 ]);
866 set
867 });
868
869 pub static PRESTO_TRINO_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
871 let mut set = SQL_RESERVED.clone();
872 set.extend([
873 "alter", "and", "as", "between", "by", "case", "cast", "constraint", "create",
874 "cross", "cube", "current_catalog", "current_date", "current_path", "current_role",
875 "current_schema", "current_time", "current_timestamp", "current_user", "deallocate",
876 "delete", "describe", "distinct", "drop", "else", "end", "escape", "except",
877 "execute", "exists", "extract", "false", "for", "from", "full", "group", "grouping",
878 "having", "in", "inner", "insert", "intersect", "into", "is", "join", "json_array",
879 "json_exists", "json_object", "json_query", "json_table", "json_value", "left",
880 "like", "listagg", "localtime", "localtimestamp", "natural", "normalize", "not",
881 "null", "on", "or", "order", "outer", "prepare", "recursive", "right", "rollup",
882 "select", "skip", "table", "then", "trim", "true", "uescape", "union", "unnest",
883 "using", "values", "when", "where", "with",
884 ]);
885 set
886 });
887
888 pub static STARROCKS_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
891 [
892 "add", "all", "alter", "analyze", "and", "array", "as", "asc",
893 "between", "bigint", "bitmap", "both", "by",
894 "case", "char", "character", "check", "collate", "column", "compaction",
895 "convert", "create", "cross", "cube", "current_date", "current_role",
896 "current_time", "current_timestamp", "current_user",
897 "database", "databases", "decimal", "decimalv2", "decimal32", "decimal64",
898 "decimal128", "default", "deferred", "delete", "dense_rank", "desc",
899 "describe", "distinct", "double", "drop", "dual",
900 "else", "except", "exists", "explain",
901 "false", "first_value", "float", "for", "force", "from", "full", "function",
902 "grant", "group", "grouping", "grouping_id", "groups",
903 "having", "hll", "host",
904 "if", "ignore", "immediate", "in", "index", "infile", "inner", "insert",
905 "int", "integer", "intersect", "into", "is",
906 "join", "json",
907 "key", "keys", "kill",
908 "lag", "largeint", "last_value", "lateral", "lead", "left", "like",
909 "limit", "load", "localtime", "localtimestamp",
910 "maxvalue", "minus", "mod",
911 "not", "ntile", "null",
912 "on", "or", "order", "outer", "outfile", "over",
913 "partition", "percentile", "primary", "procedure",
914 "qualify",
915 "range", "rank", "read", "regexp", "release", "rename", "replace",
916 "revoke", "right", "rlike", "row", "row_number", "rows",
917 "schema", "schemas", "select", "set", "set_var", "show", "smallint",
918 "system",
919 "table", "terminated", "text", "then", "tinyint", "to", "true",
920 "union", "unique", "unsigned", "update", "use", "using",
921 "values", "varchar",
922 "when", "where", "with",
923 ].into_iter().collect()
924 });
925
926 pub static SINGLESTORE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
929 let mut set = MYSQL_RESERVED.clone();
930 set.extend([
931 "abs", "account", "acos", "adddate", "addtime", "admin", "aes_decrypt", "aes_encrypt",
934 "aggregate", "aggregates", "aggregator", "anti_join", "any_value",
935 "approx_count_distinct", "approx_percentile", "arrange", "arrangement", "asin",
936 "atan", "atan2", "attach", "autostats", "avro",
937 "background", "backup", "batch", "batches", "boot_strapping",
938 "ceil", "ceiling", "coercibility", "columnar", "columnstore", "compile", "concurrent",
939 "connection_id", "cos", "cot", "current_security_groups", "current_security_roles",
940 "dayname", "dayofmonth", "dayofweek", "dayofyear", "degrees",
941 "dot_product", "dump", "durability",
942 "earliest", "echo", "election", "euclidean_distance", "exp", "extractor", "extractors",
943 "floor", "foreground", "found_rows", "from_base64", "from_days", "from_unixtime", "fs",
944 "fulltext",
945 "gc", "gcs", "geography", "geography_area", "geography_contains", "geography_distance",
946 "geography_intersects", "geography_latitude", "geography_length", "geography_longitude",
947 "geographypoint", "geography_point", "geography_within_distance", "geometry",
948 "geometry_area", "geometry_contains", "geometry_distance", "geometry_filter",
949 "geometry_intersects", "geometry_length", "geometrypoint", "geometry_point",
950 "geometry_within_distance", "geometry_x", "geometry_y", "greatest", "groups",
951 "group_concat", "gzip",
952 "hdfs", "hex", "highlight",
953 "ifnull", "ilike", "inet_aton", "inet_ntoa", "inet6_aton", "inet6_ntoa", "initcap",
954 "instr", "interpreter_mode", "isnull",
955 "json", "json_agg", "json_array_contains_double", "json_array_contains_json",
956 "json_array_contains_string", "json_delete_key", "json_extract_double",
957 "json_extract_json", "json_extract_string", "json_extract_bigint", "json_get_type",
958 "json_length", "json_set_double", "json_set_json", "json_set_string",
959 "kafka",
960 "lag", "last_day", "last_insert_id", "latest", "lcase", "lead", "leaf", "least",
961 "leaves", "length", "license", "links", "llvm", "ln", "load", "locate", "log",
962 "log10", "log2", "lpad", "lz4",
963 "management", "match", "mbc", "md5", "median", "memsql", "memsql_deserialize",
964 "memsql_serialize", "metadata", "microsecond", "minute", "model", "monthname",
965 "months_between", "mpl",
966 "namespace", "node", "noparam", "now", "nth_value", "ntile", "nullcols", "nullif",
967 "object", "octet_length", "offsets", "online", "optimizer", "orphan",
968 "parquet", "partitions", "pause", "percentile_cont", "percentile_disc", "periodic",
969 "persisted", "pi", "pipeline", "pipelines", "plancache", "plugins", "pool", "pools",
970 "pow", "power", "process", "processlist", "profile", "profiles",
971 "quarter", "queries", "query",
972 "radians", "rand", "record", "reduce", "redundancy", "regexp_match", "regexp_substr",
973 "remote", "replication", "resource", "resource_pool", "restore", "retry", "role",
974 "roles", "round", "rpad", "rtrim", "running",
975 "s3", "scalar", "sec_to_time", "second", "security_lists_intersect", "semi_join",
976 "sha", "sha1", "sha2", "shard", "sharded", "sharded_id", "sigmoid", "sign", "sin",
977 "skip", "sleep", "snapshot", "soname", "sparse", "spatial_check_index", "split",
978 "sqrt", "standalone", "std", "stddev", "stddev_pop", "stddev_samp", "stop",
979 "str_to_date", "subdate", "substr", "substring_index", "success", "synchronize",
980 "table_checksum", "tan", "task", "timediff", "time_bucket", "time_format",
981 "time_to_sec", "timestampadd", "timestampdiff", "to_base64", "to_char", "to_date",
982 "to_days", "to_json", "to_number", "to_seconds", "to_timestamp", "tracelogs",
983 "transform", "trim", "trunc", "truncate",
984 "ucase", "unhex", "unix_timestamp", "utc_date", "utc_time", "utc_timestamp",
985 "vacuum", "variance", "var_pop", "var_samp", "vector_sub", "voting",
986 "week", "weekday", "weekofyear", "workload",
987 "year",
988 ]);
989 set.remove("all");
991 set
992 });
993
994 pub static SQLITE_RESERVED: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
998 [
1000 "abort", "action", "add", "after", "all", "alter", "always", "analyze", "and", "as",
1001 "asc", "attach", "autoincrement", "before", "begin", "between", "by", "cascade", "case",
1002 "cast", "check", "collate", "column", "commit", "conflict", "constraint", "create", "cross",
1003 "current", "current_date", "current_time", "current_timestamp", "database", "default",
1004 "deferrable", "deferred", "delete", "desc", "detach", "distinct", "do", "drop", "each",
1005 "else", "end", "escape", "except", "exclude", "exclusive", "exists", "explain", "fail",
1006 "filter", "first", "following", "for", "foreign", "from", "full", "generated", "glob",
1007 "group", "groups", "having", "if", "ignore", "immediate", "in", "index", "indexed",
1008 "initially", "inner", "insert", "instead", "intersect", "into", "is", "isnull", "join",
1009 "key", "last", "left", "like", "limit", "natural", "no", "not", "nothing", "notnull",
1010 "null", "nulls", "of", "offset", "on", "or", "order", "others", "outer", "partition",
1011 "plan", "pragma", "preceding", "primary", "query", "raise", "range", "recursive",
1012 "references", "regexp", "reindex", "release", "rename", "replace", "restrict", "returning",
1013 "right", "rollback", "row", "rows", "savepoint", "select", "set", "table", "temp",
1014 "temporary", "then", "ties", "to", "transaction", "trigger", "unbounded", "union",
1015 "unique", "update", "using", "vacuum", "values", "view", "virtual", "when", "where",
1016 "window", "with", "without",
1017 ].into_iter().collect()
1018 });
1019}
1020
1021impl Generator {
1022 pub fn new() -> Self {
1028 Self::with_config(GeneratorConfig::default())
1029 }
1030
1031 pub fn with_config(config: GeneratorConfig) -> Self {
1036 Self {
1037 config,
1038 output: String::new(),
1039 indent_level: 0,
1040 athena_hive_context: false,
1041 sqlite_inline_pk_columns: std::collections::HashSet::new(),
1042 merge_strip_qualifiers: Vec::new(),
1043 }
1044 }
1045
1046 fn add_column_aliases_to_query(expr: Expression) -> Expression {
1050 match expr {
1051 Expression::Select(mut select) => {
1052 select.expressions = select.expressions
1054 .into_iter()
1055 .map(|e| Self::add_alias_to_expression(e))
1056 .collect();
1057
1058 if let Some(ref mut from) = select.from {
1060 from.expressions = from.expressions
1061 .iter()
1062 .cloned()
1063 .map(|e| Self::add_column_aliases_to_query(e))
1064 .collect();
1065 }
1066
1067 Expression::Select(select)
1068 }
1069 Expression::Subquery(mut sq) => {
1070 sq.this = Self::add_column_aliases_to_query(sq.this);
1071 Expression::Subquery(sq)
1072 }
1073 Expression::Paren(mut p) => {
1074 p.this = Self::add_column_aliases_to_query(p.this);
1075 Expression::Paren(p)
1076 }
1077 other => other,
1079 }
1080 }
1081
1082 fn add_alias_to_expression(expr: Expression) -> Expression {
1085 use crate::expressions::Alias;
1086
1087 match &expr {
1088 Expression::Alias(_) => expr,
1090
1091 Expression::Column(col) => {
1093 Expression::Alias(Box::new(Alias {
1094 this: expr.clone(),
1095 alias: col.name.clone(),
1096 column_aliases: Vec::new(),
1097 pre_alias_comments: Vec::new(),
1098 trailing_comments: Vec::new(),
1099 }))
1100 }
1101
1102 Expression::Identifier(ident) => {
1104 Expression::Alias(Box::new(Alias {
1105 this: expr.clone(),
1106 alias: ident.clone(),
1107 column_aliases: Vec::new(),
1108 pre_alias_comments: Vec::new(),
1109 trailing_comments: Vec::new(),
1110 }))
1111 }
1112
1113 Expression::Subquery(sq) => {
1115 let processed = Self::add_column_aliases_to_query(Expression::Subquery(sq.clone()));
1116 if sq.alias.is_some() {
1118 processed
1119 } else {
1120 processed
1122 }
1123 }
1124
1125 Expression::Star(_) => expr,
1127
1128 _ => expr,
1131 }
1132 }
1133
1134 fn try_evaluate_constant(expr: &Expression) -> Option<i64> {
1138 match expr {
1139 Expression::Literal(Literal::Number(n)) => n.parse::<i64>().ok(),
1140 Expression::Add(op) => {
1141 let left = Self::try_evaluate_constant(&op.left)?;
1142 let right = Self::try_evaluate_constant(&op.right)?;
1143 Some(left + right)
1144 }
1145 Expression::Sub(op) => {
1146 let left = Self::try_evaluate_constant(&op.left)?;
1147 let right = Self::try_evaluate_constant(&op.right)?;
1148 Some(left - right)
1149 }
1150 Expression::Mul(op) => {
1151 let left = Self::try_evaluate_constant(&op.left)?;
1152 let right = Self::try_evaluate_constant(&op.right)?;
1153 Some(left * right)
1154 }
1155 Expression::Div(op) => {
1156 let left = Self::try_evaluate_constant(&op.left)?;
1157 let right = Self::try_evaluate_constant(&op.right)?;
1158 if right != 0 {
1159 Some(left / right)
1160 } else {
1161 None
1162 }
1163 }
1164 Expression::Paren(p) => Self::try_evaluate_constant(&p.this),
1165 _ => None,
1166 }
1167 }
1168
1169 fn is_reserved_keyword(&self, name: &str) -> bool {
1171 use crate::dialects::DialectType;
1172 let lower = name.to_lowercase();
1173 let lower_ref = lower.as_str();
1174
1175 match self.config.dialect {
1176 Some(DialectType::BigQuery) => reserved_keywords::BIGQUERY_RESERVED.contains(lower_ref),
1177 Some(DialectType::MySQL) | Some(DialectType::TiDB) => {
1178 reserved_keywords::MYSQL_RESERVED.contains(lower_ref)
1179 }
1180 Some(DialectType::Doris) => {
1181 reserved_keywords::DORIS_RESERVED.contains(lower_ref)
1182 }
1183 Some(DialectType::SingleStore) => reserved_keywords::SINGLESTORE_RESERVED.contains(lower_ref),
1184 Some(DialectType::StarRocks) => reserved_keywords::STARROCKS_RESERVED.contains(lower_ref),
1185 Some(DialectType::PostgreSQL) | Some(DialectType::CockroachDB) | Some(DialectType::Materialize) | Some(DialectType::RisingWave) => {
1186 reserved_keywords::POSTGRES_RESERVED.contains(lower_ref)
1187 }
1188 Some(DialectType::Redshift) => reserved_keywords::REDSHIFT_RESERVED.contains(lower_ref),
1189 Some(DialectType::Snowflake) => false,
1192 Some(DialectType::ClickHouse) => false,
1194 Some(DialectType::DuckDB) => reserved_keywords::DUCKDB_RESERVED.contains(lower_ref),
1195 Some(DialectType::Teradata) => reserved_keywords::TERADATA_RESERVED.contains(lower_ref),
1196 Some(DialectType::TSQL) | Some(DialectType::Fabric) |
1198 Some(DialectType::Oracle) |
1199 Some(DialectType::Spark) | Some(DialectType::Databricks) |
1200 Some(DialectType::Hive) | Some(DialectType::Solr) => false,
1201 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
1202 reserved_keywords::PRESTO_TRINO_RESERVED.contains(lower_ref)
1203 }
1204 Some(DialectType::SQLite) => reserved_keywords::SQLITE_RESERVED.contains(lower_ref),
1205 Some(DialectType::Generic) | None => false,
1207 _ => reserved_keywords::SQL_RESERVED.contains(lower_ref),
1209 }
1210 }
1211
1212 fn normalize_func_name(&self, name: &str) -> String {
1214 match self.config.normalize_functions {
1215 NormalizeFunctions::Upper => name.to_uppercase(),
1216 NormalizeFunctions::Lower => name.to_lowercase(),
1217 NormalizeFunctions::None => name.to_string(),
1218 }
1219 }
1220
1221 pub fn generate(&mut self, expr: &Expression) -> Result<String> {
1230 self.output.clear();
1231 self.generate_expression(expr)?;
1232 Ok(std::mem::take(&mut self.output))
1233 }
1234
1235 pub fn sql(expr: &Expression) -> Result<String> {
1241 let mut gen = Generator::new();
1242 gen.generate(expr)
1243 }
1244
1245 pub fn pretty_sql(expr: &Expression) -> Result<String> {
1250 let config = GeneratorConfig {
1251 pretty: true,
1252 ..Default::default()
1253 };
1254 let mut gen = Generator::with_config(config);
1255 let mut sql = gen.generate(expr)?;
1256 if !sql.ends_with(';') {
1258 sql.push(';');
1259 }
1260 Ok(sql)
1261 }
1262
1263 fn generate_expression(&mut self, expr: &Expression) -> Result<()> {
1264 match expr {
1265 Expression::Select(select) => self.generate_select(select),
1266 Expression::Union(union) => self.generate_union(union),
1267 Expression::Intersect(intersect) => self.generate_intersect(intersect),
1268 Expression::Except(except) => self.generate_except(except),
1269 Expression::Insert(insert) => self.generate_insert(insert),
1270 Expression::Update(update) => self.generate_update(update),
1271 Expression::Delete(delete) => self.generate_delete(delete),
1272 Expression::Literal(lit) => self.generate_literal(lit),
1273 Expression::Boolean(b) => self.generate_boolean(b),
1274 Expression::Null(_) => {
1275 self.write_keyword("NULL");
1276 Ok(())
1277 }
1278 Expression::Identifier(id) => self.generate_identifier(id),
1279 Expression::Column(col) => self.generate_column(col),
1280 Expression::Pseudocolumn(pc) => self.generate_pseudocolumn(pc),
1281 Expression::Connect(c) => self.generate_connect_expr(c),
1282 Expression::Prior(p) => self.generate_prior(p),
1283 Expression::ConnectByRoot(cbr) => self.generate_connect_by_root(cbr),
1284 Expression::MatchRecognize(mr) => self.generate_match_recognize(mr),
1285 Expression::Table(table) => self.generate_table(table),
1286 Expression::StageReference(sr) => self.generate_stage_reference(sr),
1287 Expression::HistoricalData(hd) => self.generate_historical_data(hd),
1288 Expression::JoinedTable(jt) => self.generate_joined_table(jt),
1289 Expression::Star(star) => self.generate_star(star),
1290 Expression::BracedWildcard(expr) => self.generate_braced_wildcard(expr),
1291 Expression::Alias(alias) => self.generate_alias(alias),
1292 Expression::Cast(cast) => self.generate_cast(cast),
1293 Expression::Collation(coll) => self.generate_collation(coll),
1294 Expression::Case(case) => self.generate_case(case),
1295 Expression::Function(func) => self.generate_function(func),
1296 Expression::AggregateFunction(func) => self.generate_aggregate_function(func),
1297 Expression::WindowFunction(wf) => self.generate_window_function(wf),
1298 Expression::WithinGroup(wg) => self.generate_within_group(wg),
1299 Expression::Interval(interval) => self.generate_interval(interval),
1300
1301 Expression::ConcatWs(f) => self.generate_concat_ws(f),
1303 Expression::Substring(f) => self.generate_substring(f),
1304 Expression::Upper(f) => self.generate_unary_func("UPPER", f),
1305 Expression::Lower(f) => self.generate_unary_func("LOWER", f),
1306 Expression::Length(f) => self.generate_unary_func("LENGTH", f),
1307 Expression::Trim(f) => self.generate_trim(f),
1308 Expression::LTrim(f) => self.generate_simple_func("LTRIM", &f.this),
1309 Expression::RTrim(f) => self.generate_simple_func("RTRIM", &f.this),
1310 Expression::Replace(f) => self.generate_replace(f),
1311 Expression::Reverse(f) => self.generate_simple_func("REVERSE", &f.this),
1312 Expression::Left(f) => self.generate_left_right("LEFT", f),
1313 Expression::Right(f) => self.generate_left_right("RIGHT", f),
1314 Expression::Repeat(f) => self.generate_repeat(f),
1315 Expression::Lpad(f) => self.generate_pad("LPAD", f),
1316 Expression::Rpad(f) => self.generate_pad("RPAD", f),
1317 Expression::Split(f) => self.generate_split(f),
1318 Expression::RegexpLike(f) => self.generate_regexp_like(f),
1319 Expression::RegexpReplace(f) => self.generate_regexp_replace(f),
1320 Expression::RegexpExtract(f) => self.generate_regexp_extract(f),
1321 Expression::Overlay(f) => self.generate_overlay(f),
1322
1323 Expression::Abs(f) => self.generate_simple_func("ABS", &f.this),
1325 Expression::Round(f) => self.generate_round(f),
1326 Expression::Floor(f) => self.generate_floor(f),
1327 Expression::Ceil(f) => self.generate_ceil(f),
1328 Expression::Power(f) => self.generate_power(f),
1329 Expression::Sqrt(f) => self.generate_sqrt_cbrt(f, "SQRT", "|/"),
1330 Expression::Cbrt(f) => self.generate_sqrt_cbrt(f, "CBRT", "||/"),
1331 Expression::Ln(f) => self.generate_simple_func("LN", &f.this),
1332 Expression::Log(f) => self.generate_log(f),
1333 Expression::Exp(f) => self.generate_simple_func("EXP", &f.this),
1334 Expression::Sign(f) => self.generate_simple_func("SIGN", &f.this),
1335 Expression::Greatest(f) => self.generate_vararg_func("GREATEST", &f.expressions),
1336 Expression::Least(f) => self.generate_vararg_func("LEAST", &f.expressions),
1337
1338 Expression::CurrentDate(_) => {
1340 self.write_keyword("CURRENT_DATE");
1341 Ok(())
1342 }
1343 Expression::CurrentTime(f) => self.generate_current_time(f),
1344 Expression::CurrentTimestamp(f) => self.generate_current_timestamp(f),
1345 Expression::AtTimeZone(f) => self.generate_at_time_zone(f),
1346 Expression::DateAdd(f) => self.generate_date_add(f, "DATE_ADD"),
1347 Expression::DateSub(f) => self.generate_date_add(f, "DATE_SUB"),
1348 Expression::DateDiff(f) => self.generate_datediff(f),
1349 Expression::DateTrunc(f) => self.generate_date_trunc(f),
1350 Expression::Extract(f) => self.generate_extract(f),
1351 Expression::ToDate(f) => self.generate_to_date(f),
1352 Expression::ToTimestamp(f) => self.generate_to_timestamp(f),
1353
1354 Expression::Coalesce(f) => {
1356 let func_name = f.original_name.as_deref().unwrap_or("COALESCE");
1358 self.generate_vararg_func(func_name, &f.expressions)
1359 }
1360 Expression::NullIf(f) => self.generate_binary_func("NULLIF", &f.this, &f.expression),
1361 Expression::IfFunc(f) => self.generate_if_func(f),
1362 Expression::IfNull(f) => self.generate_ifnull(f),
1363 Expression::Nvl(f) => self.generate_nvl(f),
1364 Expression::Nvl2(f) => self.generate_nvl2(f),
1365
1366 Expression::TryCast(cast) => self.generate_try_cast(cast),
1368 Expression::SafeCast(cast) => self.generate_safe_cast(cast),
1369
1370 Expression::Count(f) => self.generate_count(f),
1372 Expression::Sum(f) => self.generate_agg_func("SUM", f),
1373 Expression::Avg(f) => self.generate_agg_func("AVG", f),
1374 Expression::Min(f) => self.generate_agg_func("MIN", f),
1375 Expression::Max(f) => self.generate_agg_func("MAX", f),
1376 Expression::GroupConcat(f) => self.generate_group_concat(f),
1377 Expression::StringAgg(f) => self.generate_string_agg(f),
1378 Expression::ListAgg(f) => self.generate_listagg(f),
1379 Expression::ArrayAgg(f) => {
1380 let override_name = f.name.as_ref()
1383 .filter(|n| n.to_uppercase() != "ARRAY_AGG")
1384 .map(|n| n.to_uppercase());
1385 match override_name {
1386 Some(name) => self.generate_agg_func(&name, f),
1387 None => self.generate_agg_func("ARRAY_AGG", f),
1388 }
1389 }
1390 Expression::ArrayConcatAgg(f) => self.generate_agg_func("ARRAY_CONCAT_AGG", f),
1391 Expression::CountIf(f) => self.generate_agg_func("COUNT_IF", f),
1392 Expression::SumIf(f) => self.generate_sum_if(f),
1393 Expression::Stddev(f) => self.generate_agg_func("STDDEV", f),
1394 Expression::StddevPop(f) => self.generate_agg_func("STDDEV_POP", f),
1395 Expression::StddevSamp(f) => self.generate_stddev_samp(f),
1396 Expression::Variance(f) => self.generate_agg_func("VARIANCE", f),
1397 Expression::VarPop(f) => {
1398 let name = if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
1399 "VARIANCE_POP"
1400 } else {
1401 "VAR_POP"
1402 };
1403 self.generate_agg_func(name, f)
1404 }
1405 Expression::VarSamp(f) => self.generate_agg_func("VAR_SAMP", f),
1406 Expression::Skewness(f) => {
1407 let name = match self.config.dialect {
1408 Some(DialectType::Snowflake) => "SKEW",
1409 _ => "SKEWNESS",
1410 };
1411 self.generate_agg_func(name, f)
1412 }
1413 Expression::Median(f) => self.generate_agg_func("MEDIAN", f),
1414 Expression::Mode(f) => self.generate_agg_func("MODE", f),
1415 Expression::First(f) => self.generate_agg_func("FIRST", f),
1416 Expression::Last(f) => self.generate_agg_func("LAST", f),
1417 Expression::AnyValue(f) => self.generate_agg_func("ANY_VALUE", f),
1418 Expression::ApproxDistinct(f) => {
1419 match self.config.dialect {
1420 Some(DialectType::Hive) | Some(DialectType::Spark)
1421 | Some(DialectType::Databricks) | Some(DialectType::BigQuery) => {
1422 self.generate_agg_func("APPROX_COUNT_DISTINCT", f)
1424 }
1425 Some(DialectType::Redshift) => {
1426 self.write_keyword("APPROXIMATE COUNT");
1428 self.write("(");
1429 self.write_keyword("DISTINCT");
1430 self.write(" ");
1431 self.generate_expression(&f.this)?;
1432 self.write(")");
1433 Ok(())
1434 }
1435 _ => self.generate_agg_func("APPROX_DISTINCT", f),
1436 }
1437 },
1438 Expression::ApproxCountDistinct(f) => self.generate_agg_func("APPROX_COUNT_DISTINCT", f),
1439 Expression::ApproxPercentile(f) => self.generate_approx_percentile(f),
1440 Expression::Percentile(f) => self.generate_percentile("PERCENTILE", f),
1441 Expression::LogicalAnd(f) => {
1442 let name = match self.config.dialect {
1443 Some(DialectType::Snowflake) => "BOOLAND_AGG",
1444 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::PostgreSQL) | Some(DialectType::DuckDB) | Some(DialectType::Redshift) => "BOOL_AND",
1445 Some(DialectType::Oracle) | Some(DialectType::SQLite) | Some(DialectType::MySQL) => "MIN",
1446 _ => "BOOL_AND",
1447 };
1448 self.generate_agg_func(name, f)
1449 }
1450 Expression::LogicalOr(f) => {
1451 let name = match self.config.dialect {
1452 Some(DialectType::Snowflake) => "BOOLOR_AGG",
1453 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::PostgreSQL) | Some(DialectType::DuckDB) | Some(DialectType::Redshift) => "BOOL_OR",
1454 Some(DialectType::Oracle) | Some(DialectType::SQLite) | Some(DialectType::MySQL) => "MAX",
1455 _ => "BOOL_OR",
1456 };
1457 self.generate_agg_func(name, f)
1458 }
1459
1460 Expression::RowNumber(_) => {
1462 if self.config.dialect == Some(DialectType::ClickHouse) {
1463 self.write("row_number");
1464 } else {
1465 self.write_keyword("ROW_NUMBER");
1466 }
1467 self.write("()");
1468 Ok(())
1469 }
1470 Expression::Rank(r) => {
1471 self.write_keyword("RANK");
1472 self.write("(");
1473 if !r.args.is_empty() {
1475 for (i, arg) in r.args.iter().enumerate() {
1476 if i > 0 { self.write(", "); }
1477 self.generate_expression(arg)?;
1478 }
1479 } else if let Some(order_by) = &r.order_by {
1480 self.write_keyword(" ORDER BY ");
1482 for (i, ob) in order_by.iter().enumerate() {
1483 if i > 0 { self.write(", "); }
1484 self.generate_ordered(ob)?;
1485 }
1486 }
1487 self.write(")");
1488 Ok(())
1489 }
1490 Expression::DenseRank(dr) => {
1491 self.write_keyword("DENSE_RANK");
1492 self.write("(");
1493 for (i, arg) in dr.args.iter().enumerate() {
1495 if i > 0 { self.write(", "); }
1496 self.generate_expression(arg)?;
1497 }
1498 self.write(")");
1499 Ok(())
1500 }
1501 Expression::NTile(f) => self.generate_ntile(f),
1502 Expression::Lead(f) => self.generate_lead_lag("LEAD", f),
1503 Expression::Lag(f) => self.generate_lead_lag("LAG", f),
1504 Expression::FirstValue(f) => self.generate_value_func("FIRST_VALUE", f),
1505 Expression::LastValue(f) => self.generate_value_func("LAST_VALUE", f),
1506 Expression::NthValue(f) => self.generate_nth_value(f),
1507 Expression::PercentRank(pr) => {
1508 self.write_keyword("PERCENT_RANK");
1509 self.write("(");
1510 if !pr.args.is_empty() {
1512 for (i, arg) in pr.args.iter().enumerate() {
1513 if i > 0 { self.write(", "); }
1514 self.generate_expression(arg)?;
1515 }
1516 } else if let Some(order_by) = &pr.order_by {
1517 self.write_keyword(" ORDER BY ");
1519 for (i, ob) in order_by.iter().enumerate() {
1520 if i > 0 { self.write(", "); }
1521 self.generate_ordered(ob)?;
1522 }
1523 }
1524 self.write(")");
1525 Ok(())
1526 }
1527 Expression::CumeDist(cd) => {
1528 self.write_keyword("CUME_DIST");
1529 self.write("(");
1530 if !cd.args.is_empty() {
1532 for (i, arg) in cd.args.iter().enumerate() {
1533 if i > 0 { self.write(", "); }
1534 self.generate_expression(arg)?;
1535 }
1536 } else if let Some(order_by) = &cd.order_by {
1537 self.write_keyword(" ORDER BY ");
1539 for (i, ob) in order_by.iter().enumerate() {
1540 if i > 0 { self.write(", "); }
1541 self.generate_ordered(ob)?;
1542 }
1543 }
1544 self.write(")");
1545 Ok(())
1546 }
1547 Expression::PercentileCont(f) => self.generate_percentile("PERCENTILE_CONT", f),
1548 Expression::PercentileDisc(f) => self.generate_percentile("PERCENTILE_DISC", f),
1549
1550 Expression::Contains(f) => self.generate_binary_func("CONTAINS", &f.this, &f.expression),
1552 Expression::StartsWith(f) => {
1553 let name = match self.config.dialect {
1554 Some(DialectType::Spark) | Some(DialectType::Databricks) => "STARTSWITH",
1555 _ => "STARTS_WITH",
1556 };
1557 self.generate_binary_func(name, &f.this, &f.expression)
1558 },
1559 Expression::EndsWith(f) => {
1560 let name = match self.config.dialect {
1561 Some(DialectType::Snowflake) => "ENDSWITH",
1562 Some(DialectType::Spark) | Some(DialectType::Databricks) => "ENDSWITH",
1563 Some(DialectType::ClickHouse) => "endsWith",
1564 _ => "ENDS_WITH",
1565 };
1566 self.generate_binary_func(name, &f.this, &f.expression)
1567 }
1568 Expression::Position(f) => self.generate_position(f),
1569 Expression::Initcap(f) => {
1570 match self.config.dialect {
1571 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
1572 self.write_keyword("REGEXP_REPLACE");
1573 self.write("(");
1574 self.generate_expression(&f.this)?;
1575 self.write(", '(\\w)(\\w*)', x -> UPPER(x[1]) || LOWER(x[2]))");
1576 Ok(())
1577 }
1578 _ => self.generate_simple_func("INITCAP", &f.this),
1579 }
1580 },
1581 Expression::Ascii(f) => self.generate_simple_func("ASCII", &f.this),
1582 Expression::Chr(f) => self.generate_simple_func("CHR", &f.this),
1583 Expression::CharFunc(f) => self.generate_char_func(f),
1584 Expression::Soundex(f) => self.generate_simple_func("SOUNDEX", &f.this),
1585 Expression::Levenshtein(f) => self.generate_binary_func("LEVENSHTEIN", &f.this, &f.expression),
1586
1587 Expression::ModFunc(f) => self.generate_mod_func(f),
1589 Expression::Random(_) => { self.write_keyword("RANDOM"); self.write("()"); Ok(()) }
1590 Expression::Rand(f) => self.generate_rand(f),
1591 Expression::TruncFunc(f) => self.generate_truncate_func(f),
1592 Expression::Pi(_) => { self.write_keyword("PI"); self.write("()"); Ok(()) }
1593 Expression::Radians(f) => self.generate_simple_func("RADIANS", &f.this),
1594 Expression::Degrees(f) => self.generate_simple_func("DEGREES", &f.this),
1595 Expression::Sin(f) => self.generate_simple_func("SIN", &f.this),
1596 Expression::Cos(f) => self.generate_simple_func("COS", &f.this),
1597 Expression::Tan(f) => self.generate_simple_func("TAN", &f.this),
1598 Expression::Asin(f) => self.generate_simple_func("ASIN", &f.this),
1599 Expression::Acos(f) => self.generate_simple_func("ACOS", &f.this),
1600 Expression::Atan(f) => self.generate_simple_func("ATAN", &f.this),
1601 Expression::Atan2(f) => {
1602 let name = f.original_name.as_deref().unwrap_or("ATAN2");
1603 self.generate_binary_func(name, &f.this, &f.expression)
1604 }
1605
1606 Expression::Decode(f) => self.generate_decode(f),
1608
1609 Expression::DateFormat(f) => self.generate_date_format("DATE_FORMAT", f),
1611 Expression::FormatDate(f) => self.generate_date_format("FORMAT_DATE", f),
1612 Expression::Year(f) => self.generate_simple_func("YEAR", &f.this),
1613 Expression::Month(f) => self.generate_simple_func("MONTH", &f.this),
1614 Expression::Day(f) => self.generate_simple_func("DAY", &f.this),
1615 Expression::Hour(f) => self.generate_simple_func("HOUR", &f.this),
1616 Expression::Minute(f) => self.generate_simple_func("MINUTE", &f.this),
1617 Expression::Second(f) => self.generate_simple_func("SECOND", &f.this),
1618 Expression::DayOfWeek(f) => {
1619 let name = match self.config.dialect {
1620 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => "DAY_OF_WEEK",
1621 Some(DialectType::DuckDB) => "ISODOW",
1622 _ => "DAYOFWEEK",
1623 };
1624 self.generate_simple_func(name, &f.this)
1625 }
1626 Expression::DayOfMonth(f) => {
1627 let name = match self.config.dialect {
1628 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => "DAY_OF_MONTH",
1629 _ => "DAYOFMONTH",
1630 };
1631 self.generate_simple_func(name, &f.this)
1632 }
1633 Expression::DayOfYear(f) => {
1634 let name = match self.config.dialect {
1635 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => "DAY_OF_YEAR",
1636 _ => "DAYOFYEAR",
1637 };
1638 self.generate_simple_func(name, &f.this)
1639 }
1640 Expression::WeekOfYear(f) => {
1641 let name = match self.config.dialect {
1643 Some(DialectType::Hive) | Some(DialectType::DuckDB) | Some(DialectType::Spark)
1644 | Some(DialectType::Databricks) | Some(DialectType::MySQL) => "WEEKOFYEAR",
1645 _ => "WEEK_OF_YEAR",
1646 };
1647 self.generate_simple_func(name, &f.this)
1648 }
1649 Expression::Quarter(f) => self.generate_simple_func("QUARTER", &f.this),
1650 Expression::AddMonths(f) => self.generate_binary_func("ADD_MONTHS", &f.this, &f.expression),
1651 Expression::MonthsBetween(f) => self.generate_binary_func("MONTHS_BETWEEN", &f.this, &f.expression),
1652 Expression::LastDay(f) => self.generate_last_day(f),
1653 Expression::NextDay(f) => self.generate_binary_func("NEXT_DAY", &f.this, &f.expression),
1654 Expression::Epoch(f) => self.generate_simple_func("EPOCH", &f.this),
1655 Expression::EpochMs(f) => self.generate_simple_func("EPOCH_MS", &f.this),
1656 Expression::FromUnixtime(f) => self.generate_from_unixtime(f),
1657 Expression::UnixTimestamp(f) => self.generate_unix_timestamp(f),
1658 Expression::MakeDate(f) => self.generate_make_date(f),
1659 Expression::MakeTimestamp(f) => self.generate_make_timestamp(f),
1660 Expression::TimestampTrunc(f) => self.generate_date_trunc(f),
1661
1662 Expression::ArrayFunc(f) => self.generate_array_constructor(f),
1664 Expression::ArrayLength(f) => self.generate_simple_func("ARRAY_LENGTH", &f.this),
1665 Expression::ArraySize(f) => self.generate_simple_func("ARRAY_SIZE", &f.this),
1666 Expression::Cardinality(f) => self.generate_simple_func("CARDINALITY", &f.this),
1667 Expression::ArrayContains(f) => self.generate_binary_func("ARRAY_CONTAINS", &f.this, &f.expression),
1668 Expression::ArrayPosition(f) => self.generate_binary_func("ARRAY_POSITION", &f.this, &f.expression),
1669 Expression::ArrayAppend(f) => self.generate_binary_func("ARRAY_APPEND", &f.this, &f.expression),
1670 Expression::ArrayPrepend(f) => self.generate_binary_func("ARRAY_PREPEND", &f.this, &f.expression),
1671 Expression::ArrayConcat(f) => self.generate_vararg_func("ARRAY_CONCAT", &f.expressions),
1672 Expression::ArraySort(f) => self.generate_array_sort(f),
1673 Expression::ArrayReverse(f) => self.generate_simple_func("ARRAY_REVERSE", &f.this),
1674 Expression::ArrayDistinct(f) => self.generate_simple_func("ARRAY_DISTINCT", &f.this),
1675 Expression::ArrayJoin(f) => self.generate_array_join("ARRAY_JOIN", f),
1676 Expression::ArrayToString(f) => self.generate_array_join("ARRAY_TO_STRING", f),
1677 Expression::Unnest(f) => self.generate_unnest(f),
1678 Expression::Explode(f) => self.generate_simple_func("EXPLODE", &f.this),
1679 Expression::ExplodeOuter(f) => self.generate_simple_func("EXPLODE_OUTER", &f.this),
1680 Expression::ArrayFilter(f) => self.generate_array_filter(f),
1681 Expression::ArrayTransform(f) => self.generate_array_transform(f),
1682 Expression::ArrayFlatten(f) => self.generate_simple_func("FLATTEN", &f.this),
1683 Expression::ArrayCompact(f) => self.generate_simple_func("ARRAY_COMPACT", &f.this),
1684 Expression::ArrayIntersect(f) => self.generate_binary_func("ARRAY_INTERSECT", &f.this, &f.expression),
1685 Expression::ArrayUnion(f) => self.generate_binary_func("ARRAY_UNION", &f.this, &f.expression),
1686 Expression::ArrayExcept(f) => self.generate_binary_func("ARRAY_EXCEPT", &f.this, &f.expression),
1687 Expression::ArrayRemove(f) => self.generate_binary_func("ARRAY_REMOVE", &f.this, &f.expression),
1688 Expression::ArrayZip(f) => self.generate_vararg_func("ARRAYS_ZIP", &f.expressions),
1689 Expression::Sequence(f) => self.generate_sequence("SEQUENCE", f),
1690 Expression::Generate(f) => self.generate_sequence("GENERATE_SERIES", f),
1691
1692 Expression::StructFunc(f) => self.generate_struct_constructor(f),
1694 Expression::StructExtract(f) => self.generate_struct_extract(f),
1695 Expression::NamedStruct(f) => self.generate_named_struct(f),
1696
1697 Expression::MapFunc(f) => self.generate_map_constructor(f),
1699 Expression::MapFromEntries(f) => self.generate_simple_func("MAP_FROM_ENTRIES", &f.this),
1700 Expression::MapFromArrays(f) => self.generate_binary_func("MAP_FROM_ARRAYS", &f.this, &f.expression),
1701 Expression::MapKeys(f) => self.generate_simple_func("MAP_KEYS", &f.this),
1702 Expression::MapValues(f) => self.generate_simple_func("MAP_VALUES", &f.this),
1703 Expression::MapContainsKey(f) => self.generate_binary_func("MAP_CONTAINS_KEY", &f.this, &f.expression),
1704 Expression::MapConcat(f) => self.generate_vararg_func("MAP_CONCAT", &f.expressions),
1705 Expression::ElementAt(f) => self.generate_binary_func("ELEMENT_AT", &f.this, &f.expression),
1706 Expression::TransformKeys(f) => self.generate_transform_func("TRANSFORM_KEYS", f),
1707 Expression::TransformValues(f) => self.generate_transform_func("TRANSFORM_VALUES", f),
1708
1709 Expression::JsonExtract(f) => self.generate_json_extract("JSON_EXTRACT", f),
1711 Expression::JsonExtractScalar(f) => self.generate_json_extract("JSON_EXTRACT_SCALAR", f),
1712 Expression::JsonExtractPath(f) => self.generate_json_path("JSON_EXTRACT_PATH", f),
1713 Expression::JsonArray(f) => self.generate_vararg_func("JSON_ARRAY", &f.expressions),
1714 Expression::JsonObject(f) => self.generate_json_object(f),
1715 Expression::JsonQuery(f) => self.generate_json_extract("JSON_QUERY", f),
1716 Expression::JsonValue(f) => self.generate_json_extract("JSON_VALUE", f),
1717 Expression::JsonArrayLength(f) => self.generate_simple_func("JSON_ARRAY_LENGTH", &f.this),
1718 Expression::JsonKeys(f) => self.generate_simple_func("JSON_KEYS", &f.this),
1719 Expression::JsonType(f) => self.generate_simple_func("JSON_TYPE", &f.this),
1720 Expression::ParseJson(f) => {
1721 let name = match self.config.dialect {
1722 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => "JSON_PARSE",
1723 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
1724 self.write_keyword("CAST");
1726 self.write("(");
1727 self.generate_expression(&f.this)?;
1728 self.write_keyword(" AS ");
1729 self.write_keyword("JSON");
1730 self.write(")");
1731 return Ok(());
1732 }
1733 Some(DialectType::Hive) | Some(DialectType::Spark)
1734 | Some(DialectType::MySQL)
1735 | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
1736 | Some(DialectType::TSQL) => {
1737 self.generate_expression(&f.this)?;
1739 return Ok(());
1740 }
1741 Some(DialectType::DuckDB) => "JSON",
1742 _ => "PARSE_JSON",
1743 };
1744 self.generate_simple_func(name, &f.this)
1745 }
1746 Expression::ToJson(f) => self.generate_simple_func("TO_JSON", &f.this),
1747 Expression::JsonSet(f) => self.generate_json_modify("JSON_SET", f),
1748 Expression::JsonInsert(f) => self.generate_json_modify("JSON_INSERT", f),
1749 Expression::JsonRemove(f) => self.generate_json_path("JSON_REMOVE", f),
1750 Expression::JsonMergePatch(f) => self.generate_binary_func("JSON_MERGE_PATCH", &f.this, &f.expression),
1751 Expression::JsonArrayAgg(f) => self.generate_json_array_agg(f),
1752 Expression::JsonObjectAgg(f) => self.generate_json_object_agg(f),
1753
1754 Expression::Convert(f) => self.generate_convert(f),
1756 Expression::Typeof(f) => self.generate_simple_func("TYPEOF", &f.this),
1757
1758 Expression::Lambda(f) => self.generate_lambda(f),
1760 Expression::Parameter(f) => self.generate_parameter(f),
1761 Expression::Placeholder(f) => self.generate_placeholder(f),
1762 Expression::NamedArgument(f) => self.generate_named_argument(f),
1763 Expression::TableArgument(f) => self.generate_table_argument(f),
1764 Expression::SqlComment(f) => self.generate_sql_comment(f),
1765
1766 Expression::NullSafeEq(op) => self.generate_null_safe_eq(op),
1768 Expression::NullSafeNeq(op) => self.generate_null_safe_neq(op),
1769 Expression::Glob(op) => self.generate_binary_op(op, "GLOB"),
1770 Expression::SimilarTo(f) => self.generate_similar_to(f),
1771 Expression::Any(f) => self.generate_quantified("ANY", f),
1772 Expression::All(f) => self.generate_quantified("ALL", f),
1773 Expression::Overlaps(f) => self.generate_overlaps(f),
1774
1775 Expression::BitwiseLeftShift(op) => {
1777 if matches!(self.config.dialect, Some(DialectType::Presto) | Some(DialectType::Trino)) {
1778 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_LEFT");
1779 self.write("(");
1780 self.generate_expression(&op.left)?;
1781 self.write(", ");
1782 self.generate_expression(&op.right)?;
1783 self.write(")");
1784 Ok(())
1785 } else if matches!(self.config.dialect, Some(DialectType::Spark) | Some(DialectType::Databricks)) {
1786 self.write_keyword("SHIFTLEFT");
1787 self.write("(");
1788 self.generate_expression(&op.left)?;
1789 self.write(", ");
1790 self.generate_expression(&op.right)?;
1791 self.write(")");
1792 Ok(())
1793 } else {
1794 self.generate_binary_op(op, "<<")
1795 }
1796 }
1797 Expression::BitwiseRightShift(op) => {
1798 if matches!(self.config.dialect, Some(DialectType::Presto) | Some(DialectType::Trino)) {
1799 self.write_keyword("BITWISE_ARITHMETIC_SHIFT_RIGHT");
1800 self.write("(");
1801 self.generate_expression(&op.left)?;
1802 self.write(", ");
1803 self.generate_expression(&op.right)?;
1804 self.write(")");
1805 Ok(())
1806 } else if matches!(self.config.dialect, Some(DialectType::Spark) | Some(DialectType::Databricks)) {
1807 self.write_keyword("SHIFTRIGHT");
1808 self.write("(");
1809 self.generate_expression(&op.left)?;
1810 self.write(", ");
1811 self.generate_expression(&op.right)?;
1812 self.write(")");
1813 Ok(())
1814 } else {
1815 self.generate_binary_op(op, ">>")
1816 }
1817 }
1818 Expression::BitwiseAndAgg(f) => self.generate_agg_func("BIT_AND", f),
1819 Expression::BitwiseOrAgg(f) => self.generate_agg_func("BIT_OR", f),
1820 Expression::BitwiseXorAgg(f) => self.generate_agg_func("BIT_XOR", f),
1821
1822 Expression::Subscript(s) => self.generate_subscript(s),
1824 Expression::Dot(d) => self.generate_dot_access(d),
1825 Expression::MethodCall(m) => self.generate_method_call(m),
1826 Expression::ArraySlice(s) => self.generate_array_slice(s),
1827
1828 Expression::And(op) => self.generate_binary_op(op, "AND"),
1829 Expression::Or(op) => self.generate_binary_op(op, "OR"),
1830 Expression::Add(op) => self.generate_binary_op(op, "+"),
1831 Expression::Sub(op) => self.generate_binary_op(op, "-"),
1832 Expression::Mul(op) => self.generate_binary_op(op, "*"),
1833 Expression::Div(op) => self.generate_binary_op(op, "/"),
1834 Expression::IntDiv(f) => {
1835 use crate::dialects::DialectType;
1836 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
1837 self.generate_expression(&f.this)?;
1839 self.write(" // ");
1840 self.generate_expression(&f.expression)?;
1841 Ok(())
1842 } else if matches!(self.config.dialect, Some(DialectType::Hive | DialectType::Spark | DialectType::Databricks)) {
1843 self.generate_expression(&f.this)?;
1845 self.write(" ");
1846 self.write_keyword("DIV");
1847 self.write(" ");
1848 self.generate_expression(&f.expression)?;
1849 Ok(())
1850 } else {
1851 self.write_keyword("DIV");
1853 self.write("(");
1854 self.generate_expression(&f.this)?;
1855 self.write(", ");
1856 self.generate_expression(&f.expression)?;
1857 self.write(")");
1858 Ok(())
1859 }
1860 }
1861 Expression::Mod(op) => {
1862 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
1863 self.generate_binary_op(op, "MOD")
1864 } else {
1865 self.generate_binary_op(op, "%")
1866 }
1867 }
1868 Expression::Eq(op) => self.generate_binary_op(op, "="),
1869 Expression::Neq(op) => self.generate_binary_op(op, "<>"),
1870 Expression::Lt(op) => self.generate_binary_op(op, "<"),
1871 Expression::Lte(op) => self.generate_binary_op(op, "<="),
1872 Expression::Gt(op) => self.generate_binary_op(op, ">"),
1873 Expression::Gte(op) => self.generate_binary_op(op, ">="),
1874 Expression::Like(op) => self.generate_like_op(op, "LIKE"),
1875 Expression::ILike(op) => self.generate_like_op(op, "ILIKE"),
1876 Expression::Match(op) => self.generate_binary_op(op, "MATCH"),
1877 Expression::Concat(op) => {
1878 if self.config.dialect == Some(DialectType::Solr) {
1880 self.generate_binary_op(op, "OR")
1881 } else {
1882 self.generate_binary_op(op, "||")
1883 }
1884 }
1885 Expression::BitwiseAnd(op) => {
1886 if matches!(self.config.dialect, Some(DialectType::Presto) | Some(DialectType::Trino)) {
1888 self.write_keyword("BITWISE_AND");
1889 self.write("(");
1890 self.generate_expression(&op.left)?;
1891 self.write(", ");
1892 self.generate_expression(&op.right)?;
1893 self.write(")");
1894 Ok(())
1895 } else {
1896 self.generate_binary_op(op, "&")
1897 }
1898 }
1899 Expression::BitwiseOr(op) => {
1900 if matches!(self.config.dialect, Some(DialectType::Presto) | Some(DialectType::Trino)) {
1902 self.write_keyword("BITWISE_OR");
1903 self.write("(");
1904 self.generate_expression(&op.left)?;
1905 self.write(", ");
1906 self.generate_expression(&op.right)?;
1907 self.write(")");
1908 Ok(())
1909 } else {
1910 self.generate_binary_op(op, "|")
1911 }
1912 }
1913 Expression::BitwiseXor(op) => {
1914 if matches!(self.config.dialect, Some(DialectType::Presto) | Some(DialectType::Trino)) {
1916 self.write_keyword("BITWISE_XOR");
1917 self.write("(");
1918 self.generate_expression(&op.left)?;
1919 self.write(", ");
1920 self.generate_expression(&op.right)?;
1921 self.write(")");
1922 Ok(())
1923 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
1924 self.generate_binary_op(op, "#")
1925 } else {
1926 self.generate_binary_op(op, "^")
1927 }
1928 }
1929 Expression::Adjacent(op) => self.generate_binary_op(op, "-|-"),
1930 Expression::TsMatch(op) => self.generate_binary_op(op, "@@"),
1931 Expression::PropertyEQ(op) => self.generate_binary_op(op, ":="),
1932 Expression::ArrayContainsAll(op) => self.generate_binary_op(op, "@>"),
1933 Expression::ArrayContainedBy(op) => self.generate_binary_op(op, "<@"),
1934 Expression::ArrayOverlaps(op) => self.generate_binary_op(op, "&&"),
1935 Expression::JSONBContainsAllTopKeys(op) => self.generate_binary_op(op, "?&"),
1936 Expression::JSONBContainsAnyTopKeys(op) => self.generate_binary_op(op, "?|"),
1937 Expression::JSONBContains(f) => {
1938 self.generate_expression(&f.this)?;
1940 self.write_space();
1941 self.write("?");
1942 self.write_space();
1943 self.generate_expression(&f.expression)
1944 }
1945 Expression::JSONBDeleteAtPath(op) => self.generate_binary_op(op, "#-"),
1946 Expression::ExtendsLeft(op) => self.generate_binary_op(op, "&<"),
1947 Expression::ExtendsRight(op) => self.generate_binary_op(op, "&>"),
1948 Expression::Not(op) => self.generate_unary_op(op, "NOT"),
1949 Expression::Neg(op) => self.generate_unary_op(op, "-"),
1950 Expression::BitwiseNot(op) => {
1951 if matches!(self.config.dialect, Some(DialectType::Presto) | Some(DialectType::Trino)) {
1953 self.write_keyword("BITWISE_NOT");
1954 self.write("(");
1955 self.generate_expression(&op.this)?;
1956 self.write(")");
1957 Ok(())
1958 } else {
1959 self.generate_unary_op(op, "~")
1960 }
1961 }
1962 Expression::In(in_expr) => self.generate_in(in_expr),
1963 Expression::Between(between) => self.generate_between(between),
1964 Expression::IsNull(is_null) => self.generate_is_null(is_null),
1965 Expression::IsTrue(is_true) => self.generate_is_true(is_true),
1966 Expression::IsFalse(is_false) => self.generate_is_false(is_false),
1967 Expression::IsJson(is_json) => self.generate_is_json(is_json),
1968 Expression::Is(is_expr) => self.generate_is(is_expr),
1969 Expression::Exists(exists) => self.generate_exists(exists),
1970 Expression::MemberOf(member_of) => self.generate_member_of(member_of),
1971 Expression::Subquery(subquery) => self.generate_subquery(subquery),
1972 Expression::Paren(paren) => {
1973 let skip_parens = matches!(&paren.this, Expression::JoinedTable(_));
1975
1976 let is_statement = matches!(
1978 &paren.this,
1979 Expression::Select(_) | Expression::Union(_) |
1980 Expression::Intersect(_) | Expression::Except(_) |
1981 Expression::Subquery(_)
1982 );
1983
1984 if !skip_parens {
1985 self.write("(");
1986 if self.config.pretty && is_statement {
1987 self.write_newline();
1988 self.indent_level += 1;
1989 self.write_indent();
1990 }
1991 }
1992 self.generate_expression(&paren.this)?;
1993 if !skip_parens {
1994 if self.config.pretty && is_statement {
1995 self.write_newline();
1996 self.indent_level -= 1;
1997 }
1998 self.write(")");
1999 }
2000 for comment in &paren.trailing_comments {
2002 self.write(" ");
2003 self.write(comment);
2004 }
2005 Ok(())
2006 }
2007 Expression::Array(arr) => self.generate_array(arr),
2008 Expression::Tuple(tuple) => self.generate_tuple(tuple),
2009 Expression::Ordered(ordered) => self.generate_ordered(ordered),
2010 Expression::DataType(dt) => self.generate_data_type(dt),
2011 Expression::Raw(raw) => {
2012 self.write(&raw.sql);
2013 Ok(())
2014 }
2015 Expression::Command(cmd) => {
2016 self.write(&cmd.this);
2017 Ok(())
2018 }
2019 Expression::Kill(kill) => {
2020 self.write_keyword("KILL");
2021 if let Some(kind) = &kill.kind {
2022 self.write_space();
2023 self.write_keyword(kind);
2024 }
2025 self.write_space();
2026 self.generate_expression(&kill.this)?;
2027 Ok(())
2028 }
2029 Expression::Execute(exec) => {
2030 self.write_keyword("EXEC");
2031 self.write_space();
2032 self.generate_expression(&exec.this)?;
2033 for (i, param) in exec.parameters.iter().enumerate() {
2034 if i == 0 {
2035 self.write_space();
2036 } else {
2037 self.write(", ");
2038 }
2039 self.write(¶m.name);
2040 self.write("=");
2041 self.generate_expression(¶m.value)?;
2042 }
2043 Ok(())
2044 }
2045 Expression::Annotated(annotated) => {
2046 self.generate_expression(&annotated.this)?;
2047 for comment in &annotated.trailing_comments {
2048 self.write(" ");
2049 self.write_formatted_comment(comment);
2050 }
2051 Ok(())
2052 }
2053
2054 Expression::CreateTable(ct) => self.generate_create_table(ct),
2056 Expression::DropTable(dt) => self.generate_drop_table(dt),
2057 Expression::AlterTable(at) => self.generate_alter_table(at),
2058 Expression::CreateIndex(ci) => self.generate_create_index(ci),
2059 Expression::DropIndex(di) => self.generate_drop_index(di),
2060 Expression::CreateView(cv) => self.generate_create_view(cv),
2061 Expression::DropView(dv) => self.generate_drop_view(dv),
2062 Expression::AlterView(av) => self.generate_alter_view(av),
2063 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
2064 Expression::Truncate(tr) => self.generate_truncate(tr),
2065 Expression::Use(u) => self.generate_use(u),
2066 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
2068 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
2069 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
2070 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
2071 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
2072 Expression::CreateFunction(cf) => self.generate_create_function(cf),
2073 Expression::DropFunction(df) => self.generate_drop_function(df),
2074 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
2075 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
2076 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
2077 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
2078 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
2079 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
2080 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
2081 Expression::CreateType(ct) => self.generate_create_type(ct),
2082 Expression::DropType(dt) => self.generate_drop_type(dt),
2083 Expression::Describe(d) => self.generate_describe(d),
2084 Expression::Show(s) => self.generate_show(s),
2085
2086 Expression::Cache(c) => self.generate_cache(c),
2088 Expression::Uncache(u) => self.generate_uncache(u),
2089 Expression::LoadData(l) => self.generate_load_data(l),
2090 Expression::Pragma(p) => self.generate_pragma(p),
2091 Expression::Grant(g) => self.generate_grant(g),
2092 Expression::Revoke(r) => self.generate_revoke(r),
2093 Expression::Comment(c) => self.generate_comment(c),
2094 Expression::SetStatement(s) => self.generate_set_statement(s),
2095
2096 Expression::Pivot(pivot) => self.generate_pivot(pivot),
2098 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
2099
2100 Expression::Values(values) => self.generate_values(values),
2102
2103
2104 Expression::AIAgg(e) => self.generate_ai_agg(e),
2106 Expression::AIClassify(e) => self.generate_ai_classify(e),
2107 Expression::AddPartition(e) => self.generate_add_partition(e),
2108 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
2109 Expression::Aliases(e) => self.generate_aliases(e),
2110 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
2111 Expression::AlterColumn(e) => self.generate_alter_column(e),
2112 Expression::AlterSession(e) => self.generate_alter_session(e),
2113 Expression::AlterSet(e) => self.generate_alter_set(e),
2114 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
2115 Expression::Analyze(e) => self.generate_analyze(e),
2116 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
2117 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
2118 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
2119 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
2120 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
2121 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
2122 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
2123 Expression::Anonymous(e) => self.generate_anonymous(e),
2124 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
2125 Expression::Apply(e) => self.generate_apply(e),
2126 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
2127 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
2128 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
2129 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
2130 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
2131 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
2132 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
2133 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
2134 Expression::ArgMax(e) => self.generate_arg_max(e),
2135 Expression::ArgMin(e) => self.generate_arg_min(e),
2136 Expression::ArrayAll(e) => self.generate_array_all(e),
2137 Expression::ArrayAny(e) => self.generate_array_any(e),
2138 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
2139 Expression::ArraySum(e) => self.generate_array_sum(e),
2140 Expression::AtIndex(e) => self.generate_at_index(e),
2141 Expression::Attach(e) => self.generate_attach(e),
2142 Expression::AttachOption(e) => self.generate_attach_option(e),
2143 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
2144 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
2145 Expression::BackupProperty(e) => self.generate_backup_property(e),
2146 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
2147 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
2148 Expression::Base64Encode(e) => self.generate_base64_encode(e),
2149 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
2150 Expression::Booland(e) => self.generate_booland(e),
2151 Expression::Boolor(e) => self.generate_boolor(e),
2152 Expression::BuildProperty(e) => self.generate_build_property(e),
2153 Expression::ByteString(e) => self.generate_byte_string(e),
2154 Expression::CaseSpecificColumnConstraint(e) => self.generate_case_specific_column_constraint(e),
2155 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
2156 Expression::Changes(e) => self.generate_changes(e),
2157 Expression::CharacterSetColumnConstraint(e) => self.generate_character_set_column_constraint(e),
2158 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
2159 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
2160 Expression::CheckJson(e) => self.generate_check_json(e),
2161 Expression::CheckXml(e) => self.generate_check_xml(e),
2162 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
2163 Expression::Clone(e) => self.generate_clone(e),
2164 Expression::ClusterBy(e) => self.generate_cluster_by(e),
2165 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
2166 Expression::CollateProperty(e) => self.generate_collate_property(e),
2167 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
2168 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
2169 Expression::ColumnPosition(e) => self.generate_column_position(e),
2170 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
2171 Expression::Columns(e) => self.generate_columns(e),
2172 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
2173 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
2174 Expression::Commit(e) => self.generate_commit(e),
2175 Expression::Comprehension(e) => self.generate_comprehension(e),
2176 Expression::Compress(e) => self.generate_compress(e),
2177 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
2178 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
2179 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
2180 Expression::Constraint(e) => self.generate_constraint(e),
2181 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
2182 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
2183 Expression::Copy(e) => self.generate_copy(e),
2184 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
2185 Expression::Corr(e) => self.generate_corr(e),
2186 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
2187 Expression::CovarPop(e) => self.generate_covar_pop(e),
2188 Expression::CovarSamp(e) => self.generate_covar_samp(e),
2189 Expression::Credentials(e) => self.generate_credentials(e),
2190 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
2191 Expression::Cte(e) => self.generate_cte(e),
2192 Expression::Cube(e) => self.generate_cube(e),
2193 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
2194 Expression::CurrentSchema(e) => self.generate_current_schema(e),
2195 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
2196 Expression::CurrentUser(e) => self.generate_current_user(e),
2197 Expression::DPipe(e) => self.generate_d_pipe(e),
2198 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
2199 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
2200 Expression::Date(e) => self.generate_date_func(e),
2201 Expression::DateBin(e) => self.generate_date_bin(e),
2202 Expression::DateFormatColumnConstraint(e) => self.generate_date_format_column_constraint(e),
2203 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
2204 Expression::Datetime(e) => self.generate_datetime(e),
2205 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
2206 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
2207 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
2208 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
2209 Expression::Dayname(e) => self.generate_dayname(e),
2210 Expression::Declare(e) => self.generate_declare(e),
2211 Expression::DeclareItem(e) => self.generate_declare_item(e),
2212 Expression::DecodeCase(e) => self.generate_decode_case(e),
2213 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
2214 Expression::DecompressString(e) => self.generate_decompress_string(e),
2215 Expression::Decrypt(e) => self.generate_decrypt(e),
2216 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
2217 Expression::DefinerProperty(e) => self.generate_definer_property(e),
2218 Expression::Detach(e) => self.generate_detach(e),
2219 Expression::DictProperty(e) => self.generate_dict_property(e),
2220 Expression::DictRange(e) => self.generate_dict_range(e),
2221 Expression::Directory(e) => self.generate_directory(e),
2222 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
2223 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
2224 Expression::DistributeBy(e) => self.generate_distribute_by(e),
2225 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
2226 Expression::DotProduct(e) => self.generate_dot_product(e),
2227 Expression::DropPartition(e) => self.generate_drop_partition(e),
2228 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
2229 Expression::Elt(e) => self.generate_elt(e),
2230 Expression::Encode(e) => self.generate_encode(e),
2231 Expression::EncodeProperty(e) => self.generate_encode_property(e),
2232 Expression::Encrypt(e) => self.generate_encrypt(e),
2233 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
2234 Expression::EngineProperty(e) => self.generate_engine_property(e),
2235 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
2236 Expression::EphemeralColumnConstraint(e) => self.generate_ephemeral_column_constraint(e),
2237 Expression::EqualNull(e) => self.generate_equal_null(e),
2238 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
2239 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
2240 Expression::Export(e) => self.generate_export(e),
2241 Expression::ExternalProperty(e) => self.generate_external_property(e),
2242 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
2243 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
2244 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
2245 Expression::Fetch(e) => self.generate_fetch(e),
2246 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
2247 Expression::Filter(e) => self.generate_filter(e),
2248 Expression::Float64(e) => self.generate_float64(e),
2249 Expression::ForIn(e) => self.generate_for_in(e),
2250 Expression::ForeignKey(e) => self.generate_foreign_key(e),
2251 Expression::Format(e) => self.generate_format(e),
2252 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
2253 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
2254 Expression::From(e) => self.generate_from(e),
2255 Expression::FromBase(e) => self.generate_from_base(e),
2256 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
2257 Expression::GapFill(e) => self.generate_gap_fill(e),
2258 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
2259 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
2260 Expression::GenerateSeries(e) => self.generate_generate_series(e),
2261 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
2262 Expression::GeneratedAsIdentityColumnConstraint(e) => self.generate_generated_as_identity_column_constraint(e),
2263 Expression::GeneratedAsRowColumnConstraint(e) => self.generate_generated_as_row_column_constraint(e),
2264 Expression::Get(e) => self.generate_get(e),
2265 Expression::GetExtract(e) => self.generate_get_extract(e),
2266 Expression::Getbit(e) => self.generate_getbit(e),
2267 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
2268 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
2269 Expression::Group(e) => self.generate_group(e),
2270 Expression::GroupBy(e) => self.generate_group_by(e),
2271 Expression::Grouping(e) => self.generate_grouping(e),
2272 Expression::GroupingId(e) => self.generate_grouping_id(e),
2273 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
2274 Expression::HashAgg(e) => self.generate_hash_agg(e),
2275 Expression::Having(e) => self.generate_having(e),
2276 Expression::HavingMax(e) => self.generate_having_max(e),
2277 Expression::Heredoc(e) => self.generate_heredoc(e),
2278 Expression::HexEncode(e) => self.generate_hex_encode(e),
2279 Expression::Hll(e) => self.generate_hll(e),
2280 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
2281 Expression::IncludeProperty(e) => self.generate_include_property(e),
2282 Expression::Index(e) => self.generate_index(e),
2283 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
2284 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
2285 Expression::IndexParameters(e) => self.generate_index_parameters(e),
2286 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
2287 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
2288 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
2289 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
2290 Expression::Install(e) => self.generate_install(e),
2291 Expression::IntervalOp(e) => self.generate_interval_op(e),
2292 Expression::IntervalSpan(e) => self.generate_interval_span(e),
2293 Expression::IntoClause(e) => self.generate_into_clause(e),
2294 Expression::Introducer(e) => self.generate_introducer(e),
2295 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
2296 Expression::JSON(e) => self.generate_json(e),
2297 Expression::JSONArray(e) => self.generate_json_array(e),
2298 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
2299 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
2300 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
2301 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
2302 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
2303 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
2304 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
2305 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
2306 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
2307 Expression::JSONExists(e) => self.generate_json_exists(e),
2308 Expression::JSONCast(e) => self.generate_json_cast(e),
2309 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
2310 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
2311 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
2312 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
2313 Expression::JSONFormat(e) => self.generate_json_format(e),
2314 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
2315 Expression::JSONKeys(e) => self.generate_json_keys(e),
2316 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
2317 Expression::JSONPath(e) => self.generate_json_path_expr(e),
2318 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
2319 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
2320 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
2321 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
2322 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
2323 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
2324 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
2325 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
2326 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
2327 Expression::JSONRemove(e) => self.generate_json_remove(e),
2328 Expression::JSONSchema(e) => self.generate_json_schema(e),
2329 Expression::JSONSet(e) => self.generate_json_set(e),
2330 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
2331 Expression::JSONTable(e) => self.generate_json_table(e),
2332 Expression::JSONType(e) => self.generate_json_type(e),
2333 Expression::JSONValue(e) => self.generate_json_value(e),
2334 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
2335 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
2336 Expression::JoinHint(e) => self.generate_join_hint(e),
2337 Expression::JournalProperty(e) => self.generate_journal_property(e),
2338 Expression::LanguageProperty(e) => self.generate_language_property(e),
2339 Expression::Lateral(e) => self.generate_lateral(e),
2340 Expression::LikeProperty(e) => self.generate_like_property(e),
2341 Expression::Limit(e) => self.generate_limit(e),
2342 Expression::LimitOptions(e) => self.generate_limit_options(e),
2343 Expression::List(e) => self.generate_list(e),
2344 Expression::ToMap(e) => self.generate_tomap(e),
2345 Expression::Localtime(e) => self.generate_localtime(e),
2346 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
2347 Expression::LocationProperty(e) => self.generate_location_property(e),
2348 Expression::Lock(e) => self.generate_lock(e),
2349 Expression::LockProperty(e) => self.generate_lock_property(e),
2350 Expression::LockingProperty(e) => self.generate_locking_property(e),
2351 Expression::LockingStatement(e) => self.generate_locking_statement(e),
2352 Expression::LogProperty(e) => self.generate_log_property(e),
2353 Expression::MD5Digest(e) => self.generate_md5_digest(e),
2354 Expression::MLForecast(e) => self.generate_ml_forecast(e),
2355 Expression::MLTranslate(e) => self.generate_ml_translate(e),
2356 Expression::MakeInterval(e) => self.generate_make_interval(e),
2357 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
2358 Expression::Map(e) => self.generate_map(e),
2359 Expression::MapCat(e) => self.generate_map_cat(e),
2360 Expression::MapDelete(e) => self.generate_map_delete(e),
2361 Expression::MapInsert(e) => self.generate_map_insert(e),
2362 Expression::MapPick(e) => self.generate_map_pick(e),
2363 Expression::MaskingPolicyColumnConstraint(e) => self.generate_masking_policy_column_constraint(e),
2364 Expression::MatchAgainst(e) => self.generate_match_against(e),
2365 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
2366 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
2367 Expression::Merge(e) => self.generate_merge(e),
2368 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
2369 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
2370 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
2371 Expression::Minhash(e) => self.generate_minhash(e),
2372 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
2373 Expression::Monthname(e) => self.generate_monthname(e),
2374 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
2375 Expression::NextValueFor(e) => self.generate_next_value_for(e),
2376 Expression::Normal(e) => self.generate_normal(e),
2377 Expression::Normalize(e) => self.generate_normalize(e),
2378 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
2379 Expression::Nullif(e) => self.generate_nullif(e),
2380 Expression::NumberToStr(e) => self.generate_number_to_str(e),
2381 Expression::ObjectAgg(e) => self.generate_object_agg(e),
2382 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
2383 Expression::ObjectInsert(e) => self.generate_object_insert(e),
2384 Expression::Offset(e) => self.generate_offset(e),
2385 Expression::Qualify(e) => self.generate_qualify(e),
2386 Expression::OnCluster(e) => self.generate_on_cluster(e),
2387 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
2388 Expression::OnCondition(e) => self.generate_on_condition(e),
2389 Expression::OnConflict(e) => self.generate_on_conflict(e),
2390 Expression::OnProperty(e) => self.generate_on_property(e),
2391 Expression::Opclass(e) => self.generate_opclass(e),
2392 Expression::OpenJSON(e) => self.generate_open_json(e),
2393 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
2394 Expression::Operator(e) => self.generate_operator(e),
2395 Expression::OrderBy(e) => self.generate_order_by(e),
2396 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
2397 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
2398 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
2399 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
2400 Expression::ParseIp(e) => self.generate_parse_ip(e),
2401 Expression::ParseJSON(e) => self.generate_parse_json(e),
2402 Expression::ParseTime(e) => self.generate_parse_time(e),
2403 Expression::ParseUrl(e) => self.generate_parse_url(e),
2404 Expression::Partition(e) => self.generate_partition_expr(e),
2405 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
2406 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
2407 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
2408 Expression::PartitionByRangePropertyDynamic(e) => self.generate_partition_by_range_property_dynamic(e),
2409 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
2410 Expression::PartitionList(e) => self.generate_partition_list(e),
2411 Expression::PartitionRange(e) => self.generate_partition_range(e),
2412 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
2413 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
2414 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
2415 Expression::PeriodForSystemTimeConstraint(e) => self.generate_period_for_system_time_constraint(e),
2416 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
2417 Expression::PivotAny(e) => self.generate_pivot_any(e),
2418 Expression::Predict(e) => self.generate_predict(e),
2419 Expression::PreviousDay(e) => self.generate_previous_day(e),
2420 Expression::PrimaryKey(e) => self.generate_primary_key(e),
2421 Expression::PrimaryKeyColumnConstraint(e) => self.generate_primary_key_column_constraint(e),
2422 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
2423 Expression::ProjectionDef(e) => self.generate_projection_def(e),
2424 Expression::Properties(e) => self.generate_properties(e),
2425 Expression::Property(e) => self.generate_property(e),
2426 Expression::PseudoType(e) => self.generate_pseudo_type(e),
2427 Expression::Put(e) => self.generate_put(e),
2428 Expression::Quantile(e) => self.generate_quantile(e),
2429 Expression::QueryBand(e) => self.generate_query_band(e),
2430 Expression::QueryOption(e) => self.generate_query_option(e),
2431 Expression::QueryTransform(e) => self.generate_query_transform(e),
2432 Expression::Randn(e) => self.generate_randn(e),
2433 Expression::Randstr(e) => self.generate_randstr(e),
2434 Expression::RangeBucket(e) => self.generate_range_bucket(e),
2435 Expression::RangeN(e) => self.generate_range_n(e),
2436 Expression::ReadCSV(e) => self.generate_read_csv(e),
2437 Expression::ReadParquet(e) => self.generate_read_parquet(e),
2438 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
2439 Expression::Reduce(e) => self.generate_reduce(e),
2440 Expression::Reference(e) => self.generate_reference(e),
2441 Expression::Refresh(e) => self.generate_refresh(e),
2442 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
2443 Expression::RegexpCount(e) => self.generate_regexp_count(e),
2444 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
2445 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
2446 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
2447 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
2448 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
2449 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
2450 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
2451 Expression::RegrCount(e) => self.generate_regr_count(e),
2452 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
2453 Expression::RegrR2(e) => self.generate_regr_r2(e),
2454 Expression::RegrSlope(e) => self.generate_regr_slope(e),
2455 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
2456 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
2457 Expression::RegrSyy(e) => self.generate_regr_syy(e),
2458 Expression::RegrValx(e) => self.generate_regr_valx(e),
2459 Expression::RegrValy(e) => self.generate_regr_valy(e),
2460 Expression::RemoteWithConnectionModelProperty(e) => self.generate_remote_with_connection_model_property(e),
2461 Expression::RenameColumn(e) => self.generate_rename_column(e),
2462 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
2463 Expression::Returning(e) => self.generate_returning(e),
2464 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
2465 Expression::Rollback(e) => self.generate_rollback(e),
2466 Expression::Rollup(e) => self.generate_rollup(e),
2467 Expression::RowFormatDelimitedProperty(e) => self.generate_row_format_delimited_property(e),
2468 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
2469 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
2470 Expression::SHA2(e) => self.generate_sha2(e),
2471 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
2472 Expression::SafeAdd(e) => self.generate_safe_add(e),
2473 Expression::SafeDivide(e) => self.generate_safe_divide(e),
2474 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
2475 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
2476 Expression::SampleProperty(e) => self.generate_sample_property(e),
2477 Expression::Schema(e) => self.generate_schema(e),
2478 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
2479 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
2480 Expression::Search(e) => self.generate_search(e),
2481 Expression::SearchIp(e) => self.generate_search_ip(e),
2482 Expression::SecurityProperty(e) => self.generate_security_property(e),
2483 Expression::SemanticView(e) => self.generate_semantic_view(e),
2484 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
2485 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
2486 Expression::SessionParameter(e) => self.generate_session_parameter(e),
2487 Expression::Set(e) => self.generate_set(e),
2488 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
2489 Expression::SetItem(e) => self.generate_set_item(e),
2490 Expression::SetOperation(e) => self.generate_set_operation(e),
2491 Expression::SetProperty(e) => self.generate_set_property(e),
2492 Expression::SettingsProperty(e) => self.generate_settings_property(e),
2493 Expression::SharingProperty(e) => self.generate_sharing_property(e),
2494 Expression::Slice(e) => self.generate_slice(e),
2495 Expression::SortArray(e) => self.generate_sort_array(e),
2496 Expression::SortBy(e) => self.generate_sort_by(e),
2497 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
2498 Expression::SplitPart(e) => self.generate_split_part(e),
2499 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
2500 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
2501 Expression::StDistance(e) => self.generate_st_distance(e),
2502 Expression::StPoint(e) => self.generate_st_point(e),
2503 Expression::StabilityProperty(e) => self.generate_stability_property(e),
2504 Expression::StandardHash(e) => self.generate_standard_hash(e),
2505 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
2506 Expression::StrPosition(e) => self.generate_str_position(e),
2507 Expression::StrToDate(e) => self.generate_str_to_date(e),
2508 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
2509 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
2510 Expression::StrToMap(e) => self.generate_str_to_map(e),
2511 Expression::StrToTime(e) => self.generate_str_to_time(e),
2512 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
2513 Expression::StringToArray(e) => self.generate_string_to_array(e),
2514 Expression::Struct(e) => self.generate_struct(e),
2515 Expression::Stuff(e) => self.generate_stuff(e),
2516 Expression::SubstringIndex(e) => self.generate_substring_index(e),
2517 Expression::Summarize(e) => self.generate_summarize(e),
2518 Expression::Systimestamp(e) => self.generate_systimestamp(e),
2519 Expression::TableAlias(e) => self.generate_table_alias(e),
2520 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
2521 Expression::RowsFrom(e) => self.generate_rows_from(e),
2522 Expression::TableSample(e) => self.generate_table_sample(e),
2523 Expression::Tag(e) => self.generate_tag(e),
2524 Expression::Tags(e) => self.generate_tags(e),
2525 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
2526 Expression::Time(e) => self.generate_time_func(e),
2527 Expression::TimeAdd(e) => self.generate_time_add(e),
2528 Expression::TimeDiff(e) => self.generate_time_diff(e),
2529 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
2530 Expression::TimeSlice(e) => self.generate_time_slice(e),
2531 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
2532 Expression::TimeSub(e) => self.generate_time_sub(e),
2533 Expression::TimeToStr(e) => self.generate_time_to_str(e),
2534 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
2535 Expression::TimeUnit(e) => self.generate_time_unit(e),
2536 Expression::Timestamp(e) => self.generate_timestamp_func(e),
2537 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
2538 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
2539 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
2540 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
2541 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
2542 Expression::ToBinary(e) => self.generate_to_binary(e),
2543 Expression::ToBoolean(e) => self.generate_to_boolean(e),
2544 Expression::ToChar(e) => self.generate_to_char(e),
2545 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
2546 Expression::ToDouble(e) => self.generate_to_double(e),
2547 Expression::ToFile(e) => self.generate_to_file(e),
2548 Expression::ToNumber(e) => self.generate_to_number(e),
2549 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
2550 Expression::Transaction(e) => self.generate_transaction(e),
2551 Expression::Transform(e) => self.generate_transform(e),
2552 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
2553 Expression::TransientProperty(e) => self.generate_transient_property(e),
2554 Expression::Translate(e) => self.generate_translate(e),
2555 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
2556 Expression::TruncateTable(e) => self.generate_truncate_table(e),
2557 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
2558 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
2559 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
2560 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
2561 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
2562 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
2563 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
2564 Expression::Unhex(e) => self.generate_unhex(e),
2565 Expression::UnicodeString(e) => self.generate_unicode_string(e),
2566 Expression::Uniform(e) => self.generate_uniform(e),
2567 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
2568 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
2569 Expression::RollupProperty(e) => self.generate_rollup_property(e),
2570 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
2571 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
2572 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
2573 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
2574 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
2575 Expression::UtcTime(e) => self.generate_utc_time(e),
2576 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
2577 Expression::Uuid(e) => self.generate_uuid(e),
2578 Expression::Var(v) => {
2579 if matches!(self.config.dialect, Some(DialectType::MySQL))
2580 && v.this.len() > 2
2581 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
2582 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
2583 {
2584 return self.generate_identifier(&Identifier {
2585 name: v.this.clone(),
2586 quoted: true,
2587 trailing_comments: Vec::new(),
2588 });
2589 }
2590 self.write(&v.this);
2591 Ok(())
2592 }
2593 Expression::VarMap(e) => self.generate_var_map(e),
2594 Expression::VectorSearch(e) => self.generate_vector_search(e),
2595 Expression::Version(e) => self.generate_version(e),
2596 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
2597 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
2598 Expression::WatermarkColumnConstraint(e) => self.generate_watermark_column_constraint(e),
2599 Expression::Week(e) => self.generate_week(e),
2600 Expression::When(e) => self.generate_when(e),
2601 Expression::Whens(e) => self.generate_whens(e),
2602 Expression::Where(e) => self.generate_where(e),
2603 Expression::WidthBucket(e) => self.generate_width_bucket(e),
2604 Expression::Window(e) => self.generate_window(e),
2605 Expression::WindowSpec(e) => self.generate_window_spec(e),
2606 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
2607 Expression::WithFill(e) => self.generate_with_fill(e),
2608 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
2609 Expression::WithOperator(e) => self.generate_with_operator(e),
2610 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
2611 Expression::WithSchemaBindingProperty(e) => self.generate_with_schema_binding_property(e),
2612 Expression::WithSystemVersioningProperty(e) => self.generate_with_system_versioning_property(e),
2613 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
2614 Expression::XMLElement(e) => self.generate_xml_element(e),
2615 Expression::XMLGet(e) => self.generate_xml_get(e),
2616 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
2617 Expression::XMLTable(e) => self.generate_xml_table(e),
2618 Expression::Xor(e) => self.generate_xor(e),
2619 Expression::Zipf(e) => self.generate_zipf(e),
2620 _ => {
2621 self.write(&format!("/* unimplemented: {:?} */", expr));
2623 Ok(())
2624 }
2625 }
2626 }
2627
2628 fn generate_select(&mut self, select: &Select) -> Result<()> {
2629 use crate::dialects::DialectType;
2630
2631 for comment in &select.leading_comments {
2633 self.write_formatted_comment(comment);
2634 self.write(" ");
2635 }
2636
2637 if let Some(with) = &select.with {
2639 self.generate_with(with)?;
2640 if self.config.pretty {
2641 self.write_newline();
2642 self.write_indent();
2643 } else {
2644 self.write_space();
2645 }
2646 }
2647
2648 for comment in &select.post_select_comments {
2651 self.write_formatted_comment(comment);
2652 self.write(" ");
2653 }
2654
2655 self.write_keyword("SELECT");
2656
2657 if let Some(hint) = &select.hint {
2659 self.generate_hint(hint)?;
2660 }
2661
2662 let use_top_from_limit = matches!(self.config.dialect, Some(DialectType::TSQL))
2666 && select.top.is_none()
2667 && select.limit.is_some()
2668 && select.offset.is_none(); let is_top_dialect = matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric));
2673
2674 if select.distinct && (is_top_dialect || select.top.is_some()) {
2675 self.write_space();
2676 self.write_keyword("DISTINCT");
2677 }
2678
2679 if is_top_dialect {
2680 if let Some(top) = &select.top {
2681 self.write_space();
2682 self.write_keyword("TOP");
2683 if top.parenthesized {
2684 self.write(" (");
2685 self.generate_expression(&top.this)?;
2686 self.write(")");
2687 } else {
2688 self.write_space();
2689 self.generate_expression(&top.this)?;
2690 }
2691 if top.percent {
2692 self.write_space();
2693 self.write_keyword("PERCENT");
2694 }
2695 if top.with_ties {
2696 self.write_space();
2697 self.write_keyword("WITH TIES");
2698 }
2699 } else if use_top_from_limit {
2700 if let Some(limit) = &select.limit {
2702 self.write_space();
2703 self.write_keyword("TOP");
2704 let is_simple_literal = matches!(&limit.this, Expression::Literal(Literal::Number(_)));
2706 if is_simple_literal {
2707 self.write_space();
2708 self.generate_expression(&limit.this)?;
2709 } else {
2710 self.write(" (");
2711 self.generate_expression(&limit.this)?;
2712 self.write(")");
2713 }
2714 }
2715 }
2716 }
2717
2718 if select.distinct && !is_top_dialect && select.top.is_none() {
2719 self.write_space();
2720 self.write_keyword("DISTINCT");
2721 }
2722
2723 if let Some(distinct_on) = &select.distinct_on {
2725 self.write_space();
2726 self.write_keyword("ON");
2727 self.write(" (");
2728 for (i, expr) in distinct_on.iter().enumerate() {
2729 if i > 0 {
2730 self.write(", ");
2731 }
2732 self.generate_expression(expr)?;
2733 }
2734 self.write(")");
2735 }
2736
2737 for modifier in &select.operation_modifiers {
2739 self.write_space();
2740 self.write_keyword(modifier);
2741 }
2742
2743 if let Some(kind) = &select.kind {
2745 self.write_space();
2746 self.write_keyword("AS");
2747 self.write_space();
2748 self.write_keyword(kind);
2749 }
2750
2751 if !select.expressions.is_empty() {
2753 if self.config.pretty {
2754 self.write_newline();
2755 self.indent_level += 1;
2756 } else {
2757 self.write_space();
2758 }
2759 }
2760
2761 for (i, expr) in select.expressions.iter().enumerate() {
2762 if i > 0 {
2763 self.write(",");
2764 if self.config.pretty {
2765 self.write_newline();
2766 } else {
2767 self.write_space();
2768 }
2769 }
2770 if self.config.pretty {
2771 self.write_indent();
2772 }
2773 self.generate_expression(expr)?;
2774 }
2775
2776 if self.config.pretty && !select.expressions.is_empty() {
2777 self.indent_level -= 1;
2778 }
2779
2780 if let Some(into) = &select.into {
2783 if self.config.pretty {
2784 self.write_newline();
2785 self.write_indent();
2786 } else {
2787 self.write_space();
2788 }
2789 if into.bulk_collect {
2790 self.write_keyword("BULK COLLECT INTO");
2791 } else {
2792 self.write_keyword("INTO");
2793 }
2794 if into.temporary {
2795 self.write_space();
2796 self.write_keyword("TEMPORARY");
2797 }
2798 if into.unlogged {
2799 self.write_space();
2800 self.write_keyword("UNLOGGED");
2801 }
2802 self.write_space();
2803 if !into.expressions.is_empty() {
2805 for (i, expr) in into.expressions.iter().enumerate() {
2806 if i > 0 {
2807 self.write(", ");
2808 }
2809 self.generate_expression(expr)?;
2810 }
2811 } else {
2812 self.generate_expression(&into.this)?;
2813 }
2814 }
2815
2816 if let Some(from) = &select.from {
2818 if self.config.pretty {
2819 self.write_newline();
2820 self.write_indent();
2821 } else {
2822 self.write_space();
2823 }
2824 self.write_keyword("FROM");
2825 self.write_space();
2826
2827 let has_tablesample = from.expressions.iter().any(|e| matches!(e, Expression::TableSample(_)));
2830 let use_cross_join = !has_tablesample && matches!(
2831 self.config.dialect,
2832 Some(DialectType::BigQuery)
2833 | Some(DialectType::Hive)
2834 | Some(DialectType::Spark)
2835 | Some(DialectType::Databricks)
2836 | Some(DialectType::SQLite)
2837 | Some(DialectType::ClickHouse)
2838 );
2839
2840 let wrap_values_in_parens = matches!(
2842 self.config.dialect,
2843 Some(DialectType::Snowflake)
2844 );
2845
2846 for (i, expr) in from.expressions.iter().enumerate() {
2847 if i > 0 {
2848 if use_cross_join {
2849 self.write(" CROSS JOIN ");
2850 } else {
2851 self.write(", ");
2852 }
2853 }
2854 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
2855 self.write("(");
2856 self.generate_expression(expr)?;
2857 self.write(")");
2858 } else {
2859 self.generate_expression(expr)?;
2860 }
2861 }
2862 }
2863
2864 for join in &select.joins {
2866 self.generate_join(join)?;
2867 }
2868
2869 for join in select.joins.iter().rev() {
2872 if join.deferred_condition {
2873 self.generate_join_condition(join)?;
2874 }
2875 }
2876
2877 for lateral_view in &select.lateral_views {
2879 self.generate_lateral_view(lateral_view)?;
2880 }
2881
2882 if let Some(prewhere) = &select.prewhere {
2884 self.write_clause_condition("PREWHERE", prewhere)?;
2885 }
2886
2887 if let Some(where_clause) = &select.where_clause {
2889 self.write_clause_condition("WHERE", &where_clause.this)?;
2890 }
2891
2892 if let Some(connect) = &select.connect {
2894 self.generate_connect(connect)?;
2895 }
2896
2897 if let Some(group_by) = &select.group_by {
2899 if self.config.pretty {
2900 self.write_newline();
2901 self.write_indent();
2902 } else {
2903 self.write_space();
2904 }
2905 self.write_keyword("GROUP BY");
2906 match group_by.all {
2908 Some(true) => {
2909 self.write_space();
2910 self.write_keyword("ALL");
2911 }
2912 Some(false) => {
2913 self.write_space();
2914 self.write_keyword("DISTINCT");
2915 }
2916 None => {}
2917 }
2918 if !group_by.expressions.is_empty() {
2919 let mut trailing_cube = false;
2922 let mut trailing_rollup = false;
2923 let mut plain_expressions: Vec<&Expression> = Vec::new();
2924 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
2925 let mut cube_expressions: Vec<&Expression> = Vec::new();
2926 let mut rollup_expressions: Vec<&Expression> = Vec::new();
2927
2928 for expr in &group_by.expressions {
2929 match expr {
2930 Expression::Cube(c) if c.expressions.is_empty() => {
2931 trailing_cube = true;
2932 }
2933 Expression::Rollup(r) if r.expressions.is_empty() => {
2934 trailing_rollup = true;
2935 }
2936 Expression::Function(f) if f.name == "CUBE" => {
2937 cube_expressions.push(expr);
2938 }
2939 Expression::Function(f) if f.name == "ROLLUP" => {
2940 rollup_expressions.push(expr);
2941 }
2942 Expression::Function(f) if f.name == "GROUPING SETS" => {
2943 grouping_sets_expressions.push(expr);
2944 }
2945 _ => {
2946 plain_expressions.push(expr);
2947 }
2948 }
2949 }
2950
2951 let mut regular_expressions: Vec<&Expression> = Vec::new();
2953 regular_expressions.extend(plain_expressions);
2954 regular_expressions.extend(grouping_sets_expressions);
2955 regular_expressions.extend(cube_expressions);
2956 regular_expressions.extend(rollup_expressions);
2957
2958 if self.config.pretty {
2959 self.write_newline();
2960 self.indent_level += 1;
2961 self.write_indent();
2962 } else {
2963 self.write_space();
2964 }
2965
2966 for (i, expr) in regular_expressions.iter().enumerate() {
2967 if i > 0 {
2968 self.write(", ");
2969 }
2970 self.generate_expression(expr)?;
2971 }
2972
2973 if self.config.pretty {
2974 self.indent_level -= 1;
2975 }
2976
2977 if trailing_cube {
2979 self.write_space();
2980 self.write_keyword("WITH CUBE");
2981 } else if trailing_rollup {
2982 self.write_space();
2983 self.write_keyword("WITH ROLLUP");
2984 }
2985 }
2986
2987 if group_by.totals {
2989 self.write_space();
2990 self.write_keyword("WITH TOTALS");
2991 }
2992 }
2993
2994 if let Some(having) = &select.having {
2996 self.write_clause_condition("HAVING", &having.this)?;
2997 }
2998
2999 if select.qualify_after_window {
3001 if let Some(windows) = &select.windows {
3003 self.write_window_clause(windows)?;
3004 }
3005 if let Some(qualify) = &select.qualify {
3006 self.write_clause_condition("QUALIFY", &qualify.this)?;
3007 }
3008 } else {
3009 if let Some(qualify) = &select.qualify {
3011 self.write_clause_condition("QUALIFY", &qualify.this)?;
3012 }
3013 if let Some(windows) = &select.windows {
3014 self.write_window_clause(windows)?;
3015 }
3016 }
3017
3018 if let Some(distribute_by) = &select.distribute_by {
3020 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
3021 }
3022
3023 if let Some(cluster_by) = &select.cluster_by {
3025 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
3026 }
3027
3028 if let Some(sort_by) = &select.sort_by {
3030 self.write_order_clause("SORT BY", &sort_by.expressions)?;
3031 }
3032
3033 if let Some(order_by) = &select.order_by {
3035 let keyword = if order_by.siblings { "ORDER SIBLINGS BY" } else { "ORDER BY" };
3036 self.write_order_clause(keyword, &order_by.expressions)?;
3037 }
3038
3039 if select.order_by.is_none() && select.fetch.is_some()
3041 && matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric))
3042 {
3043 if self.config.pretty {
3044 self.write_newline();
3045 self.write_indent();
3046 } else {
3047 self.write_space();
3048 }
3049 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
3050 }
3051
3052 let is_presto_like = matches!(
3057 self.config.dialect,
3058 Some(DialectType::Presto) | Some(DialectType::Trino)
3059 );
3060
3061 if is_presto_like && select.offset.is_some() {
3062 if let Some(offset) = &select.offset {
3064 if self.config.pretty {
3065 self.write_newline();
3066 self.write_indent();
3067 } else {
3068 self.write_space();
3069 }
3070 self.write_keyword("OFFSET");
3071 self.write_space();
3072 self.write_limit_expr(&offset.this)?;
3073 if offset.rows == Some(true) {
3074 self.write_space();
3075 self.write_keyword("ROWS");
3076 }
3077 }
3078 if let Some(limit) = &select.limit {
3079 if self.config.pretty {
3080 self.write_newline();
3081 self.write_indent();
3082 } else {
3083 self.write_space();
3084 }
3085 self.write_keyword("LIMIT");
3086 self.write_space();
3087 self.write_limit_expr(&limit.this)?;
3088 if limit.percent {
3089 self.write_space();
3090 self.write_keyword("PERCENT");
3091 }
3092 }
3093 } else {
3094 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
3096 !fetch.percent && !fetch.with_ties && fetch.count.is_some() && matches!(
3097 self.config.dialect,
3098 Some(DialectType::Spark) | Some(DialectType::Hive)
3099 | Some(DialectType::DuckDB) | Some(DialectType::SQLite) | Some(DialectType::MySQL)
3100 | Some(DialectType::BigQuery) | Some(DialectType::Databricks) | Some(DialectType::StarRocks)
3101 | Some(DialectType::Doris) | Some(DialectType::Athena) | Some(DialectType::ClickHouse)
3102 | Some(DialectType::Redshift)
3103 )
3104 });
3105
3106 if let Some(limit) = &select.limit {
3108 if !matches!(self.config.dialect, Some(DialectType::TSQL)) {
3110 if self.config.pretty {
3111 self.write_newline();
3112 self.write_indent();
3113 } else {
3114 self.write_space();
3115 }
3116 self.write_keyword("LIMIT");
3117 self.write_space();
3118 self.write_limit_expr(&limit.this)?;
3119 if limit.percent {
3120 self.write_space();
3121 self.write_keyword("PERCENT");
3122 }
3123 }
3124 }
3125
3126 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
3128 if let Some(top) = &select.top {
3129 if !top.percent && !top.with_ties {
3130 if self.config.pretty {
3131 self.write_newline();
3132 self.write_indent();
3133 } else {
3134 self.write_space();
3135 }
3136 self.write_keyword("LIMIT");
3137 self.write_space();
3138 self.generate_expression(&top.this)?;
3139 }
3140 }
3141 }
3142
3143 if fetch_as_limit && select.offset.is_some() {
3146 if let Some(fetch) = &select.fetch {
3147 if self.config.pretty {
3148 self.write_newline();
3149 self.write_indent();
3150 } else {
3151 self.write_space();
3152 }
3153 self.write_keyword("LIMIT");
3154 self.write_space();
3155 self.generate_expression(fetch.count.as_ref().unwrap())?;
3156 }
3157 }
3158
3159 if let Some(offset) = &select.offset {
3163 if self.config.pretty {
3164 self.write_newline();
3165 self.write_indent();
3166 } else {
3167 self.write_space();
3168 }
3169 if matches!(self.config.dialect, Some(DialectType::TSQL)) {
3170 self.write_keyword("OFFSET");
3172 self.write_space();
3173 self.write_limit_expr(&offset.this)?;
3174 self.write_space();
3175 self.write_keyword("ROWS");
3176 if let Some(limit) = &select.limit {
3178 self.write_space();
3179 self.write_keyword("FETCH NEXT");
3180 self.write_space();
3181 self.write_limit_expr(&limit.this)?;
3182 self.write_space();
3183 self.write_keyword("ROWS ONLY");
3184 }
3185 } else {
3186 self.write_keyword("OFFSET");
3187 self.write_space();
3188 self.write_limit_expr(&offset.this)?;
3189 if offset.rows == Some(true) {
3191 self.write_space();
3192 self.write_keyword("ROWS");
3193 }
3194 }
3195 }
3196 }
3197
3198 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
3200 if let Some(limit_by) = &select.limit_by {
3201 if !limit_by.is_empty() {
3202 self.write_space();
3203 self.write_keyword("BY");
3204 self.write_space();
3205 for (i, expr) in limit_by.iter().enumerate() {
3206 if i > 0 {
3207 self.write(", ");
3208 }
3209 self.generate_expression(expr)?;
3210 }
3211 }
3212 }
3213 }
3214
3215 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
3217 if let Some(settings) = &select.settings {
3218 if self.config.pretty {
3219 self.write_newline();
3220 self.write_indent();
3221 } else {
3222 self.write_space();
3223 }
3224 self.write_keyword("SETTINGS");
3225 self.write_space();
3226 for (i, expr) in settings.iter().enumerate() {
3227 if i > 0 {
3228 self.write(", ");
3229 }
3230 self.generate_expression(expr)?;
3231 }
3232 }
3233
3234 if let Some(format_expr) = &select.format {
3235 if self.config.pretty {
3236 self.write_newline();
3237 self.write_indent();
3238 } else {
3239 self.write_space();
3240 }
3241 self.write_keyword("FORMAT");
3242 self.write_space();
3243 self.generate_expression(format_expr)?;
3244 }
3245 }
3246
3247 if let Some(fetch) = &select.fetch {
3249 let fetch_already_as_limit = select.offset.is_some() && !fetch.percent && !fetch.with_ties && fetch.count.is_some() && matches!(
3251 self.config.dialect,
3252 Some(DialectType::Spark) | Some(DialectType::Hive)
3253 | Some(DialectType::DuckDB) | Some(DialectType::SQLite) | Some(DialectType::MySQL)
3254 | Some(DialectType::BigQuery) | Some(DialectType::Databricks) | Some(DialectType::StarRocks)
3255 | Some(DialectType::Doris) | Some(DialectType::Athena) | Some(DialectType::ClickHouse)
3256 | Some(DialectType::Redshift)
3257 );
3258
3259 if fetch_already_as_limit {
3260 } else {
3262 if self.config.pretty {
3263 self.write_newline();
3264 self.write_indent();
3265 } else {
3266 self.write_space();
3267 }
3268
3269 let use_limit = !fetch.percent && !fetch.with_ties && fetch.count.is_some() && matches!(
3271 self.config.dialect,
3272 Some(DialectType::Spark) | Some(DialectType::Hive)
3273 | Some(DialectType::DuckDB) | Some(DialectType::SQLite) | Some(DialectType::MySQL)
3274 | Some(DialectType::BigQuery) | Some(DialectType::Databricks) | Some(DialectType::StarRocks)
3275 | Some(DialectType::Doris) | Some(DialectType::Athena) | Some(DialectType::ClickHouse)
3276 | Some(DialectType::Redshift)
3277 );
3278
3279 if use_limit {
3280 self.write_keyword("LIMIT");
3281 self.write_space();
3282 self.generate_expression(fetch.count.as_ref().unwrap())?;
3283 } else {
3284 self.write_keyword("FETCH");
3285 self.write_space();
3286 self.write_keyword(&fetch.direction);
3287 if let Some(ref count) = fetch.count {
3288 self.write_space();
3289 self.generate_expression(count)?;
3290 }
3291 if fetch.percent {
3292 self.write_space();
3293 self.write_keyword("PERCENT");
3294 }
3295 if fetch.rows {
3296 self.write_space();
3297 self.write_keyword("ROWS");
3298 }
3299 if fetch.with_ties {
3300 self.write_space();
3301 self.write_keyword("WITH TIES");
3302 } else {
3303 self.write_space();
3304 self.write_keyword("ONLY");
3305 }
3306 }
3307 } }
3309
3310 if let Some(sample) = &select.sample {
3312 use crate::dialects::DialectType;
3313 if self.config.pretty {
3314 self.write_newline();
3315 } else {
3316 self.write_space();
3317 }
3318
3319 if sample.is_using_sample {
3320 self.write_keyword("USING SAMPLE");
3322 self.generate_sample_body(sample)?;
3323 } else {
3324 self.write_keyword("TABLESAMPLE");
3325
3326 let snowflake_bernoulli = matches!(self.config.dialect, Some(DialectType::Snowflake)) && !sample.explicit_method;
3328 if snowflake_bernoulli {
3329 self.write_space();
3330 self.write_keyword("BERNOULLI");
3331 }
3332
3333 if matches!(sample.method, SampleMethod::Bucket) {
3335 self.write_space();
3336 self.write("(");
3337 self.write_keyword("BUCKET");
3338 self.write_space();
3339 if let Some(ref num) = sample.bucket_numerator {
3340 self.generate_expression(num)?;
3341 }
3342 self.write_space();
3343 self.write_keyword("OUT OF");
3344 self.write_space();
3345 if let Some(ref denom) = sample.bucket_denominator {
3346 self.generate_expression(denom)?;
3347 }
3348 if let Some(ref field) = sample.bucket_field {
3349 self.write_space();
3350 self.write_keyword("ON");
3351 self.write_space();
3352 self.generate_expression(field)?;
3353 }
3354 self.write(")");
3355 } else if sample.unit_after_size {
3356 if sample.explicit_method && sample.method_before_size {
3358 self.write_space();
3359 match sample.method {
3360 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
3361 SampleMethod::System => self.write_keyword("SYSTEM"),
3362 SampleMethod::Block => self.write_keyword("BLOCK"),
3363 SampleMethod::Row => self.write_keyword("ROW"),
3364 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
3365 _ => {}
3366 }
3367 }
3368 self.write(" (");
3369 self.generate_expression(&sample.size)?;
3370 self.write_space();
3371 match sample.method {
3372 SampleMethod::Percent => self.write_keyword("PERCENT"),
3373 SampleMethod::Row => self.write_keyword("ROWS"),
3374 SampleMethod::Reservoir => self.write_keyword("ROWS"),
3375 _ => {
3376 self.write_keyword("PERCENT");
3377 }
3378 }
3379 self.write(")");
3380 } else {
3381 self.write_space();
3383 match sample.method {
3384 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
3385 SampleMethod::System => self.write_keyword("SYSTEM"),
3386 SampleMethod::Block => self.write_keyword("BLOCK"),
3387 SampleMethod::Row => self.write_keyword("ROW"),
3388 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
3389 SampleMethod::Bucket => {}
3390 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
3391 }
3392 self.write(" (");
3393 self.generate_expression(&sample.size)?;
3394 if matches!(sample.method, SampleMethod::Percent) {
3395 self.write_space();
3396 self.write_keyword("PERCENT");
3397 }
3398 self.write(")");
3399 }
3400 }
3401
3402 if let Some(seed) = &sample.seed {
3403 self.write_space();
3404 let use_seed = sample.use_seed_keyword
3406 && !matches!(self.config.dialect, Some(crate::dialects::DialectType::Databricks) | Some(crate::dialects::DialectType::Spark));
3407 if use_seed {
3408 self.write_keyword("SEED");
3409 } else {
3410 self.write_keyword("REPEATABLE");
3411 }
3412 self.write(" (");
3413 self.generate_expression(seed)?;
3414 self.write(")");
3415 }
3416 }
3417
3418 if self.config.locking_reads_supported {
3421 for lock in &select.locks {
3422 if self.config.pretty {
3423 self.write_newline();
3424 self.write_indent();
3425 } else {
3426 self.write_space();
3427 }
3428 self.generate_lock(lock)?;
3429 }
3430 }
3431
3432 if !select.for_xml.is_empty() {
3434 if self.config.pretty {
3435 self.write_newline();
3436 self.write_indent();
3437 } else {
3438 self.write_space();
3439 }
3440 self.write_keyword("FOR XML");
3441 for (i, opt) in select.for_xml.iter().enumerate() {
3442 if self.config.pretty {
3443 if i > 0 {
3444 self.write(",");
3445 }
3446 self.write_newline();
3447 self.write_indent();
3448 self.write(" "); } else {
3450 if i > 0 {
3451 self.write(",");
3452 }
3453 self.write_space();
3454 }
3455 self.generate_for_xml_option(opt)?;
3456 }
3457 }
3458
3459 if let Some(ref option) = select.option {
3461 if matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL) | Some(crate::dialects::DialectType::Fabric)) {
3462 self.write_space();
3463 self.write(option);
3464 }
3465 }
3466
3467 Ok(())
3468 }
3469
3470 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
3472 match opt {
3473 Expression::QueryOption(qo) => {
3474 if let Expression::Var(var) = &*qo.this {
3476 self.write(&var.this);
3477 } else {
3478 self.generate_expression(&qo.this)?;
3479 }
3480 if let Some(expr) = &qo.expression {
3482 self.write("(");
3483 self.generate_expression(expr)?;
3484 self.write(")");
3485 }
3486 }
3487 _ => {
3488 self.generate_expression(opt)?;
3489 }
3490 }
3491 Ok(())
3492 }
3493
3494 fn generate_with(&mut self, with: &With) -> Result<()> {
3495 use crate::dialects::DialectType;
3496
3497 for comment in &with.leading_comments {
3499 self.write(comment);
3500 self.write(" ");
3501 }
3502 self.write_keyword("WITH");
3503 if with.recursive {
3504 self.write_space();
3505 self.write_keyword("RECURSIVE");
3506 }
3507 self.write_space();
3508
3509 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
3511
3512 for (i, cte) in with.ctes.iter().enumerate() {
3513 if i > 0 {
3514 self.write(",");
3515 if self.config.pretty {
3516 self.write_space();
3517 } else {
3518 self.write(" ");
3519 }
3520 }
3521 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
3522 self.generate_expression(&cte.this)?;
3523 self.write_space();
3524 self.write_keyword("AS");
3525 self.write_space();
3526 self.generate_identifier(&cte.alias)?;
3527 continue;
3528 }
3529 self.generate_identifier(&cte.alias)?;
3530 if !cte.columns.is_empty() && !skip_cte_columns {
3531 self.write("(");
3532 for (j, col) in cte.columns.iter().enumerate() {
3533 if j > 0 {
3534 self.write(", ");
3535 }
3536 self.generate_identifier(col)?;
3537 }
3538 self.write(")");
3539 }
3540 if !cte.key_expressions.is_empty() {
3542 self.write_space();
3543 self.write_keyword("USING KEY");
3544 self.write(" (");
3545 for (i, key) in cte.key_expressions.iter().enumerate() {
3546 if i > 0 {
3547 self.write(", ");
3548 }
3549 self.generate_identifier(key)?;
3550 }
3551 self.write(")");
3552 }
3553 self.write_space();
3554 self.write_keyword("AS");
3555 if let Some(materialized) = cte.materialized {
3557 self.write_space();
3558 if materialized {
3559 self.write_keyword("MATERIALIZED");
3560 } else {
3561 self.write_keyword("NOT MATERIALIZED");
3562 }
3563 }
3564 self.write(" (");
3565 if self.config.pretty {
3566 self.write_newline();
3567 self.indent_level += 1;
3568 self.write_indent();
3569 }
3570 let wrap_values_in_select = matches!(
3573 self.config.dialect,
3574 Some(DialectType::Spark) | Some(DialectType::Databricks)
3575 ) && matches!(&cte.this, Expression::Values(_));
3576
3577 if wrap_values_in_select {
3578 self.write_keyword("SELECT");
3579 self.write(" * ");
3580 self.write_keyword("FROM");
3581 self.write_space();
3582 }
3583 self.generate_expression(&cte.this)?;
3584 if self.config.pretty {
3585 self.write_newline();
3586 self.indent_level -= 1;
3587 self.write_indent();
3588 }
3589 self.write(")");
3590 }
3591
3592 if let Some(search) = &with.search {
3594 self.write_space();
3595 self.generate_expression(search)?;
3596 }
3597
3598 Ok(())
3599 }
3600
3601 fn generate_join(&mut self, join: &Join) -> Result<()> {
3602 if join.kind == JoinKind::Implicit {
3604 self.write(",");
3605 if self.config.pretty {
3606 self.write_newline();
3607 self.write_indent();
3608 } else {
3609 self.write_space();
3610 }
3611 self.generate_expression(&join.this)?;
3612 return Ok(());
3613 }
3614
3615 if self.config.pretty {
3616 self.write_newline();
3617 self.write_indent();
3618 } else {
3619 self.write_space();
3620 }
3621
3622 let hint_str = if self.config.join_hints {
3625 join.join_hint.as_ref().map(|h| format!(" {}", h)).unwrap_or_default()
3626 } else {
3627 String::new()
3628 };
3629
3630 let clickhouse_join_keyword = if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
3631 if let Some(hint) = &join.join_hint {
3632 let mut global = false;
3633 let mut strictness: Option<&'static str> = None;
3634 for part in hint.split_whitespace() {
3635 match part.to_uppercase().as_str() {
3636 "GLOBAL" => global = true,
3637 "ANY" => strictness = Some("ANY"),
3638 "ASOF" => strictness = Some("ASOF"),
3639 "SEMI" => strictness = Some("SEMI"),
3640 "ANTI" => strictness = Some("ANTI"),
3641 _ => {}
3642 }
3643 }
3644
3645 if global || strictness.is_some() {
3646 let join_type = match join.kind {
3647 JoinKind::Left => {
3648 if join.use_outer_keyword {
3649 "LEFT OUTER"
3650 } else if join.use_inner_keyword {
3651 "LEFT INNER"
3652 } else {
3653 "LEFT"
3654 }
3655 }
3656 JoinKind::Right => {
3657 if join.use_outer_keyword {
3658 "RIGHT OUTER"
3659 } else if join.use_inner_keyword {
3660 "RIGHT INNER"
3661 } else {
3662 "RIGHT"
3663 }
3664 }
3665 JoinKind::Full => {
3666 if join.use_outer_keyword {
3667 "FULL OUTER"
3668 } else {
3669 "FULL"
3670 }
3671 }
3672 JoinKind::Inner => {
3673 if join.use_inner_keyword {
3674 "INNER"
3675 } else {
3676 ""
3677 }
3678 }
3679 _ => "",
3680 };
3681
3682 let mut parts = Vec::new();
3683 if global {
3684 parts.push("GLOBAL");
3685 }
3686 if !join_type.is_empty() {
3687 parts.push(join_type);
3688 }
3689 if let Some(strict) = strictness {
3690 parts.push(strict);
3691 }
3692 parts.push("JOIN");
3693 Some(parts.join(" "))
3694 } else {
3695 None
3696 }
3697 } else {
3698 None
3699 }
3700 } else {
3701 None
3702 };
3703
3704 if let Some(keyword) = clickhouse_join_keyword {
3705 self.write_keyword(&keyword);
3706 } else {
3707 match join.kind {
3708 JoinKind::Inner => {
3709 if join.use_inner_keyword {
3710 self.write_keyword(&format!("INNER{} JOIN", hint_str));
3711 } else {
3712 self.write_keyword(&format!("{}JOIN", if hint_str.is_empty() { String::new() } else { format!("{} ", hint_str.trim()) }));
3713 }
3714 }
3715 JoinKind::Left => {
3716 if join.use_outer_keyword {
3717 self.write_keyword(&format!("LEFT OUTER{} JOIN", hint_str));
3718 } else if join.use_inner_keyword {
3719 self.write_keyword(&format!("LEFT INNER{} JOIN", hint_str));
3720 } else {
3721 self.write_keyword(&format!("LEFT{} JOIN", hint_str));
3722 }
3723 }
3724 JoinKind::Right => {
3725 if join.use_outer_keyword {
3726 self.write_keyword(&format!("RIGHT OUTER{} JOIN", hint_str));
3727 } else if join.use_inner_keyword {
3728 self.write_keyword(&format!("RIGHT INNER{} JOIN", hint_str));
3729 } else {
3730 self.write_keyword(&format!("RIGHT{} JOIN", hint_str));
3731 }
3732 }
3733 JoinKind::Full => {
3734 if join.use_outer_keyword {
3735 self.write_keyword(&format!("FULL OUTER{} JOIN", hint_str));
3736 } else {
3737 self.write_keyword(&format!("FULL{} JOIN", hint_str));
3738 }
3739 }
3740 JoinKind::Outer => self.write_keyword("OUTER JOIN"),
3741 JoinKind::Cross => self.write_keyword("CROSS JOIN"),
3742 JoinKind::Natural => self.write_keyword("NATURAL JOIN"),
3743 JoinKind::NaturalLeft => {
3744 if join.use_outer_keyword {
3745 self.write_keyword("NATURAL LEFT OUTER JOIN");
3746 } else {
3747 self.write_keyword("NATURAL LEFT JOIN");
3748 }
3749 }
3750 JoinKind::NaturalRight => {
3751 if join.use_outer_keyword {
3752 self.write_keyword("NATURAL RIGHT OUTER JOIN");
3753 } else {
3754 self.write_keyword("NATURAL RIGHT JOIN");
3755 }
3756 }
3757 JoinKind::NaturalFull => {
3758 if join.use_outer_keyword {
3759 self.write_keyword("NATURAL FULL OUTER JOIN");
3760 } else {
3761 self.write_keyword("NATURAL FULL JOIN");
3762 }
3763 }
3764 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
3765 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
3766 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
3767 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
3768 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
3769 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
3770 JoinKind::CrossApply => {
3771 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
3773 self.write_keyword("CROSS APPLY");
3774 } else {
3775 self.write_keyword("INNER JOIN LATERAL");
3776 }
3777 }
3778 JoinKind::OuterApply => {
3779 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
3781 self.write_keyword("OUTER APPLY");
3782 } else {
3783 self.write_keyword("LEFT JOIN LATERAL");
3784 }
3785 }
3786 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
3787 JoinKind::AsOfLeft => {
3788 if join.use_outer_keyword {
3789 self.write_keyword("ASOF LEFT OUTER JOIN");
3790 } else {
3791 self.write_keyword("ASOF LEFT JOIN");
3792 }
3793 }
3794 JoinKind::AsOfRight => {
3795 if join.use_outer_keyword {
3796 self.write_keyword("ASOF RIGHT OUTER JOIN");
3797 } else {
3798 self.write_keyword("ASOF RIGHT JOIN");
3799 }
3800 }
3801 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
3802 JoinKind::LeftLateral => {
3803 if join.use_outer_keyword {
3804 self.write_keyword("LEFT OUTER LATERAL JOIN");
3805 } else {
3806 self.write_keyword("LEFT LATERAL JOIN");
3807 }
3808 }
3809 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
3810 JoinKind::Implicit => {
3811 use crate::dialects::DialectType;
3813 if matches!(self.config.dialect, Some(DialectType::BigQuery) | Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)) {
3814 self.write_keyword("CROSS JOIN");
3815 } else {
3816 self.output.truncate(self.output.trim_end().len());
3820 self.write(",");
3821 }
3822 }
3823 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
3824 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
3825 }
3826 }
3827
3828 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
3830 self.write_space();
3831 match &join.this {
3832 Expression::Tuple(t) => {
3833 for (i, item) in t.expressions.iter().enumerate() {
3834 if i > 0 {
3835 self.write(", ");
3836 }
3837 self.generate_expression(item)?;
3838 }
3839 }
3840 other => {
3841 self.generate_expression(other)?;
3842 }
3843 }
3844 } else {
3845 self.write_space();
3846 self.generate_expression(&join.this)?;
3847 }
3848
3849 if !join.deferred_condition {
3851 if let Some(match_cond) = &join.match_condition {
3853 self.write_space();
3854 self.write_keyword("MATCH_CONDITION");
3855 self.write(" (");
3856 self.generate_expression(match_cond)?;
3857 self.write(")");
3858 }
3859
3860 if let Some(on) = &join.on {
3861 if self.config.pretty {
3862 self.write_newline();
3863 self.indent_level += 1;
3864 self.write_indent();
3865 self.write_keyword("ON");
3866 self.write_space();
3867 self.generate_join_on_condition(on)?;
3868 self.indent_level -= 1;
3869 } else {
3870 self.write_space();
3871 self.write_keyword("ON");
3872 self.write_space();
3873 self.generate_expression(on)?;
3874 }
3875 }
3876
3877 if !join.using.is_empty() {
3878 if self.config.pretty {
3879 self.write_newline();
3880 self.indent_level += 1;
3881 self.write_indent();
3882 self.write_keyword("USING");
3883 self.write(" (");
3884 for (i, col) in join.using.iter().enumerate() {
3885 if i > 0 {
3886 self.write(", ");
3887 }
3888 self.generate_identifier(col)?;
3889 }
3890 self.write(")");
3891 self.indent_level -= 1;
3892 } else {
3893 self.write_space();
3894 self.write_keyword("USING");
3895 self.write(" (");
3896 for (i, col) in join.using.iter().enumerate() {
3897 if i > 0 {
3898 self.write(", ");
3899 }
3900 self.generate_identifier(col)?;
3901 }
3902 self.write(")");
3903 }
3904 }
3905 }
3906
3907 for pivot in &join.pivots {
3909 self.write_space();
3910 self.generate_expression(pivot)?;
3911 }
3912
3913 Ok(())
3914 }
3915
3916 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
3918 if let Some(match_cond) = &join.match_condition {
3920 self.write_space();
3921 self.write_keyword("MATCH_CONDITION");
3922 self.write(" (");
3923 self.generate_expression(match_cond)?;
3924 self.write(")");
3925 }
3926
3927 if let Some(on) = &join.on {
3928 if self.config.pretty {
3929 self.write_newline();
3930 self.indent_level += 1;
3931 self.write_indent();
3932 self.write_keyword("ON");
3933 self.write_space();
3934 self.generate_join_on_condition(on)?;
3936 self.indent_level -= 1;
3937 } else {
3938 self.write_space();
3939 self.write_keyword("ON");
3940 self.write_space();
3941 self.generate_expression(on)?;
3942 }
3943 }
3944
3945 if !join.using.is_empty() {
3946 if self.config.pretty {
3947 self.write_newline();
3948 self.indent_level += 1;
3949 self.write_indent();
3950 self.write_keyword("USING");
3951 self.write(" (");
3952 for (i, col) in join.using.iter().enumerate() {
3953 if i > 0 {
3954 self.write(", ");
3955 }
3956 self.generate_identifier(col)?;
3957 }
3958 self.write(")");
3959 self.indent_level -= 1;
3960 } else {
3961 self.write_space();
3962 self.write_keyword("USING");
3963 self.write(" (");
3964 for (i, col) in join.using.iter().enumerate() {
3965 if i > 0 {
3966 self.write(", ");
3967 }
3968 self.generate_identifier(col)?;
3969 }
3970 self.write(")");
3971 }
3972 }
3973
3974 for pivot in &join.pivots {
3976 self.write_space();
3977 self.generate_expression(pivot)?;
3978 }
3979
3980 Ok(())
3981 }
3982
3983 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
3985 if let Expression::And(and_op) = expr {
3987 self.generate_join_on_condition(&and_op.left)?;
3989 self.write_newline();
3991 self.write_indent();
3992 self.write_keyword("AND");
3993 self.write_space();
3994 self.generate_expression(&and_op.right)?;
3996 } else {
3997 self.generate_expression(expr)?;
3999 }
4000 Ok(())
4001 }
4002
4003 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
4004 self.write("(");
4006 self.generate_expression(&jt.left)?;
4007
4008 for join in &jt.joins {
4010 self.generate_join(join)?;
4011 }
4012
4013 for lv in &jt.lateral_views {
4015 self.generate_lateral_view(lv)?;
4016 }
4017
4018 self.write(")");
4019
4020 if let Some(alias) = &jt.alias {
4022 self.write_space();
4023 self.write_keyword("AS");
4024 self.write_space();
4025 self.generate_identifier(alias)?;
4026 }
4027
4028 Ok(())
4029 }
4030
4031 fn generate_lateral_view(&mut self, lv: &LateralView) -> Result<()> {
4032 use crate::dialects::DialectType;
4033
4034 if self.config.pretty {
4035 self.write_newline();
4036 self.write_indent();
4037 } else {
4038 self.write_space();
4039 }
4040
4041 let use_lateral_join = matches!(
4044 self.config.dialect,
4045 Some(DialectType::PostgreSQL) | Some(DialectType::DuckDB) |
4046 Some(DialectType::Snowflake) | Some(DialectType::TSQL) |
4047 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
4048 );
4049
4050 let use_unnest = matches!(
4052 self.config.dialect,
4053 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
4054 );
4055
4056 let (is_posexplode, func_args) = match &lv.this {
4058 Expression::Explode(uf) => {
4059 (false, vec![uf.this.clone()])
4061 }
4062 Expression::Function(func) => {
4063 let name = func.name.to_uppercase();
4064 if name == "POSEXPLODE" || name == "POSEXPLODE_OUTER" {
4065 (true, func.args.clone())
4066 } else if name == "EXPLODE" || name == "EXPLODE_OUTER" || name == "INLINE" {
4067 (false, func.args.clone())
4068 } else {
4069 (false, vec![])
4070 }
4071 }
4072 _ => (false, vec![]),
4073 };
4074
4075 if use_lateral_join {
4076 if lv.outer {
4078 self.write_keyword("LEFT JOIN LATERAL");
4079 } else {
4080 self.write_keyword("CROSS JOIN");
4081 }
4082 self.write_space();
4083
4084 if use_unnest && !func_args.is_empty() {
4085 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
4088 func_args.iter().map(|a| {
4090 if let Expression::Function(ref f) = a {
4091 if f.name.to_uppercase() == "ARRAY" && f.args.len() == 1 {
4092 return Expression::ArrayFunc(Box::new(crate::expressions::ArrayConstructor {
4093 expressions: f.args.clone(),
4094 bracket_notation: true,
4095 use_list_keyword: false,
4096 }));
4097 }
4098 }
4099 a.clone()
4100 }).collect::<Vec<_>>()
4101 } else if matches!(self.config.dialect, Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)) {
4102 func_args.iter().map(|a| {
4104 if let Expression::Function(ref f) = a {
4105 if f.name.to_uppercase() == "ARRAY" && f.args.len() >= 1 {
4106 return Expression::ArrayFunc(Box::new(crate::expressions::ArrayConstructor {
4107 expressions: f.args.clone(),
4108 bracket_notation: true,
4109 use_list_keyword: false,
4110 }));
4111 }
4112 }
4113 a.clone()
4114 }).collect::<Vec<_>>()
4115 } else {
4116 func_args
4117 };
4118
4119 self.write_keyword("UNNEST");
4120 self.write("(");
4121 for (i, arg) in unnest_args.iter().enumerate() {
4122 if i > 0 { self.write(", "); }
4123 self.generate_expression(arg)?;
4124 }
4125 self.write(")");
4126
4127 if is_posexplode {
4129 self.write_space();
4130 self.write_keyword("WITH ORDINALITY");
4131 }
4132 } else {
4133 if !lv.outer {
4135 self.write_keyword("LATERAL");
4136 self.write_space();
4137 }
4138 self.generate_expression(&lv.this)?;
4139 }
4140
4141 if let Some(alias) = &lv.table_alias {
4143 self.write_space();
4144 self.write_keyword("AS");
4145 self.write_space();
4146 self.generate_identifier(alias)?;
4147 if !lv.column_aliases.is_empty() {
4148 self.write("(");
4149 for (i, col) in lv.column_aliases.iter().enumerate() {
4150 if i > 0 {
4151 self.write(", ");
4152 }
4153 self.generate_identifier(col)?;
4154 }
4155 self.write(")");
4156 }
4157 } else if !lv.column_aliases.is_empty() {
4158 self.write_space();
4160 self.write_keyword("AS");
4161 self.write(" t(");
4162 for (i, col) in lv.column_aliases.iter().enumerate() {
4163 if i > 0 {
4164 self.write(", ");
4165 }
4166 self.generate_identifier(col)?;
4167 }
4168 self.write(")");
4169 }
4170
4171 if lv.outer {
4173 self.write_space();
4174 self.write_keyword("ON TRUE");
4175 }
4176 } else {
4177 self.write_keyword("LATERAL VIEW");
4179 if lv.outer {
4180 self.write_space();
4181 self.write_keyword("OUTER");
4182 }
4183 self.write_space();
4184 self.generate_expression(&lv.this)?;
4185
4186 if let Some(alias) = &lv.table_alias {
4188 self.write_space();
4189 self.generate_identifier(alias)?;
4190 }
4191
4192 if !lv.column_aliases.is_empty() {
4194 self.write_space();
4195 self.write_keyword("AS");
4196 self.write_space();
4197 for (i, col) in lv.column_aliases.iter().enumerate() {
4198 if i > 0 {
4199 self.write(", ");
4200 }
4201 self.generate_identifier(col)?;
4202 }
4203 }
4204 }
4205
4206 Ok(())
4207 }
4208
4209 fn generate_union(&mut self, union: &Union) -> Result<()> {
4210 if let Some(with) = &union.with {
4212 self.generate_with(with)?;
4213 self.write_space();
4214 }
4215 self.generate_expression(&union.left)?;
4216 if self.config.pretty {
4217 self.write_newline();
4218 self.write_indent();
4219 } else {
4220 self.write_space();
4221 }
4222
4223 if let Some(side) = &union.side {
4225 self.write_keyword(side);
4226 self.write_space();
4227 }
4228 if let Some(kind) = &union.kind {
4229 self.write_keyword(kind);
4230 self.write_space();
4231 }
4232
4233 self.write_keyword("UNION");
4234 if union.all {
4235 self.write_space();
4236 self.write_keyword("ALL");
4237 } else if union.distinct {
4238 self.write_space();
4239 self.write_keyword("DISTINCT");
4240 }
4241
4242 if union.corresponding || union.by_name {
4245 self.write_space();
4246 self.write_keyword("BY NAME");
4247 }
4248 if !union.on_columns.is_empty() {
4249 self.write_space();
4250 self.write_keyword("ON");
4251 self.write(" (");
4252 for (i, col) in union.on_columns.iter().enumerate() {
4253 if i > 0 {
4254 self.write(", ");
4255 }
4256 self.generate_expression(col)?;
4257 }
4258 self.write(")");
4259 }
4260
4261 if self.config.pretty {
4262 self.write_newline();
4263 self.write_indent();
4264 } else {
4265 self.write_space();
4266 }
4267 self.generate_expression(&union.right)?;
4268 if let Some(order_by) = &union.order_by {
4270 if self.config.pretty {
4271 self.write_newline();
4272 } else {
4273 self.write_space();
4274 }
4275 self.write_keyword("ORDER BY");
4276 self.write_space();
4277 for (i, ordered) in order_by.expressions.iter().enumerate() {
4278 if i > 0 {
4279 self.write(", ");
4280 }
4281 self.generate_ordered(ordered)?;
4282 }
4283 }
4284 if let Some(limit) = &union.limit {
4285 if self.config.pretty {
4286 self.write_newline();
4287 } else {
4288 self.write_space();
4289 }
4290 self.write_keyword("LIMIT");
4291 self.write_space();
4292 self.generate_expression(limit)?;
4293 }
4294 if let Some(offset) = &union.offset {
4295 if self.config.pretty {
4296 self.write_newline();
4297 } else {
4298 self.write_space();
4299 }
4300 self.write_keyword("OFFSET");
4301 self.write_space();
4302 self.generate_expression(offset)?;
4303 }
4304 if let Some(distribute_by) = &union.distribute_by {
4306 self.write_space();
4307 self.write_keyword("DISTRIBUTE BY");
4308 self.write_space();
4309 for (i, expr) in distribute_by.expressions.iter().enumerate() {
4310 if i > 0 {
4311 self.write(", ");
4312 }
4313 self.generate_expression(expr)?;
4314 }
4315 }
4316 if let Some(sort_by) = &union.sort_by {
4318 self.write_space();
4319 self.write_keyword("SORT BY");
4320 self.write_space();
4321 for (i, ord) in sort_by.expressions.iter().enumerate() {
4322 if i > 0 {
4323 self.write(", ");
4324 }
4325 self.generate_ordered(ord)?;
4326 }
4327 }
4328 if let Some(cluster_by) = &union.cluster_by {
4330 self.write_space();
4331 self.write_keyword("CLUSTER BY");
4332 self.write_space();
4333 for (i, ord) in cluster_by.expressions.iter().enumerate() {
4334 if i > 0 {
4335 self.write(", ");
4336 }
4337 self.generate_ordered(ord)?;
4338 }
4339 }
4340 Ok(())
4341 }
4342
4343 fn generate_intersect(&mut self, intersect: &Intersect) -> Result<()> {
4344 if let Some(with) = &intersect.with {
4346 self.generate_with(with)?;
4347 self.write_space();
4348 }
4349 self.generate_expression(&intersect.left)?;
4350 if self.config.pretty {
4351 self.write_newline();
4352 self.write_indent();
4353 } else {
4354 self.write_space();
4355 }
4356
4357 if let Some(side) = &intersect.side {
4359 self.write_keyword(side);
4360 self.write_space();
4361 }
4362 if let Some(kind) = &intersect.kind {
4363 self.write_keyword(kind);
4364 self.write_space();
4365 }
4366
4367 self.write_keyword("INTERSECT");
4368 if intersect.all {
4369 self.write_space();
4370 self.write_keyword("ALL");
4371 } else if intersect.distinct {
4372 self.write_space();
4373 self.write_keyword("DISTINCT");
4374 }
4375
4376 if intersect.corresponding || intersect.by_name {
4379 self.write_space();
4380 self.write_keyword("BY NAME");
4381 }
4382 if !intersect.on_columns.is_empty() {
4383 self.write_space();
4384 self.write_keyword("ON");
4385 self.write(" (");
4386 for (i, col) in intersect.on_columns.iter().enumerate() {
4387 if i > 0 {
4388 self.write(", ");
4389 }
4390 self.generate_expression(col)?;
4391 }
4392 self.write(")");
4393 }
4394
4395 if self.config.pretty {
4396 self.write_newline();
4397 self.write_indent();
4398 } else {
4399 self.write_space();
4400 }
4401 self.generate_expression(&intersect.right)?;
4402 if let Some(order_by) = &intersect.order_by {
4404 if self.config.pretty {
4405 self.write_newline();
4406 } else {
4407 self.write_space();
4408 }
4409 self.write_keyword("ORDER BY");
4410 self.write_space();
4411 for (i, ordered) in order_by.expressions.iter().enumerate() {
4412 if i > 0 {
4413 self.write(", ");
4414 }
4415 self.generate_ordered(ordered)?;
4416 }
4417 }
4418 if let Some(limit) = &intersect.limit {
4419 if self.config.pretty {
4420 self.write_newline();
4421 } else {
4422 self.write_space();
4423 }
4424 self.write_keyword("LIMIT");
4425 self.write_space();
4426 self.generate_expression(limit)?;
4427 }
4428 if let Some(offset) = &intersect.offset {
4429 if self.config.pretty {
4430 self.write_newline();
4431 } else {
4432 self.write_space();
4433 }
4434 self.write_keyword("OFFSET");
4435 self.write_space();
4436 self.generate_expression(offset)?;
4437 }
4438 if let Some(distribute_by) = &intersect.distribute_by {
4440 self.write_space();
4441 self.write_keyword("DISTRIBUTE BY");
4442 self.write_space();
4443 for (i, expr) in distribute_by.expressions.iter().enumerate() {
4444 if i > 0 {
4445 self.write(", ");
4446 }
4447 self.generate_expression(expr)?;
4448 }
4449 }
4450 if let Some(sort_by) = &intersect.sort_by {
4452 self.write_space();
4453 self.write_keyword("SORT BY");
4454 self.write_space();
4455 for (i, ord) in sort_by.expressions.iter().enumerate() {
4456 if i > 0 {
4457 self.write(", ");
4458 }
4459 self.generate_ordered(ord)?;
4460 }
4461 }
4462 if let Some(cluster_by) = &intersect.cluster_by {
4464 self.write_space();
4465 self.write_keyword("CLUSTER BY");
4466 self.write_space();
4467 for (i, ord) in cluster_by.expressions.iter().enumerate() {
4468 if i > 0 {
4469 self.write(", ");
4470 }
4471 self.generate_ordered(ord)?;
4472 }
4473 }
4474 Ok(())
4475 }
4476
4477 fn generate_except(&mut self, except: &Except) -> Result<()> {
4478 use crate::dialects::DialectType;
4479
4480 if let Some(with) = &except.with {
4482 self.generate_with(with)?;
4483 self.write_space();
4484 }
4485
4486 self.generate_expression(&except.left)?;
4487 if self.config.pretty {
4488 self.write_newline();
4489 self.write_indent();
4490 } else {
4491 self.write_space();
4492 }
4493
4494 if let Some(side) = &except.side {
4496 self.write_keyword(side);
4497 self.write_space();
4498 }
4499 if let Some(kind) = &except.kind {
4500 self.write_keyword(kind);
4501 self.write_space();
4502 }
4503
4504 match self.config.dialect {
4506 Some(DialectType::Oracle) => {
4507 self.write_keyword("MINUS");
4508 }
4510 _ => {
4511 self.write_keyword("EXCEPT");
4512 if except.all {
4513 self.write_space();
4514 self.write_keyword("ALL");
4515 } else if except.distinct {
4516 self.write_space();
4517 self.write_keyword("DISTINCT");
4518 }
4519 }
4520 }
4521
4522 if except.corresponding || except.by_name {
4525 self.write_space();
4526 self.write_keyword("BY NAME");
4527 }
4528 if !except.on_columns.is_empty() {
4529 self.write_space();
4530 self.write_keyword("ON");
4531 self.write(" (");
4532 for (i, col) in except.on_columns.iter().enumerate() {
4533 if i > 0 {
4534 self.write(", ");
4535 }
4536 self.generate_expression(col)?;
4537 }
4538 self.write(")");
4539 }
4540
4541 if self.config.pretty {
4542 self.write_newline();
4543 self.write_indent();
4544 } else {
4545 self.write_space();
4546 }
4547 self.generate_expression(&except.right)?;
4548 if let Some(order_by) = &except.order_by {
4550 if self.config.pretty {
4551 self.write_newline();
4552 } else {
4553 self.write_space();
4554 }
4555 self.write_keyword("ORDER BY");
4556 self.write_space();
4557 for (i, ordered) in order_by.expressions.iter().enumerate() {
4558 if i > 0 {
4559 self.write(", ");
4560 }
4561 self.generate_ordered(ordered)?;
4562 }
4563 }
4564 if let Some(limit) = &except.limit {
4565 if self.config.pretty {
4566 self.write_newline();
4567 } else {
4568 self.write_space();
4569 }
4570 self.write_keyword("LIMIT");
4571 self.write_space();
4572 self.generate_expression(limit)?;
4573 }
4574 if let Some(offset) = &except.offset {
4575 if self.config.pretty {
4576 self.write_newline();
4577 } else {
4578 self.write_space();
4579 }
4580 self.write_keyword("OFFSET");
4581 self.write_space();
4582 self.generate_expression(offset)?;
4583 }
4584 if let Some(distribute_by) = &except.distribute_by {
4586 self.write_space();
4587 self.write_keyword("DISTRIBUTE BY");
4588 self.write_space();
4589 for (i, expr) in distribute_by.expressions.iter().enumerate() {
4590 if i > 0 {
4591 self.write(", ");
4592 }
4593 self.generate_expression(expr)?;
4594 }
4595 }
4596 if let Some(sort_by) = &except.sort_by {
4598 self.write_space();
4599 self.write_keyword("SORT BY");
4600 self.write_space();
4601 for (i, ord) in sort_by.expressions.iter().enumerate() {
4602 if i > 0 {
4603 self.write(", ");
4604 }
4605 self.generate_ordered(ord)?;
4606 }
4607 }
4608 if let Some(cluster_by) = &except.cluster_by {
4610 self.write_space();
4611 self.write_keyword("CLUSTER BY");
4612 self.write_space();
4613 for (i, ord) in cluster_by.expressions.iter().enumerate() {
4614 if i > 0 {
4615 self.write(", ");
4616 }
4617 self.generate_ordered(ord)?;
4618 }
4619 }
4620 Ok(())
4621 }
4622
4623 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
4624 let prepend_query_cte = if insert.with.is_none() {
4626 use crate::dialects::DialectType;
4627 let should_prepend = matches!(self.config.dialect,
4628 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4629 | Some(DialectType::Spark)
4630 | Some(DialectType::Databricks) | Some(DialectType::Hive)
4631 );
4632 if should_prepend {
4633 if let Some(Expression::Select(select)) = &insert.query {
4634 select.with.clone()
4635 } else {
4636 None
4637 }
4638 } else {
4639 None
4640 }
4641 } else {
4642 None
4643 };
4644
4645 if let Some(with) = &insert.with {
4647 self.generate_with(with)?;
4648 self.write_space();
4649 } else if let Some(with) = &prepend_query_cte {
4650 self.generate_with(with)?;
4651 self.write_space();
4652 }
4653
4654 for comment in &insert.leading_comments {
4656 self.write(comment);
4657 self.write(" ");
4658 }
4659
4660 if let Some(dir) = &insert.directory {
4662 self.write_keyword("INSERT OVERWRITE");
4663 if dir.local {
4664 self.write_space();
4665 self.write_keyword("LOCAL");
4666 }
4667 self.write_space();
4668 self.write_keyword("DIRECTORY");
4669 self.write_space();
4670 self.write("'");
4671 self.write(&dir.path);
4672 self.write("'");
4673
4674 if let Some(row_format) = &dir.row_format {
4676 self.write_space();
4677 self.write_keyword("ROW FORMAT");
4678 if row_format.delimited {
4679 self.write_space();
4680 self.write_keyword("DELIMITED");
4681 }
4682 if let Some(val) = &row_format.fields_terminated_by {
4683 self.write_space();
4684 self.write_keyword("FIELDS TERMINATED BY");
4685 self.write_space();
4686 self.write("'");
4687 self.write(val);
4688 self.write("'");
4689 }
4690 if let Some(val) = &row_format.collection_items_terminated_by {
4691 self.write_space();
4692 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
4693 self.write_space();
4694 self.write("'");
4695 self.write(val);
4696 self.write("'");
4697 }
4698 if let Some(val) = &row_format.map_keys_terminated_by {
4699 self.write_space();
4700 self.write_keyword("MAP KEYS TERMINATED BY");
4701 self.write_space();
4702 self.write("'");
4703 self.write(val);
4704 self.write("'");
4705 }
4706 if let Some(val) = &row_format.lines_terminated_by {
4707 self.write_space();
4708 self.write_keyword("LINES TERMINATED BY");
4709 self.write_space();
4710 self.write("'");
4711 self.write(val);
4712 self.write("'");
4713 }
4714 if let Some(val) = &row_format.null_defined_as {
4715 self.write_space();
4716 self.write_keyword("NULL DEFINED AS");
4717 self.write_space();
4718 self.write("'");
4719 self.write(val);
4720 self.write("'");
4721 }
4722 }
4723
4724 if let Some(format) = &dir.stored_as {
4726 self.write_space();
4727 self.write_keyword("STORED AS");
4728 self.write_space();
4729 self.write_keyword(format);
4730 }
4731
4732 if let Some(query) = &insert.query {
4734 self.write_space();
4735 self.generate_expression(query)?;
4736 }
4737
4738 return Ok(());
4739 }
4740
4741 if insert.is_replace {
4742 self.write_keyword("REPLACE INTO");
4744 } else if insert.overwrite {
4745 self.write_keyword("INSERT");
4747 if let Some(ref hint) = insert.hint {
4749 self.generate_hint(hint)?;
4750 }
4751 self.write(&self.config.insert_overwrite.to_uppercase());
4752 } else if let Some(ref action) = insert.conflict_action {
4753 self.write_keyword("INSERT OR");
4755 self.write_space();
4756 self.write_keyword(action);
4757 self.write_space();
4758 self.write_keyword("INTO");
4759 } else if insert.ignore {
4760 self.write_keyword("INSERT IGNORE INTO");
4762 } else {
4763 self.write_keyword("INSERT");
4764 if let Some(ref hint) = insert.hint {
4766 self.generate_hint(hint)?;
4767 }
4768 self.write_space();
4769 self.write_keyword("INTO");
4770 }
4771 if let Some(ref func) = insert.function_target {
4773 self.write_space();
4774 self.write_keyword("FUNCTION");
4775 self.write_space();
4776 self.generate_expression(func)?;
4777 } else {
4778 self.write_space();
4779 self.generate_table(&insert.table)?;
4780 }
4781
4782 if let Some(ref alias) = insert.alias {
4784 self.write_space();
4785 if insert.alias_explicit_as {
4786 self.write_keyword("AS");
4787 self.write_space();
4788 }
4789 self.generate_identifier(alias)?;
4790 }
4791
4792 if insert.if_exists {
4794 self.write_space();
4795 self.write_keyword("IF EXISTS");
4796 }
4797
4798 if let Some(ref replace_where) = insert.replace_where {
4800 self.write_space();
4801 self.write_keyword("REPLACE WHERE");
4802 self.write_space();
4803 self.generate_expression(replace_where)?;
4804 }
4805
4806 if !insert.partition.is_empty() {
4808 self.write_space();
4809 self.write_keyword("PARTITION");
4810 self.write("(");
4811 for (i, (col, val)) in insert.partition.iter().enumerate() {
4812 if i > 0 {
4813 self.write(", ");
4814 }
4815 self.generate_identifier(col)?;
4816 if let Some(v) = val {
4817 self.write(" = ");
4818 self.generate_expression(v)?;
4819 }
4820 }
4821 self.write(")");
4822 }
4823
4824 if let Some(ref partition_by) = insert.partition_by {
4826 self.write_space();
4827 self.write_keyword("PARTITION BY");
4828 self.write_space();
4829 self.generate_expression(partition_by)?;
4830 }
4831
4832 if !insert.settings.is_empty() {
4834 self.write_space();
4835 self.write_keyword("SETTINGS");
4836 self.write_space();
4837 for (i, setting) in insert.settings.iter().enumerate() {
4838 if i > 0 {
4839 self.write(", ");
4840 }
4841 self.generate_expression(setting)?;
4842 }
4843 }
4844
4845 if !insert.columns.is_empty() {
4846 if insert.alias.is_some() && insert.alias_explicit_as {
4847 self.write("(");
4849 } else {
4850 self.write(" (");
4852 }
4853 for (i, col) in insert.columns.iter().enumerate() {
4854 if i > 0 {
4855 self.write(", ");
4856 }
4857 self.generate_identifier(col)?;
4858 }
4859 self.write(")");
4860 }
4861
4862 if let Some(ref output) = insert.output {
4864 self.generate_output_clause(output)?;
4865 }
4866
4867 if insert.by_name {
4869 self.write_space();
4870 self.write_keyword("BY NAME");
4871 }
4872
4873 if insert.default_values {
4874 self.write_space();
4875 self.write_keyword("DEFAULT VALUES");
4876 } else if let Some(query) = &insert.query {
4877 if self.config.pretty {
4878 self.write_newline();
4879 } else {
4880 self.write_space();
4881 }
4882 if prepend_query_cte.is_some() {
4884 if let Expression::Select(select) = query {
4885 let mut select_no_with = select.clone();
4886 select_no_with.with = None;
4887 self.generate_select(&select_no_with)?;
4888 } else {
4889 self.generate_expression(query)?;
4890 }
4891 } else {
4892 self.generate_expression(query)?;
4893 }
4894 } else if !insert.values.is_empty() {
4895 if self.config.pretty {
4896 self.write_newline();
4898 self.write_keyword("VALUES");
4899 self.write_newline();
4900 self.indent_level += 1;
4901 for (i, row) in insert.values.iter().enumerate() {
4902 if i > 0 {
4903 self.write(",");
4904 self.write_newline();
4905 }
4906 self.write_indent();
4907 self.write("(");
4908 for (j, val) in row.iter().enumerate() {
4909 if j > 0 {
4910 self.write(", ");
4911 }
4912 self.generate_expression(val)?;
4913 }
4914 self.write(")");
4915 }
4916 self.indent_level -= 1;
4917 } else {
4918 self.write_space();
4920 self.write_keyword("VALUES");
4921 for (i, row) in insert.values.iter().enumerate() {
4922 if i > 0 {
4923 self.write(",");
4924 }
4925 self.write(" (");
4926 for (j, val) in row.iter().enumerate() {
4927 if j > 0 {
4928 self.write(", ");
4929 }
4930 self.generate_expression(val)?;
4931 }
4932 self.write(")");
4933 }
4934 }
4935 }
4936
4937 if let Some(ref source) = insert.source {
4939 self.write_space();
4940 self.write_keyword("TABLE");
4941 self.write_space();
4942 self.generate_expression(source)?;
4943 }
4944
4945 if let Some(alias) = &insert.source_alias {
4947 self.write_space();
4948 self.write_keyword("AS");
4949 self.write_space();
4950 self.generate_identifier(alias)?;
4951 }
4952
4953 if let Some(on_conflict) = &insert.on_conflict {
4955 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
4956 self.write_space();
4957 self.generate_expression(on_conflict)?;
4958 }
4959 }
4960
4961 if !insert.returning.is_empty() {
4963 self.write_space();
4964 self.write_keyword("RETURNING");
4965 self.write_space();
4966 for (i, expr) in insert.returning.iter().enumerate() {
4967 if i > 0 {
4968 self.write(", ");
4969 }
4970 self.generate_expression(expr)?;
4971 }
4972 }
4973
4974 Ok(())
4975 }
4976
4977 fn generate_update(&mut self, update: &Update) -> Result<()> {
4978 for comment in &update.leading_comments {
4980 self.write(comment);
4981 self.write(" ");
4982 }
4983
4984 if let Some(ref with) = update.with {
4986 self.generate_with(with)?;
4987 self.write_space();
4988 }
4989
4990 self.write_keyword("UPDATE");
4991 self.write_space();
4992 self.generate_table(&update.table)?;
4993
4994 let mysql_like_update_from = matches!(
4995 self.config.dialect,
4996 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
4997 ) && update.from_clause.is_some();
4998
4999 let mut set_pairs = update.set.clone();
5000
5001 let mut pre_set_joins = update.table_joins.clone();
5003 if mysql_like_update_from {
5004 let target_name = update.table.alias
5005 .as_ref()
5006 .map(|a| a.name.clone())
5007 .unwrap_or_else(|| update.table.name.name.clone());
5008
5009 for (col, _) in &mut set_pairs {
5010 if !col.name.contains('.') {
5011 col.name = format!("{}.{}", target_name, col.name);
5012 }
5013 }
5014
5015 if let Some(from_clause) = &update.from_clause {
5016 for table_expr in &from_clause.expressions {
5017 pre_set_joins.push(crate::expressions::Join {
5018 this: table_expr.clone(),
5019 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral { value: true })),
5020 using: Vec::new(),
5021 kind: crate::expressions::JoinKind::Inner,
5022 use_inner_keyword: false,
5023 use_outer_keyword: false,
5024 deferred_condition: false,
5025 join_hint: None,
5026 match_condition: None,
5027 pivots: Vec::new(),
5028 });
5029 }
5030 }
5031 for join in &update.from_joins {
5032 let mut join = join.clone();
5033 if join.on.is_none() && join.using.is_empty() {
5034 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral { value: true }));
5035 }
5036 pre_set_joins.push(join);
5037 }
5038 }
5039
5040 for extra_table in &update.extra_tables {
5042 self.write(", ");
5043 self.generate_table(extra_table)?;
5044 }
5045
5046 for join in &pre_set_joins {
5048 self.generate_join(join)?;
5050 }
5051
5052 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
5054 if teradata_from_before_set && !mysql_like_update_from {
5055 if let Some(ref from_clause) = update.from_clause {
5056 self.write_space();
5057 self.write_keyword("FROM");
5058 self.write_space();
5059 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
5060 if i > 0 {
5061 self.write(", ");
5062 }
5063 self.generate_expression(table_expr)?;
5064 }
5065 }
5066 for join in &update.from_joins {
5067 self.generate_join(join)?;
5068 }
5069 }
5070
5071 self.write_space();
5072 self.write_keyword("SET");
5073 self.write_space();
5074
5075 for (i, (col, val)) in set_pairs.iter().enumerate() {
5076 if i > 0 {
5077 self.write(", ");
5078 }
5079 self.generate_identifier(col)?;
5080 self.write(" = ");
5081 self.generate_expression(val)?;
5082 }
5083
5084 if let Some(ref output) = update.output {
5086 self.generate_output_clause(output)?;
5087 }
5088
5089 if !mysql_like_update_from && !teradata_from_before_set {
5091 if let Some(ref from_clause) = update.from_clause {
5092 self.write_space();
5093 self.write_keyword("FROM");
5094 self.write_space();
5095 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
5097 if i > 0 {
5098 self.write(", ");
5099 }
5100 self.generate_expression(table_expr)?;
5101 }
5102 }
5103 }
5104
5105 if !mysql_like_update_from && !teradata_from_before_set {
5106 for join in &update.from_joins {
5108 self.generate_join(join)?;
5109 }
5110 }
5111
5112 if let Some(where_clause) = &update.where_clause {
5113 self.write_space();
5114 self.write_keyword("WHERE");
5115 self.write_space();
5116 self.generate_expression(&where_clause.this)?;
5117 }
5118
5119 if !update.returning.is_empty() {
5121 self.write_space();
5122 self.write_keyword("RETURNING");
5123 self.write_space();
5124 for (i, expr) in update.returning.iter().enumerate() {
5125 if i > 0 {
5126 self.write(", ");
5127 }
5128 self.generate_expression(expr)?;
5129 }
5130 }
5131
5132 if let Some(ref order_by) = update.order_by {
5134 self.write_space();
5135 self.generate_order_by(order_by)?;
5136 }
5137
5138 if let Some(ref limit) = update.limit {
5140 self.write_space();
5141 self.write_keyword("LIMIT");
5142 self.write_space();
5143 self.generate_expression(limit)?;
5144 }
5145
5146 Ok(())
5147 }
5148
5149 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
5150 if let Some(with) = &delete.with {
5152 self.generate_with(with)?;
5153 self.write_space();
5154 }
5155
5156 for comment in &delete.leading_comments {
5158 self.write(comment);
5159 self.write(" ");
5160 }
5161
5162 if !delete.tables.is_empty() && !delete.tables_from_using {
5164 self.write_keyword("DELETE");
5166 self.write_space();
5167 for (i, tbl) in delete.tables.iter().enumerate() {
5168 if i > 0 {
5169 self.write(", ");
5170 }
5171 self.generate_table(tbl)?;
5172 }
5173 if let Some(ref output) = delete.output {
5175 self.generate_output_clause(output)?;
5176 }
5177 self.write_space();
5178 self.write_keyword("FROM");
5179 self.write_space();
5180 self.generate_table(&delete.table)?;
5181 } else if !delete.tables.is_empty() && delete.tables_from_using {
5182 self.write_keyword("DELETE FROM");
5184 self.write_space();
5185 for (i, tbl) in delete.tables.iter().enumerate() {
5186 if i > 0 {
5187 self.write(", ");
5188 }
5189 self.generate_table(tbl)?;
5190 }
5191 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
5192 self.write_keyword("DELETE");
5194 self.write_space();
5195 self.generate_table(&delete.table)?;
5196 } else {
5197 self.write_keyword("DELETE FROM");
5198 self.write_space();
5199 self.generate_table(&delete.table)?;
5200 }
5201
5202 if let Some(ref on_cluster) = delete.on_cluster {
5204 self.write_space();
5205 self.generate_on_cluster(on_cluster)?;
5206 }
5207
5208 if let Some(ref idx) = delete.force_index {
5210 self.write_space();
5211 self.write_keyword("FORCE INDEX");
5212 self.write(" (");
5213 self.write(idx);
5214 self.write(")");
5215 }
5216
5217 if let Some(ref alias) = delete.alias {
5219 self.write_space();
5220 if delete.alias_explicit_as || matches!(self.config.dialect, Some(DialectType::BigQuery)) {
5221 self.write_keyword("AS");
5222 self.write_space();
5223 }
5224 self.generate_identifier(alias)?;
5225 }
5226
5227 if !delete.tables_from_using {
5229 for join in &delete.joins {
5230 self.generate_join(join)?;
5231 }
5232 }
5233
5234 if !delete.using.is_empty() {
5236 self.write_space();
5237 self.write_keyword("USING");
5238 for (i, table) in delete.using.iter().enumerate() {
5239 if i > 0 {
5240 self.write(",");
5241 }
5242 self.write_space();
5243 if !table.hints.is_empty() && table.name.is_empty() {
5245 self.generate_expression(&table.hints[0])?;
5247 if let Some(ref alias) = table.alias {
5248 self.write_space();
5249 if table.alias_explicit_as {
5250 self.write_keyword("AS");
5251 self.write_space();
5252 }
5253 self.generate_identifier(alias)?;
5254 if !table.column_aliases.is_empty() {
5255 self.write("(");
5256 for (j, col_alias) in table.column_aliases.iter().enumerate() {
5257 if j > 0 {
5258 self.write(", ");
5259 }
5260 self.generate_identifier(col_alias)?;
5261 }
5262 self.write(")");
5263 }
5264 }
5265 } else {
5266 self.generate_table(table)?;
5267 }
5268 }
5269 }
5270
5271 if delete.tables_from_using {
5273 for join in &delete.joins {
5274 self.generate_join(join)?;
5275 }
5276 }
5277
5278 let output_already_emitted = !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
5280 if !output_already_emitted {
5281 if let Some(ref output) = delete.output {
5282 self.generate_output_clause(output)?;
5283 }
5284 }
5285
5286 if let Some(where_clause) = &delete.where_clause {
5287 self.write_space();
5288 self.write_keyword("WHERE");
5289 self.write_space();
5290 self.generate_expression(&where_clause.this)?;
5291 }
5292
5293 if let Some(ref order_by) = delete.order_by {
5295 self.write_space();
5296 self.generate_order_by(order_by)?;
5297 }
5298
5299 if let Some(ref limit) = delete.limit {
5301 self.write_space();
5302 self.write_keyword("LIMIT");
5303 self.write_space();
5304 self.generate_expression(limit)?;
5305 }
5306
5307 if !delete.returning.is_empty() {
5309 self.write_space();
5310 self.write_keyword("RETURNING");
5311 self.write_space();
5312 for (i, expr) in delete.returning.iter().enumerate() {
5313 if i > 0 {
5314 self.write(", ");
5315 }
5316 self.generate_expression(expr)?;
5317 }
5318 }
5319
5320 Ok(())
5321 }
5322
5323 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
5326 let saved_athena_hive_context = self.athena_hive_context;
5330 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
5331 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Athena)) {
5332 let is_external = ct.table_modifier.as_ref().map(|m| m.eq_ignore_ascii_case("EXTERNAL")).unwrap_or(false);
5336 let has_as_select = ct.as_select.is_some();
5337 self.athena_hive_context = is_external || !has_as_select;
5338 }
5339
5340 if matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL)) {
5342 if let Some(ref query) = ct.as_select {
5343 if let Some(with_cte) = &ct.with_cte {
5345 self.generate_with(with_cte)?;
5346 self.write_space();
5347 }
5348
5349 self.write_keyword("SELECT");
5351 self.write(" * ");
5352 self.write_keyword("INTO");
5353 self.write_space();
5354
5355 if ct.temporary {
5357 self.write("#");
5358 }
5359 self.generate_table(&ct.name)?;
5360
5361 self.write_space();
5362 self.write_keyword("FROM");
5363 self.write(" (");
5364 let aliased_query = Self::add_column_aliases_to_query(query.clone());
5366 self.generate_expression(&aliased_query)?;
5367 self.write(") ");
5368 self.write_keyword("AS");
5369 self.write(" temp");
5370 return Ok(());
5371 }
5372 }
5373
5374 if let Some(with_cte) = &ct.with_cte {
5376 self.generate_with(with_cte)?;
5377 self.write_space();
5378 }
5379
5380 for comment in &ct.leading_comments {
5382 self.write(comment);
5383 self.write(" ");
5384 }
5385 self.write_keyword("CREATE");
5386
5387 if ct.or_replace {
5388 self.write_space();
5389 self.write_keyword("OR REPLACE");
5390 }
5391
5392 if ct.temporary {
5393 self.write_space();
5394 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
5396 self.write_keyword("GLOBAL TEMPORARY");
5397 } else {
5398 self.write_keyword("TEMPORARY");
5399 }
5400 }
5401
5402 let is_dictionary = ct
5404 .table_modifier
5405 .as_ref()
5406 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
5407 .unwrap_or(false);
5408 if let Some(ref modifier) = ct.table_modifier {
5409 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
5411 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
5412 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
5414 || modifier.eq_ignore_ascii_case("SET")
5415 || modifier.eq_ignore_ascii_case("MULTISET")
5416 || modifier.to_uppercase().contains("VOLATILE")
5417 || modifier.to_uppercase().starts_with("SET ")
5418 || modifier.to_uppercase().starts_with("MULTISET ");
5419 let skip_teradata = is_teradata_modifier
5420 && !matches!(self.config.dialect, Some(DialectType::Teradata));
5421 if !skip_transient && !skip_teradata {
5422 self.write_space();
5423 self.write_keyword(modifier);
5424 }
5425 }
5426
5427 if !is_dictionary {
5428 self.write_space();
5429 self.write_keyword("TABLE");
5430 }
5431
5432 if ct.if_not_exists {
5433 self.write_space();
5434 self.write_keyword("IF NOT EXISTS");
5435 }
5436
5437 self.write_space();
5438 self.generate_table(&ct.name)?;
5439
5440 if let Some(ref on_cluster) = ct.on_cluster {
5442 self.write_space();
5443 self.generate_on_cluster(on_cluster)?;
5444 }
5445
5446 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Teradata))
5448 && !ct.teradata_post_name_options.is_empty()
5449 {
5450 for opt in &ct.teradata_post_name_options {
5451 self.write(", ");
5452 self.write(opt);
5453 }
5454 }
5455
5456 if ct.copy_grants {
5458 self.write_space();
5459 self.write_keyword("COPY GRANTS");
5460 }
5461
5462 if let Some(ref using_template) = ct.using_template {
5464 self.write_space();
5465 self.write_keyword("USING TEMPLATE");
5466 self.write_space();
5467 self.generate_expression(using_template)?;
5468 return Ok(());
5469 }
5470
5471 if let Some(ref clone_source) = ct.clone_source {
5473 self.write_space();
5474 if ct.is_copy && self.config.supports_table_copy {
5475 self.write_keyword("COPY");
5477 } else if ct.shallow_clone {
5478 self.write_keyword("SHALLOW CLONE");
5479 } else {
5480 self.write_keyword("CLONE");
5481 }
5482 self.write_space();
5483 self.generate_table(clone_source)?;
5484 if let Some(ref at_clause) = ct.clone_at_clause {
5486 self.write_space();
5487 self.generate_expression(at_clause)?;
5488 }
5489 return Ok(());
5490 }
5491
5492 if let Some(ref partition_of) = ct.partition_of {
5496 self.write_space();
5497
5498 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
5500 self.write_keyword("PARTITION OF");
5502 self.write_space();
5503 self.generate_expression(&pop.this)?;
5504
5505 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
5507 self.write(" (");
5508 let mut first = true;
5509 for col in &ct.columns {
5510 if !first {
5511 self.write(", ");
5512 }
5513 first = false;
5514 self.generate_column_def(col)?;
5515 }
5516 for constraint in &ct.constraints {
5517 if !first {
5518 self.write(", ");
5519 }
5520 first = false;
5521 self.generate_table_constraint(constraint)?;
5522 }
5523 self.write(")");
5524 }
5525
5526 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
5528 self.write_space();
5529 self.write_keyword("FOR VALUES");
5530 self.write_space();
5531 self.generate_expression(&pop.expression)?;
5532 } else {
5533 self.write_space();
5534 self.write_keyword("DEFAULT");
5535 }
5536 } else {
5537 self.generate_expression(partition_of)?;
5539
5540 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
5542 self.write(" (");
5543 let mut first = true;
5544 for col in &ct.columns {
5545 if !first {
5546 self.write(", ");
5547 }
5548 first = false;
5549 self.generate_column_def(col)?;
5550 }
5551 for constraint in &ct.constraints {
5552 if !first {
5553 self.write(", ");
5554 }
5555 first = false;
5556 self.generate_table_constraint(constraint)?;
5557 }
5558 self.write(")");
5559 }
5560 }
5561
5562 for prop in &ct.properties {
5564 self.write_space();
5565 self.generate_expression(prop)?;
5566 }
5567
5568 return Ok(());
5569 }
5570
5571 self.sqlite_inline_pk_columns.clear();
5574 if matches!(self.config.dialect, Some(crate::dialects::DialectType::SQLite)) {
5575 for constraint in &ct.constraints {
5576 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
5577 if columns.len() == 1 && name.is_none() {
5579 let pk_col_name = columns[0].name.to_lowercase();
5580 if ct.columns.iter().any(|c| c.name.name.to_lowercase() == pk_col_name) {
5582 self.sqlite_inline_pk_columns.insert(pk_col_name);
5583 }
5584 }
5585 }
5586 }
5587 }
5588
5589 if !ct.columns.is_empty() {
5591 if self.config.pretty {
5592 self.write(" (");
5594 self.write_newline();
5595 self.indent_level += 1;
5596 for (i, col) in ct.columns.iter().enumerate() {
5597 if i > 0 {
5598 self.write(",");
5599 self.write_newline();
5600 }
5601 self.write_indent();
5602 self.generate_column_def(col)?;
5603 }
5604 for constraint in &ct.constraints {
5606 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
5608 if columns.len() == 1 && name.is_none() &&
5609 self.sqlite_inline_pk_columns.contains(&columns[0].name.to_lowercase()) {
5610 continue;
5611 }
5612 }
5613 self.write(",");
5614 self.write_newline();
5615 self.write_indent();
5616 self.generate_table_constraint(constraint)?;
5617 }
5618 self.indent_level -= 1;
5619 self.write_newline();
5620 self.write(")");
5621 } else {
5622 self.write(" (");
5623 for (i, col) in ct.columns.iter().enumerate() {
5624 if i > 0 {
5625 self.write(", ");
5626 }
5627 self.generate_column_def(col)?;
5628 }
5629 let mut first_constraint = true;
5631 for constraint in &ct.constraints {
5632 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
5634 if columns.len() == 1 && name.is_none() &&
5635 self.sqlite_inline_pk_columns.contains(&columns[0].name.to_lowercase()) {
5636 continue;
5637 }
5638 }
5639 if first_constraint {
5640 self.write(", ");
5641 first_constraint = false;
5642 } else {
5643 self.write(", ");
5644 }
5645 self.generate_table_constraint(constraint)?;
5646 }
5647 self.write(")");
5648 }
5649 } else if !ct.constraints.is_empty() {
5650 let has_like_only = ct.constraints.iter().all(|c| matches!(c, TableConstraint::Like { .. }));
5652 let has_tags_only = ct.constraints.iter().all(|c| matches!(c, TableConstraint::Tags(_)));
5653 let is_mysql = matches!(self.config.dialect, Some(crate::dialects::DialectType::MySQL) | Some(crate::dialects::DialectType::SingleStore) | Some(crate::dialects::DialectType::TiDB));
5657 let use_parens = !(has_like_only && is_mysql) && !has_tags_only;
5658 if self.config.pretty && use_parens {
5659 self.write(" (");
5660 self.write_newline();
5661 self.indent_level += 1;
5662 for (i, constraint) in ct.constraints.iter().enumerate() {
5663 if i > 0 {
5664 self.write(",");
5665 self.write_newline();
5666 }
5667 self.write_indent();
5668 self.generate_table_constraint(constraint)?;
5669 }
5670 self.indent_level -= 1;
5671 self.write_newline();
5672 self.write(")");
5673 } else {
5674 if use_parens {
5675 self.write(" (");
5676 } else {
5677 self.write_space();
5678 }
5679 for (i, constraint) in ct.constraints.iter().enumerate() {
5680 if i > 0 {
5681 self.write(", ");
5682 }
5683 self.generate_table_constraint(constraint)?;
5684 }
5685 if use_parens {
5686 self.write(")");
5687 }
5688 }
5689 }
5690
5691 if let Some(ref on_prop) = ct.on_property {
5693 self.write(" ");
5694 self.write_keyword("ON");
5695 self.write(" ");
5696 self.generate_expression(&on_prop.this)?;
5697 }
5698
5699 if !is_clickhouse {
5702 for prop in &ct.properties {
5703 if let Expression::SchemaCommentProperty(_) = prop {
5704 if self.config.pretty {
5705 self.write_newline();
5706 } else {
5707 self.write_space();
5708 }
5709 self.generate_expression(prop)?;
5710 }
5711 }
5712 }
5713
5714 if !ct.with_properties.is_empty() {
5716 let is_snowflake_special_table = matches!(self.config.dialect, Some(crate::dialects::DialectType::Snowflake))
5718 && (ct.table_modifier.as_deref() == Some("ICEBERG") || ct.table_modifier.as_deref() == Some("DYNAMIC"));
5719 if is_snowflake_special_table {
5720 for (key, value) in &ct.with_properties {
5721 self.write_space();
5722 self.write(key);
5723 self.write("=");
5724 self.write(value);
5725 }
5726 } else if self.config.pretty {
5727 self.write_newline();
5728 self.write_keyword("WITH");
5729 self.write(" (");
5730 self.write_newline();
5731 self.indent_level += 1;
5732 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
5733 if i > 0 {
5734 self.write(",");
5735 self.write_newline();
5736 }
5737 self.write_indent();
5738 self.write(key);
5739 self.write("=");
5740 self.write(value);
5741 }
5742 self.indent_level -= 1;
5743 self.write_newline();
5744 self.write(")");
5745 } else {
5746 self.write_space();
5747 self.write_keyword("WITH");
5748 self.write(" (");
5749 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
5750 if i > 0 {
5751 self.write(", ");
5752 }
5753 self.write(key);
5754 self.write("=");
5755 self.write(value);
5756 }
5757 self.write(")");
5758 }
5759 }
5760
5761 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) = if is_clickhouse && ct.as_select.is_some() {
5762 let mut pre = Vec::new();
5763 let mut post = Vec::new();
5764 for prop in &ct.properties {
5765 if matches!(prop, Expression::SchemaCommentProperty(_)) {
5766 post.push(prop);
5767 } else {
5768 pre.push(prop);
5769 }
5770 }
5771 (pre, post)
5772 } else {
5773 (ct.properties.iter().collect(), Vec::new())
5774 };
5775
5776 for prop in pre_as_properties {
5778 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
5780 continue;
5781 }
5782 if self.config.pretty {
5783 self.write_newline();
5784 } else {
5785 self.write_space();
5786 }
5787 if let Expression::Properties(props) = prop {
5791 let is_hive_dialect = matches!(self.config.dialect, Some(crate::dialects::DialectType::Hive) | Some(crate::dialects::DialectType::Spark) | Some(crate::dialects::DialectType::Databricks) | Some(crate::dialects::DialectType::Athena));
5792 let is_doris_starrocks = matches!(self.config.dialect, Some(crate::dialects::DialectType::Doris) | Some(crate::dialects::DialectType::StarRocks));
5793 if is_hive_dialect {
5794 self.generate_tblproperties_clause(&props.expressions)?;
5795 } else if is_doris_starrocks {
5796 self.generate_properties_clause(&props.expressions)?;
5797 } else {
5798 self.generate_options_clause(&props.expressions)?;
5799 }
5800 } else {
5801 self.generate_expression(prop)?;
5802 }
5803 }
5804
5805 for prop in &ct.post_table_properties {
5807 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
5808 self.write(" WITH(");
5809 self.generate_system_versioning_content(svp)?;
5810 self.write(")");
5811 } else if let Expression::Properties(props) = prop {
5812 let is_doris_starrocks = matches!(self.config.dialect, Some(crate::dialects::DialectType::Doris) | Some(crate::dialects::DialectType::StarRocks));
5814 self.write_space();
5815 if is_doris_starrocks {
5816 self.generate_properties_clause(&props.expressions)?;
5817 } else {
5818 self.generate_options_clause(&props.expressions)?;
5819 }
5820 } else {
5821 self.write_space();
5822 self.generate_expression(prop)?;
5823 }
5824 }
5825
5826 if let Some(ref rollup) = ct.rollup {
5829 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
5830 self.write_space();
5831 self.generate_rollup_property(rollup)?;
5832 }
5833 }
5834
5835 let is_mysql_compatible = matches!(self.config.dialect,
5839 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::Doris) | Some(DialectType::StarRocks) | None
5840 );
5841 let is_hive_compatible = matches!(self.config.dialect,
5842 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Athena)
5843 );
5844 let mysql_pretty_options = self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
5845 for (key, value) in &ct.mysql_table_options {
5846 let should_output = if is_mysql_compatible {
5848 true
5849 } else if is_hive_compatible && key == "COMMENT" {
5850 true } else {
5852 false
5853 };
5854 if should_output {
5855 if mysql_pretty_options {
5856 self.write_newline();
5857 self.write_indent();
5858 } else {
5859 self.write_space();
5860 }
5861 self.write_keyword(key);
5862 if key == "COMMENT" && !self.config.schema_comment_with_eq {
5864 self.write_space();
5865 } else {
5866 self.write("=");
5867 }
5868 self.write(value);
5869 }
5870 }
5871
5872 if ct.temporary
5874 && matches!(self.config.dialect, Some(DialectType::Spark) | Some(DialectType::Databricks))
5875 && ct.as_select.is_none()
5876 {
5877 self.write_space();
5878 self.write_keyword("USING PARQUET");
5879 }
5880
5881 if !ct.inherits.is_empty() {
5883 self.write_space();
5884 self.write_keyword("INHERITS");
5885 self.write(" (");
5886 for (i, parent) in ct.inherits.iter().enumerate() {
5887 if i > 0 {
5888 self.write(", ");
5889 }
5890 self.generate_table(parent)?;
5891 }
5892 self.write(")");
5893 }
5894
5895 if let Some(ref query) = ct.as_select {
5897 self.write_space();
5898 self.write_keyword("AS");
5899 self.write_space();
5900 if ct.as_select_parenthesized {
5901 self.write("(");
5902 }
5903 self.generate_expression(query)?;
5904 if ct.as_select_parenthesized {
5905 self.write(")");
5906 }
5907
5908 if let Some(with_data) = ct.with_data {
5910 self.write_space();
5911 self.write_keyword("WITH");
5912 if !with_data {
5913 self.write_space();
5914 self.write_keyword("NO");
5915 }
5916 self.write_space();
5917 self.write_keyword("DATA");
5918 }
5919
5920 if let Some(with_statistics) = ct.with_statistics {
5922 self.write_space();
5923 self.write_keyword("AND");
5924 if !with_statistics {
5925 self.write_space();
5926 self.write_keyword("NO");
5927 }
5928 self.write_space();
5929 self.write_keyword("STATISTICS");
5930 }
5931
5932 for index in &ct.teradata_indexes {
5934 self.write_space();
5935 match index.kind {
5936 TeradataIndexKind::NoPrimary => {
5937 self.write_keyword("NO PRIMARY INDEX");
5938 }
5939 TeradataIndexKind::Primary => {
5940 self.write_keyword("PRIMARY INDEX");
5941 }
5942 TeradataIndexKind::PrimaryAmp => {
5943 self.write_keyword("PRIMARY AMP INDEX");
5944 }
5945 TeradataIndexKind::Unique => {
5946 self.write_keyword("UNIQUE INDEX");
5947 }
5948 TeradataIndexKind::UniquePrimary => {
5949 self.write_keyword("UNIQUE PRIMARY INDEX");
5950 }
5951 TeradataIndexKind::Secondary => {
5952 self.write_keyword("INDEX");
5953 }
5954 }
5955 if let Some(ref name) = index.name {
5957 self.write_space();
5958 self.write(name);
5959 }
5960 if !index.columns.is_empty() {
5962 self.write(" (");
5963 for (i, col) in index.columns.iter().enumerate() {
5964 if i > 0 {
5965 self.write(", ");
5966 }
5967 self.write(col);
5968 }
5969 self.write(")");
5970 }
5971 }
5972
5973 if let Some(ref on_commit) = ct.on_commit {
5975 self.write_space();
5976 self.write_keyword("ON COMMIT");
5977 self.write_space();
5978 match on_commit {
5979 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
5980 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
5981 }
5982 }
5983
5984 if !post_as_properties.is_empty() {
5985 for prop in post_as_properties {
5986 self.write_space();
5987 self.generate_expression(prop)?;
5988 }
5989 }
5990
5991 self.athena_hive_context = saved_athena_hive_context;
5993 return Ok(());
5994 }
5995
5996 if let Some(ref on_commit) = ct.on_commit {
5998 self.write_space();
5999 self.write_keyword("ON COMMIT");
6000 self.write_space();
6001 match on_commit {
6002 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
6003 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
6004 }
6005 }
6006
6007 self.athena_hive_context = saved_athena_hive_context;
6009
6010 Ok(())
6011 }
6012
6013 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
6016 self.generate_identifier(&col.name)?;
6018 if !matches!(col.data_type, DataType::Unknown) {
6020 self.write_space();
6021 self.generate_data_type(&col.data_type)?;
6022 }
6023 for constraint in &col.constraints {
6025 if let ColumnConstraint::Path(path_expr) = constraint {
6026 self.write_space();
6027 self.write_keyword("PATH");
6028 self.write_space();
6029 self.generate_expression(path_expr)?;
6030 }
6031 }
6032 Ok(())
6033 }
6034
6035 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
6036 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
6038 && col.constraints.iter().any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
6039 let omit_computed_type = !self.config.computed_column_with_type
6041 && col.constraints.iter().any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
6042
6043 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
6046
6047 let has_no_type = col.no_type || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
6050 && col.constraints.is_empty());
6051
6052 self.generate_identifier(&col.name)?;
6053
6054 let serial_expansion = if matches!(self.config.dialect, Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)) {
6056 if let DataType::Custom { ref name } = col.data_type {
6057 match name.to_uppercase().as_str() {
6058 "SERIAL" => Some("INT"),
6059 "BIGSERIAL" => Some("BIGINT"),
6060 "SMALLSERIAL" => Some("SMALLINT"),
6061 _ => None,
6062 }
6063 } else {
6064 None
6065 }
6066 } else {
6067 None
6068 };
6069
6070 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type {
6071 self.write_space();
6072 if let Some(int_type) = serial_expansion {
6073 self.write_keyword(int_type);
6075 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6076 let unsigned_type = match &col.data_type {
6078 DataType::Int { .. } => Some("UINTEGER"),
6079 DataType::BigInt { .. } => Some("UBIGINT"),
6080 DataType::SmallInt { .. } => Some("USMALLINT"),
6081 DataType::TinyInt { .. } => Some("UTINYINT"),
6082 _ => None,
6083 };
6084 if let Some(utype) = unsigned_type {
6085 self.write_keyword(utype);
6086 } else {
6087 self.generate_data_type(&col.data_type)?;
6088 }
6089 } else {
6090 self.generate_data_type(&col.data_type)?;
6091 }
6092 }
6093
6094 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6097 self.write_space();
6098 self.write_keyword("UNSIGNED");
6099 }
6100 if col.zerofill {
6101 self.write_space();
6102 self.write_keyword("ZEROFILL");
6103 }
6104
6105 if let Some(ref charset) = col.character_set {
6109 self.write_space();
6110 self.write_keyword("CHARACTER SET");
6111 self.write_space();
6112 self.write(charset);
6113 }
6114
6115 if col.uppercase {
6116 self.write_space();
6117 self.write_keyword("UPPERCASE");
6118 }
6119
6120 if let Some(casespecific) = col.casespecific {
6121 self.write_space();
6122 if casespecific {
6123 self.write_keyword("CASESPECIFIC");
6124 } else {
6125 self.write_keyword("NOT CASESPECIFIC");
6126 }
6127 }
6128
6129 if let Some(ref format) = col.format {
6130 self.write_space();
6131 self.write_keyword("FORMAT");
6132 self.write(" '");
6133 self.write(format);
6134 self.write("'");
6135 }
6136
6137 if let Some(ref title) = col.title {
6138 self.write_space();
6139 self.write_keyword("TITLE");
6140 self.write(" '");
6141 self.write(title);
6142 self.write("'");
6143 }
6144
6145 if let Some(length) = col.inline_length {
6146 self.write_space();
6147 self.write_keyword("INLINE LENGTH");
6148 self.write(" ");
6149 self.write(&length.to_string());
6150 }
6151
6152 if let Some(ref compress) = col.compress {
6153 self.write_space();
6154 self.write_keyword("COMPRESS");
6155 if !compress.is_empty() {
6156 if compress.len() == 1 {
6158 if let Expression::Literal(Literal::String(_)) = &compress[0] {
6159 self.write_space();
6160 self.generate_expression(&compress[0])?;
6161 } else {
6162 self.write(" (");
6163 self.generate_expression(&compress[0])?;
6164 self.write(")");
6165 }
6166 } else {
6167 self.write(" (");
6168 for (i, val) in compress.iter().enumerate() {
6169 if i > 0 {
6170 self.write(", ");
6171 }
6172 self.generate_expression(val)?;
6173 }
6174 self.write(")");
6175 }
6176 }
6177 }
6178
6179 if !col.constraint_order.is_empty() {
6182 let mut references_idx = 0;
6185 let mut check_idx = 0;
6186 let mut generated_idx = 0;
6187 let mut collate_idx = 0;
6188 let mut comment_idx = 0;
6189 let defer_not_null_after_identity = false;
6192 let mut pending_not_null_after_identity = false;
6193
6194 for constraint_type in &col.constraint_order {
6195 match constraint_type {
6196 ConstraintType::PrimaryKey => {
6197 if col.primary_key && !matches!(self.config.dialect, Some(DialectType::Materialize)) {
6199 if let Some(ref cname) = col.primary_key_constraint_name {
6200 self.write_space();
6201 self.write_keyword("CONSTRAINT");
6202 self.write_space();
6203 self.write(cname);
6204 }
6205 self.write_space();
6206 self.write_keyword("PRIMARY KEY");
6207 if let Some(ref order) = col.primary_key_order {
6208 self.write_space();
6209 match order {
6210 SortOrder::Asc => self.write_keyword("ASC"),
6211 SortOrder::Desc => self.write_keyword("DESC"),
6212 }
6213 }
6214 }
6215 }
6216 ConstraintType::Unique => {
6217 if col.unique {
6218 if let Some(ref cname) = col.unique_constraint_name {
6219 self.write_space();
6220 self.write_keyword("CONSTRAINT");
6221 self.write_space();
6222 self.write(cname);
6223 }
6224 self.write_space();
6225 self.write_keyword("UNIQUE");
6226 if col.unique_nulls_not_distinct {
6228 self.write(" NULLS NOT DISTINCT");
6229 }
6230 }
6231 }
6232 ConstraintType::NotNull => {
6233 if col.nullable == Some(false) {
6234 if defer_not_null_after_identity {
6235 pending_not_null_after_identity = true;
6236 continue;
6237 }
6238 if let Some(ref cname) = col.not_null_constraint_name {
6239 self.write_space();
6240 self.write_keyword("CONSTRAINT");
6241 self.write_space();
6242 self.write(cname);
6243 }
6244 self.write_space();
6245 self.write_keyword("NOT NULL");
6246 }
6247 }
6248 ConstraintType::Null => {
6249 if col.nullable == Some(true) {
6250 self.write_space();
6251 self.write_keyword("NULL");
6252 }
6253 }
6254 ConstraintType::Default => {
6255 if let Some(ref default) = col.default {
6256 self.write_space();
6257 self.write_keyword("DEFAULT");
6258 self.write_space();
6259 self.generate_expression(default)?;
6260 }
6261 }
6262 ConstraintType::AutoIncrement => {
6263 if col.auto_increment {
6264 if matches!(self.config.dialect, Some(crate::dialects::DialectType::DuckDB)) {
6266 } else if matches!(self.config.dialect, Some(crate::dialects::DialectType::Materialize)) {
6268 if !matches!(col.nullable, Some(false)) {
6270 self.write_space();
6271 self.write_keyword("NOT NULL");
6272 }
6273 } else {
6274 self.write_space();
6275 self.generate_auto_increment_keyword(col)?;
6276 if pending_not_null_after_identity {
6277 self.write_space();
6278 self.write_keyword("NOT NULL");
6279 pending_not_null_after_identity = false;
6280 }
6281 }
6282 } }
6284 ConstraintType::References => {
6285 while references_idx < col.constraints.len() {
6287 if let ColumnConstraint::References(fk_ref) = &col.constraints[references_idx] {
6288 if let Some(ref name) = fk_ref.constraint_name {
6290 self.write_space();
6291 self.write_keyword("CONSTRAINT");
6292 self.write_space();
6293 self.write(name);
6294 }
6295 self.write_space();
6296 if fk_ref.has_foreign_key_keywords {
6297 self.write_keyword("FOREIGN KEY");
6298 self.write_space();
6299 }
6300 self.write_keyword("REFERENCES");
6301 self.write_space();
6302 self.generate_table(&fk_ref.table)?;
6303 if !fk_ref.columns.is_empty() {
6304 self.write(" (");
6305 for (i, c) in fk_ref.columns.iter().enumerate() {
6306 if i > 0 {
6307 self.write(", ");
6308 }
6309 self.generate_identifier(c)?;
6310 }
6311 self.write(")");
6312 }
6313 self.generate_referential_actions(fk_ref)?;
6314 references_idx += 1;
6315 break;
6316 }
6317 references_idx += 1;
6318 }
6319 }
6320 ConstraintType::Check => {
6321 while check_idx < col.constraints.len() {
6323 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
6324 if check_idx == 0 {
6326 if let Some(ref cname) = col.check_constraint_name {
6327 self.write_space();
6328 self.write_keyword("CONSTRAINT");
6329 self.write_space();
6330 self.write(cname);
6331 }
6332 }
6333 self.write_space();
6334 self.write_keyword("CHECK");
6335 self.write(" (");
6336 self.generate_expression(expr)?;
6337 self.write(")");
6338 check_idx += 1;
6339 break;
6340 }
6341 check_idx += 1;
6342 }
6343 }
6344 ConstraintType::GeneratedAsIdentity => {
6345 while generated_idx < col.constraints.len() {
6347 if let ColumnConstraint::GeneratedAsIdentity(gen) = &col.constraints[generated_idx] {
6348 self.write_space();
6349 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Redshift)) {
6351 self.write_keyword("IDENTITY");
6352 self.write("(");
6353 if let Some(ref start) = gen.start {
6354 self.generate_expression(start)?;
6355 } else {
6356 self.write("0");
6357 }
6358 self.write(", ");
6359 if let Some(ref incr) = gen.increment {
6360 self.generate_expression(incr)?;
6361 } else {
6362 self.write("1");
6363 }
6364 self.write(")");
6365 } else {
6366 self.write_keyword("GENERATED");
6367 if gen.always {
6368 self.write_space();
6369 self.write_keyword("ALWAYS");
6370 } else {
6371 self.write_space();
6372 self.write_keyword("BY DEFAULT");
6373 if gen.on_null {
6374 self.write_space();
6375 self.write_keyword("ON NULL");
6376 }
6377 }
6378 self.write_space();
6379 self.write_keyword("AS IDENTITY");
6380
6381 let has_options = gen.start.is_some() || gen.increment.is_some()
6382 || gen.minvalue.is_some() || gen.maxvalue.is_some() || gen.cycle.is_some();
6383 if has_options {
6384 self.write(" (");
6385 let mut first = true;
6386 if let Some(ref start) = gen.start {
6387 if !first { self.write(" "); }
6388 first = false;
6389 self.write_keyword("START WITH");
6390 self.write_space();
6391 self.generate_expression(start)?;
6392 }
6393 if let Some(ref incr) = gen.increment {
6394 if !first { self.write(" "); }
6395 first = false;
6396 self.write_keyword("INCREMENT BY");
6397 self.write_space();
6398 self.generate_expression(incr)?;
6399 }
6400 if let Some(ref minv) = gen.minvalue {
6401 if !first { self.write(" "); }
6402 first = false;
6403 self.write_keyword("MINVALUE");
6404 self.write_space();
6405 self.generate_expression(minv)?;
6406 }
6407 if let Some(ref maxv) = gen.maxvalue {
6408 if !first { self.write(" "); }
6409 first = false;
6410 self.write_keyword("MAXVALUE");
6411 self.write_space();
6412 self.generate_expression(maxv)?;
6413 }
6414 if let Some(cycle) = gen.cycle {
6415 if !first { self.write(" "); }
6416 if cycle {
6417 self.write_keyword("CYCLE");
6418 } else {
6419 self.write_keyword("NO CYCLE");
6420 }
6421 }
6422 self.write(")");
6423 }
6424 }
6425 generated_idx += 1;
6426 break;
6427 }
6428 generated_idx += 1;
6429 }
6430 }
6431 ConstraintType::Collate => {
6432 while collate_idx < col.constraints.len() {
6434 if let ColumnConstraint::Collate(collation) = &col.constraints[collate_idx] {
6435 self.write_space();
6436 self.write_keyword("COLLATE");
6437 self.write_space();
6438 self.generate_identifier(collation)?;
6439 collate_idx += 1;
6440 break;
6441 }
6442 collate_idx += 1;
6443 }
6444 }
6445 ConstraintType::Comment => {
6446 while comment_idx < col.constraints.len() {
6448 if let ColumnConstraint::Comment(comment) = &col.constraints[comment_idx] {
6449 self.write_space();
6450 self.write_keyword("COMMENT");
6451 self.write_space();
6452 self.generate_string_literal(comment)?;
6453 comment_idx += 1;
6454 break;
6455 }
6456 comment_idx += 1;
6457 }
6458 }
6459 ConstraintType::Tags => {
6460 for constraint in &col.constraints {
6462 if let ColumnConstraint::Tags(tags) = constraint {
6463 self.write_space();
6464 self.write_keyword("TAG");
6465 self.write(" (");
6466 for (i, expr) in tags.expressions.iter().enumerate() {
6467 if i > 0 {
6468 self.write(", ");
6469 }
6470 self.generate_expression(expr)?;
6471 }
6472 self.write(")");
6473 break;
6474 }
6475 }
6476 }
6477 ConstraintType::ComputedColumn => {
6478 for constraint in &col.constraints {
6480 if let ColumnConstraint::ComputedColumn(cc) = constraint {
6481 self.write_space();
6482 self.generate_computed_column_inline(cc)?;
6483 break;
6484 }
6485 }
6486 }
6487 ConstraintType::GeneratedAsRow => {
6488 for constraint in &col.constraints {
6490 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
6491 self.write_space();
6492 self.generate_generated_as_row_inline(gar)?;
6493 break;
6494 }
6495 }
6496 }
6497 ConstraintType::OnUpdate => {
6498 if let Some(ref expr) = col.on_update {
6499 self.write_space();
6500 self.write_keyword("ON UPDATE");
6501 self.write_space();
6502 self.generate_expression(expr)?;
6503 }
6504 }
6505 ConstraintType::Encode => {
6506 if let Some(ref encoding) = col.encoding {
6507 self.write_space();
6508 self.write_keyword("ENCODE");
6509 self.write_space();
6510 self.write(encoding);
6511 }
6512 }
6513 ConstraintType::Path => {
6514 for constraint in &col.constraints {
6516 if let ColumnConstraint::Path(path_expr) = constraint {
6517 self.write_space();
6518 self.write_keyword("PATH");
6519 self.write_space();
6520 self.generate_expression(path_expr)?;
6521 break;
6522 }
6523 }
6524 }
6525 }
6526 }
6527 if pending_not_null_after_identity {
6528 self.write_space();
6529 self.write_keyword("NOT NULL");
6530 }
6531 } else {
6532 if col.primary_key {
6534 self.write_space();
6535 self.write_keyword("PRIMARY KEY");
6536 if let Some(ref order) = col.primary_key_order {
6537 self.write_space();
6538 match order {
6539 SortOrder::Asc => self.write_keyword("ASC"),
6540 SortOrder::Desc => self.write_keyword("DESC"),
6541 }
6542 }
6543 }
6544
6545 if col.unique {
6546 self.write_space();
6547 self.write_keyword("UNIQUE");
6548 if col.unique_nulls_not_distinct {
6550 self.write(" NULLS NOT DISTINCT");
6551 }
6552 }
6553
6554 match col.nullable {
6555 Some(false) => {
6556 self.write_space();
6557 self.write_keyword("NOT NULL");
6558 }
6559 Some(true) => {
6560 self.write_space();
6561 self.write_keyword("NULL");
6562 }
6563 None => {}
6564 }
6565
6566 if let Some(ref default) = col.default {
6567 self.write_space();
6568 self.write_keyword("DEFAULT");
6569 self.write_space();
6570 self.generate_expression(default)?;
6571 }
6572
6573 if col.auto_increment {
6574 self.write_space();
6575 self.generate_auto_increment_keyword(col)?;
6576 }
6577
6578 for constraint in &col.constraints {
6580 match constraint {
6581 ColumnConstraint::References(fk_ref) => {
6582 self.write_space();
6583 if fk_ref.has_foreign_key_keywords {
6584 self.write_keyword("FOREIGN KEY");
6585 self.write_space();
6586 }
6587 self.write_keyword("REFERENCES");
6588 self.write_space();
6589 self.generate_table(&fk_ref.table)?;
6590 if !fk_ref.columns.is_empty() {
6591 self.write(" (");
6592 for (i, c) in fk_ref.columns.iter().enumerate() {
6593 if i > 0 {
6594 self.write(", ");
6595 }
6596 self.generate_identifier(c)?;
6597 }
6598 self.write(")");
6599 }
6600 self.generate_referential_actions(fk_ref)?;
6601 }
6602 ColumnConstraint::Check(expr) => {
6603 self.write_space();
6604 self.write_keyword("CHECK");
6605 self.write(" (");
6606 self.generate_expression(expr)?;
6607 self.write(")");
6608 }
6609 ColumnConstraint::GeneratedAsIdentity(gen) => {
6610 self.write_space();
6611 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Redshift)) {
6613 self.write_keyword("IDENTITY");
6614 self.write("(");
6615 if let Some(ref start) = gen.start {
6616 self.generate_expression(start)?;
6617 } else {
6618 self.write("0");
6619 }
6620 self.write(", ");
6621 if let Some(ref incr) = gen.increment {
6622 self.generate_expression(incr)?;
6623 } else {
6624 self.write("1");
6625 }
6626 self.write(")");
6627 } else {
6628 self.write_keyword("GENERATED");
6629 if gen.always {
6630 self.write_space();
6631 self.write_keyword("ALWAYS");
6632 } else {
6633 self.write_space();
6634 self.write_keyword("BY DEFAULT");
6635 if gen.on_null {
6636 self.write_space();
6637 self.write_keyword("ON NULL");
6638 }
6639 }
6640 self.write_space();
6641 self.write_keyword("AS IDENTITY");
6642
6643 let has_options = gen.start.is_some() || gen.increment.is_some()
6644 || gen.minvalue.is_some() || gen.maxvalue.is_some() || gen.cycle.is_some();
6645 if has_options {
6646 self.write(" (");
6647 let mut first = true;
6648 if let Some(ref start) = gen.start {
6649 if !first { self.write(" "); }
6650 first = false;
6651 self.write_keyword("START WITH");
6652 self.write_space();
6653 self.generate_expression(start)?;
6654 }
6655 if let Some(ref incr) = gen.increment {
6656 if !first { self.write(" "); }
6657 first = false;
6658 self.write_keyword("INCREMENT BY");
6659 self.write_space();
6660 self.generate_expression(incr)?;
6661 }
6662 if let Some(ref minv) = gen.minvalue {
6663 if !first { self.write(" "); }
6664 first = false;
6665 self.write_keyword("MINVALUE");
6666 self.write_space();
6667 self.generate_expression(minv)?;
6668 }
6669 if let Some(ref maxv) = gen.maxvalue {
6670 if !first { self.write(" "); }
6671 first = false;
6672 self.write_keyword("MAXVALUE");
6673 self.write_space();
6674 self.generate_expression(maxv)?;
6675 }
6676 if let Some(cycle) = gen.cycle {
6677 if !first { self.write(" "); }
6678 if cycle {
6679 self.write_keyword("CYCLE");
6680 } else {
6681 self.write_keyword("NO CYCLE");
6682 }
6683 }
6684 self.write(")");
6685 }
6686 }
6687 }
6688 ColumnConstraint::Collate(collation) => {
6689 self.write_space();
6690 self.write_keyword("COLLATE");
6691 self.write_space();
6692 self.generate_identifier(collation)?;
6693 }
6694 ColumnConstraint::Comment(comment) => {
6695 self.write_space();
6696 self.write_keyword("COMMENT");
6697 self.write_space();
6698 self.generate_string_literal(comment)?;
6699 }
6700 ColumnConstraint::Path(path_expr) => {
6701 self.write_space();
6702 self.write_keyword("PATH");
6703 self.write_space();
6704 self.generate_expression(path_expr)?;
6705 }
6706 _ => {} }
6708 }
6709
6710 if let Some(ref encoding) = col.encoding {
6712 self.write_space();
6713 self.write_keyword("ENCODE");
6714 self.write_space();
6715 self.write(encoding);
6716 }
6717 }
6718
6719 if let Some(ref codec) = col.codec {
6721 self.write_space();
6722 self.write_keyword("CODEC");
6723 self.write("(");
6724 self.write(codec);
6725 self.write(")");
6726 }
6727
6728 if let Some(ref ephemeral) = col.ephemeral {
6730 self.write_space();
6731 self.write_keyword("EPHEMERAL");
6732 if let Some(ref expr) = ephemeral {
6733 self.write_space();
6734 self.generate_expression(expr)?;
6735 }
6736 }
6737
6738 if let Some(ref mat_expr) = col.materialized_expr {
6740 self.write_space();
6741 self.write_keyword("MATERIALIZED");
6742 self.write_space();
6743 self.generate_expression(mat_expr)?;
6744 }
6745
6746 if let Some(ref alias_expr) = col.alias_expr {
6748 self.write_space();
6749 self.write_keyword("ALIAS");
6750 self.write_space();
6751 self.generate_expression(alias_expr)?;
6752 }
6753
6754 if let Some(ref ttl_expr) = col.ttl_expr {
6756 self.write_space();
6757 self.write_keyword("TTL");
6758 self.write_space();
6759 self.generate_expression(ttl_expr)?;
6760 }
6761
6762 if col.not_for_replication && matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL) | Some(crate::dialects::DialectType::Fabric)) {
6764 self.write_space();
6765 self.write_keyword("NOT FOR REPLICATION");
6766 }
6767
6768 if !col.options.is_empty() {
6770 self.write_space();
6771 self.generate_options_clause(&col.options)?;
6772 }
6773
6774 if !col.primary_key && self.sqlite_inline_pk_columns.contains(&col.name.name.to_lowercase()) {
6777 self.write_space();
6778 self.write_keyword("PRIMARY KEY");
6779 }
6780
6781 if serial_expansion.is_some() {
6784 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
6785 self.write_space();
6786 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
6787 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
6788 self.write_space();
6789 self.write_keyword("NOT NULL");
6790 }
6791 }
6792
6793 Ok(())
6794 }
6795
6796 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
6797 match constraint {
6798 TableConstraint::PrimaryKey { name, columns, include_columns, modifiers, has_constraint_keyword } => {
6799 if let Some(ref n) = name {
6800 if *has_constraint_keyword {
6801 self.write_keyword("CONSTRAINT");
6802 self.write_space();
6803 self.generate_identifier(n)?;
6804 self.write_space();
6805 }
6806 }
6807 self.write_keyword("PRIMARY KEY");
6808 if let Some(ref clustered) = modifiers.clustered {
6810 self.write_space();
6811 self.write_keyword(clustered);
6812 }
6813 if let Some(ref n) = name {
6815 if !*has_constraint_keyword {
6816 self.write_space();
6817 self.generate_identifier(n)?;
6818 }
6819 }
6820 self.write(" (");
6821 for (i, col) in columns.iter().enumerate() {
6822 if i > 0 {
6823 self.write(", ");
6824 }
6825 self.generate_identifier(col)?;
6826 }
6827 self.write(")");
6828 if !include_columns.is_empty() {
6829 self.write_space();
6830 self.write_keyword("INCLUDE");
6831 self.write(" (");
6832 for (i, col) in include_columns.iter().enumerate() {
6833 if i > 0 {
6834 self.write(", ");
6835 }
6836 self.generate_identifier(col)?;
6837 }
6838 self.write(")");
6839 }
6840 self.generate_constraint_modifiers(modifiers);
6841 }
6842 TableConstraint::Unique { name, columns, columns_parenthesized, modifiers, has_constraint_keyword, nulls_not_distinct } => {
6843 if let Some(ref n) = name {
6844 if *has_constraint_keyword {
6845 self.write_keyword("CONSTRAINT");
6846 self.write_space();
6847 self.generate_identifier(n)?;
6848 self.write_space();
6849 }
6850 }
6851 self.write_keyword("UNIQUE");
6852 if let Some(ref clustered) = modifiers.clustered {
6854 self.write_space();
6855 self.write_keyword(clustered);
6856 }
6857 if *nulls_not_distinct {
6859 self.write(" NULLS NOT DISTINCT");
6860 }
6861 if let Some(ref n) = name {
6863 if !*has_constraint_keyword {
6864 self.write_space();
6865 self.generate_identifier(n)?;
6866 }
6867 }
6868 if *columns_parenthesized {
6869 self.write(" (");
6870 for (i, col) in columns.iter().enumerate() {
6871 if i > 0 {
6872 self.write(", ");
6873 }
6874 self.generate_identifier(col)?;
6875 }
6876 self.write(")");
6877 } else {
6878 for col in columns.iter() {
6880 self.write_space();
6881 self.generate_identifier(col)?;
6882 }
6883 }
6884 self.generate_constraint_modifiers(modifiers);
6885 }
6886 TableConstraint::ForeignKey { name, columns, references, on_delete, on_update, modifiers } => {
6887 if let Some(ref n) = name {
6888 self.write_keyword("CONSTRAINT");
6889 self.write_space();
6890 self.generate_identifier(n)?;
6891 self.write_space();
6892 }
6893 self.write_keyword("FOREIGN KEY");
6894 self.write(" (");
6895 for (i, col) in columns.iter().enumerate() {
6896 if i > 0 {
6897 self.write(", ");
6898 }
6899 self.generate_identifier(col)?;
6900 }
6901 self.write(")");
6902 if let Some(ref refs) = references {
6903 self.write(" ");
6904 self.write_keyword("REFERENCES");
6905 self.write_space();
6906 self.generate_table(&refs.table)?;
6907 if !refs.columns.is_empty() {
6908 if self.config.pretty {
6909 self.write(" (");
6910 self.write_newline();
6911 self.indent_level += 1;
6912 for (i, col) in refs.columns.iter().enumerate() {
6913 if i > 0 {
6914 self.write(",");
6915 self.write_newline();
6916 }
6917 self.write_indent();
6918 self.generate_identifier(col)?;
6919 }
6920 self.indent_level -= 1;
6921 self.write_newline();
6922 self.write_indent();
6923 self.write(")");
6924 } else {
6925 self.write(" (");
6926 for (i, col) in refs.columns.iter().enumerate() {
6927 if i > 0 {
6928 self.write(", ");
6929 }
6930 self.generate_identifier(col)?;
6931 }
6932 self.write(")");
6933 }
6934 }
6935 self.generate_referential_actions(refs)?;
6936 } else {
6937 if let Some(ref action) = on_delete {
6939 self.write_space();
6940 self.write_keyword("ON DELETE");
6941 self.write_space();
6942 self.generate_referential_action(action);
6943 }
6944 if let Some(ref action) = on_update {
6945 self.write_space();
6946 self.write_keyword("ON UPDATE");
6947 self.write_space();
6948 self.generate_referential_action(action);
6949 }
6950 }
6951 self.generate_constraint_modifiers(modifiers);
6952 }
6953 TableConstraint::Check { name, expression, modifiers } => {
6954 if let Some(ref n) = name {
6955 self.write_keyword("CONSTRAINT");
6956 self.write_space();
6957 self.generate_identifier(n)?;
6958 self.write_space();
6959 }
6960 self.write_keyword("CHECK");
6961 self.write(" (");
6962 self.generate_expression(expression)?;
6963 self.write(")");
6964 self.generate_constraint_modifiers(modifiers);
6965 }
6966 TableConstraint::Index { name, columns, kind, modifiers, use_key_keyword, expression, index_type, granularity } => {
6967 if expression.is_some() {
6969 self.write_keyword("INDEX");
6970 if let Some(ref n) = name {
6971 self.write_space();
6972 self.generate_identifier(n)?;
6973 }
6974 if let Some(ref expr) = expression {
6975 self.write_space();
6976 self.generate_expression(expr)?;
6977 }
6978 if let Some(ref idx_type) = index_type {
6979 self.write_space();
6980 self.write_keyword("TYPE");
6981 self.write_space();
6982 self.generate_expression(idx_type)?;
6983 }
6984 if let Some(ref gran) = granularity {
6985 self.write_space();
6986 self.write_keyword("GRANULARITY");
6987 self.write_space();
6988 self.generate_expression(gran)?;
6989 }
6990 } else {
6991 use crate::dialects::DialectType;
6995 let index_keyword = if *use_key_keyword && !matches!(self.config.dialect, Some(DialectType::MySQL)) {
6996 "KEY"
6997 } else {
6998 "INDEX"
6999 };
7000
7001 if let Some(ref k) = kind {
7003 self.write_keyword(k);
7004 if k != "UNIQUE" {
7006 self.write_space();
7007 self.write_keyword(index_keyword);
7008 }
7009 } else {
7010 self.write_keyword(index_keyword);
7011 }
7012
7013 if modifiers.using_before_columns && name.is_none() {
7015 if let Some(ref using) = modifiers.using {
7016 self.write_space();
7017 self.write_keyword("USING");
7018 self.write_space();
7019 self.write_keyword(using);
7020 }
7021 }
7022
7023 if let Some(ref n) = name {
7025 self.write_space();
7026 self.generate_identifier(n)?;
7027 }
7028
7029 if modifiers.using_before_columns && name.is_some() {
7031 if let Some(ref using) = modifiers.using {
7032 self.write_space();
7033 self.write_keyword("USING");
7034 self.write_space();
7035 self.write_keyword(using);
7036 }
7037 }
7038
7039 self.write(" (");
7041 for (i, col) in columns.iter().enumerate() {
7042 if i > 0 {
7043 self.write(", ");
7044 }
7045 self.generate_identifier(col)?;
7046 }
7047 self.write(")");
7048
7049 if !modifiers.using_before_columns {
7051 if let Some(ref using) = modifiers.using {
7052 self.write_space();
7053 self.write_keyword("USING");
7054 self.write_space();
7055 self.write_keyword(using);
7056 }
7057 }
7058
7059 self.generate_constraint_modifiers_without_using(modifiers);
7061 }
7062 }
7063 TableConstraint::Projection { name, expression } => {
7064 self.write_keyword("PROJECTION");
7066 self.write_space();
7067 self.generate_identifier(name)?;
7068 self.write(" (");
7069 self.generate_expression(expression)?;
7070 self.write(")");
7071 }
7072 TableConstraint::Like { source, options } => {
7073 self.write_keyword("LIKE");
7074 self.write_space();
7075 self.generate_table(source)?;
7076 for (action, prop) in options {
7077 self.write_space();
7078 match action {
7079 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
7080 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
7081 }
7082 self.write_space();
7083 self.write_keyword(prop);
7084 }
7085 }
7086 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
7087 self.write_keyword("PERIOD FOR SYSTEM_TIME");
7088 self.write(" (");
7089 self.generate_identifier(start_col)?;
7090 self.write(", ");
7091 self.generate_identifier(end_col)?;
7092 self.write(")");
7093 }
7094 TableConstraint::Exclude { name, using, elements, include_columns, where_clause, with_params, using_index_tablespace, modifiers: _ } => {
7095 if let Some(ref n) = name {
7096 self.write_keyword("CONSTRAINT");
7097 self.write_space();
7098 self.generate_identifier(n)?;
7099 self.write_space();
7100 }
7101 self.write_keyword("EXCLUDE");
7102 if let Some(ref method) = using {
7103 self.write_space();
7104 self.write_keyword("USING");
7105 self.write_space();
7106 self.write(method);
7107 self.write("(");
7108 } else {
7109 self.write(" (");
7110 }
7111 for (i, elem) in elements.iter().enumerate() {
7112 if i > 0 {
7113 self.write(", ");
7114 }
7115 self.write(&elem.expression);
7116 self.write_space();
7117 self.write_keyword("WITH");
7118 self.write_space();
7119 self.write(&elem.operator);
7120 }
7121 self.write(")");
7122 if !include_columns.is_empty() {
7123 self.write_space();
7124 self.write_keyword("INCLUDE");
7125 self.write(" (");
7126 for (i, col) in include_columns.iter().enumerate() {
7127 if i > 0 {
7128 self.write(", ");
7129 }
7130 self.generate_identifier(col)?;
7131 }
7132 self.write(")");
7133 }
7134 if !with_params.is_empty() {
7135 self.write_space();
7136 self.write_keyword("WITH");
7137 self.write(" (");
7138 for (i, (key, val)) in with_params.iter().enumerate() {
7139 if i > 0 {
7140 self.write(", ");
7141 }
7142 self.write(key);
7143 self.write("=");
7144 self.write(val);
7145 }
7146 self.write(")");
7147 }
7148 if let Some(ref tablespace) = using_index_tablespace {
7149 self.write_space();
7150 self.write_keyword("USING INDEX TABLESPACE");
7151 self.write_space();
7152 self.write(tablespace);
7153 }
7154 if let Some(ref where_expr) = where_clause {
7155 self.write_space();
7156 self.write_keyword("WHERE");
7157 self.write(" (");
7158 self.generate_expression(where_expr)?;
7159 self.write(")");
7160 }
7161 }
7162 TableConstraint::Tags(tags) => {
7163 self.write_keyword("TAG");
7164 self.write(" (");
7165 for (i, expr) in tags.expressions.iter().enumerate() {
7166 if i > 0 {
7167 self.write(", ");
7168 }
7169 self.generate_expression(expr)?;
7170 }
7171 self.write(")");
7172 }
7173 TableConstraint::InitiallyDeferred { deferred } => {
7174 self.write_keyword("INITIALLY");
7175 self.write_space();
7176 if *deferred {
7177 self.write_keyword("DEFERRED");
7178 } else {
7179 self.write_keyword("IMMEDIATE");
7180 }
7181 }
7182 }
7183 Ok(())
7184 }
7185
7186 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
7187 if let Some(using) = &modifiers.using {
7189 self.write_space();
7190 self.write_keyword("USING");
7191 self.write_space();
7192 self.write_keyword(using);
7193 }
7194 if let Some(enforced) = modifiers.enforced {
7196 self.write_space();
7197 if enforced {
7198 self.write_keyword("ENFORCED");
7199 } else {
7200 self.write_keyword("NOT ENFORCED");
7201 }
7202 }
7203 if let Some(deferrable) = modifiers.deferrable {
7205 self.write_space();
7206 if deferrable {
7207 self.write_keyword("DEFERRABLE");
7208 } else {
7209 self.write_keyword("NOT DEFERRABLE");
7210 }
7211 }
7212 if let Some(initially_deferred) = modifiers.initially_deferred {
7214 self.write_space();
7215 if initially_deferred {
7216 self.write_keyword("INITIALLY DEFERRED");
7217 } else {
7218 self.write_keyword("INITIALLY IMMEDIATE");
7219 }
7220 }
7221 if modifiers.norely {
7223 self.write_space();
7224 self.write_keyword("NORELY");
7225 }
7226 if modifiers.rely {
7228 self.write_space();
7229 self.write_keyword("RELY");
7230 }
7231 if modifiers.not_valid {
7233 self.write_space();
7234 self.write_keyword("NOT VALID");
7235 }
7236 if let Some(on_conflict) = &modifiers.on_conflict {
7238 self.write_space();
7239 self.write_keyword("ON CONFLICT");
7240 self.write_space();
7241 self.write_keyword(on_conflict);
7242 }
7243 if !modifiers.with_options.is_empty() {
7245 self.write_space();
7246 self.write_keyword("WITH");
7247 self.write(" (");
7248 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
7249 if i > 0 {
7250 self.write(", ");
7251 }
7252 self.write(key);
7253 self.write("=");
7254 self.write(value);
7255 }
7256 self.write(")");
7257 }
7258 if let Some(ref fg) = modifiers.on_filegroup {
7260 self.write_space();
7261 self.write_keyword("ON");
7262 self.write_space();
7263 let _ = self.generate_identifier(fg);
7264 }
7265 }
7266
7267 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
7269 if let Some(enforced) = modifiers.enforced {
7271 self.write_space();
7272 if enforced {
7273 self.write_keyword("ENFORCED");
7274 } else {
7275 self.write_keyword("NOT ENFORCED");
7276 }
7277 }
7278 if let Some(deferrable) = modifiers.deferrable {
7280 self.write_space();
7281 if deferrable {
7282 self.write_keyword("DEFERRABLE");
7283 } else {
7284 self.write_keyword("NOT DEFERRABLE");
7285 }
7286 }
7287 if let Some(initially_deferred) = modifiers.initially_deferred {
7289 self.write_space();
7290 if initially_deferred {
7291 self.write_keyword("INITIALLY DEFERRED");
7292 } else {
7293 self.write_keyword("INITIALLY IMMEDIATE");
7294 }
7295 }
7296 if modifiers.norely {
7298 self.write_space();
7299 self.write_keyword("NORELY");
7300 }
7301 if modifiers.rely {
7303 self.write_space();
7304 self.write_keyword("RELY");
7305 }
7306 if modifiers.not_valid {
7308 self.write_space();
7309 self.write_keyword("NOT VALID");
7310 }
7311 if let Some(on_conflict) = &modifiers.on_conflict {
7313 self.write_space();
7314 self.write_keyword("ON CONFLICT");
7315 self.write_space();
7316 self.write_keyword(on_conflict);
7317 }
7318 self.generate_index_specific_modifiers(modifiers);
7320 }
7321
7322 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
7324 if let Some(ref comment) = modifiers.comment {
7325 self.write_space();
7326 self.write_keyword("COMMENT");
7327 self.write(" '");
7328 self.write(comment);
7329 self.write("'");
7330 }
7331 if let Some(visible) = modifiers.visible {
7332 self.write_space();
7333 if visible {
7334 self.write_keyword("VISIBLE");
7335 } else {
7336 self.write_keyword("INVISIBLE");
7337 }
7338 }
7339 if let Some(ref attr) = modifiers.engine_attribute {
7340 self.write_space();
7341 self.write_keyword("ENGINE_ATTRIBUTE");
7342 self.write(" = '");
7343 self.write(attr);
7344 self.write("'");
7345 }
7346 if let Some(ref parser) = modifiers.with_parser {
7347 self.write_space();
7348 self.write_keyword("WITH PARSER");
7349 self.write_space();
7350 self.write(parser);
7351 }
7352 }
7353
7354 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
7355 if !fk_ref.match_after_actions {
7357 if let Some(ref match_type) = fk_ref.match_type {
7358 self.write_space();
7359 self.write_keyword("MATCH");
7360 self.write_space();
7361 match match_type {
7362 MatchType::Full => self.write_keyword("FULL"),
7363 MatchType::Partial => self.write_keyword("PARTIAL"),
7364 MatchType::Simple => self.write_keyword("SIMPLE"),
7365 }
7366 }
7367 }
7368
7369 if fk_ref.on_update_first {
7371 if let Some(ref action) = fk_ref.on_update {
7372 self.write_space();
7373 self.write_keyword("ON UPDATE");
7374 self.write_space();
7375 self.generate_referential_action(action);
7376 }
7377 if let Some(ref action) = fk_ref.on_delete {
7378 self.write_space();
7379 self.write_keyword("ON DELETE");
7380 self.write_space();
7381 self.generate_referential_action(action);
7382 }
7383 } else {
7384 if let Some(ref action) = fk_ref.on_delete {
7385 self.write_space();
7386 self.write_keyword("ON DELETE");
7387 self.write_space();
7388 self.generate_referential_action(action);
7389 }
7390 if let Some(ref action) = fk_ref.on_update {
7391 self.write_space();
7392 self.write_keyword("ON UPDATE");
7393 self.write_space();
7394 self.generate_referential_action(action);
7395 }
7396 }
7397
7398 if fk_ref.match_after_actions {
7400 if let Some(ref match_type) = fk_ref.match_type {
7401 self.write_space();
7402 self.write_keyword("MATCH");
7403 self.write_space();
7404 match match_type {
7405 MatchType::Full => self.write_keyword("FULL"),
7406 MatchType::Partial => self.write_keyword("PARTIAL"),
7407 MatchType::Simple => self.write_keyword("SIMPLE"),
7408 }
7409 }
7410 }
7411
7412 if let Some(deferrable) = fk_ref.deferrable {
7414 self.write_space();
7415 if deferrable {
7416 self.write_keyword("DEFERRABLE");
7417 } else {
7418 self.write_keyword("NOT DEFERRABLE");
7419 }
7420 }
7421
7422 Ok(())
7423 }
7424
7425 fn generate_referential_action(&mut self, action: &ReferentialAction) {
7426 match action {
7427 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
7428 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
7429 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
7430 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
7431 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
7432 }
7433 }
7434
7435 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
7436 let saved_athena_hive_context = self.athena_hive_context;
7438 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Athena)) {
7439 self.athena_hive_context = true;
7440 }
7441
7442 self.write_keyword("DROP TABLE");
7443
7444 if dt.if_exists {
7445 self.write_space();
7446 self.write_keyword("IF EXISTS");
7447 }
7448
7449 self.write_space();
7450 for (i, table) in dt.names.iter().enumerate() {
7451 if i > 0 {
7452 self.write(", ");
7453 }
7454 self.generate_table(table)?;
7455 }
7456
7457 if dt.cascade_constraints {
7458 self.write_space();
7459 self.write_keyword("CASCADE CONSTRAINTS");
7460 } else if dt.cascade {
7461 self.write_space();
7462 self.write_keyword("CASCADE");
7463 }
7464
7465 if dt.purge {
7466 self.write_space();
7467 self.write_keyword("PURGE");
7468 }
7469
7470 self.athena_hive_context = saved_athena_hive_context;
7472
7473 Ok(())
7474 }
7475
7476 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
7477 let saved_athena_hive_context = self.athena_hive_context;
7479 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Athena)) {
7480 self.athena_hive_context = true;
7481 }
7482
7483 self.write_keyword("ALTER TABLE");
7484 if at.if_exists {
7485 self.write_space();
7486 self.write_keyword("IF EXISTS");
7487 }
7488 self.write_space();
7489 self.generate_table(&at.name)?;
7490
7491 if let Some(ref on_cluster) = at.on_cluster {
7493 self.write_space();
7494 self.generate_on_cluster(on_cluster)?;
7495 }
7496
7497 if let Some(ref partition) = at.partition {
7499 self.write_space();
7500 self.write_keyword("PARTITION");
7501 self.write("(");
7502 for (i, (key, value)) in partition.iter().enumerate() {
7503 if i > 0 {
7504 self.write(", ");
7505 }
7506 self.generate_identifier(key)?;
7507 self.write(" = ");
7508 self.generate_expression(value)?;
7509 }
7510 self.write(")");
7511 }
7512
7513 if let Some(ref with_check) = at.with_check {
7515 self.write_space();
7516 self.write_keyword(with_check);
7517 }
7518
7519 if self.config.pretty {
7520 self.write_newline();
7522 self.indent_level += 1;
7523 for (i, action) in at.actions.iter().enumerate() {
7524 let is_continuation = i > 0 && matches!(
7526 (&at.actions[i - 1], action),
7527 (AlterTableAction::AddColumn { .. }, AlterTableAction::AddColumn { .. })
7528 | (AlterTableAction::AddConstraint(_), AlterTableAction::AddConstraint(_))
7529 );
7530 if i > 0 {
7531 self.write(",");
7532 self.write_newline();
7533 }
7534 self.write_indent();
7535 self.generate_alter_action_with_continuation(action, is_continuation)?;
7536 }
7537 self.indent_level -= 1;
7538 } else {
7539 for (i, action) in at.actions.iter().enumerate() {
7540 let is_continuation = i > 0 && matches!(
7542 (&at.actions[i - 1], action),
7543 (AlterTableAction::AddColumn { .. }, AlterTableAction::AddColumn { .. })
7544 | (AlterTableAction::AddConstraint(_), AlterTableAction::AddConstraint(_))
7545 );
7546 if i > 0 {
7547 self.write(",");
7548 }
7549 self.write_space();
7550 self.generate_alter_action_with_continuation(action, is_continuation)?;
7551 }
7552 }
7553
7554 if let Some(ref algorithm) = at.algorithm {
7556 self.write(", ");
7557 self.write_keyword("ALGORITHM");
7558 self.write("=");
7559 self.write_keyword(algorithm);
7560 }
7561 if let Some(ref lock) = at.lock {
7562 self.write(", ");
7563 self.write_keyword("LOCK");
7564 self.write("=");
7565 self.write_keyword(lock);
7566 }
7567
7568 self.athena_hive_context = saved_athena_hive_context;
7570
7571 Ok(())
7572 }
7573
7574 fn generate_alter_action_with_continuation(&mut self, action: &AlterTableAction, is_continuation: bool) -> Result<()> {
7575 match action {
7576 AlterTableAction::AddColumn { column, if_not_exists, position } => {
7577 use crate::dialects::DialectType;
7578 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
7582 let is_tsql_like = matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric));
7583 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
7585
7586 if is_continuation && (is_snowflake || is_tsql_like) {
7587 } else if is_snowflake {
7589 self.write_keyword("ADD");
7590 self.write_space();
7591 } else if is_athena {
7592 self.write_keyword("ADD COLUMNS");
7594 self.write(" (");
7595 } else if self.config.alter_table_include_column_keyword {
7596 self.write_keyword("ADD COLUMN");
7597 self.write_space();
7598 } else {
7599 self.write_keyword("ADD");
7601 self.write_space();
7602 }
7603
7604 if *if_not_exists {
7605 self.write_keyword("IF NOT EXISTS");
7606 self.write_space();
7607 }
7608 self.generate_column_def(column)?;
7609
7610 if is_athena {
7612 self.write(")");
7613 }
7614
7615 if let Some(pos) = position {
7617 self.write_space();
7618 match pos {
7619 ColumnPosition::First => self.write_keyword("FIRST"),
7620 ColumnPosition::After(col_name) => {
7621 self.write_keyword("AFTER");
7622 self.write_space();
7623 self.generate_identifier(col_name)?;
7624 }
7625 }
7626 }
7627 }
7628 AlterTableAction::DropColumn { name, if_exists, cascade } => {
7629 self.write_keyword("DROP COLUMN");
7630 if *if_exists {
7631 self.write_space();
7632 self.write_keyword("IF EXISTS");
7633 }
7634 self.write_space();
7635 self.generate_identifier(name)?;
7636 if *cascade {
7637 self.write_space();
7638 self.write_keyword("CASCADE");
7639 }
7640 }
7641 AlterTableAction::DropColumns { names } => {
7642 self.write_keyword("DROP COLUMNS");
7643 self.write(" (");
7644 for (i, name) in names.iter().enumerate() {
7645 if i > 0 {
7646 self.write(", ");
7647 }
7648 self.generate_identifier(name)?;
7649 }
7650 self.write(")");
7651 }
7652 AlterTableAction::RenameColumn { old_name, new_name, if_exists } => {
7653 self.write_keyword("RENAME COLUMN");
7654 if *if_exists {
7655 self.write_space();
7656 self.write_keyword("IF EXISTS");
7657 }
7658 self.write_space();
7659 self.generate_identifier(old_name)?;
7660 self.write_space();
7661 self.write_keyword("TO");
7662 self.write_space();
7663 self.generate_identifier(new_name)?;
7664 }
7665 AlterTableAction::AlterColumn { name, action, use_modify_keyword } => {
7666 use crate::dialects::DialectType;
7667 let use_modify = *use_modify_keyword || (
7670 matches!(self.config.dialect, Some(DialectType::MySQL)) &&
7671 matches!(action, AlterColumnAction::SetDataType { .. })
7672 );
7673 if use_modify {
7674 self.write_keyword("MODIFY COLUMN");
7675 self.write_space();
7676 self.generate_identifier(name)?;
7677 if let AlterColumnAction::SetDataType { data_type, using: _, collate } = action {
7679 self.write_space();
7680 self.generate_data_type(data_type)?;
7681 if let Some(collate_name) = collate {
7683 self.write_space();
7684 self.write_keyword("COLLATE");
7685 self.write_space();
7686 self.write(&format!("'{}'", collate_name));
7688 }
7689 } else {
7690 self.write_space();
7691 self.generate_alter_column_action(action)?;
7692 }
7693 } else if matches!(self.config.dialect, Some(DialectType::Hive))
7694 && matches!(action, AlterColumnAction::SetDataType { .. })
7695 {
7696 self.write_keyword("CHANGE COLUMN");
7698 self.write_space();
7699 self.generate_identifier(name)?;
7700 self.write_space();
7701 self.generate_identifier(name)?;
7702 if let AlterColumnAction::SetDataType { data_type, .. } = action {
7703 self.write_space();
7704 self.generate_data_type(data_type)?;
7705 }
7706 } else {
7707 self.write_keyword("ALTER COLUMN");
7708 self.write_space();
7709 self.generate_identifier(name)?;
7710 self.write_space();
7711 self.generate_alter_column_action(action)?;
7712 }
7713 }
7714 AlterTableAction::RenameTable(new_name) => {
7715 let mysql_like = matches!(self.config.dialect, Some(DialectType::MySQL) | Some(DialectType::Doris) | Some(DialectType::StarRocks) | Some(DialectType::SingleStore));
7717 if mysql_like {
7718 self.write_keyword("RENAME");
7719 } else {
7720 self.write_keyword("RENAME TO");
7721 }
7722 self.write_space();
7723 let rename_table_with_db = !matches!(self.config.dialect, Some(DialectType::Doris) | Some(DialectType::DuckDB) | Some(DialectType::BigQuery) | Some(DialectType::PostgreSQL));
7725 if !rename_table_with_db {
7726 let mut stripped = new_name.clone();
7727 stripped.schema = None;
7728 stripped.catalog = None;
7729 self.generate_table(&stripped)?;
7730 } else {
7731 self.generate_table(new_name)?;
7732 }
7733 }
7734 AlterTableAction::AddConstraint(constraint) => {
7735 if !is_continuation {
7738 self.write_keyword("ADD");
7739 self.write_space();
7740 }
7741 self.generate_table_constraint(constraint)?;
7742 }
7743 AlterTableAction::DropConstraint { name, if_exists } => {
7744 self.write_keyword("DROP CONSTRAINT");
7745 if *if_exists {
7746 self.write_space();
7747 self.write_keyword("IF EXISTS");
7748 }
7749 self.write_space();
7750 self.generate_identifier(name)?;
7751 }
7752 AlterTableAction::DropForeignKey { name } => {
7753 self.write_keyword("DROP FOREIGN KEY");
7754 self.write_space();
7755 self.generate_identifier(name)?;
7756 }
7757 AlterTableAction::DropPartition { partitions, if_exists } => {
7758 self.write_keyword("DROP");
7759 if *if_exists {
7760 self.write_space();
7761 self.write_keyword("IF EXISTS");
7762 }
7763 for (i, partition) in partitions.iter().enumerate() {
7764 if i > 0 {
7765 self.write(",");
7766 }
7767 self.write_space();
7768 self.write_keyword("PARTITION");
7769 if partition.len() == 1 && partition[0].0.name == "__expr__" {
7771 self.write_space();
7773 self.generate_expression(&partition[0].1)?;
7774 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
7775 self.write_space();
7777 self.write_keyword("ALL");
7778 } else if partition.len() == 1 && partition[0].0.name == "ID" {
7779 self.write_space();
7781 self.write_keyword("ID");
7782 self.write_space();
7783 self.generate_expression(&partition[0].1)?;
7784 } else {
7785 self.write("(");
7787 for (j, (key, value)) in partition.iter().enumerate() {
7788 if j > 0 {
7789 self.write(", ");
7790 }
7791 self.generate_identifier(key)?;
7792 self.write(" = ");
7793 self.generate_expression(value)?;
7794 }
7795 self.write(")");
7796 }
7797 }
7798 }
7799 AlterTableAction::Delete { where_clause } => {
7800 self.write_keyword("DELETE");
7801 self.write_space();
7802 self.write_keyword("WHERE");
7803 self.write_space();
7804 self.generate_expression(where_clause)?;
7805 }
7806 AlterTableAction::SwapWith(target) => {
7807 self.write_keyword("SWAP WITH");
7808 self.write_space();
7809 self.generate_table(target)?;
7810 }
7811 AlterTableAction::SetProperty { properties } => {
7812 use crate::dialects::DialectType;
7813 self.write_keyword("SET");
7814 let is_trino_presto = matches!(self.config.dialect, Some(DialectType::Trino) | Some(DialectType::Presto));
7816 if is_trino_presto {
7817 self.write_space();
7818 self.write_keyword("PROPERTIES");
7819 }
7820 let eq = if is_trino_presto { " = " } else { "=" };
7821 for (i, (key, value)) in properties.iter().enumerate() {
7822 if i > 0 {
7823 self.write(",");
7824 }
7825 self.write_space();
7826 if key.contains(' ') {
7828 self.generate_string_literal(key)?;
7829 } else {
7830 self.write(key);
7831 }
7832 self.write(eq);
7833 self.generate_expression(value)?;
7834 }
7835 }
7836 AlterTableAction::UnsetProperty { properties } => {
7837 self.write_keyword("UNSET");
7838 for (i, name) in properties.iter().enumerate() {
7839 if i > 0 {
7840 self.write(",");
7841 }
7842 self.write_space();
7843 self.write(name);
7844 }
7845 }
7846 AlterTableAction::ClusterBy { expressions } => {
7847 self.write_keyword("CLUSTER BY");
7848 self.write(" (");
7849 for (i, expr) in expressions.iter().enumerate() {
7850 if i > 0 {
7851 self.write(", ");
7852 }
7853 self.generate_expression(expr)?;
7854 }
7855 self.write(")");
7856 }
7857 AlterTableAction::SetTag { expressions } => {
7858 self.write_keyword("SET TAG");
7859 for (i, (key, value)) in expressions.iter().enumerate() {
7860 if i > 0 {
7861 self.write(",");
7862 }
7863 self.write_space();
7864 self.write(key);
7865 self.write(" = ");
7866 self.generate_expression(value)?;
7867 }
7868 }
7869 AlterTableAction::UnsetTag { names } => {
7870 self.write_keyword("UNSET TAG");
7871 for (i, name) in names.iter().enumerate() {
7872 if i > 0 {
7873 self.write(",");
7874 }
7875 self.write_space();
7876 self.write(name);
7877 }
7878 }
7879 AlterTableAction::SetOptions { expressions } => {
7880 self.write_keyword("SET");
7881 self.write(" (");
7882 for (i, expr) in expressions.iter().enumerate() {
7883 if i > 0 {
7884 self.write(", ");
7885 }
7886 self.generate_expression(expr)?;
7887 }
7888 self.write(")");
7889 }
7890 AlterTableAction::AlterIndex { name, visible } => {
7891 self.write_keyword("ALTER INDEX");
7892 self.write_space();
7893 self.generate_identifier(name)?;
7894 self.write_space();
7895 if *visible {
7896 self.write_keyword("VISIBLE");
7897 } else {
7898 self.write_keyword("INVISIBLE");
7899 }
7900 }
7901 AlterTableAction::SetAttribute { attribute } => {
7902 self.write_keyword("SET");
7903 self.write_space();
7904 self.write_keyword(attribute);
7905 }
7906 AlterTableAction::SetStageFileFormat { options } => {
7907 self.write_keyword("SET");
7908 self.write_space();
7909 self.write_keyword("STAGE_FILE_FORMAT");
7910 self.write(" = (");
7911 if let Some(opts) = options {
7912 self.generate_space_separated_properties(opts)?;
7913 }
7914 self.write(")");
7915 }
7916 AlterTableAction::SetStageCopyOptions { options } => {
7917 self.write_keyword("SET");
7918 self.write_space();
7919 self.write_keyword("STAGE_COPY_OPTIONS");
7920 self.write(" = (");
7921 if let Some(opts) = options {
7922 self.generate_space_separated_properties(opts)?;
7923 }
7924 self.write(")");
7925 }
7926 AlterTableAction::AddColumns { columns, cascade } => {
7927 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
7930 if is_oracle {
7931 self.write_keyword("ADD");
7932 } else {
7933 self.write_keyword("ADD COLUMNS");
7934 }
7935 self.write(" (");
7936 for (i, col) in columns.iter().enumerate() {
7937 if i > 0 {
7938 self.write(", ");
7939 }
7940 self.generate_column_def(col)?;
7941 }
7942 self.write(")");
7943 if *cascade {
7944 self.write_space();
7945 self.write_keyword("CASCADE");
7946 }
7947 }
7948 AlterTableAction::ChangeColumn { old_name, new_name, data_type, comment, cascade } => {
7949 use crate::dialects::DialectType;
7950 let is_spark = matches!(self.config.dialect,
7951 Some(DialectType::Spark) | Some(DialectType::Databricks));
7952 let is_rename = old_name.name != new_name.name;
7953
7954 if is_spark {
7955 if is_rename {
7956 self.write_keyword("RENAME COLUMN");
7958 self.write_space();
7959 self.generate_identifier(old_name)?;
7960 self.write_space();
7961 self.write_keyword("TO");
7962 self.write_space();
7963 self.generate_identifier(new_name)?;
7964 } else if comment.is_some() {
7965 self.write_keyword("ALTER COLUMN");
7967 self.write_space();
7968 self.generate_identifier(old_name)?;
7969 self.write_space();
7970 self.write_keyword("COMMENT");
7971 self.write_space();
7972 self.write("'");
7973 self.write(comment.as_ref().unwrap());
7974 self.write("'");
7975 } else if data_type.is_some() {
7976 self.write_keyword("ALTER COLUMN");
7978 self.write_space();
7979 self.generate_identifier(old_name)?;
7980 self.write_space();
7981 self.write_keyword("TYPE");
7982 self.write_space();
7983 self.generate_data_type(data_type.as_ref().unwrap())?;
7984 } else {
7985 self.write_keyword("CHANGE COLUMN");
7987 self.write_space();
7988 self.generate_identifier(old_name)?;
7989 self.write_space();
7990 self.generate_identifier(new_name)?;
7991 }
7992 } else {
7993 if data_type.is_some() {
7995 self.write_keyword("CHANGE COLUMN");
7996 } else {
7997 self.write_keyword("CHANGE");
7998 }
7999 self.write_space();
8000 self.generate_identifier(old_name)?;
8001 self.write_space();
8002 self.generate_identifier(new_name)?;
8003 if let Some(ref dt) = data_type {
8004 self.write_space();
8005 self.generate_data_type(dt)?;
8006 }
8007 if let Some(ref c) = comment {
8008 self.write_space();
8009 self.write_keyword("COMMENT");
8010 self.write_space();
8011 self.write("'");
8012 self.write(c);
8013 self.write("'");
8014 }
8015 if *cascade {
8016 self.write_space();
8017 self.write_keyword("CASCADE");
8018 }
8019 }
8020 }
8021 AlterTableAction::AddPartition { partition, if_not_exists, location } => {
8022 self.write_keyword("ADD");
8023 self.write_space();
8024 if *if_not_exists {
8025 self.write_keyword("IF NOT EXISTS");
8026 self.write_space();
8027 }
8028 self.generate_expression(partition)?;
8029 if let Some(ref loc) = location {
8030 self.write_space();
8031 self.write_keyword("LOCATION");
8032 self.write_space();
8033 self.generate_expression(loc)?;
8034 }
8035 }
8036 AlterTableAction::AlterSortKey { this, expressions, compound } => {
8037 self.write_keyword("ALTER");
8039 if *compound {
8040 self.write_space();
8041 self.write_keyword("COMPOUND");
8042 }
8043 self.write_space();
8044 self.write_keyword("SORTKEY");
8045 self.write_space();
8046 if let Some(style) = this {
8047 self.write_keyword(style);
8048 } else if !expressions.is_empty() {
8049 self.write("(");
8050 for (i, expr) in expressions.iter().enumerate() {
8051 if i > 0 {
8052 self.write(", ");
8053 }
8054 self.generate_expression(expr)?;
8055 }
8056 self.write(")");
8057 }
8058 }
8059 AlterTableAction::AlterDistStyle { style, distkey } => {
8060 self.write_keyword("ALTER");
8062 self.write_space();
8063 self.write_keyword("DISTSTYLE");
8064 self.write_space();
8065 self.write_keyword(style);
8066 if let Some(col) = distkey {
8067 self.write_space();
8068 self.write_keyword("DISTKEY");
8069 self.write_space();
8070 self.generate_identifier(col)?;
8071 }
8072 }
8073 AlterTableAction::SetTableProperties { properties } => {
8074 self.write_keyword("SET TABLE PROPERTIES");
8076 self.write(" (");
8077 for (i, (key, value)) in properties.iter().enumerate() {
8078 if i > 0 {
8079 self.write(", ");
8080 }
8081 self.generate_expression(key)?;
8082 self.write(" = ");
8083 self.generate_expression(value)?;
8084 }
8085 self.write(")");
8086 }
8087 AlterTableAction::SetLocation { location } => {
8088 self.write_keyword("SET LOCATION");
8090 self.write_space();
8091 self.write("'");
8092 self.write(location);
8093 self.write("'");
8094 }
8095 AlterTableAction::SetFileFormat { format } => {
8096 self.write_keyword("SET FILE FORMAT");
8098 self.write_space();
8099 self.write_keyword(format);
8100 }
8101 AlterTableAction::ReplacePartition { partition, source } => {
8102 self.write_keyword("REPLACE PARTITION");
8104 self.write_space();
8105 self.generate_expression(partition)?;
8106 if let Some(src) = source {
8107 self.write_space();
8108 self.write_keyword("FROM");
8109 self.write_space();
8110 self.generate_expression(src)?;
8111 }
8112 }
8113 }
8114 Ok(())
8115 }
8116
8117 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
8118 match action {
8119 AlterColumnAction::SetDataType { data_type, using, collate } => {
8120 use crate::dialects::DialectType;
8121 let is_no_prefix = matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive));
8126 let is_type_only = matches!(self.config.dialect, Some(DialectType::Redshift) | Some(DialectType::Spark) | Some(DialectType::Databricks));
8127 if is_type_only {
8128 self.write_keyword("TYPE");
8129 self.write_space();
8130 } else if !is_no_prefix {
8131 self.write_keyword("SET DATA TYPE");
8132 self.write_space();
8133 }
8134 self.generate_data_type(data_type)?;
8135 if let Some(ref collation) = collate {
8136 self.write_space();
8137 self.write_keyword("COLLATE");
8138 self.write_space();
8139 self.write(collation);
8140 }
8141 if let Some(ref using_expr) = using {
8142 self.write_space();
8143 self.write_keyword("USING");
8144 self.write_space();
8145 self.generate_expression(using_expr)?;
8146 }
8147 }
8148 AlterColumnAction::SetDefault(expr) => {
8149 self.write_keyword("SET DEFAULT");
8150 self.write_space();
8151 self.generate_expression(expr)?;
8152 }
8153 AlterColumnAction::DropDefault => {
8154 self.write_keyword("DROP DEFAULT");
8155 }
8156 AlterColumnAction::SetNotNull => {
8157 self.write_keyword("SET NOT NULL");
8158 }
8159 AlterColumnAction::DropNotNull => {
8160 self.write_keyword("DROP NOT NULL");
8161 }
8162 AlterColumnAction::Comment(comment) => {
8163 self.write_keyword("COMMENT");
8164 self.write_space();
8165 self.generate_string_literal(comment)?;
8166 }
8167 AlterColumnAction::SetVisible => {
8168 self.write_keyword("SET VISIBLE");
8169 }
8170 AlterColumnAction::SetInvisible => {
8171 self.write_keyword("SET INVISIBLE");
8172 }
8173 }
8174 Ok(())
8175 }
8176
8177 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
8178 self.write_keyword("CREATE");
8179
8180 if ci.unique {
8181 self.write_space();
8182 self.write_keyword("UNIQUE");
8183 }
8184
8185 if let Some(ref clustered) = ci.clustered {
8187 self.write_space();
8188 self.write_keyword(clustered);
8189 }
8190
8191 self.write_space();
8192 self.write_keyword("INDEX");
8193
8194 if ci.concurrently {
8196 self.write_space();
8197 self.write_keyword("CONCURRENTLY");
8198 }
8199
8200 if ci.if_not_exists {
8201 self.write_space();
8202 self.write_keyword("IF NOT EXISTS");
8203 }
8204
8205 if !ci.name.name.is_empty() {
8207 self.write_space();
8208 self.generate_identifier(&ci.name)?;
8209 }
8210 self.write_space();
8211 self.write_keyword("ON");
8212 self.write_space();
8213 self.generate_table(&ci.table)?;
8214
8215 if !ci.columns.is_empty() || ci.using.is_some() {
8218 let space_before_paren = false;
8219
8220 if let Some(ref using) = ci.using {
8221 self.write_space();
8222 self.write_keyword("USING");
8223 self.write_space();
8224 self.write(using);
8225 if space_before_paren {
8226 self.write(" (");
8227 } else {
8228 self.write("(");
8229 }
8230 } else {
8231 if space_before_paren {
8232 self.write(" (");
8233 } else {
8234 self.write("(");
8235 }
8236 }
8237 for (i, col) in ci.columns.iter().enumerate() {
8238 if i > 0 {
8239 self.write(", ");
8240 }
8241 self.generate_identifier(&col.column)?;
8242 if let Some(ref opclass) = col.opclass {
8243 self.write_space();
8244 self.write(opclass);
8245 }
8246 if col.desc {
8247 self.write_space();
8248 self.write_keyword("DESC");
8249 } else if col.asc {
8250 self.write_space();
8251 self.write_keyword("ASC");
8252 }
8253 if let Some(nulls_first) = col.nulls_first {
8254 self.write_space();
8255 self.write_keyword("NULLS");
8256 self.write_space();
8257 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
8258 }
8259 }
8260 self.write(")");
8261 }
8262
8263 if !ci.include_columns.is_empty() {
8265 self.write_space();
8266 self.write_keyword("INCLUDE");
8267 self.write(" (");
8268 for (i, col) in ci.include_columns.iter().enumerate() {
8269 if i > 0 {
8270 self.write(", ");
8271 }
8272 self.generate_identifier(col)?;
8273 }
8274 self.write(")");
8275 }
8276
8277 if !ci.with_options.is_empty() {
8279 self.write_space();
8280 self.write_keyword("WITH");
8281 self.write(" (");
8282 for (i, (key, value)) in ci.with_options.iter().enumerate() {
8283 if i > 0 {
8284 self.write(", ");
8285 }
8286 self.write(key);
8287 self.write("=");
8288 self.write(value);
8289 }
8290 self.write(")");
8291 }
8292
8293 if let Some(ref where_clause) = ci.where_clause {
8295 self.write_space();
8296 self.write_keyword("WHERE");
8297 self.write_space();
8298 self.generate_expression(where_clause)?;
8299 }
8300
8301 if let Some(ref on_fg) = ci.on_filegroup {
8303 self.write_space();
8304 self.write_keyword("ON");
8305 self.write_space();
8306 self.write(on_fg);
8307 }
8308
8309 Ok(())
8310 }
8311
8312 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
8313 self.write_keyword("DROP INDEX");
8314
8315 if di.concurrently {
8316 self.write_space();
8317 self.write_keyword("CONCURRENTLY");
8318 }
8319
8320 if di.if_exists {
8321 self.write_space();
8322 self.write_keyword("IF EXISTS");
8323 }
8324
8325 self.write_space();
8326 self.generate_identifier(&di.name)?;
8327
8328 if let Some(ref table) = di.table {
8329 self.write_space();
8330 self.write_keyword("ON");
8331 self.write_space();
8332 self.generate_table(table)?;
8333 }
8334
8335 Ok(())
8336 }
8337
8338 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
8339 self.write_keyword("CREATE");
8340
8341 if let Some(ref algorithm) = cv.algorithm {
8343 self.write_space();
8344 self.write_keyword("ALGORITHM");
8345 self.write("=");
8346 self.write_keyword(algorithm);
8347 }
8348
8349 if let Some(ref definer) = cv.definer {
8351 self.write_space();
8352 self.write_keyword("DEFINER");
8353 self.write("=");
8354 self.write(definer);
8355 }
8356
8357 if cv.security_sql_style {
8359 if let Some(ref security) = cv.security {
8360 self.write_space();
8361 self.write_keyword("SQL SECURITY");
8362 self.write_space();
8363 match security {
8364 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
8365 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
8366 FunctionSecurity::None => self.write_keyword("NONE"),
8367 }
8368 }
8369 }
8370
8371 if cv.or_replace {
8372 self.write_space();
8373 self.write_keyword("OR REPLACE");
8374 }
8375
8376 if cv.temporary {
8377 self.write_space();
8378 self.write_keyword("TEMPORARY");
8379 }
8380
8381 if cv.materialized {
8382 self.write_space();
8383 self.write_keyword("MATERIALIZED");
8384 }
8385
8386 if cv.secure {
8388 self.write_space();
8389 self.write_keyword("SECURE");
8390 }
8391
8392 self.write_space();
8393 self.write_keyword("VIEW");
8394
8395 if cv.if_not_exists {
8396 self.write_space();
8397 self.write_keyword("IF NOT EXISTS");
8398 }
8399
8400 self.write_space();
8401 self.generate_table(&cv.name)?;
8402
8403 if let Some(ref on_cluster) = cv.on_cluster {
8405 self.write_space();
8406 self.generate_on_cluster(on_cluster)?;
8407 }
8408
8409 if let Some(ref to_table) = cv.to_table {
8411 self.write_space();
8412 self.write_keyword("TO");
8413 self.write_space();
8414 self.generate_table(to_table)?;
8415 }
8416
8417 if !cv.materialized {
8420 if !cv.columns.is_empty() {
8422 self.write(" (");
8423 for (i, col) in cv.columns.iter().enumerate() {
8424 if i > 0 {
8425 self.write(", ");
8426 }
8427 self.generate_identifier(&col.name)?;
8428 if !col.options.is_empty() {
8430 self.write_space();
8431 self.generate_options_clause(&col.options)?;
8432 }
8433 if let Some(ref comment) = col.comment {
8434 self.write_space();
8435 self.write_keyword("COMMENT");
8436 self.write_space();
8437 self.generate_string_literal(comment)?;
8438 }
8439 }
8440 self.write(")");
8441 }
8442
8443 if !cv.security_sql_style {
8445 if let Some(ref security) = cv.security {
8446 self.write_space();
8447 self.write_keyword("SECURITY");
8448 self.write_space();
8449 match security {
8450 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
8451 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
8452 FunctionSecurity::None => self.write_keyword("NONE"),
8453 }
8454 }
8455 }
8456
8457 if cv.copy_grants {
8459 self.write_space();
8460 self.write_keyword("COPY GRANTS");
8461 }
8462 } else {
8463 if cv.copy_grants {
8465 self.write_space();
8466 self.write_keyword("COPY GRANTS");
8467 }
8468
8469 if let Some(ref schema) = cv.schema {
8471 self.write(" (");
8472 for (i, expr) in schema.expressions.iter().enumerate() {
8473 if i > 0 {
8474 self.write(", ");
8475 }
8476 self.generate_expression(expr)?;
8477 }
8478 self.write(")");
8479 } else if !cv.columns.is_empty() {
8480 self.write(" (");
8482 for (i, col) in cv.columns.iter().enumerate() {
8483 if i > 0 {
8484 self.write(", ");
8485 }
8486 self.generate_identifier(&col.name)?;
8487 if !col.options.is_empty() {
8489 self.write_space();
8490 self.generate_options_clause(&col.options)?;
8491 }
8492 if let Some(ref comment) = col.comment {
8493 self.write_space();
8494 self.write_keyword("COMMENT");
8495 self.write_space();
8496 self.generate_string_literal(comment)?;
8497 }
8498 }
8499 self.write(")");
8500 }
8501
8502 if let Some(ref unique_key) = cv.unique_key {
8504 self.write_space();
8505 self.write_keyword("KEY");
8506 self.write(" (");
8507 for (i, expr) in unique_key.expressions.iter().enumerate() {
8508 if i > 0 {
8509 self.write(", ");
8510 }
8511 self.generate_expression(expr)?;
8512 }
8513 self.write(")");
8514 }
8515 }
8516
8517 if let Some(ref comment) = cv.comment {
8519 self.write_space();
8520 self.write_keyword("COMMENT");
8521 self.write("=");
8522 self.generate_string_literal(comment)?;
8523 }
8524
8525 if !cv.tags.is_empty() {
8527 self.write_space();
8528 self.write_keyword("TAG");
8529 self.write(" (");
8530 for (i, (name, value)) in cv.tags.iter().enumerate() {
8531 if i > 0 {
8532 self.write(", ");
8533 }
8534 self.write(name);
8535 self.write("='");
8536 self.write(value);
8537 self.write("'");
8538 }
8539 self.write(")");
8540 }
8541
8542 if !cv.options.is_empty() {
8544 self.write_space();
8545 self.generate_options_clause(&cv.options)?;
8546 }
8547
8548 if let Some(ref build) = cv.build {
8550 self.write_space();
8551 self.write_keyword("BUILD");
8552 self.write_space();
8553 self.write_keyword(build);
8554 }
8555
8556 if let Some(ref refresh) = cv.refresh {
8558 self.write_space();
8559 self.generate_refresh_trigger_property(refresh)?;
8560 }
8561
8562 if let Some(auto_refresh) = cv.auto_refresh {
8564 self.write_space();
8565 self.write_keyword("AUTO REFRESH");
8566 self.write_space();
8567 if auto_refresh {
8568 self.write_keyword("YES");
8569 } else {
8570 self.write_keyword("NO");
8571 }
8572 }
8573
8574 for prop in &cv.table_properties {
8576 self.write_space();
8577 self.generate_expression(prop)?;
8578 }
8579
8580 if !matches!(&cv.query, Expression::Null(_)) {
8582 self.write_space();
8583 self.write_keyword("AS");
8584 self.write_space();
8585
8586 if let Some(ref mode) = cv.locking_mode {
8588 self.write_keyword("LOCKING");
8589 self.write_space();
8590 self.write_keyword(mode);
8591 if let Some(ref access) = cv.locking_access {
8592 self.write_space();
8593 self.write_keyword("FOR");
8594 self.write_space();
8595 self.write_keyword(access);
8596 }
8597 self.write_space();
8598 }
8599
8600 if cv.query_parenthesized {
8601 self.write("(");
8602 }
8603 self.generate_expression(&cv.query)?;
8604 if cv.query_parenthesized {
8605 self.write(")");
8606 }
8607 }
8608
8609 if cv.no_schema_binding {
8611 self.write_space();
8612 self.write_keyword("WITH NO SCHEMA BINDING");
8613 }
8614
8615 Ok(())
8616 }
8617
8618 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
8619 self.write_keyword("DROP");
8620
8621 if dv.materialized {
8622 self.write_space();
8623 self.write_keyword("MATERIALIZED");
8624 }
8625
8626 self.write_space();
8627 self.write_keyword("VIEW");
8628
8629 if dv.if_exists {
8630 self.write_space();
8631 self.write_keyword("IF EXISTS");
8632 }
8633
8634 self.write_space();
8635 self.generate_table(&dv.name)?;
8636
8637 Ok(())
8638 }
8639
8640 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
8641 match tr.target {
8642 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
8643 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
8644 }
8645 self.write_space();
8646 self.generate_table(&tr.table)?;
8647
8648 if let Some(ref on_cluster) = tr.on_cluster {
8650 self.write_space();
8651 self.generate_on_cluster(on_cluster)?;
8652 }
8653
8654 if !tr.extra_tables.is_empty() {
8656 let skip_first = if let Some(first) = tr.extra_tables.first() {
8658 first.table.name == tr.table.name && first.star
8659 } else {
8660 false
8661 };
8662
8663 let strip_star = matches!(self.config.dialect, Some(crate::dialects::DialectType::PostgreSQL) | Some(crate::dialects::DialectType::Redshift));
8665 if skip_first && !strip_star {
8666 self.write("*");
8667 }
8668
8669 for (i, entry) in tr.extra_tables.iter().enumerate() {
8671 if i == 0 && skip_first {
8672 continue; }
8674 self.write(", ");
8675 self.generate_table(&entry.table)?;
8676 if entry.star && !strip_star {
8677 self.write("*");
8678 }
8679 }
8680 }
8681
8682 if let Some(identity) = &tr.identity {
8684 self.write_space();
8685 match identity {
8686 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
8687 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
8688 }
8689 }
8690
8691 if tr.cascade {
8692 self.write_space();
8693 self.write_keyword("CASCADE");
8694 }
8695
8696 if tr.restrict {
8697 self.write_space();
8698 self.write_keyword("RESTRICT");
8699 }
8700
8701 if let Some(ref partition) = tr.partition {
8703 self.write_space();
8704 self.generate_expression(partition)?;
8705 }
8706
8707 Ok(())
8708 }
8709
8710 fn generate_use(&mut self, u: &Use) -> Result<()> {
8711 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
8713 self.write_keyword("DATABASE");
8714 self.write_space();
8715 self.generate_identifier(&u.this)?;
8716 return Ok(());
8717 }
8718
8719 self.write_keyword("USE");
8720
8721 if let Some(kind) = &u.kind {
8722 self.write_space();
8723 match kind {
8724 UseKind::Database => self.write_keyword("DATABASE"),
8725 UseKind::Schema => self.write_keyword("SCHEMA"),
8726 UseKind::Role => self.write_keyword("ROLE"),
8727 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
8728 UseKind::Catalog => self.write_keyword("CATALOG"),
8729 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
8730 }
8731 }
8732
8733 self.write_space();
8734 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
8737 self.write(&u.this.name);
8738 } else {
8739 self.generate_identifier(&u.this)?;
8740 }
8741 Ok(())
8742 }
8743
8744 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
8745 self.write_keyword("CACHE");
8746 if c.lazy {
8747 self.write_space();
8748 self.write_keyword("LAZY");
8749 }
8750 self.write_space();
8751 self.write_keyword("TABLE");
8752 self.write_space();
8753 self.generate_identifier(&c.table)?;
8754
8755 if !c.options.is_empty() {
8757 self.write_space();
8758 self.write_keyword("OPTIONS");
8759 self.write("(");
8760 for (i, (key, value)) in c.options.iter().enumerate() {
8761 if i > 0 {
8762 self.write(", ");
8763 }
8764 self.generate_expression(key)?;
8765 self.write(" = ");
8766 self.generate_expression(value)?;
8767 }
8768 self.write(")");
8769 }
8770
8771 if let Some(query) = &c.query {
8773 self.write_space();
8774 self.write_keyword("AS");
8775 self.write_space();
8776 self.generate_expression(query)?;
8777 }
8778
8779 Ok(())
8780 }
8781
8782 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
8783 self.write_keyword("UNCACHE TABLE");
8784 if u.if_exists {
8785 self.write_space();
8786 self.write_keyword("IF EXISTS");
8787 }
8788 self.write_space();
8789 self.generate_identifier(&u.table)?;
8790 Ok(())
8791 }
8792
8793 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
8794 self.write_keyword("LOAD DATA");
8795 if l.local {
8796 self.write_space();
8797 self.write_keyword("LOCAL");
8798 }
8799 self.write_space();
8800 self.write_keyword("INPATH");
8801 self.write_space();
8802 self.write("'");
8803 self.write(&l.inpath);
8804 self.write("'");
8805
8806 if l.overwrite {
8807 self.write_space();
8808 self.write_keyword("OVERWRITE");
8809 }
8810
8811 self.write_space();
8812 self.write_keyword("INTO TABLE");
8813 self.write_space();
8814 self.generate_expression(&l.table)?;
8815
8816 if !l.partition.is_empty() {
8818 self.write_space();
8819 self.write_keyword("PARTITION");
8820 self.write("(");
8821 for (i, (col, val)) in l.partition.iter().enumerate() {
8822 if i > 0 {
8823 self.write(", ");
8824 }
8825 self.generate_identifier(col)?;
8826 self.write(" = ");
8827 self.generate_expression(val)?;
8828 }
8829 self.write(")");
8830 }
8831
8832 if let Some(fmt) = &l.input_format {
8834 self.write_space();
8835 self.write_keyword("INPUTFORMAT");
8836 self.write_space();
8837 self.write("'");
8838 self.write(fmt);
8839 self.write("'");
8840 }
8841
8842 if let Some(serde) = &l.serde {
8844 self.write_space();
8845 self.write_keyword("SERDE");
8846 self.write_space();
8847 self.write("'");
8848 self.write(serde);
8849 self.write("'");
8850 }
8851
8852 Ok(())
8853 }
8854
8855 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
8856 self.write_keyword("PRAGMA");
8857 self.write_space();
8858
8859 if let Some(schema) = &p.schema {
8861 self.generate_identifier(schema)?;
8862 self.write(".");
8863 }
8864
8865 self.generate_identifier(&p.name)?;
8867
8868 if let Some(value) = &p.value {
8870 self.write(" = ");
8871 self.generate_expression(value)?;
8872 } else if !p.args.is_empty() {
8873 self.write("(");
8874 for (i, arg) in p.args.iter().enumerate() {
8875 if i > 0 {
8876 self.write(", ");
8877 }
8878 self.generate_expression(arg)?;
8879 }
8880 self.write(")");
8881 }
8882
8883 Ok(())
8884 }
8885
8886 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
8887 self.write_keyword("GRANT");
8888 self.write_space();
8889
8890 for (i, privilege) in g.privileges.iter().enumerate() {
8892 if i > 0 {
8893 self.write(", ");
8894 }
8895 self.write_keyword(&privilege.name);
8896 if !privilege.columns.is_empty() {
8898 self.write("(");
8899 for (j, col) in privilege.columns.iter().enumerate() {
8900 if j > 0 {
8901 self.write(", ");
8902 }
8903 self.write(col);
8904 }
8905 self.write(")");
8906 }
8907 }
8908
8909 self.write_space();
8910 self.write_keyword("ON");
8911 self.write_space();
8912
8913 if let Some(kind) = &g.kind {
8915 self.write_keyword(kind);
8916 self.write_space();
8917 }
8918
8919 {
8921 use crate::dialects::DialectType;
8922 let should_upper = matches!(
8923 self.config.dialect,
8924 Some(DialectType::PostgreSQL)
8925 | Some(DialectType::CockroachDB)
8926 | Some(DialectType::Materialize)
8927 | Some(DialectType::RisingWave)
8928 ) && (g.kind.as_deref() == Some("FUNCTION") || g.kind.as_deref() == Some("PROCEDURE"));
8929 if should_upper {
8930 use crate::expressions::Identifier;
8931 let upper_id = Identifier {
8932 name: g.securable.name.to_uppercase(),
8933 quoted: g.securable.quoted,
8934 ..g.securable.clone()
8935 };
8936 self.generate_identifier(&upper_id)?;
8937 } else {
8938 self.generate_identifier(&g.securable)?;
8939 }
8940 }
8941
8942 if !g.function_params.is_empty() {
8944 self.write("(");
8945 for (i, param) in g.function_params.iter().enumerate() {
8946 if i > 0 {
8947 self.write(", ");
8948 }
8949 self.write(param);
8950 }
8951 self.write(")");
8952 }
8953
8954 self.write_space();
8955 self.write_keyword("TO");
8956 self.write_space();
8957
8958 for (i, principal) in g.principals.iter().enumerate() {
8960 if i > 0 {
8961 self.write(", ");
8962 }
8963 if principal.is_role {
8964 self.write_keyword("ROLE");
8965 self.write_space();
8966 } else if principal.is_group {
8967 self.write_keyword("GROUP");
8968 self.write_space();
8969 }
8970 self.generate_identifier(&principal.name)?;
8971 }
8972
8973 if g.grant_option {
8975 self.write_space();
8976 self.write_keyword("WITH GRANT OPTION");
8977 }
8978
8979 if let Some(ref principal) = g.as_principal {
8981 self.write_space();
8982 self.write_keyword("AS");
8983 self.write_space();
8984 self.generate_identifier(principal)?;
8985 }
8986
8987 Ok(())
8988 }
8989
8990 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
8991 self.write_keyword("REVOKE");
8992 self.write_space();
8993
8994 if r.grant_option {
8996 self.write_keyword("GRANT OPTION FOR");
8997 self.write_space();
8998 }
8999
9000 for (i, privilege) in r.privileges.iter().enumerate() {
9002 if i > 0 {
9003 self.write(", ");
9004 }
9005 self.write_keyword(&privilege.name);
9006 if !privilege.columns.is_empty() {
9008 self.write("(");
9009 for (j, col) in privilege.columns.iter().enumerate() {
9010 if j > 0 {
9011 self.write(", ");
9012 }
9013 self.write(col);
9014 }
9015 self.write(")");
9016 }
9017 }
9018
9019 self.write_space();
9020 self.write_keyword("ON");
9021 self.write_space();
9022
9023 if let Some(kind) = &r.kind {
9025 self.write_keyword(kind);
9026 self.write_space();
9027 }
9028
9029 {
9031 use crate::dialects::DialectType;
9032 let should_upper = matches!(
9033 self.config.dialect,
9034 Some(DialectType::PostgreSQL)
9035 | Some(DialectType::CockroachDB)
9036 | Some(DialectType::Materialize)
9037 | Some(DialectType::RisingWave)
9038 ) && (r.kind.as_deref() == Some("FUNCTION") || r.kind.as_deref() == Some("PROCEDURE"));
9039 if should_upper {
9040 use crate::expressions::Identifier;
9041 let upper_id = Identifier {
9042 name: r.securable.name.to_uppercase(),
9043 quoted: r.securable.quoted,
9044 ..r.securable.clone()
9045 };
9046 self.generate_identifier(&upper_id)?;
9047 } else {
9048 self.generate_identifier(&r.securable)?;
9049 }
9050 }
9051
9052 if !r.function_params.is_empty() {
9054 self.write("(");
9055 for (i, param) in r.function_params.iter().enumerate() {
9056 if i > 0 {
9057 self.write(", ");
9058 }
9059 self.write(param);
9060 }
9061 self.write(")");
9062 }
9063
9064 self.write_space();
9065 self.write_keyword("FROM");
9066 self.write_space();
9067
9068 for (i, principal) in r.principals.iter().enumerate() {
9070 if i > 0 {
9071 self.write(", ");
9072 }
9073 if principal.is_role {
9074 self.write_keyword("ROLE");
9075 self.write_space();
9076 } else if principal.is_group {
9077 self.write_keyword("GROUP");
9078 self.write_space();
9079 }
9080 self.generate_identifier(&principal.name)?;
9081 }
9082
9083 if r.cascade {
9085 self.write_space();
9086 self.write_keyword("CASCADE");
9087 } else if r.restrict {
9088 self.write_space();
9089 self.write_keyword("RESTRICT");
9090 }
9091
9092 Ok(())
9093 }
9094
9095 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
9096 self.write_keyword("COMMENT");
9097
9098 if c.exists {
9100 self.write_space();
9101 self.write_keyword("IF EXISTS");
9102 }
9103
9104 self.write_space();
9105 self.write_keyword("ON");
9106
9107 if c.materialized {
9109 self.write_space();
9110 self.write_keyword("MATERIALIZED");
9111 }
9112
9113 self.write_space();
9114 self.write_keyword(&c.kind);
9115 self.write_space();
9116
9117 self.generate_expression(&c.this)?;
9119
9120 self.write_space();
9121 self.write_keyword("IS");
9122 self.write_space();
9123
9124 self.generate_expression(&c.expression)?;
9126
9127 Ok(())
9128 }
9129
9130 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
9131 self.write_keyword("SET");
9132
9133 for (i, item) in s.items.iter().enumerate() {
9134 if i > 0 {
9135 self.write(",");
9136 }
9137 self.write_space();
9138
9139 if let Some(ref kind) = item.kind {
9141 self.write_keyword(kind);
9142 self.write_space();
9143 }
9144
9145 let name_str = match &item.name {
9147 Expression::Identifier(id) => Some(id.name.as_str()),
9148 _ => None,
9149 };
9150
9151 let is_transaction = name_str == Some("TRANSACTION");
9152 let is_character_set = name_str == Some("CHARACTER SET");
9153 let is_names = name_str == Some("NAMES");
9154 let is_collate = name_str == Some("COLLATE");
9155 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
9156 let name_has_variable_prefix = name_str.map_or(false, |n| n.starts_with("VARIABLE "));
9157 let is_variable = has_variable_kind || name_has_variable_prefix;
9158 let is_value_only = matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
9159
9160 if is_transaction {
9161 self.write_keyword("TRANSACTION");
9163 if let Expression::Identifier(id) = &item.value {
9164 if !id.name.is_empty() {
9165 self.write_space();
9166 self.write(&id.name);
9167 }
9168 }
9169 } else if is_character_set {
9170 self.write_keyword("CHARACTER SET");
9172 self.write_space();
9173 self.generate_set_value(&item.value)?;
9174 } else if is_names {
9175 self.write_keyword("NAMES");
9177 self.write_space();
9178 self.generate_set_value(&item.value)?;
9179 } else if is_collate {
9180 self.write_keyword("COLLATE");
9182 self.write_space();
9183 self.generate_set_value(&item.value)?;
9184 } else if is_variable {
9185 if name_has_variable_prefix && !has_variable_kind {
9189 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
9190 self.write_keyword("VARIABLE");
9191 self.write_space();
9192 }
9193 }
9194 if let Some(ns) = name_str {
9196 let var_name = if name_has_variable_prefix {
9197 &ns["VARIABLE ".len()..]
9198 } else {
9199 ns
9200 };
9201 self.write(var_name);
9202 } else {
9203 self.generate_expression(&item.name)?;
9204 }
9205 self.write(" = ");
9206 self.generate_set_value(&item.value)?;
9207 } else if is_value_only {
9208 self.generate_expression(&item.name)?;
9210 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
9211 self.generate_expression(&item.name)?;
9213 self.write_space();
9214 self.generate_set_value(&item.value)?;
9215 } else {
9216 match &item.name {
9219 Expression::Identifier(id) => {
9220 self.write(&id.name);
9221 }
9222 _ => {
9223 self.generate_expression(&item.name)?;
9224 }
9225 }
9226 self.write(" = ");
9227 self.generate_set_value(&item.value)?;
9228 }
9229 }
9230
9231 Ok(())
9232 }
9233
9234 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
9237 if let Expression::Identifier(id) = value {
9238 match id.name.as_str() {
9239 "DEFAULT" | "ON" | "OFF" => {
9240 self.write_keyword(&id.name);
9241 return Ok(());
9242 }
9243 _ => {}
9244 }
9245 }
9246 self.generate_expression(value)
9247 }
9248
9249 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
9252 self.write_keyword("ALTER");
9253 if let Some(ref algorithm) = av.algorithm {
9255 self.write_space();
9256 self.write_keyword("ALGORITHM");
9257 self.write(" = ");
9258 self.write_keyword(algorithm);
9259 }
9260 if let Some(ref definer) = av.definer {
9261 self.write_space();
9262 self.write_keyword("DEFINER");
9263 self.write(" = ");
9264 self.write(definer);
9265 }
9266 if let Some(ref sql_security) = av.sql_security {
9267 self.write_space();
9268 self.write_keyword("SQL SECURITY");
9269 self.write(" = ");
9270 self.write_keyword(sql_security);
9271 }
9272 self.write_space();
9273 self.write_keyword("VIEW");
9274 self.write_space();
9275 self.generate_table(&av.name)?;
9276
9277 if !av.columns.is_empty() {
9279 self.write(" (");
9280 for (i, col) in av.columns.iter().enumerate() {
9281 if i > 0 {
9282 self.write(", ");
9283 }
9284 self.generate_identifier(&col.name)?;
9285 if let Some(ref comment) = col.comment {
9286 self.write_space();
9287 self.write_keyword("COMMENT");
9288 self.write(" ");
9289 self.generate_string_literal(comment)?;
9290 }
9291 }
9292 self.write(")");
9293 }
9294
9295 if let Some(ref opt) = av.with_option {
9297 self.write_space();
9298 self.write_keyword("WITH");
9299 self.write_space();
9300 self.write_keyword(opt);
9301 }
9302
9303 for action in &av.actions {
9304 self.write_space();
9305 match action {
9306 AlterViewAction::Rename(new_name) => {
9307 self.write_keyword("RENAME TO");
9308 self.write_space();
9309 self.generate_table(new_name)?;
9310 }
9311 AlterViewAction::OwnerTo(owner) => {
9312 self.write_keyword("OWNER TO");
9313 self.write_space();
9314 self.generate_identifier(owner)?;
9315 }
9316 AlterViewAction::SetSchema(schema) => {
9317 self.write_keyword("SET SCHEMA");
9318 self.write_space();
9319 self.generate_identifier(schema)?;
9320 }
9321 AlterViewAction::SetAuthorization(auth) => {
9322 self.write_keyword("SET AUTHORIZATION");
9323 self.write_space();
9324 self.write(auth);
9325 }
9326 AlterViewAction::AlterColumn { name, action } => {
9327 self.write_keyword("ALTER COLUMN");
9328 self.write_space();
9329 self.generate_identifier(name)?;
9330 self.write_space();
9331 self.generate_alter_column_action(action)?;
9332 }
9333 AlterViewAction::AsSelect(query) => {
9334 self.write_keyword("AS");
9335 self.write_space();
9336 self.generate_expression(query)?;
9337 }
9338 AlterViewAction::SetTblproperties(props) => {
9339 self.write_keyword("SET TBLPROPERTIES");
9340 self.write(" (");
9341 for (i, (key, value)) in props.iter().enumerate() {
9342 if i > 0 {
9343 self.write(", ");
9344 }
9345 self.generate_string_literal(key)?;
9346 self.write("=");
9347 self.generate_string_literal(value)?;
9348 }
9349 self.write(")");
9350 }
9351 AlterViewAction::UnsetTblproperties(keys) => {
9352 self.write_keyword("UNSET TBLPROPERTIES");
9353 self.write(" (");
9354 for (i, key) in keys.iter().enumerate() {
9355 if i > 0 {
9356 self.write(", ");
9357 }
9358 self.generate_string_literal(key)?;
9359 }
9360 self.write(")");
9361 }
9362 }
9363 }
9364
9365 Ok(())
9366 }
9367
9368 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
9369 self.write_keyword("ALTER INDEX");
9370 self.write_space();
9371 self.generate_identifier(&ai.name)?;
9372
9373 if let Some(table) = &ai.table {
9374 self.write_space();
9375 self.write_keyword("ON");
9376 self.write_space();
9377 self.generate_table(table)?;
9378 }
9379
9380 for action in &ai.actions {
9381 self.write_space();
9382 match action {
9383 AlterIndexAction::Rename(new_name) => {
9384 self.write_keyword("RENAME TO");
9385 self.write_space();
9386 self.generate_identifier(new_name)?;
9387 }
9388 AlterIndexAction::SetTablespace(tablespace) => {
9389 self.write_keyword("SET TABLESPACE");
9390 self.write_space();
9391 self.generate_identifier(tablespace)?;
9392 }
9393 AlterIndexAction::Visible(visible) => {
9394 if *visible {
9395 self.write_keyword("VISIBLE");
9396 } else {
9397 self.write_keyword("INVISIBLE");
9398 }
9399 }
9400 }
9401 }
9402
9403 Ok(())
9404 }
9405
9406 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
9407 for comment in &cs.leading_comments {
9409 self.write(comment);
9410 self.write_space();
9411 }
9412
9413 let saved_athena_hive_context = self.athena_hive_context;
9415 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Athena)) {
9416 self.athena_hive_context = true;
9417 }
9418
9419 self.write_keyword("CREATE SCHEMA");
9420
9421 if cs.if_not_exists {
9422 self.write_space();
9423 self.write_keyword("IF NOT EXISTS");
9424 }
9425
9426 self.write_space();
9427 self.generate_identifier(&cs.name)?;
9428
9429 if let Some(ref clone_src) = cs.clone_from {
9430 self.write_keyword(" CLONE ");
9431 self.generate_identifier(clone_src)?;
9432 }
9433
9434 if let Some(ref at_clause) = cs.at_clause {
9435 self.write_space();
9436 self.generate_expression(at_clause)?;
9437 }
9438
9439 if let Some(auth) = &cs.authorization {
9440 self.write_space();
9441 self.write_keyword("AUTHORIZATION");
9442 self.write_space();
9443 self.generate_identifier(auth)?;
9444 }
9445
9446 let with_properties: Vec<_> = cs.properties.iter()
9449 .filter(|p| matches!(p, Expression::Property(_)))
9450 .collect();
9451 let other_properties: Vec<_> = cs.properties.iter()
9452 .filter(|p| !matches!(p, Expression::Property(_)))
9453 .collect();
9454
9455 if !with_properties.is_empty() {
9457 self.write_space();
9458 self.write_keyword("WITH");
9459 self.write(" (");
9460 for (i, prop) in with_properties.iter().enumerate() {
9461 if i > 0 {
9462 self.write(", ");
9463 }
9464 self.generate_expression(prop)?;
9465 }
9466 self.write(")");
9467 }
9468
9469 for prop in other_properties {
9471 self.write_space();
9472 self.generate_expression(prop)?;
9473 }
9474
9475 self.athena_hive_context = saved_athena_hive_context;
9477
9478 Ok(())
9479 }
9480
9481 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
9482 self.write_keyword("DROP SCHEMA");
9483
9484 if ds.if_exists {
9485 self.write_space();
9486 self.write_keyword("IF EXISTS");
9487 }
9488
9489 self.write_space();
9490 self.generate_identifier(&ds.name)?;
9491
9492 if ds.cascade {
9493 self.write_space();
9494 self.write_keyword("CASCADE");
9495 }
9496
9497 Ok(())
9498 }
9499
9500 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
9501 self.write_keyword("DROP NAMESPACE");
9502
9503 if dn.if_exists {
9504 self.write_space();
9505 self.write_keyword("IF EXISTS");
9506 }
9507
9508 self.write_space();
9509 self.generate_identifier(&dn.name)?;
9510
9511 if dn.cascade {
9512 self.write_space();
9513 self.write_keyword("CASCADE");
9514 }
9515
9516 Ok(())
9517 }
9518
9519 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
9520 self.write_keyword("CREATE DATABASE");
9521
9522 if cd.if_not_exists {
9523 self.write_space();
9524 self.write_keyword("IF NOT EXISTS");
9525 }
9526
9527 self.write_space();
9528 self.generate_identifier(&cd.name)?;
9529
9530 if let Some(ref clone_src) = cd.clone_from {
9531 self.write_keyword(" CLONE ");
9532 self.generate_identifier(clone_src)?;
9533 }
9534
9535 if let Some(ref at_clause) = cd.at_clause {
9537 self.write_space();
9538 self.generate_expression(at_clause)?;
9539 }
9540
9541 for option in &cd.options {
9542 self.write_space();
9543 match option {
9544 DatabaseOption::CharacterSet(charset) => {
9545 self.write_keyword("CHARACTER SET");
9546 self.write(" = ");
9547 self.write(&format!("'{}'", charset));
9548 }
9549 DatabaseOption::Collate(collate) => {
9550 self.write_keyword("COLLATE");
9551 self.write(" = ");
9552 self.write(&format!("'{}'", collate));
9553 }
9554 DatabaseOption::Owner(owner) => {
9555 self.write_keyword("OWNER");
9556 self.write(" = ");
9557 self.generate_identifier(owner)?;
9558 }
9559 DatabaseOption::Template(template) => {
9560 self.write_keyword("TEMPLATE");
9561 self.write(" = ");
9562 self.generate_identifier(template)?;
9563 }
9564 DatabaseOption::Encoding(encoding) => {
9565 self.write_keyword("ENCODING");
9566 self.write(" = ");
9567 self.write(&format!("'{}'", encoding));
9568 }
9569 DatabaseOption::Location(location) => {
9570 self.write_keyword("LOCATION");
9571 self.write(" = ");
9572 self.write(&format!("'{}'", location));
9573 }
9574 }
9575 }
9576
9577 Ok(())
9578 }
9579
9580 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
9581 self.write_keyword("DROP DATABASE");
9582
9583 if dd.if_exists {
9584 self.write_space();
9585 self.write_keyword("IF EXISTS");
9586 }
9587
9588 self.write_space();
9589 self.generate_identifier(&dd.name)?;
9590
9591 Ok(())
9592 }
9593
9594 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
9595 self.write_keyword("CREATE");
9596
9597 if cf.or_replace {
9598 self.write_space();
9599 self.write_keyword("OR REPLACE");
9600 }
9601
9602 if cf.temporary {
9603 self.write_space();
9604 self.write_keyword("TEMPORARY");
9605 }
9606
9607 self.write_space();
9608 if cf.is_table_function {
9609 self.write_keyword("TABLE FUNCTION");
9610 } else {
9611 self.write_keyword("FUNCTION");
9612 }
9613
9614 if cf.if_not_exists {
9615 self.write_space();
9616 self.write_keyword("IF NOT EXISTS");
9617 }
9618
9619 self.write_space();
9620 self.generate_table(&cf.name)?;
9621 if cf.has_parens {
9622 let func_multiline = self.config.pretty && matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL) | Some(crate::dialects::DialectType::Fabric)) && !cf.parameters.is_empty();
9623 if func_multiline {
9624 self.write("(\n");
9625 self.indent_level += 2;
9626 self.write_indent();
9627 self.generate_function_parameters(&cf.parameters)?;
9628 self.write("\n");
9629 self.indent_level -= 2;
9630 self.write(")");
9631 } else {
9632 self.write("(");
9633 self.generate_function_parameters(&cf.parameters)?;
9634 self.write(")");
9635 }
9636 }
9637
9638 let use_multiline = self.config.pretty && matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery) | Some(crate::dialects::DialectType::TSQL) | Some(crate::dialects::DialectType::Fabric));
9641
9642 if cf.language_first {
9643 if let Some(lang) = &cf.language {
9645 if use_multiline {
9646 self.write_newline();
9647 } else {
9648 self.write_space();
9649 }
9650 self.write_keyword("LANGUAGE");
9651 self.write_space();
9652 self.write(lang);
9653 }
9654
9655 if let Some(sql_data) = &cf.sql_data_access {
9657 self.write_space();
9658 match sql_data {
9659 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
9660 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
9661 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
9662 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
9663 }
9664 }
9665
9666 if let Some(ref rtb) = cf.returns_table_body {
9667 if use_multiline {
9668 self.write_newline();
9669 } else {
9670 self.write_space();
9671 }
9672 self.write_keyword("RETURNS");
9673 self.write_space();
9674 self.write(rtb);
9675 } else if let Some(return_type) = &cf.return_type {
9676 if use_multiline {
9677 self.write_newline();
9678 } else {
9679 self.write_space();
9680 }
9681 self.write_keyword("RETURNS");
9682 self.write_space();
9683 self.generate_data_type(return_type)?;
9684 }
9685 } else {
9686 let is_duckdb = matches!(self.config.dialect, Some(crate::dialects::DialectType::DuckDB));
9689 if let Some(ref rtb) = cf.returns_table_body {
9690 if !(is_duckdb && rtb.is_empty()) {
9691 if use_multiline {
9692 self.write_newline();
9693 } else {
9694 self.write_space();
9695 }
9696 self.write_keyword("RETURNS");
9697 self.write_space();
9698 self.write(rtb);
9699 }
9700 } else if let Some(return_type) = &cf.return_type {
9701 if use_multiline {
9702 self.write_newline();
9703 } else {
9704 self.write_space();
9705 }
9706 self.write_keyword("RETURNS");
9707 self.write_space();
9708 self.generate_data_type(return_type)?;
9709 }
9710 }
9711
9712 if !cf.property_order.is_empty() {
9714 let is_bigquery = matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery));
9716 let property_order = if is_bigquery {
9717 let mut reordered = Vec::new();
9719 let mut has_as = false;
9720 let mut has_options = false;
9721 for prop in &cf.property_order {
9722 match prop {
9723 FunctionPropertyKind::As => has_as = true,
9724 FunctionPropertyKind::Options => has_options = true,
9725 _ => {}
9726 }
9727 }
9728 if has_as && has_options {
9729 for prop in &cf.property_order {
9731 if *prop != FunctionPropertyKind::As && *prop != FunctionPropertyKind::Options {
9732 reordered.push(*prop);
9733 }
9734 }
9735 reordered.push(FunctionPropertyKind::Options);
9736 reordered.push(FunctionPropertyKind::As);
9737 reordered
9738 } else {
9739 cf.property_order.clone()
9740 }
9741 } else {
9742 cf.property_order.clone()
9743 };
9744
9745 for prop in &property_order {
9746 match prop {
9747 FunctionPropertyKind::Set => {
9748 self.generate_function_set_options(cf)?;
9749 }
9750 FunctionPropertyKind::As => {
9751 self.generate_function_body(cf)?;
9752 }
9753 FunctionPropertyKind::Language => {
9754 if !cf.language_first {
9755 if let Some(lang) = &cf.language {
9757 let use_multiline = self.config.pretty && matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery));
9759 if use_multiline {
9760 self.write_newline();
9761 } else {
9762 self.write_space();
9763 }
9764 self.write_keyword("LANGUAGE");
9765 self.write_space();
9766 self.write(lang);
9767 }
9768 }
9769 }
9770 FunctionPropertyKind::Determinism => {
9771 self.generate_function_determinism(cf)?;
9772 }
9773 FunctionPropertyKind::NullInput => {
9774 self.generate_function_null_input(cf)?;
9775 }
9776 FunctionPropertyKind::Security => {
9777 self.generate_function_security(cf)?;
9778 }
9779 FunctionPropertyKind::SqlDataAccess => {
9780 if !cf.language_first {
9781 self.generate_function_sql_data_access(cf)?;
9783 }
9784 }
9785 FunctionPropertyKind::Options => {
9786 if !cf.options.is_empty() {
9787 self.write_space();
9788 self.generate_options_clause(&cf.options)?;
9789 }
9790 }
9791 FunctionPropertyKind::Environment => {
9792 if !cf.environment.is_empty() {
9793 self.write_space();
9794 self.generate_environment_clause(&cf.environment)?;
9795 }
9796 }
9797 }
9798 }
9799
9800 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options) {
9802 self.write_space();
9803 self.generate_options_clause(&cf.options)?;
9804 }
9805
9806 if !cf.environment.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Environment) {
9808 self.write_space();
9809 self.generate_environment_clause(&cf.environment)?;
9810 }
9811 } else {
9812 if matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery)) {
9815 self.generate_function_determinism(cf)?;
9816 }
9817
9818 let use_multiline = self.config.pretty && matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery));
9820
9821 if !cf.language_first {
9822 if let Some(lang) = &cf.language {
9823 if use_multiline {
9824 self.write_newline();
9825 } else {
9826 self.write_space();
9827 }
9828 self.write_keyword("LANGUAGE");
9829 self.write_space();
9830 self.write(lang);
9831 }
9832
9833 self.generate_function_sql_data_access(cf)?;
9835 }
9836
9837 if !matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery)) {
9839 self.generate_function_determinism(cf)?;
9840 }
9841
9842 self.generate_function_null_input(cf)?;
9843 self.generate_function_security(cf)?;
9844 self.generate_function_set_options(cf)?;
9845
9846 if !cf.options.is_empty() {
9848 self.write_space();
9849 self.generate_options_clause(&cf.options)?;
9850 }
9851
9852 if !cf.environment.is_empty() {
9854 self.write_space();
9855 self.generate_environment_clause(&cf.environment)?;
9856 }
9857
9858 self.generate_function_body(cf)?;
9859 }
9860
9861 Ok(())
9862 }
9863
9864 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
9866 for opt in &cf.set_options {
9867 self.write_space();
9868 self.write_keyword("SET");
9869 self.write_space();
9870 self.write(&opt.name);
9871 match &opt.value {
9872 FunctionSetValue::Value { value, use_to } => {
9873 if *use_to && !matches!(self.config.dialect, Some(crate::dialects::DialectType::PostgreSQL)) {
9875 self.write(" TO ");
9876 } else {
9877 self.write(" = ");
9878 }
9879 self.write(value);
9880 }
9881 FunctionSetValue::FromCurrent => {
9882 self.write_space();
9883 self.write_keyword("FROM CURRENT");
9884 }
9885 }
9886 }
9887 Ok(())
9888 }
9889
9890 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
9892 if let Some(body) = &cf.body {
9893 self.write_space();
9895 let use_multiline = self.config.pretty && matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery));
9897 match body {
9898 FunctionBody::Block(block) => {
9899 self.write_keyword("AS");
9900 if matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL)) {
9901 self.write(" BEGIN ");
9902 self.write(block);
9903 self.write(" END");
9904 } else if matches!(self.config.dialect, Some(crate::dialects::DialectType::PostgreSQL)) {
9905 self.write(" $$");
9906 self.write(block);
9907 self.write("$$");
9908 } else {
9909 let escaped = self.escape_block_for_single_quote(block);
9911 if use_multiline {
9913 self.write_newline();
9914 } else {
9915 self.write(" ");
9916 }
9917 self.write("'");
9918 self.write(&escaped);
9919 self.write("'");
9920 }
9921 }
9922 FunctionBody::StringLiteral(s) => {
9923 self.write_keyword("AS");
9924 if use_multiline {
9926 self.write_newline();
9927 } else {
9928 self.write(" ");
9929 }
9930 self.write("'");
9931 self.write(s);
9932 self.write("'");
9933 }
9934 FunctionBody::Expression(expr) => {
9935 self.write_keyword("AS");
9936 self.write_space();
9937 self.generate_expression(expr)?;
9938 }
9939 FunctionBody::External(name) => {
9940 self.write_keyword("EXTERNAL NAME");
9941 self.write(" '");
9942 self.write(name);
9943 self.write("'");
9944 }
9945 FunctionBody::Return(expr) => {
9946 if matches!(self.config.dialect, Some(crate::dialects::DialectType::DuckDB)) {
9947 self.write_keyword("AS");
9949 self.write_space();
9950 if cf.returns_table_body.is_some() {
9952 self.write_keyword("TABLE");
9953 self.write_space();
9954 }
9955 self.generate_expression(expr)?;
9956 } else {
9957 if self.config.create_function_return_as {
9958 self.write_keyword("AS");
9959 if self.config.pretty && matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL) | Some(crate::dialects::DialectType::Fabric)) {
9961 self.write_newline();
9962 } else {
9963 self.write_space();
9964 }
9965 }
9966 self.write_keyword("RETURN");
9967 self.write_space();
9968 self.generate_expression(expr)?;
9969 }
9970 }
9971 FunctionBody::Statements(stmts) => {
9972 self.write_keyword("AS");
9973 self.write(" BEGIN ");
9974 for (i, stmt) in stmts.iter().enumerate() {
9975 if i > 0 {
9976 self.write(" ");
9977 }
9978 self.generate_expression(stmt)?;
9979 }
9980 self.write(" END");
9981 }
9982 FunctionBody::DollarQuoted { content, tag } => {
9983 self.write_keyword("AS");
9984 self.write(" ");
9985 let supports_dollar_quoting = matches!(
9987 self.config.dialect,
9988 Some(crate::dialects::DialectType::PostgreSQL)
9989 | Some(crate::dialects::DialectType::Databricks)
9990 | Some(crate::dialects::DialectType::Redshift)
9991 | Some(crate::dialects::DialectType::DuckDB)
9992 );
9993 if supports_dollar_quoting {
9994 self.write("$");
9996 if let Some(t) = tag {
9997 self.write(t);
9998 }
9999 self.write("$");
10000 self.write(content);
10001 self.write("$");
10002 if let Some(t) = tag {
10003 self.write(t);
10004 }
10005 self.write("$");
10006 } else {
10007 let escaped = self.escape_block_for_single_quote(content);
10009 self.write("'");
10010 self.write(&escaped);
10011 self.write("'");
10012 }
10013 }
10014 }
10015 }
10016 Ok(())
10017 }
10018
10019 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
10021 if let Some(det) = cf.deterministic {
10022 self.write_space();
10023 if matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery)) {
10024 if det {
10026 self.write_keyword("DETERMINISTIC");
10027 } else {
10028 self.write_keyword("NOT DETERMINISTIC");
10029 }
10030 } else {
10031 if det {
10033 self.write_keyword("IMMUTABLE");
10034 } else {
10035 self.write_keyword("VOLATILE");
10036 }
10037 }
10038 }
10039 Ok(())
10040 }
10041
10042 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
10044 if let Some(returns_null) = cf.returns_null_on_null_input {
10045 self.write_space();
10046 if returns_null {
10047 if cf.strict {
10048 self.write_keyword("STRICT");
10049 } else {
10050 self.write_keyword("RETURNS NULL ON NULL INPUT");
10051 }
10052 } else {
10053 self.write_keyword("CALLED ON NULL INPUT");
10054 }
10055 }
10056 Ok(())
10057 }
10058
10059 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
10061 if let Some(security) = &cf.security {
10062 self.write_space();
10063 self.write_keyword("SECURITY");
10064 self.write_space();
10065 match security {
10066 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10067 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10068 FunctionSecurity::None => self.write_keyword("NONE"),
10069 }
10070 }
10071 Ok(())
10072 }
10073
10074 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
10076 if let Some(sql_data) = &cf.sql_data_access {
10077 self.write_space();
10078 match sql_data {
10079 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
10080 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
10081 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
10082 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
10083 }
10084 }
10085 Ok(())
10086 }
10087
10088 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
10089 for (i, param) in params.iter().enumerate() {
10090 if i > 0 {
10091 self.write(", ");
10092 }
10093
10094 if let Some(mode) = ¶m.mode {
10095 match mode {
10096 ParameterMode::In => self.write_keyword("IN"),
10097 ParameterMode::Out => self.write_keyword("OUT"),
10098 ParameterMode::InOut => self.write_keyword("INOUT"),
10099 }
10100 self.write_space();
10101 }
10102
10103 if let Some(name) = ¶m.name {
10104 self.generate_identifier(name)?;
10105 let skip_type = matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
10107 if !skip_type {
10108 self.write_space();
10109 self.generate_data_type(¶m.data_type)?;
10110 }
10111 } else {
10112 self.generate_data_type(¶m.data_type)?;
10113 }
10114
10115 if let Some(default) = ¶m.default {
10116 if self.config.parameter_default_equals {
10117 self.write(" = ");
10118 } else {
10119 self.write(" DEFAULT ");
10120 }
10121 self.generate_expression(default)?;
10122 }
10123 }
10124
10125 Ok(())
10126 }
10127
10128 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
10129 self.write_keyword("DROP FUNCTION");
10130
10131 if df.if_exists {
10132 self.write_space();
10133 self.write_keyword("IF EXISTS");
10134 }
10135
10136 self.write_space();
10137 self.generate_table(&df.name)?;
10138
10139 if let Some(params) = &df.parameters {
10140 self.write(" (");
10141 for (i, dt) in params.iter().enumerate() {
10142 if i > 0 {
10143 self.write(", ");
10144 }
10145 self.generate_data_type(dt)?;
10146 }
10147 self.write(")");
10148 }
10149
10150 if df.cascade {
10151 self.write_space();
10152 self.write_keyword("CASCADE");
10153 }
10154
10155 Ok(())
10156 }
10157
10158 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
10159 self.write_keyword("CREATE");
10160
10161 if cp.or_replace {
10162 self.write_space();
10163 self.write_keyword("OR REPLACE");
10164 }
10165
10166 self.write_space();
10167 if cp.use_proc_keyword {
10168 self.write_keyword("PROC");
10169 } else {
10170 self.write_keyword("PROCEDURE");
10171 }
10172
10173 if cp.if_not_exists {
10174 self.write_space();
10175 self.write_keyword("IF NOT EXISTS");
10176 }
10177
10178 self.write_space();
10179 self.generate_table(&cp.name)?;
10180 if cp.has_parens {
10181 self.write("(");
10182 self.generate_function_parameters(&cp.parameters)?;
10183 self.write(")");
10184 } else if !cp.parameters.is_empty() {
10185 self.write_space();
10187 self.generate_function_parameters(&cp.parameters)?;
10188 }
10189
10190 if let Some(return_type) = &cp.return_type {
10192 self.write_space();
10193 self.write_keyword("RETURNS");
10194 self.write_space();
10195 self.generate_data_type(return_type)?;
10196 }
10197
10198 if let Some(execute_as) = &cp.execute_as {
10200 self.write_space();
10201 self.write_keyword("EXECUTE AS");
10202 self.write_space();
10203 self.write_keyword(execute_as);
10204 }
10205
10206 if let Some(lang) = &cp.language {
10207 self.write_space();
10208 self.write_keyword("LANGUAGE");
10209 self.write_space();
10210 self.write(lang);
10211 }
10212
10213 if let Some(security) = &cp.security {
10214 self.write_space();
10215 self.write_keyword("SECURITY");
10216 self.write_space();
10217 match security {
10218 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10219 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10220 FunctionSecurity::None => self.write_keyword("NONE"),
10221 }
10222 }
10223
10224 if !cp.with_options.is_empty() {
10226 self.write_space();
10227 self.write_keyword("WITH");
10228 self.write_space();
10229 for (i, opt) in cp.with_options.iter().enumerate() {
10230 if i > 0 {
10231 self.write(", ");
10232 }
10233 self.write(opt);
10234 }
10235 }
10236
10237 if let Some(body) = &cp.body {
10238 self.write_space();
10239 match body {
10240 FunctionBody::Block(block) => {
10241 self.write_keyword("AS");
10242 if matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL)) {
10243 self.write(" BEGIN ");
10244 self.write(block);
10245 self.write(" END");
10246 } else if matches!(self.config.dialect, Some(crate::dialects::DialectType::PostgreSQL)) {
10247 self.write(" $$");
10248 self.write(block);
10249 self.write("$$");
10250 } else {
10251 let escaped = self.escape_block_for_single_quote(block);
10253 self.write(" '");
10254 self.write(&escaped);
10255 self.write("'");
10256 }
10257 }
10258 FunctionBody::StringLiteral(s) => {
10259 self.write_keyword("AS");
10260 self.write(" '");
10261 self.write(s);
10262 self.write("'");
10263 }
10264 FunctionBody::Expression(expr) => {
10265 self.write_keyword("AS");
10266 self.write_space();
10267 self.generate_expression(expr)?;
10268 }
10269 FunctionBody::External(name) => {
10270 self.write_keyword("EXTERNAL NAME");
10271 self.write(" '");
10272 self.write(name);
10273 self.write("'");
10274 }
10275 FunctionBody::Return(expr) => {
10276 self.write_keyword("RETURN");
10277 self.write_space();
10278 self.generate_expression(expr)?;
10279 }
10280 FunctionBody::Statements(stmts) => {
10281 self.write_keyword("AS");
10282 self.write(" BEGIN ");
10283 for (i, stmt) in stmts.iter().enumerate() {
10284 if i > 0 {
10285 self.write(" ");
10286 }
10287 self.generate_expression(stmt)?;
10288 }
10289 self.write(" END");
10290 }
10291 FunctionBody::DollarQuoted { content, tag } => {
10292 self.write_keyword("AS");
10293 self.write(" ");
10294 let supports_dollar_quoting = matches!(
10296 self.config.dialect,
10297 Some(crate::dialects::DialectType::PostgreSQL)
10298 | Some(crate::dialects::DialectType::Databricks)
10299 | Some(crate::dialects::DialectType::Redshift)
10300 | Some(crate::dialects::DialectType::DuckDB)
10301 );
10302 if supports_dollar_quoting {
10303 self.write("$");
10305 if let Some(t) = tag {
10306 self.write(t);
10307 }
10308 self.write("$");
10309 self.write(content);
10310 self.write("$");
10311 if let Some(t) = tag {
10312 self.write(t);
10313 }
10314 self.write("$");
10315 } else {
10316 let escaped = self.escape_block_for_single_quote(content);
10318 self.write("'");
10319 self.write(&escaped);
10320 self.write("'");
10321 }
10322 }
10323 }
10324 }
10325
10326 Ok(())
10327 }
10328
10329 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
10330 self.write_keyword("DROP PROCEDURE");
10331
10332 if dp.if_exists {
10333 self.write_space();
10334 self.write_keyword("IF EXISTS");
10335 }
10336
10337 self.write_space();
10338 self.generate_table(&dp.name)?;
10339
10340 if let Some(params) = &dp.parameters {
10341 self.write(" (");
10342 for (i, dt) in params.iter().enumerate() {
10343 if i > 0 {
10344 self.write(", ");
10345 }
10346 self.generate_data_type(dt)?;
10347 }
10348 self.write(")");
10349 }
10350
10351 if dp.cascade {
10352 self.write_space();
10353 self.write_keyword("CASCADE");
10354 }
10355
10356 Ok(())
10357 }
10358
10359 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
10360 self.write_keyword("CREATE");
10361
10362 if cs.temporary {
10363 self.write_space();
10364 self.write_keyword("TEMPORARY");
10365 }
10366
10367 self.write_space();
10368 self.write_keyword("SEQUENCE");
10369
10370 if cs.if_not_exists {
10371 self.write_space();
10372 self.write_keyword("IF NOT EXISTS");
10373 }
10374
10375 self.write_space();
10376 self.generate_table(&cs.name)?;
10377
10378 if let Some(comment) = &cs.comment {
10380 self.write_space();
10381 self.write_keyword("COMMENT");
10382 self.write("=");
10383 self.generate_string_literal(comment)?;
10384 }
10385
10386 if !cs.property_order.is_empty() {
10388 for prop in &cs.property_order {
10389 match prop {
10390 SeqPropKind::Start => {
10391 if let Some(start) = cs.start {
10392 self.write_space();
10393 self.write_keyword("START WITH");
10394 self.write(&format!(" {}", start));
10395 }
10396 }
10397 SeqPropKind::Increment => {
10398 if let Some(inc) = cs.increment {
10399 self.write_space();
10400 self.write_keyword("INCREMENT BY");
10401 self.write(&format!(" {}", inc));
10402 }
10403 }
10404 SeqPropKind::Minvalue => {
10405 if let Some(min) = &cs.minvalue {
10406 self.write_space();
10407 match min {
10408 SequenceBound::Value(v) => {
10409 self.write_keyword("MINVALUE");
10410 self.write(&format!(" {}", v));
10411 }
10412 SequenceBound::None => {
10413 self.write_keyword("NO MINVALUE");
10414 }
10415 }
10416 }
10417 }
10418 SeqPropKind::Maxvalue => {
10419 if let Some(max) = &cs.maxvalue {
10420 self.write_space();
10421 match max {
10422 SequenceBound::Value(v) => {
10423 self.write_keyword("MAXVALUE");
10424 self.write(&format!(" {}", v));
10425 }
10426 SequenceBound::None => {
10427 self.write_keyword("NO MAXVALUE");
10428 }
10429 }
10430 }
10431 }
10432 SeqPropKind::Cache => {
10433 if let Some(cache) = cs.cache {
10434 self.write_space();
10435 self.write_keyword("CACHE");
10436 self.write(&format!(" {}", cache));
10437 }
10438 }
10439 SeqPropKind::Cycle => {
10440 self.write_space();
10441 self.write_keyword("CYCLE");
10442 }
10443 SeqPropKind::NoCycle => {
10444 self.write_space();
10445 self.write_keyword("NO CYCLE");
10446 }
10447 SeqPropKind::OwnedBy => {
10448 if let Some(owned) = &cs.owned_by {
10449 self.write_space();
10450 self.write_keyword("OWNED BY");
10451 self.write_space();
10452 self.generate_table(owned)?;
10453 }
10454 }
10455 SeqPropKind::Order => {
10456 self.write_space();
10457 self.write_keyword("ORDER");
10458 }
10459 SeqPropKind::NoOrder => {
10460 self.write_space();
10461 self.write_keyword("NOORDER");
10462 }
10463 SeqPropKind::Comment => {
10464 }
10466 }
10467 }
10468 } else {
10469 if let Some(inc) = cs.increment {
10471 self.write_space();
10472 self.write_keyword("INCREMENT BY");
10473 self.write(&format!(" {}", inc));
10474 }
10475
10476 if let Some(min) = &cs.minvalue {
10477 self.write_space();
10478 match min {
10479 SequenceBound::Value(v) => {
10480 self.write_keyword("MINVALUE");
10481 self.write(&format!(" {}", v));
10482 }
10483 SequenceBound::None => {
10484 self.write_keyword("NO MINVALUE");
10485 }
10486 }
10487 }
10488
10489 if let Some(max) = &cs.maxvalue {
10490 self.write_space();
10491 match max {
10492 SequenceBound::Value(v) => {
10493 self.write_keyword("MAXVALUE");
10494 self.write(&format!(" {}", v));
10495 }
10496 SequenceBound::None => {
10497 self.write_keyword("NO MAXVALUE");
10498 }
10499 }
10500 }
10501
10502 if let Some(start) = cs.start {
10503 self.write_space();
10504 self.write_keyword("START WITH");
10505 self.write(&format!(" {}", start));
10506 }
10507
10508 if let Some(cache) = cs.cache {
10509 self.write_space();
10510 self.write_keyword("CACHE");
10511 self.write(&format!(" {}", cache));
10512 }
10513
10514 if cs.cycle {
10515 self.write_space();
10516 self.write_keyword("CYCLE");
10517 }
10518
10519 if let Some(owned) = &cs.owned_by {
10520 self.write_space();
10521 self.write_keyword("OWNED BY");
10522 self.write_space();
10523 self.generate_table(owned)?;
10524 }
10525 }
10526
10527 Ok(())
10528 }
10529
10530 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
10531 self.write_keyword("DROP SEQUENCE");
10532
10533 if ds.if_exists {
10534 self.write_space();
10535 self.write_keyword("IF EXISTS");
10536 }
10537
10538 self.write_space();
10539 self.generate_table(&ds.name)?;
10540
10541 if ds.cascade {
10542 self.write_space();
10543 self.write_keyword("CASCADE");
10544 }
10545
10546 Ok(())
10547 }
10548
10549 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
10550 self.write_keyword("ALTER SEQUENCE");
10551
10552 if als.if_exists {
10553 self.write_space();
10554 self.write_keyword("IF EXISTS");
10555 }
10556
10557 self.write_space();
10558 self.generate_table(&als.name)?;
10559
10560 if let Some(inc) = als.increment {
10561 self.write_space();
10562 self.write_keyword("INCREMENT BY");
10563 self.write(&format!(" {}", inc));
10564 }
10565
10566 if let Some(min) = &als.minvalue {
10567 self.write_space();
10568 match min {
10569 SequenceBound::Value(v) => {
10570 self.write_keyword("MINVALUE");
10571 self.write(&format!(" {}", v));
10572 }
10573 SequenceBound::None => {
10574 self.write_keyword("NO MINVALUE");
10575 }
10576 }
10577 }
10578
10579 if let Some(max) = &als.maxvalue {
10580 self.write_space();
10581 match max {
10582 SequenceBound::Value(v) => {
10583 self.write_keyword("MAXVALUE");
10584 self.write(&format!(" {}", v));
10585 }
10586 SequenceBound::None => {
10587 self.write_keyword("NO MAXVALUE");
10588 }
10589 }
10590 }
10591
10592 if let Some(start) = als.start {
10593 self.write_space();
10594 self.write_keyword("START WITH");
10595 self.write(&format!(" {}", start));
10596 }
10597
10598 if let Some(restart) = &als.restart {
10599 self.write_space();
10600 self.write_keyword("RESTART");
10601 if let Some(val) = restart {
10602 self.write_keyword(" WITH");
10603 self.write(&format!(" {}", val));
10604 }
10605 }
10606
10607 if let Some(cache) = als.cache {
10608 self.write_space();
10609 self.write_keyword("CACHE");
10610 self.write(&format!(" {}", cache));
10611 }
10612
10613 if let Some(cycle) = als.cycle {
10614 self.write_space();
10615 if cycle {
10616 self.write_keyword("CYCLE");
10617 } else {
10618 self.write_keyword("NO CYCLE");
10619 }
10620 }
10621
10622 if let Some(owned) = &als.owned_by {
10623 self.write_space();
10624 self.write_keyword("OWNED BY");
10625 self.write_space();
10626 if let Some(table) = owned {
10627 self.generate_table(table)?;
10628 } else {
10629 self.write_keyword("NONE");
10630 }
10631 }
10632
10633 Ok(())
10634 }
10635
10636 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
10637 self.write_keyword("CREATE");
10638
10639 if ct.or_replace {
10640 self.write_space();
10641 self.write_keyword("OR REPLACE");
10642 }
10643
10644 if ct.constraint {
10645 self.write_space();
10646 self.write_keyword("CONSTRAINT");
10647 }
10648
10649 self.write_space();
10650 self.write_keyword("TRIGGER");
10651 self.write_space();
10652 self.generate_identifier(&ct.name)?;
10653
10654 self.write_space();
10655 match ct.timing {
10656 TriggerTiming::Before => self.write_keyword("BEFORE"),
10657 TriggerTiming::After => self.write_keyword("AFTER"),
10658 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
10659 }
10660
10661 for (i, event) in ct.events.iter().enumerate() {
10663 if i > 0 {
10664 self.write_keyword(" OR");
10665 }
10666 self.write_space();
10667 match event {
10668 TriggerEvent::Insert => self.write_keyword("INSERT"),
10669 TriggerEvent::Update(cols) => {
10670 self.write_keyword("UPDATE");
10671 if let Some(cols) = cols {
10672 self.write_space();
10673 self.write_keyword("OF");
10674 for (j, col) in cols.iter().enumerate() {
10675 if j > 0 {
10676 self.write(",");
10677 }
10678 self.write_space();
10679 self.generate_identifier(col)?;
10680 }
10681 }
10682 }
10683 TriggerEvent::Delete => self.write_keyword("DELETE"),
10684 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
10685 }
10686 }
10687
10688 self.write_space();
10689 self.write_keyword("ON");
10690 self.write_space();
10691 self.generate_table(&ct.table)?;
10692
10693 if let Some(ref_clause) = &ct.referencing {
10695 self.write_space();
10696 self.write_keyword("REFERENCING");
10697 if let Some(old_table) = &ref_clause.old_table {
10698 self.write_space();
10699 self.write_keyword("OLD TABLE AS");
10700 self.write_space();
10701 self.generate_identifier(old_table)?;
10702 }
10703 if let Some(new_table) = &ref_clause.new_table {
10704 self.write_space();
10705 self.write_keyword("NEW TABLE AS");
10706 self.write_space();
10707 self.generate_identifier(new_table)?;
10708 }
10709 if let Some(old_row) = &ref_clause.old_row {
10710 self.write_space();
10711 self.write_keyword("OLD ROW AS");
10712 self.write_space();
10713 self.generate_identifier(old_row)?;
10714 }
10715 if let Some(new_row) = &ref_clause.new_row {
10716 self.write_space();
10717 self.write_keyword("NEW ROW AS");
10718 self.write_space();
10719 self.generate_identifier(new_row)?;
10720 }
10721 }
10722
10723 if let Some(deferrable) = ct.deferrable {
10725 self.write_space();
10726 if deferrable {
10727 self.write_keyword("DEFERRABLE");
10728 } else {
10729 self.write_keyword("NOT DEFERRABLE");
10730 }
10731 }
10732
10733 if let Some(initially) = ct.initially_deferred {
10734 self.write_space();
10735 self.write_keyword("INITIALLY");
10736 self.write_space();
10737 if initially {
10738 self.write_keyword("DEFERRED");
10739 } else {
10740 self.write_keyword("IMMEDIATE");
10741 }
10742 }
10743
10744 self.write_space();
10745 self.write_keyword("FOR EACH");
10746 self.write_space();
10747 match ct.for_each {
10748 TriggerForEach::Row => self.write_keyword("ROW"),
10749 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
10750 }
10751
10752 if let Some(when) = &ct.when {
10754 self.write_space();
10755 self.write_keyword("WHEN");
10756 self.write(" (");
10757 self.generate_expression(when)?;
10758 self.write(")");
10759 }
10760
10761 self.write_space();
10763 match &ct.body {
10764 TriggerBody::Execute { function, args } => {
10765 self.write_keyword("EXECUTE FUNCTION");
10766 self.write_space();
10767 self.generate_table(function)?;
10768 self.write("(");
10769 for (i, arg) in args.iter().enumerate() {
10770 if i > 0 {
10771 self.write(", ");
10772 }
10773 self.generate_expression(arg)?;
10774 }
10775 self.write(")");
10776 }
10777 TriggerBody::Block(block) => {
10778 self.write_keyword("BEGIN");
10779 self.write_space();
10780 self.write(block);
10781 self.write_space();
10782 self.write_keyword("END");
10783 }
10784 }
10785
10786 Ok(())
10787 }
10788
10789 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
10790 self.write_keyword("DROP TRIGGER");
10791
10792 if dt.if_exists {
10793 self.write_space();
10794 self.write_keyword("IF EXISTS");
10795 }
10796
10797 self.write_space();
10798 self.generate_identifier(&dt.name)?;
10799
10800 if let Some(table) = &dt.table {
10801 self.write_space();
10802 self.write_keyword("ON");
10803 self.write_space();
10804 self.generate_table(table)?;
10805 }
10806
10807 if dt.cascade {
10808 self.write_space();
10809 self.write_keyword("CASCADE");
10810 }
10811
10812 Ok(())
10813 }
10814
10815 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
10816 self.write_keyword("CREATE TYPE");
10817
10818 if ct.if_not_exists {
10819 self.write_space();
10820 self.write_keyword("IF NOT EXISTS");
10821 }
10822
10823 self.write_space();
10824 self.generate_table(&ct.name)?;
10825
10826 self.write_space();
10827 self.write_keyword("AS");
10828 self.write_space();
10829
10830 match &ct.definition {
10831 TypeDefinition::Enum(values) => {
10832 self.write_keyword("ENUM");
10833 self.write(" (");
10834 for (i, val) in values.iter().enumerate() {
10835 if i > 0 {
10836 self.write(", ");
10837 }
10838 self.write(&format!("'{}'", val));
10839 }
10840 self.write(")");
10841 }
10842 TypeDefinition::Composite(attrs) => {
10843 self.write("(");
10844 for (i, attr) in attrs.iter().enumerate() {
10845 if i > 0 {
10846 self.write(", ");
10847 }
10848 self.generate_identifier(&attr.name)?;
10849 self.write_space();
10850 self.generate_data_type(&attr.data_type)?;
10851 if let Some(collate) = &attr.collate {
10852 self.write_space();
10853 self.write_keyword("COLLATE");
10854 self.write_space();
10855 self.generate_identifier(collate)?;
10856 }
10857 }
10858 self.write(")");
10859 }
10860 TypeDefinition::Range { subtype, subtype_diff, canonical } => {
10861 self.write_keyword("RANGE");
10862 self.write(" (");
10863 self.write_keyword("SUBTYPE");
10864 self.write(" = ");
10865 self.generate_data_type(subtype)?;
10866 if let Some(diff) = subtype_diff {
10867 self.write(", ");
10868 self.write_keyword("SUBTYPE_DIFF");
10869 self.write(" = ");
10870 self.write(diff);
10871 }
10872 if let Some(canon) = canonical {
10873 self.write(", ");
10874 self.write_keyword("CANONICAL");
10875 self.write(" = ");
10876 self.write(canon);
10877 }
10878 self.write(")");
10879 }
10880 TypeDefinition::Base { input, output, internallength } => {
10881 self.write("(");
10882 self.write_keyword("INPUT");
10883 self.write(" = ");
10884 self.write(input);
10885 self.write(", ");
10886 self.write_keyword("OUTPUT");
10887 self.write(" = ");
10888 self.write(output);
10889 if let Some(len) = internallength {
10890 self.write(", ");
10891 self.write_keyword("INTERNALLENGTH");
10892 self.write(" = ");
10893 self.write(&len.to_string());
10894 }
10895 self.write(")");
10896 }
10897 TypeDefinition::Domain { base_type, default, constraints } => {
10898 self.generate_data_type(base_type)?;
10899 if let Some(def) = default {
10900 self.write_space();
10901 self.write_keyword("DEFAULT");
10902 self.write_space();
10903 self.generate_expression(def)?;
10904 }
10905 for constr in constraints {
10906 self.write_space();
10907 if let Some(name) = &constr.name {
10908 self.write_keyword("CONSTRAINT");
10909 self.write_space();
10910 self.generate_identifier(name)?;
10911 self.write_space();
10912 }
10913 self.write_keyword("CHECK");
10914 self.write(" (");
10915 self.generate_expression(&constr.check)?;
10916 self.write(")");
10917 }
10918 }
10919 }
10920
10921 Ok(())
10922 }
10923
10924 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
10925 self.write_keyword("DROP TYPE");
10926
10927 if dt.if_exists {
10928 self.write_space();
10929 self.write_keyword("IF EXISTS");
10930 }
10931
10932 self.write_space();
10933 self.generate_table(&dt.name)?;
10934
10935 if dt.cascade {
10936 self.write_space();
10937 self.write_keyword("CASCADE");
10938 }
10939
10940 Ok(())
10941 }
10942
10943 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
10944 let saved_athena_hive_context = self.athena_hive_context;
10946 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Athena)) {
10947 self.athena_hive_context = true;
10948 }
10949
10950 for comment in &d.leading_comments {
10952 self.write_formatted_comment(comment);
10953 self.write(" ");
10954 }
10955
10956 self.write_keyword("DESCRIBE");
10957
10958 if d.extended {
10959 self.write_space();
10960 self.write_keyword("EXTENDED");
10961 } else if d.formatted {
10962 self.write_space();
10963 self.write_keyword("FORMATTED");
10964 }
10965
10966 if let Some(ref style) = d.style {
10968 self.write_space();
10969 self.write_keyword(style);
10970 }
10971
10972 let should_output_kind = match self.config.dialect {
10974 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => false,
10976 Some(DialectType::Snowflake) => true,
10978 _ => d.kind.is_some(),
10979 };
10980 if should_output_kind {
10981 if let Some(ref kind) = d.kind {
10982 self.write_space();
10983 self.write_keyword(kind);
10984 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
10985 self.write_space();
10986 self.write_keyword("TABLE");
10987 }
10988 }
10989
10990 self.write_space();
10991 self.generate_expression(&d.target)?;
10992
10993 if let Some(ref partition) = d.partition {
10995 self.write_space();
10996 self.generate_expression(partition)?;
10997 }
10998
10999 for (name, value) in &d.properties {
11001 self.write_space();
11002 self.write(name);
11003 self.write("=");
11004 self.write(value);
11005 }
11006
11007 self.athena_hive_context = saved_athena_hive_context;
11009
11010 Ok(())
11011 }
11012
11013 fn generate_show(&mut self, s: &Show) -> Result<()> {
11016 self.write_keyword("SHOW");
11017 self.write_space();
11018
11019 let show_terse = s.terse && !matches!(
11022 s.this.as_str(),
11023 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
11024 );
11025 if show_terse {
11026 self.write_keyword("TERSE");
11027 self.write_space();
11028 }
11029
11030 self.write_keyword(&s.this);
11032
11033 if let Some(ref target_expr) = s.target {
11035 self.write_space();
11036 self.generate_expression(target_expr)?;
11037 }
11038
11039 if s.history {
11041 self.write_space();
11042 self.write_keyword("HISTORY");
11043 }
11044
11045 if let Some(ref for_target) = s.for_target {
11047 self.write_space();
11048 self.write_keyword("FOR");
11049 self.write_space();
11050 self.generate_expression(for_target)?;
11051 }
11052
11053 use crate::dialects::DialectType;
11057 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
11058
11059 if !is_snowflake && s.from.is_some() {
11060 if let Some(ref scope_kind) = s.scope_kind {
11064 self.write_space();
11065 self.write_keyword("IN");
11066 self.write_space();
11067 self.write_keyword(scope_kind);
11068 if let Some(ref scope) = s.scope {
11069 self.write_space();
11070 self.generate_expression(scope)?;
11071 }
11072 } else if let Some(ref scope) = s.scope {
11073 self.write_space();
11074 self.write_keyword("IN");
11075 self.write_space();
11076 self.generate_expression(scope)?;
11077 }
11078
11079 if let Some(ref from) = s.from {
11081 self.write_space();
11082 self.write_keyword("FROM");
11083 self.write_space();
11084 self.generate_expression(from)?;
11085 }
11086
11087 if let Some(ref db) = s.db {
11089 self.write_space();
11090 self.write_keyword("FROM");
11091 self.write_space();
11092 self.generate_expression(db)?;
11093 }
11094
11095 if let Some(ref like) = s.like {
11097 self.write_space();
11098 self.write_keyword("LIKE");
11099 self.write_space();
11100 self.generate_expression(like)?;
11101 }
11102 } else {
11103 if let Some(ref like) = s.like {
11107 self.write_space();
11108 self.write_keyword("LIKE");
11109 self.write_space();
11110 self.generate_expression(like)?;
11111 }
11112
11113 if let Some(ref scope_kind) = s.scope_kind {
11115 self.write_space();
11116 self.write_keyword("IN");
11117 self.write_space();
11118 self.write_keyword(scope_kind);
11119 if let Some(ref scope) = s.scope {
11120 self.write_space();
11121 self.generate_expression(scope)?;
11122 }
11123 } else if let Some(ref scope) = s.scope {
11124 self.write_space();
11125 self.write_keyword("IN");
11126 self.write_space();
11127 self.generate_expression(scope)?;
11128 }
11129 }
11130
11131 if let Some(ref starts_with) = s.starts_with {
11133 self.write_space();
11134 self.write_keyword("STARTS WITH");
11135 self.write_space();
11136 self.generate_expression(starts_with)?;
11137 }
11138
11139 if let Some(ref limit) = s.limit {
11141 self.write_space();
11142 self.generate_limit(limit)?;
11143 }
11144
11145 if is_snowflake {
11147 if let Some(ref from) = s.from {
11148 self.write_space();
11149 self.write_keyword("FROM");
11150 self.write_space();
11151 self.generate_expression(from)?;
11152 }
11153 }
11154
11155 if let Some(ref where_clause) = s.where_clause {
11157 self.write_space();
11158 self.write_keyword("WHERE");
11159 self.write_space();
11160 self.generate_expression(where_clause)?;
11161 }
11162
11163 if let Some(is_mutex) = s.mutex {
11165 self.write_space();
11166 if is_mutex {
11167 self.write_keyword("MUTEX");
11168 } else {
11169 self.write_keyword("STATUS");
11170 }
11171 }
11172
11173 if !s.privileges.is_empty() {
11175 self.write_space();
11176 self.write_keyword("WITH PRIVILEGES");
11177 self.write_space();
11178 for (i, priv_name) in s.privileges.iter().enumerate() {
11179 if i > 0 {
11180 self.write(", ");
11181 }
11182 self.write_keyword(priv_name);
11183 }
11184 }
11185
11186 Ok(())
11187 }
11188
11189 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
11192 use crate::dialects::DialectType;
11193 match lit {
11194 Literal::String(s) => {
11195 self.generate_string_literal(s)?;
11196 }
11197 Literal::Number(n) => {
11198 if matches!(self.config.dialect, Some(DialectType::MySQL))
11199 && n.len() > 2
11200 && (n.starts_with("0x") || n.starts_with("0X"))
11201 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
11202 {
11203 return self.generate_identifier(&Identifier {
11204 name: n.clone(),
11205 quoted: true,
11206 trailing_comments: Vec::new(),
11207 });
11208 }
11209 if n.starts_with('.') {
11212 self.write("0");
11213 self.write(n);
11214 } else if n.starts_with("-.") {
11215 self.write("-0");
11217 self.write(&n[1..]);
11218 } else {
11219 self.write(n);
11220 }
11221 }
11222 Literal::HexString(h) => {
11223 match self.config.dialect {
11225 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Teradata) => self.write("X'"),
11226 _ => self.write("x'"),
11227 }
11228 self.write(h);
11229 self.write("'");
11230 }
11231 Literal::HexNumber(h) => {
11232 match self.config.dialect {
11236 Some(DialectType::BigQuery) => {
11237 self.write("0x");
11238 self.write(h);
11239 }
11240 _ => {
11241 if let Ok(val) = u64::from_str_radix(h, 16) {
11243 self.write(&val.to_string());
11244 } else {
11245 self.write("0x");
11247 self.write(h);
11248 }
11249 }
11250 }
11251 }
11252 Literal::BitString(b) => {
11253 self.write("B'");
11255 self.write(b);
11256 self.write("'");
11257 }
11258 Literal::ByteString(b) => {
11259 self.write("b'");
11261 self.write_escaped_byte_string(b);
11263 self.write("'");
11264 }
11265 Literal::NationalString(s) => {
11266 let keep_n_prefix = matches!(self.config.dialect,
11269 Some(DialectType::TSQL) | Some(DialectType::Oracle) | Some(DialectType::MySQL) | None
11270 );
11271 if keep_n_prefix {
11272 self.write("N'");
11273 } else {
11274 self.write("'");
11275 }
11276 self.write(s);
11277 self.write("'");
11278 }
11279 Literal::Date(d) => {
11280 self.generate_date_literal(d)?;
11281 }
11282 Literal::Time(t) => {
11283 self.generate_time_literal(t)?;
11284 }
11285 Literal::Timestamp(ts) => {
11286 self.generate_timestamp_literal(ts)?;
11287 }
11288 Literal::Datetime(dt) => {
11289 self.generate_datetime_literal(dt)?;
11290 }
11291 Literal::TripleQuotedString(s, _quote_char) => {
11292 if matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery)
11294 | Some(crate::dialects::DialectType::DuckDB)
11295 | Some(crate::dialects::DialectType::Snowflake)
11296 | Some(crate::dialects::DialectType::Spark)
11297 | Some(crate::dialects::DialectType::Hive)
11298 | Some(crate::dialects::DialectType::Presto)
11299 | Some(crate::dialects::DialectType::Trino)
11300 | Some(crate::dialects::DialectType::PostgreSQL)
11301 | Some(crate::dialects::DialectType::MySQL)
11302 | Some(crate::dialects::DialectType::Redshift)
11303 | Some(crate::dialects::DialectType::TSQL)
11304 | Some(crate::dialects::DialectType::Oracle)
11305 | Some(crate::dialects::DialectType::ClickHouse)
11306 | Some(crate::dialects::DialectType::Databricks)
11307 | Some(crate::dialects::DialectType::SQLite)
11308 ) {
11309 self.generate_string_literal(s)?;
11310 } else {
11311 let quotes = format!("{0}{0}{0}", _quote_char);
11313 self.write("es);
11314 self.write(s);
11315 self.write("es);
11316 }
11317 }
11318 Literal::EscapeString(s) => {
11319 use crate::dialects::DialectType;
11323 let content = if let Some(c) = s.strip_prefix("e:") {
11324 c
11325 } else if let Some(c) = s.strip_prefix("E:") {
11326 c
11327 } else {
11328 s.as_str()
11329 };
11330
11331 if matches!(self.config.dialect, Some(DialectType::MySQL) | Some(DialectType::TiDB)) {
11333 self.write(content);
11334 } else {
11335 let prefix = if matches!(
11337 self.config.dialect,
11338 Some(DialectType::SingleStore)
11339 | Some(DialectType::DuckDB)
11340 | Some(DialectType::PostgreSQL)
11341 | Some(DialectType::CockroachDB)
11342 | Some(DialectType::Materialize)
11343 | Some(DialectType::RisingWave)
11344 ) {
11345 "e'"
11346 } else {
11347 "E'"
11348 };
11349
11350 let normalized = content.replace("\\'", "''");
11352 self.write(prefix);
11353 self.write(&normalized);
11354 self.write("'");
11355 }
11356 }
11357 Literal::DollarString(s) => {
11358 use crate::dialects::DialectType;
11361 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
11363 let escape_backslash = matches!(
11365 self.config.dialect,
11366 Some(DialectType::Snowflake)
11367 );
11368 let use_backslash_quote = matches!(
11372 self.config.dialect,
11373 Some(DialectType::Snowflake)
11374 );
11375
11376 let mut escaped = String::with_capacity(content.len() + 4);
11377 for ch in content.chars() {
11378 if escape_backslash && ch == '\\' {
11379 escaped.push('\\');
11381 escaped.push('\\');
11382 } else if ch == '\'' {
11383 if use_backslash_quote {
11384 escaped.push('\\');
11385 escaped.push('\'');
11386 } else {
11387 escaped.push('\'');
11388 escaped.push('\'');
11389 }
11390 } else {
11391 escaped.push(ch);
11392 }
11393 }
11394 self.write("'");
11395 self.write(&escaped);
11396 self.write("'");
11397 }
11398 Literal::RawString(s) => {
11399 use crate::dialects::DialectType;
11405
11406 let escape_backslash = matches!(
11408 self.config.dialect,
11409 Some(DialectType::BigQuery)
11410 | Some(DialectType::MySQL)
11411 | Some(DialectType::SingleStore)
11412 | Some(DialectType::TiDB)
11413 | Some(DialectType::Hive)
11414 | Some(DialectType::Spark)
11415
11416 | Some(DialectType::Databricks)
11417 | Some(DialectType::Drill)
11418 | Some(DialectType::Snowflake)
11419 | Some(DialectType::Redshift)
11420 | Some(DialectType::ClickHouse)
11421 );
11422
11423 let backslash_escapes_quote = matches!(
11426 self.config.dialect,
11427 Some(DialectType::BigQuery)
11428 | Some(DialectType::Hive)
11429 | Some(DialectType::Spark)
11430
11431 | Some(DialectType::Databricks)
11432 | Some(DialectType::Drill)
11433 | Some(DialectType::Snowflake)
11434 | Some(DialectType::Redshift)
11435 );
11436
11437 let supports_escape_sequences = escape_backslash;
11440
11441 let mut escaped = String::with_capacity(s.len() + 4);
11442 for ch in s.chars() {
11443 if escape_backslash && ch == '\\' {
11444 escaped.push('\\');
11446 escaped.push('\\');
11447 } else if ch == '\'' {
11448 if backslash_escapes_quote {
11449 escaped.push('\\');
11451 escaped.push('\'');
11452 } else {
11453 escaped.push('\'');
11455 escaped.push('\'');
11456 }
11457 } else if supports_escape_sequences {
11458 match ch {
11461 '\n' => { escaped.push('\\'); escaped.push('n'); }
11462 '\r' => { escaped.push('\\'); escaped.push('r'); }
11463 '\t' => { escaped.push('\\'); escaped.push('t'); }
11464 '\x07' => { escaped.push('\\'); escaped.push('a'); }
11465 '\x08' => { escaped.push('\\'); escaped.push('b'); }
11466 '\x0C' => { escaped.push('\\'); escaped.push('f'); }
11467 '\x0B' => { escaped.push('\\'); escaped.push('v'); }
11468 _ => escaped.push(ch),
11469 }
11470 } else {
11471 escaped.push(ch);
11472 }
11473 }
11474 self.write("'");
11475 self.write(&escaped);
11476 self.write("'");
11477 }
11478 }
11479 Ok(())
11480 }
11481
11482 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
11484 use crate::dialects::DialectType;
11485
11486 match self.config.dialect {
11487 Some(DialectType::TSQL) => {
11489 self.write("CAST('");
11490 self.write(d);
11491 self.write("' AS DATE)");
11492 }
11493 Some(DialectType::BigQuery) => {
11496 self.write("CAST('");
11497 self.write(d);
11498 self.write("' AS DATE)");
11499 }
11500 Some(DialectType::Exasol) => {
11503 self.write("CAST('");
11504 self.write(d);
11505 self.write("' AS DATE)");
11506 }
11507 Some(DialectType::Snowflake) => {
11510 self.write("CAST('");
11511 self.write(d);
11512 self.write("' AS DATE)");
11513 }
11514 Some(DialectType::PostgreSQL) | Some(DialectType::MySQL)
11516 | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
11517 | Some(DialectType::Redshift) => {
11518 self.write("CAST('");
11519 self.write(d);
11520 self.write("' AS DATE)");
11521 }
11522 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
11524 | Some(DialectType::Athena) | Some(DialectType::Spark)
11525 | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
11526 self.write("CAST('");
11527 self.write(d);
11528 self.write("' AS DATE)");
11529 }
11530 Some(DialectType::Oracle) => {
11532 self.write("TO_DATE('");
11533 self.write(d);
11534 self.write("', 'YYYY-MM-DD')");
11535 }
11536 _ => {
11538 self.write_keyword("DATE");
11539 self.write(" '");
11540 self.write(d);
11541 self.write("'");
11542 }
11543 }
11544 Ok(())
11545 }
11546
11547 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
11549 use crate::dialects::DialectType;
11550
11551 match self.config.dialect {
11552 Some(DialectType::TSQL) => {
11554 self.write("CAST('");
11555 self.write(t);
11556 self.write("' AS TIME)");
11557 }
11558 _ => {
11560 self.write_keyword("TIME");
11561 self.write(" '");
11562 self.write(t);
11563 self.write("'");
11564 }
11565 }
11566 Ok(())
11567 }
11568
11569 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
11571 use crate::expressions::Literal;
11572
11573 match expr {
11574 Expression::Literal(Literal::Date(d)) => {
11575 self.write("CAST('");
11577 self.write(d);
11578 self.write("' AS DATE)");
11579 }
11580 _ => {
11581 self.generate_expression(expr)?;
11583 }
11584 }
11585 Ok(())
11586 }
11587
11588 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
11590 use crate::dialects::DialectType;
11591
11592 match self.config.dialect {
11593 Some(DialectType::TSQL) => {
11595 self.write("CAST('");
11596 self.write(ts);
11597 self.write("' AS DATETIME2)");
11598 }
11599 Some(DialectType::BigQuery) => {
11602 self.write("CAST('");
11603 self.write(ts);
11604 self.write("' AS TIMESTAMP)");
11605 }
11606 Some(DialectType::Snowflake) => {
11609 self.write("CAST('");
11610 self.write(ts);
11611 self.write("' AS TIMESTAMP)");
11612 }
11613 Some(DialectType::Dremio) => {
11616 self.write("CAST('");
11617 self.write(ts);
11618 self.write("' AS TIMESTAMP)");
11619 }
11620 Some(DialectType::Exasol) => {
11623 self.write("CAST('");
11624 self.write(ts);
11625 self.write("' AS TIMESTAMP)");
11626 }
11627 Some(DialectType::Oracle) => {
11630 self.write("TO_TIMESTAMP('");
11631 self.write(ts);
11632 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
11633 }
11634 Some(DialectType::Presto) | Some(DialectType::Trino) => {
11636 if Self::timestamp_has_timezone(ts) {
11637 self.write("CAST('");
11638 self.write(ts);
11639 self.write("' AS TIMESTAMP WITH TIME ZONE)");
11640 } else {
11641 self.write("CAST('");
11642 self.write(ts);
11643 self.write("' AS TIMESTAMP)");
11644 }
11645 }
11646 Some(DialectType::ClickHouse) => {
11648 self.write("CAST('");
11649 self.write(ts);
11650 self.write("' AS Nullable(DateTime))");
11651 }
11652 Some(DialectType::Spark) => {
11654 self.write("CAST('");
11655 self.write(ts);
11656 self.write("' AS TIMESTAMP)");
11657 }
11658 Some(DialectType::Redshift) => {
11661 if ts == "epoch" {
11662 self.write_keyword("TIMESTAMP");
11663 self.write(" '");
11664 self.write(ts);
11665 self.write("'");
11666 } else {
11667 self.write("CAST('");
11668 self.write(ts);
11669 self.write("' AS TIMESTAMP)");
11670 }
11671 }
11672 Some(DialectType::PostgreSQL) | Some(DialectType::Hive) |
11674 Some(DialectType::SQLite) | Some(DialectType::DuckDB) |
11675 Some(DialectType::Athena) | Some(DialectType::Drill) |
11676 Some(DialectType::Teradata) => {
11677 self.write("CAST('");
11678 self.write(ts);
11679 self.write("' AS TIMESTAMP)");
11680 }
11681 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
11683 self.write("CAST('");
11684 self.write(ts);
11685 self.write("' AS DATETIME)");
11686 }
11687 Some(DialectType::Databricks) => {
11689 self.write("CAST('");
11690 self.write(ts);
11691 self.write("' AS TIMESTAMP_NTZ)");
11692 }
11693 _ => {
11695 self.write_keyword("TIMESTAMP");
11696 self.write(" '");
11697 self.write(ts);
11698 self.write("'");
11699 }
11700 }
11701 Ok(())
11702 }
11703
11704 fn timestamp_has_timezone(ts: &str) -> bool {
11707 let ts_lower = ts.to_lowercase();
11711
11712 let continent_prefixes = [
11714 "africa/", "america/", "antarctica/", "arctic/", "asia/",
11715 "atlantic/", "australia/", "europe/", "indian/", "pacific/",
11716 "etc/", "brazil/", "canada/", "chile/", "mexico/", "us/",
11717 ];
11718
11719 for prefix in &continent_prefixes {
11720 if ts_lower.contains(prefix) {
11721 return true;
11722 }
11723 }
11724
11725 let tz_abbrevs = [
11728 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west",
11729 " est", " edt", " cst", " cdt", " mst", " mdt", " pst", " pdt",
11730 " ist", " bst", " jst", " kst", " hkt", " sgt", " aest", " aedt",
11731 " acst", " acdt", " awst",
11732 ];
11733
11734 for abbrev in &tz_abbrevs {
11735 if ts_lower.ends_with(abbrev) {
11736 return true;
11737 }
11738 }
11739
11740 let trimmed = ts.trim();
11744 if let Some(last_space) = trimmed.rfind(' ') {
11745 let suffix = &trimmed[last_space + 1..];
11746 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
11747 let rest = &suffix[1..];
11749 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
11750 return true;
11751 }
11752 }
11753 }
11754
11755 false
11756 }
11757
11758 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
11760 use crate::dialects::DialectType;
11761
11762 match self.config.dialect {
11763 Some(DialectType::BigQuery) => {
11766 self.write("CAST('");
11767 self.write(dt);
11768 self.write("' AS DATETIME)");
11769 }
11770 Some(DialectType::DuckDB) => {
11772 self.write("CAST('");
11773 self.write(dt);
11774 self.write("' AS TIMESTAMP)");
11775 }
11776 _ => {
11779 self.write_keyword("DATETIME");
11780 self.write(" '");
11781 self.write(dt);
11782 self.write("'");
11783 }
11784 }
11785 Ok(())
11786 }
11787
11788 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
11790 use crate::dialects::DialectType;
11791
11792 match self.config.dialect {
11793 Some(DialectType::Hive)
11797 | Some(DialectType::Spark)
11798
11799 | Some(DialectType::Databricks)
11800 | Some(DialectType::Drill) => {
11801 self.write("'");
11803 for c in s.chars() {
11804 match c {
11805 '\'' => self.write("\\'"),
11806 '\\' => self.write("\\\\"),
11807 '\n' => self.write("\\n"),
11808 '\r' => self.write("\\r"),
11809 '\t' => self.write("\\t"),
11810 '\0' => self.write("\\0"),
11811 _ => self.output.push(c),
11812 }
11813 }
11814 self.write("'");
11815 }
11816 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
11817 self.write("'");
11818 for c in s.chars() {
11819 match c {
11820 '\'' => self.write("''"),
11822 '\\' => self.write("\\\\"),
11823 '\n' => self.write("\\n"),
11824 '\r' => self.write("\\r"),
11825 '\t' => self.write("\\t"),
11826 '\0' => self.output.push('\0'),
11828 _ => self.output.push(c),
11829 }
11830 }
11831 self.write("'");
11832 }
11833 Some(DialectType::BigQuery) => {
11835 self.write("'");
11836 for c in s.chars() {
11837 match c {
11838 '\'' => self.write("\\'"),
11839 '\\' => self.write("\\\\"),
11840 '\n' => self.write("\\n"),
11841 '\r' => self.write("\\r"),
11842 '\t' => self.write("\\t"),
11843 '\0' => self.write("\\0"),
11844 '\x07' => self.write("\\a"),
11845 '\x08' => self.write("\\b"),
11846 '\x0C' => self.write("\\f"),
11847 '\x0B' => self.write("\\v"),
11848 _ => self.output.push(c),
11849 }
11850 }
11851 self.write("'");
11852 }
11853 Some(DialectType::Athena) => {
11857 if self.athena_hive_context {
11858 self.write("'");
11860 for c in s.chars() {
11861 match c {
11862 '\'' => self.write("\\'"),
11863 '\\' => self.write("\\\\"),
11864 '\n' => self.write("\\n"),
11865 '\r' => self.write("\\r"),
11866 '\t' => self.write("\\t"),
11867 '\0' => self.write("\\0"),
11868 _ => self.output.push(c),
11869 }
11870 }
11871 self.write("'");
11872 } else {
11873 self.write("'");
11875 for c in s.chars() {
11876 match c {
11877 '\'' => self.write("''"),
11878 _ => self.output.push(c),
11880 }
11881 }
11882 self.write("'");
11883 }
11884 }
11885 Some(DialectType::Snowflake) => {
11890 self.write("'");
11891 for c in s.chars() {
11892 match c {
11893 '\'' => self.write("\\'"),
11894 '\n' => self.write("\\n"),
11897 '\r' => self.write("\\r"),
11898 '\t' => self.write("\\t"),
11899 _ => self.output.push(c),
11900 }
11901 }
11902 self.write("'");
11903 }
11904 Some(DialectType::PostgreSQL) => {
11906 self.write("'");
11907 for c in s.chars() {
11908 match c {
11909 '\'' => self.write("''"),
11910 _ => self.output.push(c),
11911 }
11912 }
11913 self.write("'");
11914 }
11915 Some(DialectType::Redshift) => {
11917 self.write("'");
11918 for c in s.chars() {
11919 match c {
11920 '\'' => self.write("\\'"),
11921 _ => self.output.push(c),
11922 }
11923 }
11924 self.write("'");
11925 }
11926 Some(DialectType::Oracle) => {
11928 self.write("'");
11929 self.write(&s.replace('\'', "''"));
11930 self.write("'");
11931 }
11932 Some(DialectType::ClickHouse) => {
11935 self.write("'");
11936 for c in s.chars() {
11937 match c {
11938 '\'' => self.write("''"),
11939 '\\' => self.write("\\\\"),
11940 '\n' => self.write("\\n"),
11941 '\r' => self.write("\\r"),
11942 '\t' => self.write("\\t"),
11943 '\0' => self.write("\\0"),
11944 _ => self.output.push(c),
11945 }
11946 }
11947 self.write("'");
11948 }
11949 _ => {
11952 self.write("'");
11953 self.write(&s.replace('\'', "''"));
11954 self.write("'");
11955 }
11956 }
11957 Ok(())
11958 }
11959
11960 fn write_escaped_byte_string(&mut self, s: &str) {
11963 for c in s.chars() {
11964 match c {
11965 '\'' => self.write("\\'"),
11967 '\\' => self.write("\\\\"),
11969 _ if !c.is_control() => self.output.push(c),
11971 _ => {
11973 let byte = c as u32;
11974 if byte < 256 {
11975 self.write(&format!("\\x{:02x}", byte));
11976 } else {
11977 for b in c.to_string().as_bytes() {
11979 self.write(&format!("\\x{:02x}", b));
11980 }
11981 }
11982 }
11983 }
11984 }
11985 }
11986
11987 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
11988 use crate::dialects::DialectType;
11989
11990 match self.config.dialect {
11992 Some(DialectType::TSQL) => {
11995 self.write(if b.value { "1" } else { "0" });
11996 }
11997 Some(DialectType::Oracle) => {
11999 self.write(if b.value { "1" } else { "0" });
12000 }
12001 Some(DialectType::MySQL) => {
12003 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
12004 }
12005 _ => {
12007 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
12008 }
12009 }
12010 Ok(())
12011 }
12012
12013 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
12016 let name = &id.name;
12017 let quote_style = &self.config.identifier_quote_style;
12018
12019 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
12023
12024 let output_name = if self.config.normalize_identifiers && !id.quoted {
12026 name.to_lowercase()
12027 } else {
12028 name.to_string()
12029 };
12030
12031 if needs_quoting {
12032 let escaped_name = if quote_style.start == quote_style.end {
12034 output_name.replace(
12035 quote_style.end,
12036 &format!("{}{}", quote_style.end, quote_style.end)
12037 )
12038 } else {
12039 output_name.replace(
12040 quote_style.end,
12041 &format!("{}{}", quote_style.end, quote_style.end)
12042 )
12043 };
12044 self.write(&format!("{}{}{}", quote_style.start, escaped_name, quote_style.end));
12045 } else {
12046 self.write(&output_name);
12047 }
12048
12049 for comment in &id.trailing_comments {
12051 self.write(" ");
12052 self.write(comment);
12053 }
12054 Ok(())
12055 }
12056
12057 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
12058 use crate::dialects::DialectType;
12059
12060 let name = &id.name;
12061
12062 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena)) && self.athena_hive_context {
12064 &IdentifierQuoteStyle::BACKTICK
12065 } else {
12066 &self.config.identifier_quote_style
12067 };
12068
12069 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
12076 let needs_digit_quoting = starts_with_digit && !self.config.identifiers_can_start_with_digit && self.config.dialect.is_some();
12077 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
12078 && name.len() > 2
12079 && (name.starts_with("0x") || name.starts_with("0X"))
12080 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
12081 let needs_quoting = id.quoted
12082 || self.is_reserved_keyword(name)
12083 || self.config.always_quote_identifiers
12084 || needs_digit_quoting
12085 || mysql_invalid_hex_identifier;
12086
12087 let (base_name, suffix) = if needs_quoting {
12090 if let Some(paren_pos) = name.find('(') {
12092 let base = &name[..paren_pos];
12093 let rest = &name[paren_pos..];
12094 if rest.starts_with('(') && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC")) {
12096 let close_paren = rest.find(')').unwrap_or(rest.len());
12098 let inside = &rest[1..close_paren];
12099 if inside.chars().all(|c| c.is_ascii_digit()) {
12100 (base.to_string(), rest.to_string())
12101 } else {
12102 (name.to_string(), String::new())
12103 }
12104 } else {
12105 (name.to_string(), String::new())
12106 }
12107 } else if name.ends_with(" ASC") {
12108 let base = &name[..name.len() - 4];
12109 (base.to_string(), " ASC".to_string())
12110 } else if name.ends_with(" DESC") {
12111 let base = &name[..name.len() - 5];
12112 (base.to_string(), " DESC".to_string())
12113 } else {
12114 (name.to_string(), String::new())
12115 }
12116 } else {
12117 (name.to_string(), String::new())
12118 };
12119
12120 let output_name = if self.config.normalize_identifiers && !id.quoted {
12124 base_name.to_lowercase()
12125 } else if matches!(self.config.dialect, Some(DialectType::Exasol)) && !id.quoted && self.is_reserved_keyword(name) {
12126 base_name.to_uppercase()
12129 } else {
12130 base_name
12131 };
12132
12133 if needs_quoting {
12134 let escaped_name = if quote_style.start == quote_style.end {
12136 output_name.replace(
12138 quote_style.end,
12139 &format!("{}{}", quote_style.end, quote_style.end)
12140 )
12141 } else {
12142 output_name.replace(
12144 quote_style.end,
12145 &format!("{}{}", quote_style.end, quote_style.end)
12146 )
12147 };
12148 self.write(&format!("{}{}{}{}", quote_style.start, escaped_name, quote_style.end, suffix));
12149 } else {
12150 self.write(&output_name);
12151 }
12152
12153 for comment in &id.trailing_comments {
12155 self.write(" ");
12156 self.write(comment);
12157 }
12158 Ok(())
12159 }
12160
12161 fn generate_column(&mut self, col: &Column) -> Result<()> {
12162 use crate::dialects::DialectType;
12163
12164 if let Some(table) = &col.table {
12165 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
12169 && !table.quoted
12170 && table.name.eq_ignore_ascii_case("LOCAL");
12171
12172 if is_exasol_local_prefix {
12173 self.write("LOCAL");
12175 } else {
12176 self.generate_identifier(table)?;
12177 }
12178 self.write(".");
12179 }
12180 self.generate_identifier(&col.name)?;
12181 if col.join_mark && self.config.supports_column_join_marks {
12184 self.write(" (+)");
12185 }
12186 for comment in &col.trailing_comments {
12188 self.write_space();
12189 self.write(comment);
12190 }
12191 Ok(())
12192 }
12193
12194 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
12197 use crate::dialects::DialectType;
12198 use crate::expressions::PseudocolumnType;
12199
12200 if pc.kind == PseudocolumnType::Sysdate
12202 && !matches!(self.config.dialect, Some(DialectType::Oracle) | Some(DialectType::Redshift) | None)
12203 {
12204 self.write_keyword("CURRENT_TIMESTAMP");
12205 if matches!(self.config.dialect, Some(DialectType::MySQL) | Some(DialectType::ClickHouse)
12207 | Some(DialectType::Spark) | Some(DialectType::Databricks)
12208 | Some(DialectType::Hive)) {
12209 self.write("()");
12210 }
12211 } else {
12212 self.write(pc.kind.as_str());
12213 }
12214 Ok(())
12215 }
12216
12217 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
12219 use crate::dialects::DialectType;
12220
12221 let supports_connect_by = matches!(self.config.dialect, Some(DialectType::Oracle) | Some(DialectType::Snowflake));
12224
12225 if !supports_connect_by && self.config.dialect.is_some() {
12226 if self.config.pretty {
12228 self.write_newline();
12229 } else {
12230 self.write_space();
12231 }
12232 self.write("/* CONNECT BY requires manual conversion to recursive CTE */");
12233 }
12234
12235 if let Some(start) = &connect.start {
12237 if self.config.pretty {
12238 self.write_newline();
12239 } else {
12240 self.write_space();
12241 }
12242 self.write_keyword("START WITH");
12243 self.write_space();
12244 self.generate_expression(start)?;
12245 }
12246
12247 if self.config.pretty {
12249 self.write_newline();
12250 } else {
12251 self.write_space();
12252 }
12253 self.write_keyword("CONNECT BY");
12254 if connect.nocycle {
12255 self.write_space();
12256 self.write_keyword("NOCYCLE");
12257 }
12258 self.write_space();
12259 self.generate_expression(&connect.connect)?;
12260
12261 Ok(())
12262 }
12263
12264 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
12266 self.generate_connect(connect)
12267 }
12268
12269 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
12271 self.write_keyword("PRIOR");
12272 self.write_space();
12273 self.generate_expression(&prior.this)?;
12274 Ok(())
12275 }
12276
12277 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
12280 self.write_keyword("CONNECT_BY_ROOT");
12281 self.write_space();
12282 self.generate_expression(&cbr.this)?;
12283 Ok(())
12284 }
12285
12286 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
12288 use crate::dialects::DialectType;
12289
12290 let supports_match_recognize = matches!(
12292 self.config.dialect,
12293 Some(DialectType::Oracle) | Some(DialectType::Snowflake) | Some(DialectType::Presto) | Some(DialectType::Trino)
12294 );
12295
12296 if let Some(source) = &mr.this {
12298 self.generate_expression(source)?;
12299 }
12300
12301 if !supports_match_recognize {
12302 self.write("/* MATCH_RECOGNIZE not supported in this dialect */");
12303 return Ok(());
12304 }
12305
12306 if self.config.pretty {
12308 self.write_newline();
12309 } else {
12310 self.write_space();
12311 }
12312
12313 self.write_keyword("MATCH_RECOGNIZE");
12314 self.write(" (");
12315
12316 if self.config.pretty {
12317 self.indent_level += 1;
12318 }
12319
12320 let mut needs_separator = false;
12321
12322 if let Some(partition_by) = &mr.partition_by {
12324 if !partition_by.is_empty() {
12325 if self.config.pretty {
12326 self.write_newline();
12327 self.write_indent();
12328 }
12329 self.write_keyword("PARTITION BY");
12330 self.write_space();
12331 for (i, expr) in partition_by.iter().enumerate() {
12332 if i > 0 {
12333 self.write(", ");
12334 }
12335 self.generate_expression(expr)?;
12336 }
12337 needs_separator = true;
12338 }
12339 }
12340
12341 if let Some(order_by) = &mr.order_by {
12343 if !order_by.is_empty() {
12344 if needs_separator {
12345 if self.config.pretty {
12346 self.write_newline();
12347 self.write_indent();
12348 } else {
12349 self.write_space();
12350 }
12351 } else if self.config.pretty {
12352 self.write_newline();
12353 self.write_indent();
12354 }
12355 self.write_keyword("ORDER BY");
12356 if self.config.pretty {
12358 self.indent_level += 1;
12359 for (i, ordered) in order_by.iter().enumerate() {
12360 if i > 0 {
12361 self.write(",");
12362 }
12363 self.write_newline();
12364 self.write_indent();
12365 self.generate_ordered(ordered)?;
12366 }
12367 self.indent_level -= 1;
12368 } else {
12369 self.write_space();
12370 for (i, ordered) in order_by.iter().enumerate() {
12371 if i > 0 {
12372 self.write(", ");
12373 }
12374 self.generate_ordered(ordered)?;
12375 }
12376 }
12377 needs_separator = true;
12378 }
12379 }
12380
12381 if let Some(measures) = &mr.measures {
12383 if !measures.is_empty() {
12384 if needs_separator {
12385 if self.config.pretty {
12386 self.write_newline();
12387 self.write_indent();
12388 } else {
12389 self.write_space();
12390 }
12391 } else if self.config.pretty {
12392 self.write_newline();
12393 self.write_indent();
12394 }
12395 self.write_keyword("MEASURES");
12396 if self.config.pretty {
12398 self.indent_level += 1;
12399 for (i, measure) in measures.iter().enumerate() {
12400 if i > 0 {
12401 self.write(",");
12402 }
12403 self.write_newline();
12404 self.write_indent();
12405 if let Some(semantics) = &measure.window_frame {
12407 match semantics {
12408 MatchRecognizeSemantics::Running => {
12409 self.write_keyword("RUNNING");
12410 self.write_space();
12411 }
12412 MatchRecognizeSemantics::Final => {
12413 self.write_keyword("FINAL");
12414 self.write_space();
12415 }
12416 }
12417 }
12418 self.generate_expression(&measure.this)?;
12419 }
12420 self.indent_level -= 1;
12421 } else {
12422 self.write_space();
12423 for (i, measure) in measures.iter().enumerate() {
12424 if i > 0 {
12425 self.write(", ");
12426 }
12427 if let Some(semantics) = &measure.window_frame {
12429 match semantics {
12430 MatchRecognizeSemantics::Running => {
12431 self.write_keyword("RUNNING");
12432 self.write_space();
12433 }
12434 MatchRecognizeSemantics::Final => {
12435 self.write_keyword("FINAL");
12436 self.write_space();
12437 }
12438 }
12439 }
12440 self.generate_expression(&measure.this)?;
12441 }
12442 }
12443 needs_separator = true;
12444 }
12445 }
12446
12447 if let Some(rows) = &mr.rows {
12449 if needs_separator {
12450 if self.config.pretty {
12451 self.write_newline();
12452 self.write_indent();
12453 } else {
12454 self.write_space();
12455 }
12456 } else if self.config.pretty {
12457 self.write_newline();
12458 self.write_indent();
12459 }
12460 match rows {
12461 MatchRecognizeRows::OneRowPerMatch => {
12462 self.write_keyword("ONE ROW PER MATCH");
12463 }
12464 MatchRecognizeRows::AllRowsPerMatch => {
12465 self.write_keyword("ALL ROWS PER MATCH");
12466 }
12467 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
12468 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
12469 }
12470 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
12471 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
12472 }
12473 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
12474 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
12475 }
12476 }
12477 needs_separator = true;
12478 }
12479
12480 if let Some(after) = &mr.after {
12482 if needs_separator {
12483 if self.config.pretty {
12484 self.write_newline();
12485 self.write_indent();
12486 } else {
12487 self.write_space();
12488 }
12489 } else if self.config.pretty {
12490 self.write_newline();
12491 self.write_indent();
12492 }
12493 match after {
12494 MatchRecognizeAfter::PastLastRow => {
12495 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
12496 }
12497 MatchRecognizeAfter::ToNextRow => {
12498 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
12499 }
12500 MatchRecognizeAfter::ToFirst(ident) => {
12501 self.write_keyword("AFTER MATCH SKIP TO FIRST");
12502 self.write_space();
12503 self.generate_identifier(ident)?;
12504 }
12505 MatchRecognizeAfter::ToLast(ident) => {
12506 self.write_keyword("AFTER MATCH SKIP TO LAST");
12507 self.write_space();
12508 self.generate_identifier(ident)?;
12509 }
12510 }
12511 needs_separator = true;
12512 }
12513
12514 if let Some(pattern) = &mr.pattern {
12516 if needs_separator {
12517 if self.config.pretty {
12518 self.write_newline();
12519 self.write_indent();
12520 } else {
12521 self.write_space();
12522 }
12523 } else if self.config.pretty {
12524 self.write_newline();
12525 self.write_indent();
12526 }
12527 self.write_keyword("PATTERN");
12528 self.write_space();
12529 self.write("(");
12530 self.write(pattern);
12531 self.write(")");
12532 needs_separator = true;
12533 }
12534
12535 if let Some(define) = &mr.define {
12537 if !define.is_empty() {
12538 if needs_separator {
12539 if self.config.pretty {
12540 self.write_newline();
12541 self.write_indent();
12542 } else {
12543 self.write_space();
12544 }
12545 } else if self.config.pretty {
12546 self.write_newline();
12547 self.write_indent();
12548 }
12549 self.write_keyword("DEFINE");
12550 if self.config.pretty {
12552 self.indent_level += 1;
12553 for (i, (name, expr)) in define.iter().enumerate() {
12554 if i > 0 {
12555 self.write(",");
12556 }
12557 self.write_newline();
12558 self.write_indent();
12559 self.generate_identifier(name)?;
12560 self.write(" AS ");
12561 self.generate_expression(expr)?;
12562 }
12563 self.indent_level -= 1;
12564 } else {
12565 self.write_space();
12566 for (i, (name, expr)) in define.iter().enumerate() {
12567 if i > 0 {
12568 self.write(", ");
12569 }
12570 self.generate_identifier(name)?;
12571 self.write(" AS ");
12572 self.generate_expression(expr)?;
12573 }
12574 }
12575 }
12576 }
12577
12578 if self.config.pretty {
12579 self.indent_level -= 1;
12580 self.write_newline();
12581 }
12582 self.write(")");
12583
12584 if let Some(alias) = &mr.alias {
12586 self.write(" ");
12587 if mr.alias_explicit_as {
12588 self.write_keyword("AS");
12589 self.write(" ");
12590 }
12591 self.generate_identifier(alias)?;
12592 }
12593
12594 Ok(())
12595 }
12596
12597 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
12599 use crate::dialects::DialectType;
12600
12601 let supports_hints = matches!(
12603 self.config.dialect,
12604 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
12606 Some(DialectType::Spark) | Some(DialectType::Hive) |
12607 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
12608 );
12609
12610 if !supports_hints || hint.expressions.is_empty() {
12611 return Ok(());
12612 }
12613
12614 let mut hint_strings: Vec<String> = Vec::new();
12617 for expr in &hint.expressions {
12618 match expr {
12619 HintExpression::Raw(text) => {
12620 let parsed = self.parse_raw_hint_text(text);
12622 hint_strings.extend(parsed);
12623 }
12624 _ => {
12625 hint_strings.push(self.hint_expression_to_string(expr)?);
12626 }
12627 }
12628 }
12629
12630 let use_multiline = self.config.pretty && hint_strings.len() > 1;
12634
12635 if use_multiline {
12636 self.write(" /*+ ");
12638 for (i, hint_str) in hint_strings.iter().enumerate() {
12639 if i > 0 {
12640 self.write_newline();
12641 self.write(" "); }
12643 self.write(hint_str);
12644 }
12645 self.write(" */");
12646 } else {
12647 self.write(" /*+ ");
12649 let sep = match self.config.dialect {
12650 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
12651 _ => " ",
12652 };
12653 for (i, hint_str) in hint_strings.iter().enumerate() {
12654 if i > 0 {
12655 self.write(sep);
12656 }
12657 self.write(hint_str);
12658 }
12659 self.write(" */");
12660 }
12661
12662 Ok(())
12663 }
12664
12665 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
12669 let mut results = Vec::new();
12670 let mut chars = text.chars().peekable();
12671 let mut current = String::new();
12672 let mut paren_depth = 0;
12673 let mut has_unparseable_content = false;
12674 let mut position_after_last_function = 0;
12675 let mut char_position = 0;
12676
12677 while let Some(c) = chars.next() {
12678 char_position += c.len_utf8();
12679 match c {
12680 '(' => {
12681 paren_depth += 1;
12682 current.push(c);
12683 }
12684 ')' => {
12685 paren_depth -= 1;
12686 current.push(c);
12687 if paren_depth == 0 {
12689 let trimmed = current.trim().to_string();
12690 if !trimmed.is_empty() {
12691 let formatted = self.format_hint_function(&trimmed);
12693 results.push(formatted);
12694 }
12695 current.clear();
12696 position_after_last_function = char_position;
12697 }
12698 }
12699 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
12700 }
12702 _ if paren_depth == 0 => {
12703 current.push(c);
12705 }
12706 _ => {
12707 current.push(c);
12708 }
12709 }
12710 }
12711
12712 let remaining_text = text[position_after_last_function..].trim();
12714 if !remaining_text.is_empty() {
12715 let words: Vec<&str> = remaining_text.split_whitespace().collect();
12719 let looks_like_hint_functions = words.iter().all(|word| {
12720 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
12722 });
12723
12724 if !looks_like_hint_functions && words.len() > 1 {
12725 has_unparseable_content = true;
12726 }
12727 }
12728
12729 if has_unparseable_content {
12731 return vec![text.trim().to_string()];
12732 }
12733
12734 if results.is_empty() {
12736 results.push(text.trim().to_string());
12737 }
12738
12739 results
12740 }
12741
12742 fn format_hint_function(&self, hint: &str) -> String {
12745 if !self.config.pretty {
12746 return hint.to_string();
12747 }
12748
12749 if let Some(paren_pos) = hint.find('(') {
12751 if hint.ends_with(')') {
12752 let name = &hint[..paren_pos];
12753 let args_str = &hint[paren_pos + 1..hint.len() - 1];
12754
12755 let args: Vec<&str> = args_str.split_whitespace().collect();
12757
12758 let total_args_width: usize = args.iter().map(|s| s.len()).sum::<usize>()
12760 + args.len().saturating_sub(1); if total_args_width > self.config.max_text_width && !args.is_empty() {
12764 let mut result = format!("{}(\n", name);
12765 for arg in &args {
12766 result.push_str(" "); result.push_str(arg);
12768 result.push('\n');
12769 }
12770 result.push_str(" )"); return result;
12772 }
12773 }
12774 }
12775
12776 hint.to_string()
12777 }
12778
12779 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
12781 match expr {
12782 HintExpression::Function { name, args } => {
12783 let arg_strings: Vec<String> = args.iter()
12785 .map(|arg| {
12786 let mut gen = Generator::with_config(self.config.clone());
12787 gen.generate_expression(arg)?;
12788 Ok(gen.output)
12789 })
12790 .collect::<Result<Vec<_>>>()?;
12791
12792 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
12794 + arg_strings.len().saturating_sub(1); let args_multiline = self.config.pretty
12799 && total_args_width > self.config.max_text_width;
12800
12801 if args_multiline && !arg_strings.is_empty() {
12802 let mut result = format!("{}(\n", name);
12804 for arg_str in &arg_strings {
12805 result.push_str(" "); result.push_str(arg_str);
12807 result.push('\n');
12808 }
12809 result.push_str(" )"); Ok(result)
12811 } else {
12812 let args_str = arg_strings.join(" ");
12814 Ok(format!("{}({})", name, args_str))
12815 }
12816 }
12817 HintExpression::Identifier(name) => Ok(name.clone()),
12818 HintExpression::Raw(text) => {
12819 if self.config.pretty {
12821 Ok(self.format_hint_function(text))
12822 } else {
12823 Ok(text.clone())
12824 }
12825 }
12826 }
12827 }
12828
12829 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
12830 if table.only {
12832 self.write_keyword("ONLY");
12833 self.write_space();
12834 }
12835
12836 if let Some(ref identifier_func) = table.identifier_func {
12838 self.generate_expression(identifier_func)?;
12839 } else {
12840 if let Some(catalog) = &table.catalog {
12841 self.generate_identifier(catalog)?;
12842 self.write(".");
12843 }
12844 if let Some(schema) = &table.schema {
12845 self.generate_identifier(schema)?;
12846 self.write(".");
12847 }
12848 self.generate_identifier(&table.name)?;
12849 }
12850
12851 if let Some(changes) = &table.changes {
12853 self.write(" ");
12854 self.generate_changes(changes)?;
12855 }
12856
12857 if !table.partitions.is_empty() {
12859 self.write_space();
12860 self.write_keyword("PARTITION");
12861 self.write("(");
12862 for (i, partition) in table.partitions.iter().enumerate() {
12863 if i > 0 {
12864 self.write(", ");
12865 }
12866 self.generate_identifier(partition)?;
12867 }
12868 self.write(")");
12869 }
12870
12871 if table.changes.is_none() {
12874 if let Some(when) = &table.when {
12875 self.write_space();
12876 self.generate_historical_data(when)?;
12877 }
12878 }
12879
12880 if let Some(ref system_time) = table.system_time {
12882 self.write_space();
12883 self.write(system_time);
12884 }
12885
12886 if let Some(ref version) = table.version {
12888 self.write_space();
12889 self.generate_version(version)?;
12890 }
12891
12892 let alias_post_tablesample = self.config.alias_post_tablesample;
12896
12897 if alias_post_tablesample {
12898 self.generate_table_sample_clause(table)?;
12900 }
12901
12902 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
12905 && table.hints.iter().any(|h| {
12906 if let Expression::Identifier(id) = h {
12907 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
12908 } else {
12909 false
12910 }
12911 });
12912 if !table.hints.is_empty() && !is_sqlite_hint {
12913 for hint in &table.hints {
12914 self.write_space();
12915 self.generate_expression(hint)?;
12916 }
12917 }
12918
12919 if let Some(alias) = &table.alias {
12920 self.write_space();
12921 let always_use_as = matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) | Some(DialectType::Snowflake) | Some(DialectType::BigQuery) | Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::MySQL) | Some(DialectType::Spark) | Some(DialectType::Hive));
12924 let is_stage_ref = table.name.name.starts_with('@');
12925 if table.alias_explicit_as || always_use_as || is_stage_ref {
12926 self.write_keyword("AS");
12927 self.write_space();
12928 }
12929 self.generate_identifier(alias)?;
12930
12931 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
12934 self.write("(");
12935 for (i, col_alias) in table.column_aliases.iter().enumerate() {
12936 if i > 0 {
12937 self.write(", ");
12938 }
12939 self.generate_identifier(col_alias)?;
12940 }
12941 self.write(")");
12942 }
12943 }
12944
12945 if !alias_post_tablesample {
12947 self.generate_table_sample_clause(table)?;
12948 }
12949
12950 if is_sqlite_hint {
12952 for hint in &table.hints {
12953 self.write_space();
12954 self.generate_expression(hint)?;
12955 }
12956 }
12957
12958 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
12960 self.write_space();
12961 self.write_keyword("FINAL");
12962 }
12963
12964 for comment in &table.trailing_comments {
12966 self.write_space();
12967 self.write_formatted_comment(comment);
12968 }
12969
12970 Ok(())
12971 }
12972
12973 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
12975 if let Some(ref ts) = table.table_sample {
12976 self.write_space();
12977 if ts.is_using_sample {
12978 self.write_keyword("USING SAMPLE");
12979 } else {
12980 self.write_keyword(self.config.tablesample_keywords);
12982 }
12983 self.generate_sample_body(ts)?;
12984 if let Some(ref seed) = ts.seed {
12986 self.write_space();
12987 self.write_keyword(self.config.tablesample_seed_keyword);
12988 self.write(" (");
12989 self.generate_expression(seed)?;
12990 self.write(")");
12991 }
12992 }
12993 Ok(())
12994 }
12995
12996 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
12997 if sr.quoted {
13001 self.write("'");
13002 }
13003
13004 self.write(&sr.name);
13005 if let Some(path) = &sr.path {
13006 self.write(path);
13007 }
13008
13009 if sr.quoted {
13010 self.write("'");
13011 }
13012
13013 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
13015 if has_options {
13016 self.write(" (");
13017 let mut first = true;
13018
13019 if let Some(file_format) = &sr.file_format {
13020 if !first {
13021 self.write(", ");
13022 }
13023 self.write_keyword("FILE_FORMAT");
13024 self.write(" => ");
13025 self.generate_expression(file_format)?;
13026 first = false;
13027 }
13028
13029 if let Some(pattern) = &sr.pattern {
13030 if !first {
13031 self.write(", ");
13032 }
13033 self.write_keyword("PATTERN");
13034 self.write(" => '");
13035 self.write(pattern);
13036 self.write("'");
13037 }
13038
13039 self.write(")");
13040 }
13041 Ok(())
13042 }
13043
13044
13045 fn generate_star(&mut self, star: &Star) -> Result<()> {
13046 use crate::dialects::DialectType;
13047
13048 if let Some(table) = &star.table {
13049 self.generate_identifier(table)?;
13050 self.write(".");
13051 }
13052 self.write("*");
13053
13054 if let Some(except) = &star.except {
13056 if !except.is_empty() {
13057 self.write_space();
13058 match self.config.dialect {
13060 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
13061 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
13062 self.write_keyword("EXCLUDE")
13063 }
13064 _ => self.write_keyword("EXCEPT"), }
13066 self.write(" (");
13067 for (i, col) in except.iter().enumerate() {
13068 if i > 0 {
13069 self.write(", ");
13070 }
13071 self.generate_identifier(col)?;
13072 }
13073 self.write(")");
13074 }
13075 }
13076
13077 if let Some(replace) = &star.replace {
13079 if !replace.is_empty() {
13080 self.write_space();
13081 self.write_keyword("REPLACE");
13082 self.write(" (");
13083 for (i, alias) in replace.iter().enumerate() {
13084 if i > 0 {
13085 self.write(", ");
13086 }
13087 self.generate_expression(&alias.this)?;
13088 self.write_space();
13089 self.write_keyword("AS");
13090 self.write_space();
13091 self.generate_identifier(&alias.alias)?;
13092 }
13093 self.write(")");
13094 }
13095 }
13096
13097 if let Some(rename) = &star.rename {
13099 if !rename.is_empty() {
13100 self.write_space();
13101 self.write_keyword("RENAME");
13102 self.write(" (");
13103 for (i, (old_name, new_name)) in rename.iter().enumerate() {
13104 if i > 0 {
13105 self.write(", ");
13106 }
13107 self.generate_identifier(old_name)?;
13108 self.write_space();
13109 self.write_keyword("AS");
13110 self.write_space();
13111 self.generate_identifier(new_name)?;
13112 }
13113 self.write(")");
13114 }
13115 }
13116
13117 for comment in &star.trailing_comments {
13119 self.write_space();
13120 self.write(comment);
13121 }
13122
13123 Ok(())
13124 }
13125
13126 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
13128 self.write("{");
13129 match expr {
13130 Expression::Star(star) => {
13131 self.generate_star(star)?;
13133 }
13134 Expression::ILike(ilike) => {
13135 self.generate_expression(&ilike.left)?;
13137 self.write_space();
13138 self.write_keyword("ILIKE");
13139 self.write_space();
13140 self.generate_expression(&ilike.right)?;
13141 }
13142 _ => {
13143 self.generate_expression(expr)?;
13144 }
13145 }
13146 self.write("}");
13147 Ok(())
13148 }
13149
13150 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
13151 match &alias.this {
13155 Expression::Column(col) => {
13156 if let Some(table) = &col.table {
13158 self.generate_identifier(table)?;
13159 self.write(".");
13160 }
13161 self.generate_identifier(&col.name)?;
13162 }
13163 _ => {
13164 self.generate_expression(&alias.this)?;
13165 }
13166 }
13167
13168 for comment in &alias.pre_alias_comments {
13170 self.write_space();
13171 self.write(comment);
13172 }
13173
13174 use crate::dialects::DialectType;
13175
13176 let is_table_source = matches!(
13182 &alias.this,
13183 Expression::JSONTable(_)
13184 | Expression::XMLTable(_)
13185 | Expression::TableFromRows(_)
13186 | Expression::Unnest(_)
13187 | Expression::MatchRecognize(_)
13188 | Expression::Select(_)
13189 | Expression::Subquery(_)
13190 | Expression::Paren(_)
13191 );
13192 let dialect_skips_table_alias_as = matches!(
13193 self.config.dialect,
13194 Some(DialectType::Oracle)
13195 );
13196 let skip_as = is_table_source && dialect_skips_table_alias_as;
13197
13198 self.write_space();
13199 if !skip_as {
13200 self.write_keyword("AS");
13201 self.write_space();
13202 }
13203
13204 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
13206
13207 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
13209 self.write("(");
13211 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
13212 if i > 0 {
13213 self.write(", ");
13214 }
13215 self.generate_alias_identifier(col_alias)?;
13216 }
13217 self.write(")");
13218 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
13219 self.generate_alias_identifier(&alias.alias)?;
13221 self.write("(");
13222 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
13223 if i > 0 {
13224 self.write(", ");
13225 }
13226 self.generate_alias_identifier(col_alias)?;
13227 }
13228 self.write(")");
13229 } else {
13230 self.generate_alias_identifier(&alias.alias)?;
13232 }
13233
13234 for comment in &alias.trailing_comments {
13236 self.write_space();
13237 self.write(comment);
13238 }
13239
13240 Ok(())
13241 }
13242
13243 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
13244 use crate::dialects::DialectType;
13245
13246 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
13248 self.generate_expression(&cast.this)?;
13249 self.write(" :> ");
13250 self.generate_data_type(&cast.to)?;
13251 return Ok(());
13252 }
13253
13254 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
13256 let is_unknown_type = matches!(cast.to, DataType::Unknown)
13257 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
13258 if is_unknown_type {
13259 if let Some(format) = &cast.format {
13260 self.write_keyword("CAST");
13261 self.write("(");
13262 self.generate_expression(&cast.this)?;
13263 self.write_space();
13264 self.write_keyword("AS");
13265 self.write_space();
13266 self.write_keyword("FORMAT");
13267 self.write_space();
13268 self.generate_expression(format)?;
13269 self.write(")");
13270 return Ok(());
13271 }
13272 }
13273 }
13274
13275 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
13278 if let Some(format) = &cast.format {
13279 let is_date = matches!(cast.to, DataType::Date);
13281 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
13282
13283 if is_date || is_timestamp {
13284 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
13285 self.write_keyword(func_name);
13286 self.write("(");
13287 self.generate_expression(&cast.this)?;
13288 self.write(", ");
13289
13290 if let Expression::Literal(Literal::String(fmt_str)) = format.as_ref() {
13293 let normalized = self.normalize_oracle_format(fmt_str);
13294 self.write("'");
13295 self.write(&normalized);
13296 self.write("'");
13297 } else {
13298 self.generate_expression(format)?;
13299 }
13300
13301 self.write(")");
13302 return Ok(());
13303 }
13304 }
13305 }
13306
13307 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
13310 if let Expression::Array(arr) = &cast.this {
13311 self.generate_data_type(&cast.to)?;
13312 self.write("[");
13314 for (i, expr) in arr.expressions.iter().enumerate() {
13315 if i > 0 {
13316 self.write(", ");
13317 }
13318 self.generate_expression(expr)?;
13319 }
13320 self.write("]");
13321 return Ok(());
13322 }
13323 if matches!(&cast.this, Expression::ArrayFunc(_)) {
13324 self.generate_data_type(&cast.to)?;
13325 self.generate_expression(&cast.this)?;
13326 return Ok(());
13327 }
13328 }
13329
13330 if matches!(self.config.dialect, Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)) {
13333 if let Expression::Struct(ref s) = cast.this {
13334 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
13335 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
13336 self.write_keyword("CAST");
13337 self.write("(");
13338 self.generate_struct_as_row(s)?;
13339 self.write_space();
13340 self.write_keyword("AS");
13341 self.write_space();
13342 self.generate_data_type(&cast.to)?;
13343 self.write(")");
13344 return Ok(());
13345 }
13346 }
13347 }
13348
13349 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
13352
13353 if use_double_colon {
13354 self.generate_expression(&cast.this)?;
13356 self.write("::");
13357 self.generate_data_type(&cast.to)?;
13358 } else {
13359 self.write_keyword("CAST");
13361 self.write("(");
13362 self.generate_expression(&cast.this)?;
13363 self.write_space();
13364 self.write_keyword("AS");
13365 self.write_space();
13366 if matches!(self.config.dialect, Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)) {
13369 if let DataType::Custom { ref name } = cast.to {
13370 let upper = name.to_uppercase();
13371 match upper.as_str() {
13372 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" | "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => {
13373 self.write_keyword("CHAR");
13374 }
13375 _ => {
13376 self.generate_data_type(&cast.to)?;
13377 }
13378 }
13379 } else {
13380 self.generate_data_type(&cast.to)?;
13381 }
13382 } else {
13383 self.generate_data_type(&cast.to)?;
13384 }
13385
13386 if let Some(default) = &cast.default {
13388 self.write_space();
13389 self.write_keyword("DEFAULT");
13390 self.write_space();
13391 self.generate_expression(default)?;
13392 self.write_space();
13393 self.write_keyword("ON");
13394 self.write_space();
13395 self.write_keyword("CONVERSION");
13396 self.write_space();
13397 self.write_keyword("ERROR");
13398 }
13399
13400 if let Some(format) = &cast.format {
13403 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Oracle)) {
13405 self.write(", ");
13406 } else {
13407 self.write_space();
13408 self.write_keyword("FORMAT");
13409 self.write_space();
13410 }
13411 self.generate_expression(format)?;
13412 }
13413
13414 self.write(")");
13415 for comment in &cast.trailing_comments {
13417 self.write_space();
13418 self.write(comment);
13419 }
13420 }
13421 Ok(())
13422 }
13423
13424 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
13427 self.write_keyword("ROW");
13428 self.write("(");
13429 for (i, (_, expr)) in s.fields.iter().enumerate() {
13430 if i > 0 { self.write(", "); }
13431 if let Expression::Struct(ref inner_s) = expr {
13433 self.generate_struct_as_row(inner_s)?;
13434 } else {
13435 self.generate_expression(expr)?;
13436 }
13437 }
13438 self.write(")");
13439 Ok(())
13440 }
13441
13442 fn normalize_oracle_format(&self, format: &str) -> String {
13445 let mut result = String::new();
13448 let chars: Vec<char> = format.chars().collect();
13449 let mut i = 0;
13450
13451 while i < chars.len() {
13452 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
13453 if i + 2 < chars.len() {
13455 let next = chars[i + 2];
13456 if next == '1' || next == '2' {
13457 result.push('H');
13459 result.push('H');
13460 i += 2;
13461 continue;
13462 }
13463 }
13464 result.push_str("HH12");
13466 i += 2;
13467 } else {
13468 result.push(chars[i]);
13469 i += 1;
13470 }
13471 }
13472
13473 result
13474 }
13475
13476 fn dialect_prefers_double_colon(&self) -> bool {
13480 false
13483 }
13484
13485 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
13487 use crate::dialects::DialectType;
13488
13489 let use_percent_operator = matches!(
13491 self.config.dialect,
13492 Some(DialectType::Snowflake) | Some(DialectType::MySQL) | Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::PostgreSQL) | Some(DialectType::DuckDB)
13493 );
13494
13495 if use_percent_operator {
13496 self.generate_expression(&f.this)?;
13497 self.write(" % ");
13498 self.generate_expression(&f.expression)?;
13499 Ok(())
13500 } else {
13501 self.generate_binary_func("MOD", &f.this, &f.expression)
13502 }
13503 }
13504
13505 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
13507 use crate::dialects::DialectType;
13508
13509 let func_name = match self.config.dialect {
13511 Some(DialectType::Snowflake) => "COALESCE",
13512 _ => "IFNULL",
13513 };
13514
13515 self.generate_binary_func(func_name, &f.this, &f.expression)
13516 }
13517
13518 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
13520 if let Some(ref original_name) = f.original_name {
13522 return self.generate_binary_func(original_name, &f.this, &f.expression);
13523 }
13524
13525 use crate::dialects::DialectType;
13527 let func_name = match self.config.dialect {
13528 Some(DialectType::Snowflake) |
13529 Some(DialectType::ClickHouse) |
13530 Some(DialectType::PostgreSQL) |
13531 Some(DialectType::Presto) |
13532 Some(DialectType::Trino) |
13533 Some(DialectType::Athena) |
13534 Some(DialectType::DuckDB) |
13535 Some(DialectType::BigQuery) |
13536 Some(DialectType::Spark) |
13537 Some(DialectType::Databricks) |
13538 Some(DialectType::Hive) => "COALESCE",
13539 Some(DialectType::MySQL) |
13540 Some(DialectType::Doris) |
13541 Some(DialectType::StarRocks) |
13542 Some(DialectType::SingleStore) |
13543 Some(DialectType::TiDB) => "IFNULL",
13544 _ => "NVL",
13545 };
13546
13547 self.generate_binary_func(func_name, &f.this, &f.expression)
13548 }
13549
13550 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
13552 use crate::dialects::DialectType;
13553
13554 let func_name = match self.config.dialect {
13556 Some(DialectType::Snowflake) => "STDDEV",
13557 _ => "STDDEV_SAMP",
13558 };
13559
13560 self.generate_agg_func(func_name, f)
13561 }
13562
13563 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
13564 self.generate_expression(&coll.this)?;
13565 self.write_space();
13566 self.write_keyword("COLLATE");
13567 self.write_space();
13568 if coll.quoted {
13569 self.write("'");
13571 self.write(&coll.collation);
13572 self.write("'");
13573 } else if coll.double_quoted {
13574 self.write("\"");
13576 self.write(&coll.collation);
13577 self.write("\"");
13578 } else {
13579 self.write(&coll.collation);
13581 }
13582 Ok(())
13583 }
13584
13585 fn generate_case(&mut self, case: &Case) -> Result<()> {
13586 let multiline_case = self.config.pretty
13587 && matches!(self.config.dialect, Some(DialectType::Snowflake));
13588
13589 self.write_keyword("CASE");
13590 if let Some(operand) = &case.operand {
13591 self.write_space();
13592 self.generate_expression(operand)?;
13593 }
13594 if multiline_case {
13595 self.indent_level += 1;
13596 }
13597 for (condition, result) in &case.whens {
13598 if multiline_case {
13599 self.write_newline();
13600 self.write_indent();
13601 } else {
13602 self.write_space();
13603 }
13604 self.write_keyword("WHEN");
13605 self.write_space();
13606 self.generate_expression(condition)?;
13607 if multiline_case {
13608 self.write_newline();
13609 self.write_indent();
13610 } else {
13611 self.write_space();
13612 }
13613 self.write_keyword("THEN");
13614 self.write_space();
13615 self.generate_expression(result)?;
13616 }
13617 if let Some(else_) = &case.else_ {
13618 if multiline_case {
13619 self.write_newline();
13620 self.write_indent();
13621 } else {
13622 self.write_space();
13623 }
13624 self.write_keyword("ELSE");
13625 self.write_space();
13626 self.generate_expression(else_)?;
13627 }
13628 if multiline_case {
13629 self.indent_level -= 1;
13630 self.write_newline();
13631 self.write_indent();
13632 } else {
13633 self.write_space();
13634 }
13635 self.write_keyword("END");
13636 Ok(())
13637 }
13638
13639 fn generate_function(&mut self, func: &Function) -> Result<()> {
13640 let normalized_name = self.normalize_func_name(&func.name);
13642 let upper_name = func.name.to_uppercase();
13643
13644 if upper_name == "STRUCT" && !matches!(self.config.dialect, Some(DialectType::BigQuery) | Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) | None) {
13646 return self.generate_struct_function_cross_dialect(func);
13647 }
13648
13649 if upper_name == "__SS_JSON_PATH_QMARK__" && func.args.len() == 2 {
13652 self.generate_expression(&func.args[0])?;
13653 self.write("::?");
13654 if let Expression::Literal(crate::expressions::Literal::String(key)) = &func.args[1] {
13656 self.write(key);
13657 } else {
13658 self.generate_expression(&func.args[1])?;
13659 }
13660 return Ok(());
13661 }
13662
13663 if upper_name == "__PG_BITWISE_XOR__" && func.args.len() == 2 {
13665 self.generate_expression(&func.args[0])?;
13666 self.write(" # ");
13667 self.generate_expression(&func.args[1])?;
13668 return Ok(());
13669 }
13670
13671 if matches!(
13673 self.config.dialect,
13674 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
13675 ) && upper_name == "TRY"
13676 && func.args.len() == 1
13677 {
13678 self.generate_expression(&func.args[0])?;
13679 return Ok(());
13680 }
13681
13682 if self.config.dialect == Some(DialectType::ClickHouse)
13684 && upper_name == "TOSTARTOFDAY"
13685 && func.args.len() == 1
13686 {
13687 self.write("dateTrunc('DAY', ");
13688 self.generate_expression(&func.args[0])?;
13689 self.write(")");
13690 return Ok(());
13691 }
13692
13693 if self.config.dialect == Some(DialectType::Redshift) && upper_name == "CONCAT" && func.args.len() >= 2 {
13695 for (i, arg) in func.args.iter().enumerate() {
13696 if i > 0 {
13697 self.write(" || ");
13698 }
13699 self.generate_expression(arg)?;
13700 }
13701 return Ok(());
13702 }
13703
13704 if self.config.dialect == Some(DialectType::Redshift) && upper_name == "CONCAT_WS" && func.args.len() >= 2 {
13706 let sep = &func.args[0];
13707 for (i, arg) in func.args.iter().skip(1).enumerate() {
13708 if i > 0 {
13709 self.write(" || ");
13710 self.generate_expression(sep)?;
13711 self.write(" || ");
13712 }
13713 self.generate_expression(arg)?;
13714 }
13715 return Ok(());
13716 }
13717
13718 if self.config.dialect == Some(DialectType::Redshift)
13721 && (upper_name == "DATEDIFF" || upper_name == "DATE_DIFF")
13722 && func.args.len() == 3
13723 {
13724 self.write_keyword("DATEDIFF");
13725 self.write("(");
13726 self.write_redshift_date_part(&func.args[0]);
13728 self.write(", ");
13729 self.generate_expression(&func.args[1])?;
13730 self.write(", ");
13731 self.generate_expression(&func.args[2])?;
13732 self.write(")");
13733 return Ok(());
13734 }
13735
13736 if self.config.dialect == Some(DialectType::Redshift)
13739 && (upper_name == "DATEADD" || upper_name == "DATE_ADD")
13740 && func.args.len() == 3
13741 {
13742 self.write_keyword("DATEADD");
13743 self.write("(");
13744 self.write_redshift_date_part(&func.args[0]);
13746 self.write(", ");
13747 self.generate_expression(&func.args[1])?;
13748 self.write(", ");
13749 self.generate_expression(&func.args[2])?;
13750 self.write(")");
13751 return Ok(());
13752 }
13753
13754 if upper_name == "UUID_STRING" && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
13756 let func_name = match self.config.dialect {
13757 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
13758 Some(DialectType::BigQuery) => "GENERATE_UUID",
13759 _ => "UUID",
13760 };
13761 self.write_keyword(func_name);
13762 self.write("()");
13763 return Ok(());
13764 }
13765
13766 if self.config.dialect == Some(DialectType::Redshift)
13769 && upper_name == "DATE_TRUNC"
13770 && func.args.len() == 2
13771 {
13772 self.write_keyword("DATE_TRUNC");
13773 self.write("(");
13774 self.write_redshift_date_part_quoted(&func.args[0]);
13776 self.write(", ");
13777 self.generate_expression(&func.args[1])?;
13778 self.write(")");
13779 return Ok(());
13780 }
13781
13782 if matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric))
13784 && (upper_name == "DATE_PART" || upper_name == "DATEPART")
13785 && func.args.len() == 2
13786 {
13787 self.write_keyword("DATEPART");
13788 self.write("(");
13789 self.generate_expression(&func.args[0])?;
13790 self.write(", ");
13791 self.generate_expression(&func.args[1])?;
13792 self.write(")");
13793 return Ok(());
13794 }
13795
13796 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift))
13798 && (upper_name == "DATE_PART" || upper_name == "DATEPART")
13799 && func.args.len() == 2
13800 {
13801 self.write_keyword("EXTRACT");
13802 self.write("(");
13803 match &func.args[0] {
13805 Expression::Literal(crate::expressions::Literal::String(s)) => {
13806 self.write(&s.to_lowercase());
13807 }
13808 _ => self.generate_expression(&func.args[0])?,
13809 }
13810 self.write_space();
13811 self.write_keyword("FROM");
13812 self.write_space();
13813 self.generate_expression(&func.args[1])?;
13814 self.write(")");
13815 return Ok(());
13816 }
13817
13818 if self.config.dialect == Some(DialectType::Dremio)
13821 && (upper_name == "DATE_PART" || upper_name == "DATEPART")
13822 && func.args.len() == 2
13823 {
13824 self.write_keyword("EXTRACT");
13825 self.write("(");
13826 self.generate_expression(&func.args[0])?;
13827 self.write_space();
13828 self.write_keyword("FROM");
13829 self.write_space();
13830 self.generate_dremio_date_expression(&func.args[1])?;
13832 self.write(")");
13833 return Ok(());
13834 }
13835
13836 if self.config.dialect == Some(DialectType::Dremio)
13838 && upper_name == "CURRENT_DATE_UTC"
13839 && func.args.is_empty()
13840 {
13841 self.write_keyword("CURRENT_DATE_UTC");
13842 return Ok(());
13843 }
13844
13845 if self.config.dialect == Some(DialectType::Dremio)
13849 && upper_name == "DATETYPE"
13850 && func.args.len() == 3
13851 {
13852 fn get_int_literal(expr: &Expression) -> Option<i64> {
13854 if let Expression::Literal(crate::expressions::Literal::Number(s)) = expr {
13855 s.parse::<i64>().ok()
13856 } else {
13857 None
13858 }
13859 }
13860
13861 if let (Some(year), Some(month), Some(day)) = (
13863 get_int_literal(&func.args[0]),
13864 get_int_literal(&func.args[1]),
13865 get_int_literal(&func.args[2]),
13866 ) {
13867 self.write_keyword("DATE");
13869 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
13870 return Ok(());
13871 }
13872
13873 self.write_keyword("CAST");
13875 self.write("(");
13876 self.write_keyword("CONCAT");
13877 self.write("(");
13878 self.generate_expression(&func.args[0])?;
13879 self.write(", '-', ");
13880 self.generate_expression(&func.args[1])?;
13881 self.write(", '-', ");
13882 self.generate_expression(&func.args[2])?;
13883 self.write(")");
13884 self.write_space();
13885 self.write_keyword("AS");
13886 self.write_space();
13887 self.write_keyword("DATE");
13888 self.write(")");
13889 return Ok(());
13890 }
13891
13892 let is_presto_like = matches!(
13895 self.config.dialect,
13896 Some(DialectType::Presto) | Some(DialectType::Trino)
13897 );
13898 if is_presto_like
13899 && upper_name == "DATE_ADD"
13900 && func.args.len() == 3
13901 {
13902 self.write_keyword("DATE_ADD");
13903 self.write("(");
13904 self.generate_expression(&func.args[0])?;
13906 self.write(", ");
13907 let interval = &func.args[1];
13909 let needs_cast = !self.returns_integer_type(interval);
13910 if needs_cast {
13911 self.write_keyword("CAST");
13912 self.write("(");
13913 }
13914 self.generate_expression(interval)?;
13915 if needs_cast {
13916 self.write_space();
13917 self.write_keyword("AS");
13918 self.write_space();
13919 self.write_keyword("BIGINT");
13920 self.write(")");
13921 }
13922 self.write(", ");
13923 self.generate_expression(&func.args[2])?;
13925 self.write(")");
13926 return Ok(());
13927 }
13928
13929 let use_brackets = func.use_bracket_syntax;
13931
13932 let has_ordinality = upper_name.ends_with(" WITH ORDINALITY");
13937 let output_name = if has_ordinality {
13938 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
13939 self.normalize_func_name(base_name)
13940 } else {
13941 normalized_name.clone()
13942 };
13943
13944 if func.name.contains('.') && !has_ordinality {
13947 if func.quoted {
13950 self.write("`");
13951 self.write(&func.name);
13952 self.write("`");
13953 } else {
13954 self.write(&func.name);
13955 }
13956 } else {
13957 self.write(&output_name);
13958 }
13959
13960 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
13963 let needs_parens = match upper_name.as_str() {
13964 "CURRENT_USER" | "SESSION_USER" | "SYSTEM_USER" => matches!(
13965 self.config.dialect,
13966 Some(DialectType::Snowflake) | Some(DialectType::Spark)
13967 | Some(DialectType::Databricks) | Some(DialectType::Hive)
13968 ),
13969 _ => false,
13970 };
13971 !needs_parens
13972 };
13973 if force_parens {
13974 for comment in &func.trailing_comments {
13976 self.write_space();
13977 self.write(comment);
13978 }
13979 return Ok(());
13980 }
13981
13982 if upper_name == "CUBE" || upper_name == "ROLLUP" || upper_name == "GROUPING SETS" {
13984 self.write(" (");
13985 } else if use_brackets {
13986 self.write("[");
13987 } else {
13988 self.write("(");
13989 }
13990 if func.distinct {
13991 self.write_keyword("DISTINCT");
13992 self.write_space();
13993 }
13994
13995 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
13997 && (upper_name == "TABLE" || upper_name == "FLATTEN");
13998 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
13999 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
14001 for arg in &func.args {
14002 let mut temp_gen = Generator::with_config(self.config.clone());
14003 temp_gen.config.pretty = false; temp_gen.generate_expression(arg)?;
14005 expr_strings.push(temp_gen.output);
14006 }
14007 self.too_wide(&expr_strings)
14008 } else {
14009 false
14010 };
14011
14012 if should_split {
14013 self.write_newline();
14015 self.indent_level += 1;
14016 for (i, arg) in func.args.iter().enumerate() {
14017 self.write_indent();
14018 self.generate_expression(arg)?;
14019 if i + 1 < func.args.len() {
14020 self.write(",");
14021 }
14022 self.write_newline();
14023 }
14024 self.indent_level -= 1;
14025 self.write_indent();
14026 } else {
14027 for (i, arg) in func.args.iter().enumerate() {
14029 if i > 0 {
14030 self.write(", ");
14031 }
14032 self.generate_expression(arg)?;
14033 }
14034 }
14035
14036 if use_brackets {
14037 self.write("]");
14038 } else {
14039 self.write(")");
14040 }
14041 if has_ordinality {
14043 self.write_space();
14044 self.write_keyword("WITH ORDINALITY");
14045 }
14046 for comment in &func.trailing_comments {
14048 self.write_space();
14049 self.write(comment);
14050 }
14051 Ok(())
14052 }
14053
14054 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
14055 let mut normalized_name = self.normalize_func_name(&func.name);
14057
14058 let upper = normalized_name.to_uppercase();
14060 if upper == "MAX_BY" || upper == "MIN_BY" {
14061 let is_max = upper == "MAX_BY";
14062 match self.config.dialect {
14063 Some(DialectType::ClickHouse) => {
14064 normalized_name = if is_max { "argMax".to_string() } else { "argMin".to_string() };
14065 }
14066 Some(DialectType::DuckDB) => {
14067 normalized_name = if is_max { "ARG_MAX".to_string() } else { "ARG_MIN".to_string() };
14068 }
14069 _ => {}
14070 }
14071 }
14072 self.write(&normalized_name);
14073 self.write("(");
14074 if func.distinct {
14075 self.write_keyword("DISTINCT");
14076 self.write_space();
14077 }
14078
14079 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
14083 let needs_multi_arg_transform = func.distinct
14084 && is_count
14085 && func.args.len() > 1
14086 && !self.config.multi_arg_distinct;
14087
14088 if needs_multi_arg_transform {
14089 self.write_keyword("CASE");
14091 for arg in &func.args {
14092 self.write_space();
14093 self.write_keyword("WHEN");
14094 self.write_space();
14095 self.generate_expression(arg)?;
14096 self.write_space();
14097 self.write_keyword("IS NULL THEN NULL");
14098 }
14099 self.write_space();
14100 self.write_keyword("ELSE");
14101 self.write(" (");
14102 for (i, arg) in func.args.iter().enumerate() {
14103 if i > 0 {
14104 self.write(", ");
14105 }
14106 self.generate_expression(arg)?;
14107 }
14108 self.write(")");
14109 self.write_space();
14110 self.write_keyword("END");
14111 } else {
14112 for (i, arg) in func.args.iter().enumerate() {
14113 if i > 0 {
14114 self.write(", ");
14115 }
14116 self.generate_expression(arg)?;
14117 }
14118 }
14119
14120 if self.config.ignore_nulls_in_func && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
14122 if let Some(ignore) = func.ignore_nulls {
14123 self.write_space();
14124 if ignore {
14125 self.write_keyword("IGNORE NULLS");
14126 } else {
14127 self.write_keyword("RESPECT NULLS");
14128 }
14129 }
14130 }
14131
14132 if !func.order_by.is_empty() {
14134 self.write_space();
14135 self.write_keyword("ORDER BY");
14136 self.write_space();
14137 for (i, ord) in func.order_by.iter().enumerate() {
14138 if i > 0 {
14139 self.write(", ");
14140 }
14141 self.generate_ordered(ord)?;
14142 }
14143 }
14144
14145 if let Some(limit) = &func.limit {
14147 self.write_space();
14148 self.write_keyword("LIMIT");
14149 self.write_space();
14150 if let Expression::Tuple(t) = limit.as_ref() {
14152 if t.expressions.len() == 2 {
14153 self.generate_expression(&t.expressions[0])?;
14154 self.write(", ");
14155 self.generate_expression(&t.expressions[1])?;
14156 } else {
14157 self.generate_expression(limit)?;
14158 }
14159 } else {
14160 self.generate_expression(limit)?;
14161 }
14162 }
14163
14164 self.write(")");
14165
14166 if !self.config.ignore_nulls_in_func && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
14168 if let Some(ignore) = func.ignore_nulls {
14169 self.write_space();
14170 if ignore {
14171 self.write_keyword("IGNORE NULLS");
14172 } else {
14173 self.write_keyword("RESPECT NULLS");
14174 }
14175 }
14176 }
14177
14178 if let Some(filter) = &func.filter {
14179 self.write_space();
14180 self.write_keyword("FILTER");
14181 self.write("(");
14182 self.write_keyword("WHERE");
14183 self.write_space();
14184 self.generate_expression(filter)?;
14185 self.write(")");
14186 }
14187
14188 Ok(())
14189 }
14190
14191 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
14192 self.generate_expression(&wf.this)?;
14193
14194 if let Some(keep) = &wf.keep {
14196 self.write_space();
14197 self.write_keyword("KEEP");
14198 self.write(" (");
14199 self.write_keyword("DENSE_RANK");
14200 self.write_space();
14201 if keep.first {
14202 self.write_keyword("FIRST");
14203 } else {
14204 self.write_keyword("LAST");
14205 }
14206 self.write_space();
14207 self.write_keyword("ORDER BY");
14208 self.write_space();
14209 for (i, ord) in keep.order_by.iter().enumerate() {
14210 if i > 0 {
14211 self.write(", ");
14212 }
14213 self.generate_ordered(ord)?;
14214 }
14215 self.write(")");
14216 }
14217
14218 let has_over = !wf.over.partition_by.is_empty()
14220 || !wf.over.order_by.is_empty()
14221 || wf.over.frame.is_some()
14222 || wf.over.window_name.is_some();
14223
14224 if has_over {
14226 self.write_space();
14227 self.write_keyword("OVER");
14228
14229 let has_specs = !wf.over.partition_by.is_empty()
14231 || !wf.over.order_by.is_empty()
14232 || wf.over.frame.is_some();
14233
14234 if wf.over.window_name.is_some() && !has_specs {
14235 self.write_space();
14237 self.write(&wf.over.window_name.as_ref().unwrap().name);
14238 } else {
14239 self.write(" (");
14241 self.generate_over(&wf.over)?;
14242 self.write(")");
14243 }
14244 } else if wf.keep.is_none() {
14245 self.write_space();
14247 self.write_keyword("OVER");
14248 self.write(" ()");
14249 }
14250
14251 Ok(())
14252 }
14253
14254 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
14256 self.generate_expression(&wg.this)?;
14257 self.write_space();
14258 self.write_keyword("WITHIN GROUP");
14259 self.write(" (");
14260 self.write_keyword("ORDER BY");
14261 self.write_space();
14262 for (i, ord) in wg.order_by.iter().enumerate() {
14263 if i > 0 {
14264 self.write(", ");
14265 }
14266 self.generate_ordered(ord)?;
14267 }
14268 self.write(")");
14269 Ok(())
14270 }
14271
14272 fn generate_over(&mut self, over: &Over) -> Result<()> {
14274 let mut has_content = false;
14275
14276 if let Some(name) = &over.window_name {
14278 self.write(&name.name);
14279 has_content = true;
14280 }
14281
14282 if !over.partition_by.is_empty() {
14284 if has_content {
14285 self.write_space();
14286 }
14287 self.write_keyword("PARTITION BY");
14288 self.write_space();
14289 for (i, expr) in over.partition_by.iter().enumerate() {
14290 if i > 0 {
14291 self.write(", ");
14292 }
14293 self.generate_expression(expr)?;
14294 }
14295 has_content = true;
14296 }
14297
14298 if !over.order_by.is_empty() {
14300 if has_content {
14301 self.write_space();
14302 }
14303 self.write_keyword("ORDER BY");
14304 self.write_space();
14305 for (i, ordered) in over.order_by.iter().enumerate() {
14306 if i > 0 {
14307 self.write(", ");
14308 }
14309 self.generate_ordered(ordered)?;
14310 }
14311 has_content = true;
14312 }
14313
14314 if let Some(frame) = &over.frame {
14316 if has_content {
14317 self.write_space();
14318 }
14319 self.generate_window_frame(frame)?;
14320 }
14321
14322 Ok(())
14323 }
14324
14325 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
14326 let lowercase_frame = self.config.lowercase_window_frame_keywords;
14328
14329 if !lowercase_frame {
14331 if let Some(kind_text) = &frame.kind_text {
14332 self.write(kind_text);
14333 } else {
14334 match frame.kind {
14335 WindowFrameKind::Rows => self.write_keyword("ROWS"),
14336 WindowFrameKind::Range => self.write_keyword("RANGE"),
14337 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
14338 }
14339 }
14340 } else {
14341 match frame.kind {
14342 WindowFrameKind::Rows => self.write("rows"),
14343 WindowFrameKind::Range => self.write("range"),
14344 WindowFrameKind::Groups => self.write("groups"),
14345 }
14346 }
14347
14348 self.write_space();
14351 let should_normalize = self.config.normalize_window_frame_between
14352 && frame.end.is_none()
14353 && matches!(
14354 frame.start,
14355 WindowFrameBound::Preceding(_)
14356 | WindowFrameBound::Following(_)
14357 | WindowFrameBound::UnboundedPreceding
14358 | WindowFrameBound::UnboundedFollowing
14359 );
14360
14361 if let Some(end) = &frame.end {
14362 self.write_keyword("BETWEEN");
14364 self.write_space();
14365 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
14366 self.write_space();
14367 self.write_keyword("AND");
14368 self.write_space();
14369 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
14370 } else if should_normalize {
14371 self.write_keyword("BETWEEN");
14373 self.write_space();
14374 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
14375 self.write_space();
14376 self.write_keyword("AND");
14377 self.write_space();
14378 self.write_keyword("CURRENT ROW");
14379 } else {
14380 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
14382 }
14383
14384 if let Some(exclude) = &frame.exclude {
14386 self.write_space();
14387 self.write_keyword("EXCLUDE");
14388 self.write_space();
14389 match exclude {
14390 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
14391 WindowFrameExclude::Group => self.write_keyword("GROUP"),
14392 WindowFrameExclude::Ties => self.write_keyword("TIES"),
14393 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
14394 }
14395 }
14396
14397 Ok(())
14398 }
14399
14400 fn generate_window_frame_bound(&mut self, bound: &WindowFrameBound, side_text: Option<&str>) -> Result<()> {
14401 let lowercase_frame = self.config.lowercase_window_frame_keywords;
14403
14404 match bound {
14405 WindowFrameBound::CurrentRow => {
14406 self.write_keyword("CURRENT ROW");
14407 }
14408 WindowFrameBound::UnboundedPreceding => {
14409 self.write_keyword("UNBOUNDED");
14410 self.write_space();
14411 if lowercase_frame {
14412 self.write("preceding");
14413 } else if let Some(text) = side_text {
14414 self.write(text);
14415 } else {
14416 self.write_keyword("PRECEDING");
14417 }
14418 }
14419 WindowFrameBound::UnboundedFollowing => {
14420 self.write_keyword("UNBOUNDED");
14421 self.write_space();
14422 if lowercase_frame {
14423 self.write("following");
14424 } else if let Some(text) = side_text {
14425 self.write(text);
14426 } else {
14427 self.write_keyword("FOLLOWING");
14428 }
14429 }
14430 WindowFrameBound::Preceding(expr) => {
14431 self.generate_expression(expr)?;
14432 self.write_space();
14433 if lowercase_frame {
14434 self.write("preceding");
14435 } else if let Some(text) = side_text {
14436 self.write(text);
14437 } else {
14438 self.write_keyword("PRECEDING");
14439 }
14440 }
14441 WindowFrameBound::Following(expr) => {
14442 self.generate_expression(expr)?;
14443 self.write_space();
14444 if lowercase_frame {
14445 self.write("following");
14446 } else if let Some(text) = side_text {
14447 self.write(text);
14448 } else {
14449 self.write_keyword("FOLLOWING");
14450 }
14451 }
14452 WindowFrameBound::BarePreceding => {
14453 if lowercase_frame {
14454 self.write("preceding");
14455 } else if let Some(text) = side_text {
14456 self.write(text);
14457 } else {
14458 self.write_keyword("PRECEDING");
14459 }
14460 }
14461 WindowFrameBound::BareFollowing => {
14462 if lowercase_frame {
14463 self.write("following");
14464 } else if let Some(text) = side_text {
14465 self.write(text);
14466 } else {
14467 self.write_keyword("FOLLOWING");
14468 }
14469 }
14470 WindowFrameBound::Value(expr) => {
14471 self.generate_expression(expr)?;
14473 }
14474 }
14475 Ok(())
14476 }
14477
14478 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
14479 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
14482 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
14483 && !matches!(&interval.this, Some(Expression::Literal(_)));
14484
14485 if !skip_interval_keyword {
14486 self.write_keyword("INTERVAL");
14487 }
14488
14489 if let Some(ref value) = interval.this {
14491 if !skip_interval_keyword {
14492 self.write_space();
14493 }
14494 let needs_parens = interval.unit.is_some() && matches!(value,
14498 Expression::Add(_) | Expression::Sub(_) | Expression::Mul(_) |
14499 Expression::Div(_) | Expression::Mod(_) | Expression::BitwiseAnd(_) |
14500 Expression::BitwiseOr(_) | Expression::BitwiseXor(_)
14501 );
14502 if needs_parens {
14503 self.write("(");
14504 }
14505 self.generate_expression(value)?;
14506 if needs_parens {
14507 self.write(")");
14508 }
14509 }
14510
14511 if let Some(ref unit_spec) = interval.unit {
14513 self.write_space();
14514 self.write_interval_unit_spec(unit_spec)?;
14515 }
14516
14517 Ok(())
14518 }
14519
14520 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
14521 match unit_spec {
14522 IntervalUnitSpec::Simple { unit, use_plural } => {
14523 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
14525 self.write_simple_interval_unit(unit, effective_plural);
14526 }
14527 IntervalUnitSpec::Span(span) => {
14528 self.write_simple_interval_unit(&span.this, false);
14529 self.write_space();
14530 self.write_keyword("TO");
14531 self.write_space();
14532 self.write_simple_interval_unit(&span.expression, false);
14533 }
14534 IntervalUnitSpec::ExprSpan(span) => {
14535 self.generate_expression(&span.this)?;
14537 self.write_space();
14538 self.write_keyword("TO");
14539 self.write_space();
14540 self.generate_expression(&span.expression)?;
14541 }
14542 IntervalUnitSpec::Expr(expr) => {
14543 self.generate_expression(expr)?;
14544 }
14545 }
14546 Ok(())
14547 }
14548
14549 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
14550 match (unit, use_plural) {
14552 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
14553 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
14554 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
14555 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
14556 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
14557 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
14558 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
14559 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
14560 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
14561 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
14562 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
14563 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
14564 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
14565 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
14566 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
14567 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
14568 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
14569 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
14570 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
14571 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
14572 }
14573 }
14574
14575 fn write_redshift_date_part(&mut self, expr: &Expression) {
14578 let part_str = self.extract_date_part_string(expr);
14579 if let Some(part) = part_str {
14580 let normalized = self.normalize_date_part(&part);
14581 self.write_keyword(&normalized);
14582 } else {
14583 let _ = self.generate_expression(expr);
14585 }
14586 }
14587
14588 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
14591 let part_str = self.extract_date_part_string(expr);
14592 if let Some(part) = part_str {
14593 let normalized = self.normalize_date_part(&part);
14594 self.write("'");
14595 self.write(&normalized);
14596 self.write("'");
14597 } else {
14598 let _ = self.generate_expression(expr);
14600 }
14601 }
14602
14603 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
14605 match expr {
14606 Expression::Literal(crate::expressions::Literal::String(s)) => Some(s.clone()),
14607 Expression::Identifier(id) => Some(id.name.clone()),
14608 Expression::Column(col) if col.table.is_none() => {
14609 Some(col.name.name.clone())
14611 }
14612 _ => None,
14613 }
14614 }
14615
14616 fn normalize_date_part(&self, part: &str) -> String {
14619 let lower = part.to_lowercase();
14620 match lower.as_str() {
14621 "day" | "days" | "d" => "DAY".to_string(),
14622 "month" | "months" | "mon" | "mm" => "MONTH".to_string(),
14623 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
14624 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
14625 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
14626 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
14627 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
14628 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
14629 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
14630 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
14631 _ => part.to_uppercase(),
14632 }
14633 }
14634
14635 fn write_datetime_field(&mut self, field: &DateTimeField) {
14636 match field {
14637 DateTimeField::Year => self.write_keyword("YEAR"),
14638 DateTimeField::Month => self.write_keyword("MONTH"),
14639 DateTimeField::Day => self.write_keyword("DAY"),
14640 DateTimeField::Hour => self.write_keyword("HOUR"),
14641 DateTimeField::Minute => self.write_keyword("MINUTE"),
14642 DateTimeField::Second => self.write_keyword("SECOND"),
14643 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
14644 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
14645 DateTimeField::DayOfWeek => {
14646 let name = match self.config.dialect {
14647 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
14648 _ => "DOW",
14649 };
14650 self.write_keyword(name);
14651 }
14652 DateTimeField::DayOfYear => {
14653 let name = match self.config.dialect {
14654 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
14655 _ => "DOY",
14656 };
14657 self.write_keyword(name);
14658 }
14659 DateTimeField::Week => self.write_keyword("WEEK"),
14660 DateTimeField::WeekWithModifier(modifier) => {
14661 self.write_keyword("WEEK");
14662 self.write("(");
14663 self.write(modifier);
14664 self.write(")");
14665 }
14666 DateTimeField::Quarter => self.write_keyword("QUARTER"),
14667 DateTimeField::Epoch => self.write_keyword("EPOCH"),
14668 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
14669 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
14670 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
14671 DateTimeField::Date => self.write_keyword("DATE"),
14672 DateTimeField::Time => self.write_keyword("TIME"),
14673 DateTimeField::Custom(name) => self.write(name),
14674 }
14675 }
14676
14677 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
14679 match field {
14680 DateTimeField::Year => self.write("year"),
14681 DateTimeField::Month => self.write("month"),
14682 DateTimeField::Day => self.write("day"),
14683 DateTimeField::Hour => self.write("hour"),
14684 DateTimeField::Minute => self.write("minute"),
14685 DateTimeField::Second => self.write("second"),
14686 DateTimeField::Millisecond => self.write("millisecond"),
14687 DateTimeField::Microsecond => self.write("microsecond"),
14688 DateTimeField::DayOfWeek => self.write("dow"),
14689 DateTimeField::DayOfYear => self.write("doy"),
14690 DateTimeField::Week => self.write("week"),
14691 DateTimeField::WeekWithModifier(modifier) => {
14692 self.write("week(");
14693 self.write(modifier);
14694 self.write(")");
14695 }
14696 DateTimeField::Quarter => self.write("quarter"),
14697 DateTimeField::Epoch => self.write("epoch"),
14698 DateTimeField::Timezone => self.write("timezone"),
14699 DateTimeField::TimezoneHour => self.write("timezone_hour"),
14700 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
14701 DateTimeField::Date => self.write("date"),
14702 DateTimeField::Time => self.write("time"),
14703 DateTimeField::Custom(name) => self.write(name),
14704 }
14705 }
14706
14707 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
14710 self.write_keyword(name);
14711 self.write("(");
14712 self.generate_expression(arg)?;
14713 self.write(")");
14714 Ok(())
14715 }
14716
14717 fn generate_unary_func(&mut self, default_name: &str, f: &crate::expressions::UnaryFunc) -> Result<()> {
14719 let name = f.original_name.as_deref().unwrap_or(default_name);
14720 self.write_keyword(name);
14721 self.write("(");
14722 self.generate_expression(&f.this)?;
14723 self.write(")");
14724 Ok(())
14725 }
14726
14727 fn generate_sqrt_cbrt(&mut self, f: &crate::expressions::UnaryFunc, func_name: &str, _op: &str) -> Result<()> {
14729 self.write_keyword(func_name);
14732 self.write("(");
14733 self.generate_expression(&f.this)?;
14734 self.write(")");
14735 Ok(())
14736 }
14737
14738 fn generate_binary_func(&mut self, name: &str, arg1: &Expression, arg2: &Expression) -> Result<()> {
14739 self.write_keyword(name);
14740 self.write("(");
14741 self.generate_expression(arg1)?;
14742 self.write(", ");
14743 self.generate_expression(arg2)?;
14744 self.write(")");
14745 Ok(())
14746 }
14747
14748 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
14752 let func_name = f.name.as_deref().unwrap_or("CHAR");
14754 self.write_keyword(func_name);
14755 self.write("(");
14756 for (i, arg) in f.args.iter().enumerate() {
14757 if i > 0 {
14758 self.write(", ");
14759 }
14760 self.generate_expression(arg)?;
14761 }
14762 if let Some(ref charset) = f.charset {
14763 self.write(" ");
14764 self.write_keyword("USING");
14765 self.write(" ");
14766 self.write(charset);
14767 }
14768 self.write(")");
14769 Ok(())
14770 }
14771
14772 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
14773 use crate::dialects::DialectType;
14774
14775 match self.config.dialect {
14776 Some(DialectType::Teradata) => {
14777 self.generate_expression(&f.this)?;
14779 self.write(" ** ");
14780 self.generate_expression(&f.expression)?;
14781 Ok(())
14782 }
14783 _ => {
14784 self.generate_binary_func("POWER", &f.this, &f.expression)
14786 }
14787 }
14788 }
14789
14790 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
14791 self.write_keyword(name);
14792 self.write("(");
14793 for (i, arg) in args.iter().enumerate() {
14794 if i > 0 {
14795 self.write(", ");
14796 }
14797 self.generate_expression(arg)?;
14798 }
14799 self.write(")");
14800 Ok(())
14801 }
14802
14803 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
14806 self.write_keyword("CONCAT_WS");
14807 self.write("(");
14808 self.generate_expression(&f.separator)?;
14809 for expr in &f.expressions {
14810 self.write(", ");
14811 self.generate_expression(expr)?;
14812 }
14813 self.write(")");
14814 Ok(())
14815 }
14816
14817 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
14818 self.write_keyword("SUBSTRING");
14819 self.write("(");
14820 self.generate_expression(&f.this)?;
14821 let use_comma_syntax = matches!(
14823 self.config.dialect,
14824 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
14825 );
14826 if f.from_for_syntax && !use_comma_syntax {
14827 self.write_space();
14829 self.write_keyword("FROM");
14830 self.write_space();
14831 self.generate_expression(&f.start)?;
14832 if let Some(length) = &f.length {
14833 self.write_space();
14834 self.write_keyword("FOR");
14835 self.write_space();
14836 self.generate_expression(length)?;
14837 }
14838 } else {
14839 self.write(", ");
14841 self.generate_expression(&f.start)?;
14842 if let Some(length) = &f.length {
14843 self.write(", ");
14844 self.generate_expression(length)?;
14845 }
14846 }
14847 self.write(")");
14848 Ok(())
14849 }
14850
14851 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
14852 self.write_keyword("OVERLAY");
14853 self.write("(");
14854 self.generate_expression(&f.this)?;
14855 self.write_space();
14856 self.write_keyword("PLACING");
14857 self.write_space();
14858 self.generate_expression(&f.replacement)?;
14859 self.write_space();
14860 self.write_keyword("FROM");
14861 self.write_space();
14862 self.generate_expression(&f.from)?;
14863 if let Some(length) = &f.length {
14864 self.write_space();
14865 self.write_keyword("FOR");
14866 self.write_space();
14867 self.generate_expression(length)?;
14868 }
14869 self.write(")");
14870 Ok(())
14871 }
14872
14873 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
14874 if f.position_explicit && f.characters.is_none() {
14877 match f.position {
14878 TrimPosition::Leading => {
14879 self.write_keyword("LTRIM");
14880 self.write("(");
14881 self.generate_expression(&f.this)?;
14882 self.write(")");
14883 return Ok(());
14884 }
14885 TrimPosition::Trailing => {
14886 self.write_keyword("RTRIM");
14887 self.write("(");
14888 self.generate_expression(&f.this)?;
14889 self.write(")");
14890 return Ok(());
14891 }
14892 TrimPosition::Both => {
14893 }
14896 }
14897 }
14898
14899 self.write_keyword("TRIM");
14900 self.write("(");
14901 let use_standard = f.sql_standard_syntax
14903 && !(f.position_explicit && f.characters.is_none() && matches!(f.position, TrimPosition::Both));
14904 if use_standard {
14905 if f.position_explicit {
14908 match f.position {
14909 TrimPosition::Both => self.write_keyword("BOTH"),
14910 TrimPosition::Leading => self.write_keyword("LEADING"),
14911 TrimPosition::Trailing => self.write_keyword("TRAILING"),
14912 }
14913 self.write_space();
14914 }
14915 if let Some(chars) = &f.characters {
14916 self.generate_expression(chars)?;
14917 self.write_space();
14918 }
14919 self.write_keyword("FROM");
14920 self.write_space();
14921 self.generate_expression(&f.this)?;
14922 } else {
14923 self.generate_expression(&f.this)?;
14925 if let Some(chars) = &f.characters {
14926 self.write(", ");
14927 self.generate_expression(chars)?;
14928 }
14929 }
14930 self.write(")");
14931 Ok(())
14932 }
14933
14934 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
14935 self.write_keyword("REPLACE");
14936 self.write("(");
14937 self.generate_expression(&f.this)?;
14938 self.write(", ");
14939 self.generate_expression(&f.old)?;
14940 self.write(", ");
14941 self.generate_expression(&f.new)?;
14942 self.write(")");
14943 Ok(())
14944 }
14945
14946 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
14947 self.write_keyword(name);
14948 self.write("(");
14949 self.generate_expression(&f.this)?;
14950 self.write(", ");
14951 self.generate_expression(&f.length)?;
14952 self.write(")");
14953 Ok(())
14954 }
14955
14956 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
14957 self.write_keyword("REPEAT");
14958 self.write("(");
14959 self.generate_expression(&f.this)?;
14960 self.write(", ");
14961 self.generate_expression(&f.times)?;
14962 self.write(")");
14963 Ok(())
14964 }
14965
14966 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
14967 self.write_keyword(name);
14968 self.write("(");
14969 self.generate_expression(&f.this)?;
14970 self.write(", ");
14971 self.generate_expression(&f.length)?;
14972 if let Some(fill) = &f.fill {
14973 self.write(", ");
14974 self.generate_expression(fill)?;
14975 }
14976 self.write(")");
14977 Ok(())
14978 }
14979
14980 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
14981 self.write_keyword("SPLIT");
14982 self.write("(");
14983 self.generate_expression(&f.this)?;
14984 self.write(", ");
14985 self.generate_expression(&f.delimiter)?;
14986 self.write(")");
14987 Ok(())
14988 }
14989
14990 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
14991 use crate::dialects::DialectType;
14992 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
14994 self.generate_expression(&f.this)?;
14995 self.write(" ~ ");
14996 self.generate_expression(&f.pattern)?;
14997 } else if matches!(self.config.dialect, Some(DialectType::SingleStore) | Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)) && f.flags.is_none() {
14998 self.generate_expression(&f.this)?;
15000 self.write_keyword(" RLIKE ");
15001 self.generate_expression(&f.pattern)?;
15002 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
15003 self.write_keyword("REGEXP");
15005 self.write("(");
15006 self.generate_expression(&f.this)?;
15007 self.write(", ");
15008 self.generate_expression(&f.pattern)?;
15009 if let Some(flags) = &f.flags {
15010 self.write(", ");
15011 self.generate_expression(flags)?;
15012 }
15013 self.write(")");
15014 } else {
15015 self.write_keyword("REGEXP_LIKE");
15016 self.write("(");
15017 self.generate_expression(&f.this)?;
15018 self.write(", ");
15019 self.generate_expression(&f.pattern)?;
15020 if let Some(flags) = &f.flags {
15021 self.write(", ");
15022 self.generate_expression(flags)?;
15023 }
15024 self.write(")");
15025 }
15026 Ok(())
15027 }
15028
15029 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
15030 self.write_keyword("REGEXP_REPLACE");
15031 self.write("(");
15032 self.generate_expression(&f.this)?;
15033 self.write(", ");
15034 self.generate_expression(&f.pattern)?;
15035 self.write(", ");
15036 self.generate_expression(&f.replacement)?;
15037 if let Some(flags) = &f.flags {
15038 self.write(", ");
15039 self.generate_expression(flags)?;
15040 }
15041 self.write(")");
15042 Ok(())
15043 }
15044
15045 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
15046 self.write_keyword("REGEXP_EXTRACT");
15047 self.write("(");
15048 self.generate_expression(&f.this)?;
15049 self.write(", ");
15050 self.generate_expression(&f.pattern)?;
15051 if let Some(group) = &f.group {
15052 self.write(", ");
15053 self.generate_expression(group)?;
15054 }
15055 self.write(")");
15056 Ok(())
15057 }
15058
15059 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
15062 self.write_keyword("ROUND");
15063 self.write("(");
15064 self.generate_expression(&f.this)?;
15065 if let Some(decimals) = &f.decimals {
15066 self.write(", ");
15067 self.generate_expression(decimals)?;
15068 }
15069 self.write(")");
15070 Ok(())
15071 }
15072
15073 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
15074 self.write_keyword("FLOOR");
15075 self.write("(");
15076 self.generate_expression(&f.this)?;
15077 if let Some(to) = &f.to {
15079 self.write(" ");
15080 self.write_keyword("TO");
15081 self.write(" ");
15082 self.generate_expression(to)?;
15083 } else if let Some(scale) = &f.scale {
15084 self.write(", ");
15085 self.generate_expression(scale)?;
15086 }
15087 self.write(")");
15088 Ok(())
15089 }
15090
15091 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
15092 self.write_keyword("CEIL");
15093 self.write("(");
15094 self.generate_expression(&f.this)?;
15095 if let Some(to) = &f.to {
15097 self.write(" ");
15098 self.write_keyword("TO");
15099 self.write(" ");
15100 self.generate_expression(to)?;
15101 } else if let Some(decimals) = &f.decimals {
15102 self.write(", ");
15103 self.generate_expression(decimals)?;
15104 }
15105 self.write(")");
15106 Ok(())
15107 }
15108
15109 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
15110 self.write_keyword("LOG");
15111 self.write("(");
15112 if let Some(base) = &f.base {
15113 self.generate_expression(base)?;
15114 self.write(", ");
15115 }
15116 self.generate_expression(&f.this)?;
15117 self.write(")");
15118 Ok(())
15119 }
15120
15121 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
15124 self.write_keyword("CURRENT_TIME");
15125 if let Some(precision) = f.precision {
15126 self.write(&format!("({})", precision));
15127 }
15128 Ok(())
15129 }
15130
15131 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
15132 use crate::dialects::DialectType;
15133
15134 if f.sysdate {
15136 match self.config.dialect {
15137 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
15138 self.write_keyword("SYSDATE");
15139 return Ok(());
15140 }
15141 Some(DialectType::Snowflake) => {
15142 self.write_keyword("SYSDATE");
15144 self.write("()");
15145 return Ok(());
15146 }
15147 _ => {
15148 }
15150 }
15151 }
15152
15153 self.write_keyword("CURRENT_TIMESTAMP");
15154 if let Some(precision) = f.precision {
15156 self.write(&format!("({})", precision));
15157 } else if matches!(
15158 self.config.dialect,
15159 Some(crate::dialects::DialectType::MySQL) | Some(crate::dialects::DialectType::SingleStore) |
15160 Some(crate::dialects::DialectType::TiDB) | Some(crate::dialects::DialectType::Spark) |
15161 Some(crate::dialects::DialectType::Hive) |
15162 Some(crate::dialects::DialectType::Databricks) | Some(crate::dialects::DialectType::ClickHouse) |
15163 Some(crate::dialects::DialectType::BigQuery) | Some(crate::dialects::DialectType::Snowflake)
15164 ) {
15165 self.write("()");
15166 }
15167 Ok(())
15168 }
15169
15170 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
15171 if self.config.dialect == Some(DialectType::Exasol) {
15173 self.write_keyword("CONVERT_TZ");
15174 self.write("(");
15175 self.generate_expression(&f.this)?;
15176 self.write(", 'UTC', ");
15177 self.generate_expression(&f.zone)?;
15178 self.write(")");
15179 return Ok(());
15180 }
15181
15182 self.generate_expression(&f.this)?;
15183 self.write_space();
15184 self.write_keyword("AT TIME ZONE");
15185 self.write_space();
15186 self.generate_expression(&f.zone)?;
15187 Ok(())
15188 }
15189
15190 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
15191 use crate::dialects::DialectType;
15192
15193 let is_presto_like = matches!(
15196 self.config.dialect,
15197 Some(DialectType::Presto) | Some(DialectType::Trino)
15198 );
15199
15200 if is_presto_like {
15201 self.write_keyword(name);
15202 self.write("(");
15203 self.write("'");
15205 self.write_simple_interval_unit(&f.unit, false);
15206 self.write("'");
15207 self.write(", ");
15208 let needs_cast = !self.returns_integer_type(&f.interval);
15210 if needs_cast {
15211 self.write_keyword("CAST");
15212 self.write("(");
15213 }
15214 self.generate_expression(&f.interval)?;
15215 if needs_cast {
15216 self.write_space();
15217 self.write_keyword("AS");
15218 self.write_space();
15219 self.write_keyword("BIGINT");
15220 self.write(")");
15221 }
15222 self.write(", ");
15223 self.generate_expression(&f.this)?;
15224 self.write(")");
15225 } else {
15226 self.write_keyword(name);
15227 self.write("(");
15228 self.generate_expression(&f.this)?;
15229 self.write(", ");
15230 self.write_keyword("INTERVAL");
15231 self.write_space();
15232 self.generate_expression(&f.interval)?;
15233 self.write_space();
15234 self.write_simple_interval_unit(&f.unit, false); self.write(")");
15236 }
15237 Ok(())
15238 }
15239
15240 fn returns_integer_type(&self, expr: &Expression) -> bool {
15243 use crate::expressions::{DataType, Literal};
15244 match expr {
15245 Expression::Literal(Literal::Number(n)) => !n.contains('.'),
15247
15248 Expression::Floor(f) => self.returns_integer_type(&f.this),
15250
15251 Expression::Round(f) => {
15253 f.decimals.is_none() && self.returns_integer_type(&f.this)
15255 }
15256
15257 Expression::Sign(f) => self.returns_integer_type(&f.this),
15259
15260 Expression::Abs(f) => self.returns_integer_type(&f.this),
15262
15263 Expression::Mul(op) => self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right),
15265 Expression::Add(op) => self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right),
15266 Expression::Sub(op) => self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right),
15267 Expression::Mod(op) => self.returns_integer_type(&op.left),
15268
15269 Expression::Cast(c) => matches!(&c.to,
15271 DataType::BigInt { .. } | DataType::Int { .. } |
15272 DataType::SmallInt { .. } | DataType::TinyInt { .. }
15273 ),
15274
15275 Expression::Neg(op) => self.returns_integer_type(&op.this),
15277
15278 Expression::Paren(p) => self.returns_integer_type(&p.this),
15280
15281 _ => false,
15284 }
15285 }
15286
15287 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
15288 self.write_keyword("DATEDIFF");
15289 self.write("(");
15290 if let Some(unit) = &f.unit {
15291 self.write_simple_interval_unit(unit, false); self.write(", ");
15293 }
15294 self.generate_expression(&f.this)?;
15295 self.write(", ");
15296 self.generate_expression(&f.expression)?;
15297 self.write(")");
15298 Ok(())
15299 }
15300
15301 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
15302 self.write_keyword("DATE_TRUNC");
15303 self.write("('");
15304 self.write_datetime_field(&f.unit);
15305 self.write("', ");
15306 self.generate_expression(&f.this)?;
15307 self.write(")");
15308 Ok(())
15309 }
15310
15311 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
15312 use crate::dialects::DialectType;
15313 use crate::expressions::DateTimeField;
15314
15315 self.write_keyword("LAST_DAY");
15316 self.write("(");
15317 self.generate_expression(&f.this)?;
15318 if let Some(unit) = &f.unit {
15319 self.write(", ");
15320 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
15323 if let DateTimeField::WeekWithModifier(_) = unit {
15324 self.write_keyword("WEEK");
15325 } else {
15326 self.write_datetime_field(unit);
15327 }
15328 } else {
15329 self.write_datetime_field(unit);
15330 }
15331 }
15332 self.write(")");
15333 Ok(())
15334 }
15335
15336 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
15337 if matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) {
15339 self.write_keyword("DATEPART");
15340 self.write("(");
15341 self.write_datetime_field(&f.field);
15342 self.write(", ");
15343 self.generate_expression(&f.this)?;
15344 self.write(")");
15345 return Ok(());
15346 }
15347 self.write_keyword("EXTRACT");
15348 self.write("(");
15349 if matches!(self.config.dialect, Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)) {
15351 self.write_datetime_field_lower(&f.field);
15352 } else {
15353 self.write_datetime_field(&f.field);
15354 }
15355 self.write_space();
15356 self.write_keyword("FROM");
15357 self.write_space();
15358 self.generate_expression(&f.this)?;
15359 self.write(")");
15360 Ok(())
15361 }
15362
15363 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
15364 self.write_keyword("TO_DATE");
15365 self.write("(");
15366 self.generate_expression(&f.this)?;
15367 if let Some(format) = &f.format {
15368 self.write(", ");
15369 self.generate_expression(format)?;
15370 }
15371 self.write(")");
15372 Ok(())
15373 }
15374
15375 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
15376 self.write_keyword("TO_TIMESTAMP");
15377 self.write("(");
15378 self.generate_expression(&f.this)?;
15379 if let Some(format) = &f.format {
15380 self.write(", ");
15381 self.generate_expression(format)?;
15382 }
15383 self.write(")");
15384 Ok(())
15385 }
15386
15387 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
15390 use crate::dialects::DialectType;
15391
15392 if self.config.dialect == Some(DialectType::Exasol) {
15394 self.write_keyword("IF");
15395 self.write_space();
15396 self.generate_expression(&f.condition)?;
15397 self.write_space();
15398 self.write_keyword("THEN");
15399 self.write_space();
15400 self.generate_expression(&f.true_value)?;
15401 if let Some(false_val) = &f.false_value {
15402 self.write_space();
15403 self.write_keyword("ELSE");
15404 self.write_space();
15405 self.generate_expression(false_val)?;
15406 }
15407 self.write_space();
15408 self.write_keyword("ENDIF");
15409 return Ok(());
15410 }
15411
15412 let func_name = match self.config.dialect {
15414 Some(DialectType::Snowflake) => "IFF",
15415 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
15416 _ => "IF",
15417 };
15418 self.write_keyword(func_name);
15419 self.write("(");
15420 self.generate_expression(&f.condition)?;
15421 self.write(", ");
15422 self.generate_expression(&f.true_value)?;
15423 if let Some(false_val) = &f.false_value {
15424 self.write(", ");
15425 self.generate_expression(false_val)?;
15426 }
15427 self.write(")");
15428 Ok(())
15429 }
15430
15431 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
15432 self.write_keyword("NVL2");
15433 self.write("(");
15434 self.generate_expression(&f.this)?;
15435 self.write(", ");
15436 self.generate_expression(&f.true_value)?;
15437 self.write(", ");
15438 self.generate_expression(&f.false_value)?;
15439 self.write(")");
15440 Ok(())
15441 }
15442
15443 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
15446 let count_name = match self.config.normalize_functions {
15448 NormalizeFunctions::Upper => "COUNT".to_string(),
15449 NormalizeFunctions::Lower => "count".to_string(),
15450 NormalizeFunctions::None => f.original_name.clone().unwrap_or_else(|| "COUNT".to_string()),
15451 };
15452 self.write(&count_name);
15453 self.write("(");
15454 if f.distinct {
15455 self.write_keyword("DISTINCT");
15456 self.write_space();
15457 }
15458 if f.star {
15459 self.write("*");
15460 } else if let Some(ref expr) = f.this {
15461 if let Expression::Tuple(tuple) = expr {
15463 let needs_transform = f.distinct
15467 && tuple.expressions.len() > 1
15468 && !self.config.multi_arg_distinct;
15469
15470 if needs_transform {
15471 self.write_keyword("CASE");
15473 for e in &tuple.expressions {
15474 self.write_space();
15475 self.write_keyword("WHEN");
15476 self.write_space();
15477 self.generate_expression(e)?;
15478 self.write_space();
15479 self.write_keyword("IS NULL THEN NULL");
15480 }
15481 self.write_space();
15482 self.write_keyword("ELSE");
15483 self.write(" (");
15484 for (i, e) in tuple.expressions.iter().enumerate() {
15485 if i > 0 {
15486 self.write(", ");
15487 }
15488 self.generate_expression(e)?;
15489 }
15490 self.write(")");
15491 self.write_space();
15492 self.write_keyword("END");
15493 } else {
15494 for (i, e) in tuple.expressions.iter().enumerate() {
15495 if i > 0 {
15496 self.write(", ");
15497 }
15498 self.generate_expression(e)?;
15499 }
15500 }
15501 } else {
15502 self.generate_expression(expr)?;
15503 }
15504 }
15505 if let Some(ignore) = f.ignore_nulls {
15507 self.write_space();
15508 if ignore {
15509 self.write_keyword("IGNORE NULLS");
15510 } else {
15511 self.write_keyword("RESPECT NULLS");
15512 }
15513 }
15514 self.write(")");
15515 if let Some(ref filter) = f.filter {
15516 self.write_space();
15517 self.write_keyword("FILTER");
15518 self.write("(");
15519 self.write_keyword("WHERE");
15520 self.write_space();
15521 self.generate_expression(filter)?;
15522 self.write(")");
15523 }
15524 Ok(())
15525 }
15526
15527 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
15528 let func_name = match self.config.normalize_functions {
15530 NormalizeFunctions::Upper => name.to_uppercase(),
15531 NormalizeFunctions::Lower => name.to_lowercase(),
15532 NormalizeFunctions::None => {
15533 if let Some(ref original) = f.name {
15536 original.clone()
15537 } else {
15538 name.to_lowercase()
15539 }
15540 }
15541 };
15542 self.write(&func_name);
15543 self.write("(");
15544 if f.distinct {
15545 self.write_keyword("DISTINCT");
15546 self.write_space();
15547 }
15548 if !matches!(f.this, Expression::Null(_)) {
15550 self.generate_expression(&f.this)?;
15551 }
15552 if self.config.ignore_nulls_in_func && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
15555 match f.ignore_nulls {
15556 Some(true) => {
15557 self.write_space();
15558 self.write_keyword("IGNORE NULLS");
15559 }
15560 Some(false) => {
15561 self.write_space();
15562 self.write_keyword("RESPECT NULLS");
15563 }
15564 None => {}
15565 }
15566 }
15567 if let Some((ref expr, is_max)) = f.having_max {
15570 self.write_space();
15571 self.write_keyword("HAVING");
15572 self.write_space();
15573 if is_max {
15574 self.write_keyword("MAX");
15575 } else {
15576 self.write_keyword("MIN");
15577 }
15578 self.write_space();
15579 self.generate_expression(expr)?;
15580 }
15581 if !f.order_by.is_empty() {
15583 self.write_space();
15584 self.write_keyword("ORDER BY");
15585 self.write_space();
15586 for (i, ord) in f.order_by.iter().enumerate() {
15587 if i > 0 { self.write(", "); }
15588 self.generate_ordered(ord)?;
15589 }
15590 }
15591 if let Some(ref limit) = f.limit {
15593 self.write_space();
15594 self.write_keyword("LIMIT");
15595 self.write_space();
15596 if let Expression::Tuple(t) = limit.as_ref() {
15598 if t.expressions.len() == 2 {
15599 self.generate_expression(&t.expressions[0])?;
15600 self.write(", ");
15601 self.generate_expression(&t.expressions[1])?;
15602 } else {
15603 self.generate_expression(limit)?;
15604 }
15605 } else {
15606 self.generate_expression(limit)?;
15607 }
15608 }
15609 self.write(")");
15610 if !self.config.ignore_nulls_in_func && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
15613 match f.ignore_nulls {
15614 Some(true) => {
15615 self.write_space();
15616 self.write_keyword("IGNORE NULLS");
15617 }
15618 Some(false) => {
15619 self.write_space();
15620 self.write_keyword("RESPECT NULLS");
15621 }
15622 None => {}
15623 }
15624 }
15625 if let Some(ref filter) = f.filter {
15626 self.write_space();
15627 self.write_keyword("FILTER");
15628 self.write("(");
15629 self.write_keyword("WHERE");
15630 self.write_space();
15631 self.generate_expression(filter)?;
15632 self.write(")");
15633 }
15634 Ok(())
15635 }
15636
15637 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
15638 self.write_keyword("GROUP_CONCAT");
15639 self.write("(");
15640 if f.distinct {
15641 self.write_keyword("DISTINCT");
15642 self.write_space();
15643 }
15644 self.generate_expression(&f.this)?;
15645 if let Some(ref order_by) = f.order_by {
15646 self.write_space();
15647 self.write_keyword("ORDER BY");
15648 self.write_space();
15649 for (i, ord) in order_by.iter().enumerate() {
15650 if i > 0 { self.write(", "); }
15651 self.generate_ordered(ord)?;
15652 }
15653 }
15654 if let Some(ref sep) = f.separator {
15655 if matches!(self.config.dialect, Some(crate::dialects::DialectType::SQLite)) {
15658 self.write(", ");
15659 self.generate_expression(sep)?;
15660 } else {
15661 self.write_space();
15662 self.write_keyword("SEPARATOR");
15663 self.write_space();
15664 self.generate_expression(sep)?;
15665 }
15666 }
15667 self.write(")");
15668 if let Some(ref filter) = f.filter {
15669 self.write_space();
15670 self.write_keyword("FILTER");
15671 self.write("(");
15672 self.write_keyword("WHERE");
15673 self.write_space();
15674 self.generate_expression(filter)?;
15675 self.write(")");
15676 }
15677 Ok(())
15678 }
15679
15680 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
15681 let is_tsql = matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL));
15682 self.write_keyword("STRING_AGG");
15683 self.write("(");
15684 if f.distinct {
15685 self.write_keyword("DISTINCT");
15686 self.write_space();
15687 }
15688 self.generate_expression(&f.this)?;
15689 if let Some(ref separator) = f.separator {
15690 self.write(", ");
15691 self.generate_expression(separator)?;
15692 }
15693 if !is_tsql {
15695 if let Some(ref order_by) = f.order_by {
15696 self.write_space();
15697 self.write_keyword("ORDER BY");
15698 self.write_space();
15699 for (i, ord) in order_by.iter().enumerate() {
15700 if i > 0 { self.write(", "); }
15701 self.generate_ordered(ord)?;
15702 }
15703 }
15704 }
15705 if let Some(ref limit) = f.limit {
15706 self.write_space();
15707 self.write_keyword("LIMIT");
15708 self.write_space();
15709 self.generate_expression(limit)?;
15710 }
15711 self.write(")");
15712 if is_tsql {
15714 if let Some(ref order_by) = f.order_by {
15715 self.write_space();
15716 self.write_keyword("WITHIN GROUP");
15717 self.write(" (");
15718 self.write_keyword("ORDER BY");
15719 self.write_space();
15720 for (i, ord) in order_by.iter().enumerate() {
15721 if i > 0 { self.write(", "); }
15722 self.generate_ordered(ord)?;
15723 }
15724 self.write(")");
15725 }
15726 }
15727 if let Some(ref filter) = f.filter {
15728 self.write_space();
15729 self.write_keyword("FILTER");
15730 self.write("(");
15731 self.write_keyword("WHERE");
15732 self.write_space();
15733 self.generate_expression(filter)?;
15734 self.write(")");
15735 }
15736 Ok(())
15737 }
15738
15739 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
15740 use crate::dialects::DialectType;
15741 self.write_keyword("LISTAGG");
15742 self.write("(");
15743 if f.distinct {
15744 self.write_keyword("DISTINCT");
15745 self.write_space();
15746 }
15747 self.generate_expression(&f.this)?;
15748 if let Some(ref sep) = f.separator {
15749 self.write(", ");
15750 self.generate_expression(sep)?;
15751 } else if matches!(self.config.dialect, Some(DialectType::Trino) | Some(DialectType::Presto)) {
15752 self.write(", ','");
15754 }
15755 if let Some(ref overflow) = f.on_overflow {
15756 self.write_space();
15757 self.write_keyword("ON OVERFLOW");
15758 self.write_space();
15759 match overflow {
15760 ListAggOverflow::Error => self.write_keyword("ERROR"),
15761 ListAggOverflow::Truncate { filler, with_count } => {
15762 self.write_keyword("TRUNCATE");
15763 if let Some(ref fill) = filler {
15764 self.write_space();
15765 self.generate_expression(fill)?;
15766 }
15767 if *with_count {
15768 self.write_space();
15769 self.write_keyword("WITH COUNT");
15770 } else {
15771 self.write_space();
15772 self.write_keyword("WITHOUT COUNT");
15773 }
15774 }
15775 }
15776 }
15777 self.write(")");
15778 if let Some(ref order_by) = f.order_by {
15779 self.write_space();
15780 self.write_keyword("WITHIN GROUP");
15781 self.write(" (");
15782 self.write_keyword("ORDER BY");
15783 self.write_space();
15784 for (i, ord) in order_by.iter().enumerate() {
15785 if i > 0 { self.write(", "); }
15786 self.generate_ordered(ord)?;
15787 }
15788 self.write(")");
15789 }
15790 if let Some(ref filter) = f.filter {
15791 self.write_space();
15792 self.write_keyword("FILTER");
15793 self.write("(");
15794 self.write_keyword("WHERE");
15795 self.write_space();
15796 self.generate_expression(filter)?;
15797 self.write(")");
15798 }
15799 Ok(())
15800 }
15801
15802 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
15803 self.write_keyword("SUM_IF");
15804 self.write("(");
15805 self.generate_expression(&f.this)?;
15806 self.write(", ");
15807 self.generate_expression(&f.condition)?;
15808 self.write(")");
15809 if let Some(ref filter) = f.filter {
15810 self.write_space();
15811 self.write_keyword("FILTER");
15812 self.write("(");
15813 self.write_keyword("WHERE");
15814 self.write_space();
15815 self.generate_expression(filter)?;
15816 self.write(")");
15817 }
15818 Ok(())
15819 }
15820
15821 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
15822 self.write_keyword("APPROX_PERCENTILE");
15823 self.write("(");
15824 self.generate_expression(&f.this)?;
15825 self.write(", ");
15826 self.generate_expression(&f.percentile)?;
15827 if let Some(ref acc) = f.accuracy {
15828 self.write(", ");
15829 self.generate_expression(acc)?;
15830 }
15831 self.write(")");
15832 if let Some(ref filter) = f.filter {
15833 self.write_space();
15834 self.write_keyword("FILTER");
15835 self.write("(");
15836 self.write_keyword("WHERE");
15837 self.write_space();
15838 self.generate_expression(filter)?;
15839 self.write(")");
15840 }
15841 Ok(())
15842 }
15843
15844 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
15845 self.write_keyword(name);
15846 self.write("(");
15847 self.generate_expression(&f.percentile)?;
15848 self.write(")");
15849 if let Some(ref order_by) = f.order_by {
15850 self.write_space();
15851 self.write_keyword("WITHIN GROUP");
15852 self.write(" (");
15853 self.write_keyword("ORDER BY");
15854 self.write_space();
15855 self.generate_expression(&f.this)?;
15856 for ord in order_by.iter() {
15857 if ord.desc {
15858 self.write_space();
15859 self.write_keyword("DESC");
15860 }
15861 }
15862 self.write(")");
15863 }
15864 if let Some(ref filter) = f.filter {
15865 self.write_space();
15866 self.write_keyword("FILTER");
15867 self.write("(");
15868 self.write_keyword("WHERE");
15869 self.write_space();
15870 self.generate_expression(filter)?;
15871 self.write(")");
15872 }
15873 Ok(())
15874 }
15875
15876 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
15879 self.write_keyword("NTILE");
15880 self.write("(");
15881 if let Some(num_buckets) = &f.num_buckets {
15882 self.generate_expression(num_buckets)?;
15883 }
15884 if let Some(order_by) = &f.order_by {
15885 self.write_keyword(" ORDER BY ");
15886 for (i, ob) in order_by.iter().enumerate() {
15887 if i > 0 { self.write(", "); }
15888 self.generate_ordered(ob)?;
15889 }
15890 }
15891 self.write(")");
15892 Ok(())
15893 }
15894
15895 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
15896 self.write_keyword(name);
15897 self.write("(");
15898 self.generate_expression(&f.this)?;
15899 if let Some(ref offset) = f.offset {
15900 self.write(", ");
15901 self.generate_expression(offset)?;
15902 if let Some(ref default) = f.default {
15903 self.write(", ");
15904 self.generate_expression(default)?;
15905 }
15906 }
15907 if f.ignore_nulls && self.config.ignore_nulls_in_func {
15909 self.write_space();
15910 self.write_keyword("IGNORE NULLS");
15911 }
15912 self.write(")");
15913 if f.ignore_nulls && !self.config.ignore_nulls_in_func {
15915 self.write_space();
15916 self.write_keyword("IGNORE NULLS");
15917 }
15918 Ok(())
15919 }
15920
15921 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
15922 self.write_keyword(name);
15923 self.write("(");
15924 self.generate_expression(&f.this)?;
15925 if self.config.ignore_nulls_in_func {
15927 match f.ignore_nulls {
15928 Some(true) => {
15929 self.write_space();
15930 self.write_keyword("IGNORE NULLS");
15931 }
15932 Some(false) => {
15933 self.write_space();
15934 self.write_keyword("RESPECT NULLS");
15935 }
15936 None => {}
15937 }
15938 }
15939 self.write(")");
15940 if !self.config.ignore_nulls_in_func {
15942 match f.ignore_nulls {
15943 Some(true) => {
15944 self.write_space();
15945 self.write_keyword("IGNORE NULLS");
15946 }
15947 Some(false) => {
15948 self.write_space();
15949 self.write_keyword("RESPECT NULLS");
15950 }
15951 None => {}
15952 }
15953 }
15954 Ok(())
15955 }
15956
15957 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
15958 self.write_keyword("NTH_VALUE");
15959 self.write("(");
15960 self.generate_expression(&f.this)?;
15961 self.write(", ");
15962 self.generate_expression(&f.offset)?;
15963 if self.config.ignore_nulls_in_func {
15965 match f.ignore_nulls {
15966 Some(true) => {
15967 self.write_space();
15968 self.write_keyword("IGNORE NULLS");
15969 }
15970 Some(false) => {
15971 self.write_space();
15972 self.write_keyword("RESPECT NULLS");
15973 }
15974 None => {}
15975 }
15976 }
15977 self.write(")");
15978 if !self.config.ignore_nulls_in_func {
15980 match f.ignore_nulls {
15981 Some(true) => {
15982 self.write_space();
15983 self.write_keyword("IGNORE NULLS");
15984 }
15985 Some(false) => {
15986 self.write_space();
15987 self.write_keyword("RESPECT NULLS");
15988 }
15989 None => {}
15990 }
15991 }
15992 Ok(())
15993 }
15994
15995 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
15998 if matches!(self.config.dialect, Some(crate::dialects::DialectType::ClickHouse)) {
16001 self.write_keyword("POSITION");
16002 self.write("(");
16003 self.generate_expression(&f.string)?;
16004 self.write(", ");
16005 self.generate_expression(&f.substring)?;
16006 if let Some(ref start) = f.start {
16007 self.write(", ");
16008 self.generate_expression(start)?;
16009 }
16010 self.write(")");
16011 return Ok(());
16012 }
16013
16014 self.write_keyword("POSITION");
16015 self.write("(");
16016 self.generate_expression(&f.substring)?;
16017 self.write_space();
16018 self.write_keyword("IN");
16019 self.write_space();
16020 self.generate_expression(&f.string)?;
16021 if let Some(ref start) = f.start {
16022 self.write(", ");
16023 self.generate_expression(start)?;
16024 }
16025 self.write(")");
16026 Ok(())
16027 }
16028
16029 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
16032 if f.lower.is_some() || f.upper.is_some() {
16034 self.write_keyword("RANDOM");
16035 self.write("(");
16036 if let Some(ref lower) = f.lower {
16037 self.generate_expression(lower)?;
16038 }
16039 if let Some(ref upper) = f.upper {
16040 self.write(", ");
16041 self.generate_expression(upper)?;
16042 }
16043 self.write(")");
16044 return Ok(());
16045 }
16046 let func_name = match self.config.dialect {
16048 Some(crate::dialects::DialectType::Snowflake) | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
16049 _ => "RAND",
16050 };
16051 self.write_keyword(func_name);
16052 self.write("(");
16053 if !matches!(self.config.dialect, Some(crate::dialects::DialectType::DuckDB)) {
16055 if let Some(ref seed) = f.seed {
16056 self.generate_expression(seed)?;
16057 }
16058 }
16059 self.write(")");
16060 Ok(())
16061 }
16062
16063 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
16064 self.write_keyword("TRUNCATE");
16065 self.write("(");
16066 self.generate_expression(&f.this)?;
16067 if let Some(ref decimals) = f.decimals {
16068 self.write(", ");
16069 self.generate_expression(decimals)?;
16070 }
16071 self.write(")");
16072 Ok(())
16073 }
16074
16075 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
16078 self.write_keyword("DECODE");
16079 self.write("(");
16080 self.generate_expression(&f.this)?;
16081 for (search, result) in &f.search_results {
16082 self.write(", ");
16083 self.generate_expression(search)?;
16084 self.write(", ");
16085 self.generate_expression(result)?;
16086 }
16087 if let Some(ref default) = f.default {
16088 self.write(", ");
16089 self.generate_expression(default)?;
16090 }
16091 self.write(")");
16092 Ok(())
16093 }
16094
16095 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
16098 self.write_keyword(name);
16099 self.write("(");
16100 self.generate_expression(&f.this)?;
16101 self.write(", ");
16102 self.generate_expression(&f.format)?;
16103 self.write(")");
16104 Ok(())
16105 }
16106
16107 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
16108 self.write_keyword("FROM_UNIXTIME");
16109 self.write("(");
16110 self.generate_expression(&f.this)?;
16111 if let Some(ref format) = f.format {
16112 self.write(", ");
16113 self.generate_expression(format)?;
16114 }
16115 self.write(")");
16116 Ok(())
16117 }
16118
16119 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
16120 self.write_keyword("UNIX_TIMESTAMP");
16121 self.write("(");
16122 if let Some(ref expr) = f.this {
16123 self.generate_expression(expr)?;
16124 if let Some(ref format) = f.format {
16125 self.write(", ");
16126 self.generate_expression(format)?;
16127 }
16128 } else if matches!(
16129 self.config.dialect,
16130 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
16131 ) {
16132 self.write_keyword("CURRENT_TIMESTAMP");
16134 self.write("()");
16135 }
16136 self.write(")");
16137 Ok(())
16138 }
16139
16140 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
16141 self.write_keyword("MAKE_DATE");
16142 self.write("(");
16143 self.generate_expression(&f.year)?;
16144 self.write(", ");
16145 self.generate_expression(&f.month)?;
16146 self.write(", ");
16147 self.generate_expression(&f.day)?;
16148 self.write(")");
16149 Ok(())
16150 }
16151
16152 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
16153 self.write_keyword("MAKE_TIMESTAMP");
16154 self.write("(");
16155 self.generate_expression(&f.year)?;
16156 self.write(", ");
16157 self.generate_expression(&f.month)?;
16158 self.write(", ");
16159 self.generate_expression(&f.day)?;
16160 self.write(", ");
16161 self.generate_expression(&f.hour)?;
16162 self.write(", ");
16163 self.generate_expression(&f.minute)?;
16164 self.write(", ");
16165 self.generate_expression(&f.second)?;
16166 if let Some(ref tz) = f.timezone {
16167 self.write(", ");
16168 self.generate_expression(tz)?;
16169 }
16170 self.write(")");
16171 Ok(())
16172 }
16173
16174 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
16176 match expr {
16177 Expression::Struct(s) => {
16178 if s.fields.iter().all(|(name, _)| name.is_some()) {
16179 Some(s.fields.iter().map(|(name, _)| name.as_deref().unwrap_or("").to_string()).collect())
16180 } else {
16181 None
16182 }
16183 }
16184 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
16185 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
16187 Some(f.args.iter().filter_map(|a| {
16188 if let Expression::Alias(alias) = a {
16189 Some(alias.alias.name.clone())
16190 } else {
16191 None
16192 }
16193 }).collect())
16194 } else {
16195 None
16196 }
16197 }
16198 _ => None,
16199 }
16200 }
16201
16202 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
16204 match expr {
16205 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
16206 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
16207 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
16208 }
16209 _ => false,
16210 }
16211 }
16212
16213 fn struct_field_count(expr: &Expression) -> usize {
16215 match expr {
16216 Expression::Struct(s) => s.fields.len(),
16217 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => f.args.len(),
16218 _ => 0,
16219 }
16220 }
16221
16222 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
16224 match expr {
16225 Expression::Struct(s) => {
16226 let mut new_fields = Vec::with_capacity(s.fields.len());
16227 for (i, (name, value)) in s.fields.iter().enumerate() {
16228 if name.is_none() && i < field_names.len() {
16229 new_fields.push((Some(field_names[i].clone()), value.clone()));
16230 } else {
16231 new_fields.push((name.clone(), value.clone()));
16232 }
16233 }
16234 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
16235 }
16236 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
16237 let mut new_args = Vec::with_capacity(f.args.len());
16238 for (i, arg) in f.args.iter().enumerate() {
16239 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
16240 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
16242 this: arg.clone(),
16243 alias: crate::expressions::Identifier::new(field_names[i].clone()),
16244 column_aliases: Vec::new(),
16245 pre_alias_comments: Vec::new(),
16246 trailing_comments: Vec::new(),
16247 })));
16248 } else {
16249 new_args.push(arg.clone());
16250 }
16251 }
16252 Expression::Function(Box::new(crate::expressions::Function {
16253 name: f.name.clone(),
16254 args: new_args,
16255 distinct: f.distinct,
16256 trailing_comments: f.trailing_comments.clone(),
16257 use_bracket_syntax: f.use_bracket_syntax,
16258 no_parens: f.no_parens,
16259 quoted: f.quoted,
16260 }))
16261 }
16262 _ => expr.clone(),
16263 }
16264 }
16265
16266 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
16270 let first = match expressions.first() {
16271 Some(e) => e,
16272 None => return expressions.to_vec(),
16273 };
16274
16275 let field_names = match Self::extract_struct_field_names(first) {
16276 Some(names) if !names.is_empty() => names,
16277 _ => return expressions.to_vec(),
16278 };
16279
16280 let mut result = Vec::with_capacity(expressions.len());
16281 for (idx, expr) in expressions.iter().enumerate() {
16282 if idx == 0 {
16283 result.push(expr.clone());
16284 continue;
16285 }
16286 if Self::struct_field_count(expr) == field_names.len() && Self::struct_has_unnamed_fields(expr) {
16288 result.push(Self::apply_struct_field_names(expr, &field_names));
16289 } else {
16290 result.push(expr.clone());
16291 }
16292 }
16293 result
16294 }
16295
16296 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
16299 let needs_inheritance = matches!(self.config.dialect,
16302 Some(DialectType::DuckDB) | Some(DialectType::Spark)
16303 | Some(DialectType::Databricks) | Some(DialectType::Hive)
16304 | Some(DialectType::Snowflake) | Some(DialectType::Presto) | Some(DialectType::Trino)
16305 );
16306 let propagated: Vec<Expression>;
16307 let expressions = if needs_inheritance && f.expressions.len() > 1 {
16308 propagated = Self::inherit_struct_field_names(&f.expressions);
16309 &propagated
16310 } else {
16311 &f.expressions
16312 };
16313
16314 let should_split = if self.config.pretty && !expressions.is_empty() {
16316 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
16317 for expr in expressions {
16318 let mut temp_gen = Generator::with_config(self.config.clone());
16319 temp_gen.config.pretty = false;
16320 temp_gen.generate_expression(expr)?;
16321 expr_strings.push(temp_gen.output);
16322 }
16323 self.too_wide(&expr_strings)
16324 } else {
16325 false
16326 };
16327
16328 if f.bracket_notation {
16329 let (open, close) = match self.config.dialect {
16333 Some(DialectType::Spark) | Some(DialectType::Databricks)
16334 | Some(DialectType::Hive) => {
16335 self.write_keyword("ARRAY");
16336 ("(", ")")
16337 }
16338 Some(DialectType::Presto) | Some(DialectType::Trino)
16339 | Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
16340 | Some(DialectType::Materialize) | Some(DialectType::RisingWave)
16341 | Some(DialectType::CockroachDB) => {
16342 self.write_keyword("ARRAY");
16343 ("[", "]")
16344 }
16345 _ => ("[", "]"),
16346 };
16347 self.write(open);
16348 if should_split {
16349 self.write_newline();
16350 self.indent_level += 1;
16351 for (i, expr) in expressions.iter().enumerate() {
16352 self.write_indent();
16353 self.generate_expression(expr)?;
16354 if i + 1 < expressions.len() {
16355 self.write(",");
16356 }
16357 self.write_newline();
16358 }
16359 self.indent_level -= 1;
16360 self.write_indent();
16361 } else {
16362 for (i, expr) in expressions.iter().enumerate() {
16363 if i > 0 { self.write(", "); }
16364 self.generate_expression(expr)?;
16365 }
16366 }
16367 self.write(close);
16368 } else {
16369 if f.use_list_keyword {
16371 self.write_keyword("LIST");
16372 } else {
16373 self.write_keyword("ARRAY");
16374 }
16375 let (open, close) = if matches!(self.config.dialect,
16377 Some(DialectType::Spark)
16378 | Some(DialectType::Databricks) | Some(DialectType::Hive)) {
16379 ("(", ")")
16380 } else {
16381 ("[", "]")
16382 };
16383 self.write(open);
16384 if should_split {
16385 self.write_newline();
16386 self.indent_level += 1;
16387 for (i, expr) in expressions.iter().enumerate() {
16388 self.write_indent();
16389 self.generate_expression(expr)?;
16390 if i + 1 < expressions.len() {
16391 self.write(",");
16392 }
16393 self.write_newline();
16394 }
16395 self.indent_level -= 1;
16396 self.write_indent();
16397 } else {
16398 for (i, expr) in expressions.iter().enumerate() {
16399 if i > 0 { self.write(", "); }
16400 self.generate_expression(expr)?;
16401 }
16402 }
16403 self.write(close);
16404 }
16405 Ok(())
16406 }
16407
16408 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
16409 self.write_keyword("ARRAY_SORT");
16410 self.write("(");
16411 self.generate_expression(&f.this)?;
16412 if let Some(ref comp) = f.comparator {
16413 self.write(", ");
16414 self.generate_expression(comp)?;
16415 }
16416 self.write(")");
16417 Ok(())
16418 }
16419
16420 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
16421 self.write_keyword(name);
16422 self.write("(");
16423 self.generate_expression(&f.this)?;
16424 self.write(", ");
16425 self.generate_expression(&f.separator)?;
16426 if let Some(ref null_rep) = f.null_replacement {
16427 self.write(", ");
16428 self.generate_expression(null_rep)?;
16429 }
16430 self.write(")");
16431 Ok(())
16432 }
16433
16434 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
16435 self.write_keyword("UNNEST");
16436 self.write("(");
16437 self.generate_expression(&f.this)?;
16438 for extra in &f.expressions {
16439 self.write(", ");
16440 self.generate_expression(extra)?;
16441 }
16442 self.write(")");
16443 if f.with_ordinality {
16444 self.write_space();
16445 if self.config.unnest_with_ordinality {
16446 self.write_keyword("WITH ORDINALITY");
16448 } else if f.offset_alias.is_some() {
16449 if let Some(ref alias) = f.alias {
16452 self.write_keyword("AS");
16453 self.write_space();
16454 self.generate_identifier(alias)?;
16455 self.write_space();
16456 }
16457 self.write_keyword("WITH OFFSET");
16458 if let Some(ref offset_alias) = f.offset_alias {
16459 self.write_space();
16460 self.write_keyword("AS");
16461 self.write_space();
16462 self.generate_identifier(offset_alias)?;
16463 }
16464 } else {
16465 self.write_keyword("WITH OFFSET");
16467 if f.alias.is_none() {
16468 self.write(" AS offset");
16469 }
16470 }
16471 }
16472 if let Some(ref alias) = f.alias {
16473 let should_add_alias = if !f.with_ordinality {
16475 true
16476 } else if self.config.unnest_with_ordinality {
16477 true
16479 } else if f.offset_alias.is_some() {
16480 false
16482 } else {
16483 true
16485 };
16486 if should_add_alias {
16487 self.write_space();
16488 self.write_keyword("AS");
16489 self.write_space();
16490 self.generate_identifier(alias)?;
16491 }
16492 }
16493 Ok(())
16494 }
16495
16496 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
16497 self.write_keyword("FILTER");
16498 self.write("(");
16499 self.generate_expression(&f.this)?;
16500 self.write(", ");
16501 self.generate_expression(&f.filter)?;
16502 self.write(")");
16503 Ok(())
16504 }
16505
16506 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
16507 self.write_keyword("TRANSFORM");
16508 self.write("(");
16509 self.generate_expression(&f.this)?;
16510 self.write(", ");
16511 self.generate_expression(&f.transform)?;
16512 self.write(")");
16513 Ok(())
16514 }
16515
16516 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
16517 self.write_keyword(name);
16518 self.write("(");
16519 self.generate_expression(&f.start)?;
16520 self.write(", ");
16521 self.generate_expression(&f.stop)?;
16522 if let Some(ref step) = f.step {
16523 self.write(", ");
16524 self.generate_expression(step)?;
16525 }
16526 self.write(")");
16527 Ok(())
16528 }
16529
16530 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
16533 self.write_keyword("STRUCT");
16534 self.write("(");
16535 for (i, (name, expr)) in f.fields.iter().enumerate() {
16536 if i > 0 { self.write(", "); }
16537 if let Some(ref id) = name {
16538 self.generate_identifier(id)?;
16539 self.write(" ");
16540 self.write_keyword("AS");
16541 self.write(" ");
16542 }
16543 self.generate_expression(expr)?;
16544 }
16545 self.write(")");
16546 Ok(())
16547 }
16548
16549 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
16551 let mut names: Vec<Option<String>> = Vec::new();
16554 let mut values: Vec<&Expression> = Vec::new();
16555 let mut all_named = true;
16556
16557 for arg in &func.args {
16558 match arg {
16559 Expression::Alias(a) => {
16560 names.push(Some(a.alias.name.clone()));
16561 values.push(&a.this);
16562 }
16563 _ => {
16564 names.push(None);
16565 values.push(arg);
16566 all_named = false;
16567 }
16568 }
16569 }
16570
16571 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
16572 self.write("{");
16574 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
16575 if i > 0 { self.write(", "); }
16576 if let Some(n) = name {
16577 self.write("'");
16578 self.write(n);
16579 self.write("'");
16580 } else {
16581 self.write("'_");
16582 self.write(&i.to_string());
16583 self.write("'");
16584 }
16585 self.write(": ");
16586 self.generate_expression(value)?;
16587 }
16588 self.write("}");
16589 return Ok(());
16590 }
16591
16592 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
16593 self.write_keyword("OBJECT_CONSTRUCT");
16595 self.write("(");
16596 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
16597 if i > 0 { self.write(", "); }
16598 if let Some(n) = name {
16599 self.write("'");
16600 self.write(n);
16601 self.write("'");
16602 } else {
16603 self.write("'_");
16604 self.write(&i.to_string());
16605 self.write("'");
16606 }
16607 self.write(", ");
16608 self.generate_expression(value)?;
16609 }
16610 self.write(")");
16611 return Ok(());
16612 }
16613
16614 if matches!(self.config.dialect, Some(DialectType::Presto) | Some(DialectType::Trino)) {
16615 if all_named && !names.is_empty() {
16616 self.write_keyword("CAST");
16619 self.write("(");
16620 self.write_keyword("ROW");
16621 self.write("(");
16622 for (i, value) in values.iter().enumerate() {
16623 if i > 0 { self.write(", "); }
16624 self.generate_expression(value)?;
16625 }
16626 self.write(")");
16627 self.write(" ");
16628 self.write_keyword("AS");
16629 self.write(" ");
16630 self.write_keyword("ROW");
16631 self.write("(");
16632 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
16633 if i > 0 { self.write(", "); }
16634 if let Some(n) = name {
16635 self.write(n);
16636 }
16637 self.write(" ");
16638 let type_str = Self::infer_sql_type_for_presto(value);
16639 self.write_keyword(&type_str);
16640 }
16641 self.write(")");
16642 self.write(")");
16643 } else {
16644 self.write_keyword("ROW");
16646 self.write("(");
16647 for (i, value) in values.iter().enumerate() {
16648 if i > 0 { self.write(", "); }
16649 self.generate_expression(value)?;
16650 }
16651 self.write(")");
16652 }
16653 return Ok(());
16654 }
16655
16656 self.write_keyword("ROW");
16658 self.write("(");
16659 for (i, value) in values.iter().enumerate() {
16660 if i > 0 { self.write(", "); }
16661 self.generate_expression(value)?;
16662 }
16663 self.write(")");
16664 Ok(())
16665 }
16666
16667 fn infer_sql_type_for_presto(expr: &Expression) -> String {
16669 match expr {
16670 Expression::Literal(crate::expressions::Literal::String(_)) => "VARCHAR".to_string(),
16671 Expression::Literal(crate::expressions::Literal::Number(n)) => {
16672 if n.contains('.') { "DOUBLE".to_string() } else { "INTEGER".to_string() }
16673 }
16674 Expression::Boolean(_) => "BOOLEAN".to_string(),
16675 Expression::Literal(crate::expressions::Literal::Date(_)) => "DATE".to_string(),
16676 Expression::Literal(crate::expressions::Literal::Timestamp(_)) => "TIMESTAMP".to_string(),
16677 Expression::Literal(crate::expressions::Literal::Datetime(_)) => "TIMESTAMP".to_string(),
16678 Expression::Array(_) | Expression::ArrayFunc(_) => {
16679 "ARRAY(VARCHAR)".to_string()
16681 }
16682 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
16684 Expression::Function(f) => {
16685 let up = f.name.to_uppercase();
16686 if up == "STRUCT" { "ROW".to_string() }
16687 else if up == "CURRENT_DATE" { "DATE".to_string() }
16688 else if up == "CURRENT_TIMESTAMP" || up == "NOW" { "TIMESTAMP".to_string() }
16689 else { "VARCHAR".to_string() }
16690 }
16691 _ => "VARCHAR".to_string(),
16692 }
16693 }
16694
16695 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
16696 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
16698 self.write_keyword("STRUCT_EXTRACT");
16699 self.write("(");
16700 self.generate_expression(&f.this)?;
16701 self.write(", ");
16702 self.write("'");
16704 self.write(&f.field.name);
16705 self.write("'");
16706 self.write(")");
16707 return Ok(());
16708 }
16709 self.generate_expression(&f.this)?;
16710 self.write(".");
16711 self.generate_identifier(&f.field)
16712 }
16713
16714 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
16715 self.write_keyword("NAMED_STRUCT");
16716 self.write("(");
16717 for (i, (name, value)) in f.pairs.iter().enumerate() {
16718 if i > 0 { self.write(", "); }
16719 self.generate_expression(name)?;
16720 self.write(", ");
16721 self.generate_expression(value)?;
16722 }
16723 self.write(")");
16724 Ok(())
16725 }
16726
16727 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
16730 if f.curly_brace_syntax {
16731 if f.with_map_keyword {
16733 self.write_keyword("MAP");
16734 self.write(" ");
16735 }
16736 self.write("{");
16737 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
16738 if i > 0 { self.write(", "); }
16739 self.generate_expression(key)?;
16740 self.write(": ");
16741 self.generate_expression(val)?;
16742 }
16743 self.write("}");
16744 } else {
16745 self.write_keyword("MAP");
16747 self.write("(");
16748 self.write_keyword("ARRAY");
16749 self.write("[");
16750 for (i, key) in f.keys.iter().enumerate() {
16751 if i > 0 { self.write(", "); }
16752 self.generate_expression(key)?;
16753 }
16754 self.write("], ");
16755 self.write_keyword("ARRAY");
16756 self.write("[");
16757 for (i, val) in f.values.iter().enumerate() {
16758 if i > 0 { self.write(", "); }
16759 self.generate_expression(val)?;
16760 }
16761 self.write("])");
16762 }
16763 Ok(())
16764 }
16765
16766 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
16767 self.write_keyword(name);
16768 self.write("(");
16769 self.generate_expression(&f.this)?;
16770 self.write(", ");
16771 self.generate_expression(&f.transform)?;
16772 self.write(")");
16773 Ok(())
16774 }
16775
16776 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
16779 use crate::dialects::DialectType;
16780
16781 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
16783
16784 if use_arrow {
16785 self.generate_expression(&f.this)?;
16787 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
16788 self.write(" ->> ");
16789 } else {
16790 self.write(" -> ");
16791 }
16792 self.generate_expression(&f.path)?;
16793 return Ok(());
16794 }
16795
16796 if f.hash_arrow_syntax && matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) {
16798 self.generate_expression(&f.this)?;
16799 self.write(" #>> ");
16800 self.generate_expression(&f.path)?;
16801 return Ok(());
16802 }
16803
16804 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
16807 match name {
16808 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" | "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
16809 _ => name,
16810 }
16811 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
16812 match name {
16813 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
16814 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
16815 _ => name,
16816 }
16817 } else {
16818 name
16819 };
16820
16821 self.write_keyword(func_name);
16822 self.write("(");
16823 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
16825 if let Expression::Cast(ref cast) = f.this {
16826 if matches!(cast.to, crate::expressions::DataType::Json) {
16827 self.generate_expression(&cast.this)?;
16828 } else {
16829 self.generate_expression(&f.this)?;
16830 }
16831 } else {
16832 self.generate_expression(&f.this)?;
16833 }
16834 } else {
16835 self.generate_expression(&f.this)?;
16836 }
16837 self.write(", ");
16838 self.generate_expression(&f.path)?;
16839
16840 if let Some(ref wrapper) = f.wrapper_option {
16843 self.write_space();
16844 self.write_keyword(wrapper);
16845 }
16846 if let Some(ref quotes) = f.quotes_option {
16847 self.write_space();
16848 self.write_keyword(quotes);
16849 if f.on_scalar_string {
16850 self.write_space();
16851 self.write_keyword("ON SCALAR STRING");
16852 }
16853 }
16854 if let Some(ref on_err) = f.on_error {
16855 self.write_space();
16856 self.write_keyword(on_err);
16857 }
16858 if let Some(ref ret_type) = f.returning {
16859 self.write_space();
16860 self.write_keyword("RETURNING");
16861 self.write_space();
16862 self.generate_data_type(ret_type)?;
16863 }
16864
16865 self.write(")");
16866 Ok(())
16867 }
16868
16869 fn dialect_supports_json_arrow(&self) -> bool {
16871 use crate::dialects::DialectType;
16872 match self.config.dialect {
16873 Some(DialectType::PostgreSQL) => true,
16875 Some(DialectType::MySQL) => true,
16876 Some(DialectType::DuckDB) => true,
16877 Some(DialectType::CockroachDB) => true,
16878 Some(DialectType::StarRocks) => true,
16879 Some(DialectType::SQLite) => true,
16880 _ => false,
16882 }
16883 }
16884
16885 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
16886 use crate::dialects::DialectType;
16887
16888 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) && name == "JSON_EXTRACT_PATH" {
16890 self.generate_expression(&f.this)?;
16891 self.write(" #> ");
16892 if f.paths.len() == 1 {
16893 self.generate_expression(&f.paths[0])?;
16894 } else {
16895 self.write_keyword("ARRAY");
16897 self.write("[");
16898 for (i, path) in f.paths.iter().enumerate() {
16899 if i > 0 { self.write(", "); }
16900 self.generate_expression(path)?;
16901 }
16902 self.write("]");
16903 }
16904 return Ok(());
16905 }
16906
16907 self.write_keyword(name);
16908 self.write("(");
16909 self.generate_expression(&f.this)?;
16910 for path in &f.paths {
16911 self.write(", ");
16912 self.generate_expression(path)?;
16913 }
16914 self.write(")");
16915 Ok(())
16916 }
16917
16918 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
16919 use crate::dialects::DialectType;
16920
16921 self.write_keyword("JSON_OBJECT");
16922 self.write("(");
16923 if f.star {
16924 self.write("*");
16925 } else {
16926 let use_comma_syntax = self.config.json_key_value_pair_sep == "," ||
16930 matches!(self.config.dialect, Some(DialectType::BigQuery) | Some(DialectType::MySQL) | Some(DialectType::SQLite));
16931
16932 for (i, (key, value)) in f.pairs.iter().enumerate() {
16933 if i > 0 { self.write(", "); }
16934 self.generate_expression(key)?;
16935 if use_comma_syntax {
16936 self.write(", ");
16937 } else {
16938 self.write(": ");
16939 }
16940 self.generate_expression(value)?;
16941 }
16942 }
16943 if let Some(null_handling) = f.null_handling {
16944 self.write_space();
16945 match null_handling {
16946 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
16947 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
16948 }
16949 }
16950 if f.with_unique_keys {
16951 self.write_space();
16952 self.write_keyword("WITH UNIQUE KEYS");
16953 }
16954 if let Some(ref ret_type) = f.returning_type {
16955 self.write_space();
16956 self.write_keyword("RETURNING");
16957 self.write_space();
16958 self.generate_data_type(ret_type)?;
16959 if f.format_json {
16960 self.write_space();
16961 self.write_keyword("FORMAT JSON");
16962 }
16963 if let Some(ref enc) = f.encoding {
16964 self.write_space();
16965 self.write_keyword("ENCODING");
16966 self.write_space();
16967 self.write(enc);
16968 }
16969 }
16970 self.write(")");
16971 Ok(())
16972 }
16973
16974 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
16975 self.write_keyword(name);
16976 self.write("(");
16977 self.generate_expression(&f.this)?;
16978 for (path, value) in &f.path_values {
16979 self.write(", ");
16980 self.generate_expression(path)?;
16981 self.write(", ");
16982 self.generate_expression(value)?;
16983 }
16984 self.write(")");
16985 Ok(())
16986 }
16987
16988 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
16989 self.write_keyword("JSON_ARRAYAGG");
16990 self.write("(");
16991 self.generate_expression(&f.this)?;
16992 if let Some(ref order_by) = f.order_by {
16993 self.write_space();
16994 self.write_keyword("ORDER BY");
16995 self.write_space();
16996 for (i, ord) in order_by.iter().enumerate() {
16997 if i > 0 { self.write(", "); }
16998 self.generate_ordered(ord)?;
16999 }
17000 }
17001 if let Some(null_handling) = f.null_handling {
17002 self.write_space();
17003 match null_handling {
17004 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
17005 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
17006 }
17007 }
17008 self.write(")");
17009 if let Some(ref filter) = f.filter {
17010 self.write_space();
17011 self.write_keyword("FILTER");
17012 self.write("(");
17013 self.write_keyword("WHERE");
17014 self.write_space();
17015 self.generate_expression(filter)?;
17016 self.write(")");
17017 }
17018 Ok(())
17019 }
17020
17021 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
17022 self.write_keyword("JSON_OBJECTAGG");
17023 self.write("(");
17024 self.generate_expression(&f.key)?;
17025 self.write(": ");
17026 self.generate_expression(&f.value)?;
17027 if let Some(null_handling) = f.null_handling {
17028 self.write_space();
17029 match null_handling {
17030 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
17031 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
17032 }
17033 }
17034 self.write(")");
17035 if let Some(ref filter) = f.filter {
17036 self.write_space();
17037 self.write_keyword("FILTER");
17038 self.write("(");
17039 self.write_keyword("WHERE");
17040 self.write_space();
17041 self.generate_expression(filter)?;
17042 self.write(")");
17043 }
17044 Ok(())
17045 }
17046
17047 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
17050 use crate::dialects::DialectType;
17051
17052 if self.config.dialect == Some(DialectType::Redshift) {
17054 self.write_keyword("CAST");
17055 self.write("(");
17056 self.generate_expression(&f.this)?;
17057 self.write_space();
17058 self.write_keyword("AS");
17059 self.write_space();
17060 self.generate_data_type(&f.to)?;
17061 self.write(")");
17062 return Ok(());
17063 }
17064
17065 self.write_keyword("CONVERT");
17066 self.write("(");
17067 self.generate_data_type(&f.to)?;
17068 self.write(", ");
17069 self.generate_expression(&f.this)?;
17070 if let Some(ref style) = f.style {
17071 self.write(", ");
17072 self.generate_expression(style)?;
17073 }
17074 self.write(")");
17075 Ok(())
17076 }
17077
17078 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
17081 if f.colon {
17082 self.write_keyword("LAMBDA");
17084 self.write_space();
17085 for (i, param) in f.parameters.iter().enumerate() {
17086 if i > 0 { self.write(", "); }
17087 self.generate_identifier(param)?;
17088 }
17089 self.write(" : ");
17090 } else {
17091 if f.parameters.len() == 1 {
17093 self.generate_identifier(&f.parameters[0])?;
17094 } else {
17095 self.write("(");
17096 for (i, param) in f.parameters.iter().enumerate() {
17097 if i > 0 { self.write(", "); }
17098 self.generate_identifier(param)?;
17099 }
17100 self.write(")");
17101 }
17102 self.write(" -> ");
17103 }
17104 self.generate_expression(&f.body)
17105 }
17106
17107 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
17108 self.generate_identifier(&f.name)?;
17109 match f.separator {
17110 NamedArgSeparator::DArrow => self.write(" => "),
17111 NamedArgSeparator::ColonEq => self.write(" := "),
17112 NamedArgSeparator::Eq => self.write(" = "),
17113 }
17114 self.generate_expression(&f.value)
17115 }
17116
17117 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
17118 self.write_keyword(&f.prefix);
17119 self.write(" ");
17120 self.generate_expression(&f.this)
17121 }
17122
17123 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
17124 match f.style {
17125 ParameterStyle::Question => self.write("?"),
17126 ParameterStyle::Dollar => {
17127 self.write("$");
17128 if let Some(idx) = f.index {
17129 self.write(&idx.to_string());
17130 } else if let Some(ref name) = f.name {
17131 self.write(name);
17133 }
17134 }
17135 ParameterStyle::DollarBrace => {
17136 self.write("${");
17138 if let Some(ref name) = f.name {
17139 self.write(name);
17140 }
17141 if let Some(ref expr) = f.expression {
17142 self.write(":");
17143 self.write(expr);
17144 }
17145 self.write("}");
17146 }
17147 ParameterStyle::Colon => {
17148 self.write(":");
17149 if let Some(idx) = f.index {
17150 self.write(&idx.to_string());
17151 } else if let Some(ref name) = f.name {
17152 self.write(name);
17153 }
17154 }
17155 ParameterStyle::At => {
17156 self.write("@");
17157 if let Some(ref name) = f.name {
17158 if f.quoted {
17159 self.write("\"");
17160 self.write(name);
17161 self.write("\"");
17162 } else {
17163 self.write(name);
17164 }
17165 }
17166 }
17167 ParameterStyle::DoubleAt => {
17168 self.write("@@");
17169 if let Some(ref name) = f.name {
17170 self.write(name);
17171 }
17172 }
17173 ParameterStyle::DoubleDollar => {
17174 self.write("$$");
17175 if let Some(ref name) = f.name {
17176 self.write(name);
17177 }
17178 }
17179 ParameterStyle::Percent => {
17180 if let Some(ref name) = f.name {
17181 self.write("%(");
17183 self.write(name);
17184 self.write(")s");
17185 } else {
17186 self.write("%s");
17188 }
17189 }
17190 ParameterStyle::Brace => {
17191 self.write("{");
17194 if let Some(ref name) = f.name {
17195 self.write(name);
17196 }
17197 if let Some(ref expr) = f.expression {
17198 self.write(": ");
17199 self.write(expr);
17200 }
17201 self.write("}");
17202 }
17203 }
17204 Ok(())
17205 }
17206
17207 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
17208 self.write("?");
17209 if let Some(idx) = f.index {
17210 self.write(&idx.to_string());
17211 }
17212 Ok(())
17213 }
17214
17215 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
17216 if f.is_block {
17217 self.write("/*");
17218 self.write(&f.text);
17219 self.write("*/");
17220 } else {
17221 self.write("--");
17222 self.write(&f.text);
17223 }
17224 Ok(())
17225 }
17226
17227 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
17230 self.generate_expression(&f.this)?;
17231 if f.not {
17232 self.write_space();
17233 self.write_keyword("NOT");
17234 }
17235 self.write_space();
17236 self.write_keyword("SIMILAR TO");
17237 self.write_space();
17238 self.generate_expression(&f.pattern)?;
17239 if let Some(ref escape) = f.escape {
17240 self.write_space();
17241 self.write_keyword("ESCAPE");
17242 self.write_space();
17243 self.generate_expression(escape)?;
17244 }
17245 Ok(())
17246 }
17247
17248 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
17249 self.generate_expression(&f.this)?;
17250 self.write_space();
17251 if let Some(op) = &f.op {
17253 match op {
17254 QuantifiedOp::Eq => self.write("="),
17255 QuantifiedOp::Neq => self.write("<>"),
17256 QuantifiedOp::Lt => self.write("<"),
17257 QuantifiedOp::Lte => self.write("<="),
17258 QuantifiedOp::Gt => self.write(">"),
17259 QuantifiedOp::Gte => self.write(">="),
17260 }
17261 self.write_space();
17262 }
17263 self.write_keyword(name);
17264 if self.config.quantified_no_paren_space {
17265 self.write("(");
17266 } else {
17267 self.write(" (");
17268 }
17269 self.generate_expression(&f.subquery)?;
17270 self.write(")");
17271 Ok(())
17272 }
17273
17274 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
17275 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
17277 self.generate_expression(this)?;
17278 self.write_space();
17279 self.write_keyword("OVERLAPS");
17280 self.write_space();
17281 self.generate_expression(expr)?;
17282 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
17283 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
17284 {
17285 self.write("(");
17287 self.generate_expression(ls)?;
17288 self.write(", ");
17289 self.generate_expression(le)?;
17290 self.write(")");
17291 self.write_space();
17292 self.write_keyword("OVERLAPS");
17293 self.write_space();
17294 self.write("(");
17295 self.generate_expression(rs)?;
17296 self.write(", ");
17297 self.generate_expression(re)?;
17298 self.write(")");
17299 }
17300 Ok(())
17301 }
17302
17303 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
17306 use crate::dialects::DialectType;
17307
17308 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
17310 self.generate_expression(&cast.this)?;
17311 self.write(" !:> ");
17312 self.generate_data_type(&cast.to)?;
17313 return Ok(());
17314 }
17315
17316 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
17318 self.write_keyword("TRYCAST");
17319 self.write("(");
17320 self.generate_expression(&cast.this)?;
17321 self.write_space();
17322 self.write_keyword("AS");
17323 self.write_space();
17324 self.generate_data_type(&cast.to)?;
17325 self.write(")");
17326 return Ok(());
17327 }
17328
17329 let keyword = if matches!(self.config.dialect,
17331 Some(DialectType::Hive)
17332 | Some(DialectType::MySQL) | Some(DialectType::SQLite) | Some(DialectType::Oracle)
17333 | Some(DialectType::ClickHouse)
17334 | Some(DialectType::Redshift) | Some(DialectType::PostgreSQL)
17335 | Some(DialectType::StarRocks) | Some(DialectType::Doris)
17336 ) {
17337 "CAST"
17338 } else {
17339 "TRY_CAST"
17340 };
17341
17342 self.write_keyword(keyword);
17343 self.write("(");
17344 self.generate_expression(&cast.this)?;
17345 self.write_space();
17346 self.write_keyword("AS");
17347 self.write_space();
17348 self.generate_data_type(&cast.to)?;
17349
17350 if let Some(format) = &cast.format {
17352 self.write_space();
17353 self.write_keyword("FORMAT");
17354 self.write_space();
17355 self.generate_expression(format)?;
17356 }
17357
17358 self.write(")");
17359 Ok(())
17360 }
17361
17362 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
17363 self.write_keyword("SAFE_CAST");
17364 self.write("(");
17365 self.generate_expression(&cast.this)?;
17366 self.write_space();
17367 self.write_keyword("AS");
17368 self.write_space();
17369 self.generate_data_type(&cast.to)?;
17370
17371 if let Some(format) = &cast.format {
17373 self.write_space();
17374 self.write_keyword("FORMAT");
17375 self.write_space();
17376 self.generate_expression(format)?;
17377 }
17378
17379 self.write(")");
17380 Ok(())
17381 }
17382
17383 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
17386 self.generate_expression(&s.this)?;
17387 self.write("[");
17388 self.generate_expression(&s.index)?;
17389 self.write("]");
17390 Ok(())
17391 }
17392
17393 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
17394 self.generate_expression(&d.this)?;
17395 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
17398 && matches!(&d.this, Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_));
17399 if use_colon {
17400 self.write(":");
17401 } else {
17402 self.write(".");
17403 }
17404 self.generate_identifier(&d.field)
17405 }
17406
17407 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
17408 self.generate_expression(&m.this)?;
17409 self.write(".");
17410 if m.method.quoted {
17413 let q = self.config.identifier_quote;
17414 self.write(&format!("{}{}{}", q, m.method.name, q));
17415 } else {
17416 self.write(&m.method.name);
17417 }
17418 self.write("(");
17419 for (i, arg) in m.args.iter().enumerate() {
17420 if i > 0 {
17421 self.write(", ");
17422 }
17423 self.generate_expression(arg)?;
17424 }
17425 self.write(")");
17426 Ok(())
17427 }
17428
17429 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
17430 let needs_parens = matches!(
17433 &s.this,
17434 Expression::JsonExtract(f) if f.arrow_syntax
17435 ) || matches!(
17436 &s.this,
17437 Expression::JsonExtractScalar(f) if f.arrow_syntax
17438 );
17439
17440 if needs_parens {
17441 self.write("(");
17442 }
17443 self.generate_expression(&s.this)?;
17444 if needs_parens {
17445 self.write(")");
17446 }
17447 self.write("[");
17448 if let Some(start) = &s.start {
17449 self.generate_expression(start)?;
17450 }
17451 self.write(":");
17452 if let Some(end) = &s.end {
17453 self.generate_expression(end)?;
17454 }
17455 self.write("]");
17456 Ok(())
17457 }
17458
17459
17460 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
17461 match &op.left {
17465 Expression::Column(col) => {
17466 if let Some(table) = &col.table {
17468 self.generate_identifier(table)?;
17469 self.write(".");
17470 }
17471 self.generate_identifier(&col.name)?;
17472 if col.join_mark && self.config.supports_column_join_marks {
17474 self.write(" (+)");
17475 }
17476 }
17477 Expression::Add(inner_op) | Expression::Sub(inner_op) |
17478 Expression::Mul(inner_op) | Expression::Div(inner_op) |
17479 Expression::Concat(inner_op) => {
17480 self.generate_binary_op_no_trailing(inner_op, match &op.left {
17482 Expression::Add(_) => "+",
17483 Expression::Sub(_) => "-",
17484 Expression::Mul(_) => "*",
17485 Expression::Div(_) => "/",
17486 Expression::Concat(_) => "||",
17487 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
17488 })?;
17489 }
17490 _ => {
17491 self.generate_expression(&op.left)?;
17492 }
17493 }
17494 for comment in &op.left_comments {
17496 self.write_space();
17497 self.write(comment);
17498 }
17499 if self.config.pretty
17500 && matches!(self.config.dialect, Some(DialectType::Snowflake))
17501 && (operator == "AND" || operator == "OR")
17502 {
17503 self.write_newline();
17504 self.write_indent();
17505 self.write_keyword(operator);
17506 } else {
17507 self.write_space();
17508 if operator.chars().all(|c| c.is_alphabetic()) {
17509 self.write_keyword(operator);
17510 } else {
17511 self.write(operator);
17512 }
17513 }
17514 for comment in &op.operator_comments {
17516 self.write_space();
17517 self.write(comment);
17518 }
17519 self.write_space();
17520 self.generate_expression(&op.right)?;
17521 for comment in &op.trailing_comments {
17523 self.write_space();
17524 self.write(comment);
17525 }
17526 Ok(())
17527 }
17528
17529 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
17531 self.generate_expression(&op.left)?;
17532 self.write_space();
17533 self.write_keyword(operator);
17534 if let Some(quantifier) = &op.quantifier {
17535 self.write_space();
17536 self.write_keyword(quantifier);
17537 }
17538 self.write_space();
17539 self.generate_expression(&op.right)?;
17540 if let Some(escape) = &op.escape {
17541 self.write_space();
17542 self.write_keyword("ESCAPE");
17543 self.write_space();
17544 self.generate_expression(escape)?;
17545 }
17546 Ok(())
17547 }
17548
17549 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
17552 use crate::dialects::DialectType;
17553 self.generate_expression(&op.left)?;
17554 self.write_space();
17555 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
17556 self.write("<=>");
17557 } else {
17558 self.write_keyword("IS NOT DISTINCT FROM");
17559 }
17560 self.write_space();
17561 self.generate_expression(&op.right)?;
17562 Ok(())
17563 }
17564
17565 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
17567 self.generate_expression(&op.left)?;
17568 self.write_space();
17569 self.write_keyword("IS DISTINCT FROM");
17570 self.write_space();
17571 self.generate_expression(&op.right)?;
17572 Ok(())
17573 }
17574
17575 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
17577 match &op.left {
17579 Expression::Column(col) => {
17580 if let Some(table) = &col.table {
17581 self.generate_identifier(table)?;
17582 self.write(".");
17583 }
17584 self.generate_identifier(&col.name)?;
17585 if col.join_mark && self.config.supports_column_join_marks {
17587 self.write(" (+)");
17588 }
17589 }
17590 Expression::Add(inner_op) | Expression::Sub(inner_op) |
17591 Expression::Mul(inner_op) | Expression::Div(inner_op) |
17592 Expression::Concat(inner_op) => {
17593 self.generate_binary_op_no_trailing(inner_op, match &op.left {
17594 Expression::Add(_) => "+",
17595 Expression::Sub(_) => "-",
17596 Expression::Mul(_) => "*",
17597 Expression::Div(_) => "/",
17598 Expression::Concat(_) => "||",
17599 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
17600 })?;
17601 }
17602 _ => {
17603 self.generate_expression(&op.left)?;
17604 }
17605 }
17606 for comment in &op.left_comments {
17608 self.write_space();
17609 self.write(comment);
17610 }
17611 self.write_space();
17612 if operator.chars().all(|c| c.is_alphabetic()) {
17613 self.write_keyword(operator);
17614 } else {
17615 self.write(operator);
17616 }
17617 for comment in &op.operator_comments {
17619 self.write_space();
17620 self.write(comment);
17621 }
17622 self.write_space();
17623 match &op.right {
17626 Expression::Column(col) => {
17627 if let Some(table) = &col.table {
17628 self.generate_identifier(table)?;
17629 self.write(".");
17630 }
17631 self.generate_identifier(&col.name)?;
17632 if col.join_mark && self.config.supports_column_join_marks {
17634 self.write(" (+)");
17635 }
17636 }
17637 _ => {
17638 self.generate_expression(&op.right)?;
17639 }
17640 }
17641 Ok(())
17643 }
17644
17645 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
17646 if operator.chars().all(|c| c.is_alphabetic()) {
17647 self.write_keyword(operator);
17648 self.write_space();
17649 } else {
17650 self.write(operator);
17651 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
17653 self.write_space();
17654 }
17655 }
17656 self.generate_expression(&op.this)
17657 }
17658
17659 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
17660 self.generate_expression(&in_expr.this)?;
17661 if in_expr.global {
17662 self.write_space();
17663 self.write_keyword("GLOBAL");
17664 }
17665 if in_expr.not {
17666 self.write_space();
17667 self.write_keyword("NOT");
17668 }
17669 self.write_space();
17670 self.write_keyword("IN");
17671
17672 if let Some(unnest_expr) = &in_expr.unnest {
17674 self.write_space();
17675 self.write_keyword("UNNEST");
17676 self.write("(");
17677 self.generate_expression(unnest_expr)?;
17678 self.write(")");
17679 return Ok(());
17680 }
17681
17682 if let Some(query) = &in_expr.query {
17683 let is_bare = in_expr.expressions.is_empty() && !matches!(
17686 query,
17687 Expression::Select(_) | Expression::Union(_) |
17688 Expression::Intersect(_) | Expression::Except(_) |
17689 Expression::Subquery(_)
17690 );
17691 if is_bare {
17692 self.write_space();
17694 self.generate_expression(query)?;
17695 } else {
17696 self.write(" (");
17698 let is_statement = matches!(
17699 query,
17700 Expression::Select(_) | Expression::Union(_) |
17701 Expression::Intersect(_) | Expression::Except(_) |
17702 Expression::Subquery(_)
17703 );
17704 if self.config.pretty && is_statement {
17705 self.write_newline();
17706 self.indent_level += 1;
17707 self.write_indent();
17708 }
17709 self.generate_expression(query)?;
17710 if self.config.pretty && is_statement {
17711 self.write_newline();
17712 self.indent_level -= 1;
17713 self.write_indent();
17714 }
17715 self.write(")");
17716 }
17717 } else {
17718 let is_duckdb = matches!(self.config.dialect, Some(crate::dialects::DialectType::DuckDB));
17722 let is_clickhouse = matches!(self.config.dialect, Some(crate::dialects::DialectType::ClickHouse));
17723 let single_expr = in_expr.expressions.len() == 1;
17724 if is_clickhouse && single_expr {
17725 if let Expression::Array(arr) = &in_expr.expressions[0] {
17726 self.write(" (");
17728 for (i, expr) in arr.expressions.iter().enumerate() {
17729 if i > 0 {
17730 self.write(", ");
17731 }
17732 self.generate_expression(expr)?;
17733 }
17734 self.write(")");
17735 } else {
17736 self.write_space();
17737 self.generate_expression(&in_expr.expressions[0])?;
17738 }
17739 } else {
17740 let is_bare_ref = single_expr && matches!(
17741 &in_expr.expressions[0],
17742 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
17743 );
17744 if is_duckdb && is_bare_ref {
17745 self.write_space();
17746 self.generate_expression(&in_expr.expressions[0])?;
17747 } else {
17748 self.write(" (");
17750 for (i, expr) in in_expr.expressions.iter().enumerate() {
17751 if i > 0 {
17752 self.write(", ");
17753 }
17754 self.generate_expression(expr)?;
17755 }
17756 self.write(")");
17757 }
17758 }
17759 }
17760
17761 Ok(())
17762 }
17763
17764 fn generate_between(&mut self, between: &Between) -> Result<()> {
17765 self.generate_expression(&between.this)?;
17766 if between.not {
17767 self.write_space();
17768 self.write_keyword("NOT");
17769 }
17770 self.write_space();
17771 self.write_keyword("BETWEEN");
17772 self.write_space();
17773 self.generate_expression(&between.low)?;
17774 self.write_space();
17775 self.write_keyword("AND");
17776 self.write_space();
17777 self.generate_expression(&between.high)
17778 }
17779
17780 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
17781 if is_null.not && is_null.postfix_form {
17783 self.write_keyword("NOT");
17785 self.write_space();
17786 self.generate_expression(&is_null.this)?;
17787 self.write_space();
17788 self.write_keyword("IS");
17789 self.write_space();
17790 self.write_keyword("NULL");
17791 } else {
17792 self.generate_expression(&is_null.this)?;
17793 self.write_space();
17794 self.write_keyword("IS");
17795 if is_null.not {
17796 self.write_space();
17797 self.write_keyword("NOT");
17798 }
17799 self.write_space();
17800 self.write_keyword("NULL");
17801 }
17802 Ok(())
17803 }
17804
17805 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
17806 self.generate_expression(&is_true.this)?;
17807 self.write_space();
17808 self.write_keyword("IS");
17809 if is_true.not {
17810 self.write_space();
17811 self.write_keyword("NOT");
17812 }
17813 self.write_space();
17814 self.write_keyword("TRUE");
17815 Ok(())
17816 }
17817
17818 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
17819 self.generate_expression(&is_false.this)?;
17820 self.write_space();
17821 self.write_keyword("IS");
17822 if is_false.not {
17823 self.write_space();
17824 self.write_keyword("NOT");
17825 }
17826 self.write_space();
17827 self.write_keyword("FALSE");
17828 Ok(())
17829 }
17830
17831 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
17832 self.generate_expression(&is_json.this)?;
17833 self.write_space();
17834 self.write_keyword("IS");
17835 if is_json.negated {
17836 self.write_space();
17837 self.write_keyword("NOT");
17838 }
17839 self.write_space();
17840 self.write_keyword("JSON");
17841
17842 if let Some(ref json_type) = is_json.json_type {
17844 self.write_space();
17845 self.write_keyword(json_type);
17846 }
17847
17848 match &is_json.unique_keys {
17850 Some(JsonUniqueKeys::With) => {
17851 self.write_space();
17852 self.write_keyword("WITH UNIQUE KEYS");
17853 }
17854 Some(JsonUniqueKeys::Without) => {
17855 self.write_space();
17856 self.write_keyword("WITHOUT UNIQUE KEYS");
17857 }
17858 Some(JsonUniqueKeys::Shorthand) => {
17859 self.write_space();
17860 self.write_keyword("UNIQUE KEYS");
17861 }
17862 None => {}
17863 }
17864
17865 Ok(())
17866 }
17867
17868 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
17869 self.generate_expression(&is_expr.left)?;
17870 self.write_space();
17871 self.write_keyword("IS");
17872 self.write_space();
17873 self.generate_expression(&is_expr.right)
17874 }
17875
17876 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
17877 if exists.not {
17878 self.write_keyword("NOT");
17879 self.write_space();
17880 }
17881 self.write_keyword("EXISTS");
17882 self.write("(");
17883 self.generate_expression(&exists.this)?;
17884 self.write(")");
17885 Ok(())
17886 }
17887
17888 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
17889 self.generate_expression(&op.left)?;
17890 self.write_space();
17891 self.write_keyword("MEMBER OF");
17892 self.write("(");
17893 self.generate_expression(&op.right)?;
17894 self.write(")");
17895 Ok(())
17896 }
17897
17898 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
17899 if subquery.lateral {
17900 self.write_keyword("LATERAL");
17901 self.write_space();
17902 }
17903
17904 let skip_outer_parens = matches!(&subquery.this, Expression::Paren(_));
17908
17909 let is_statement = matches!(
17911 &subquery.this,
17912 Expression::Select(_) | Expression::Union(_) |
17913 Expression::Intersect(_) | Expression::Except(_) |
17914 Expression::Merge(_)
17915 );
17916
17917 if !skip_outer_parens {
17918 self.write("(");
17919 if self.config.pretty && is_statement {
17920 self.write_newline();
17921 self.indent_level += 1;
17922 self.write_indent();
17923 }
17924 }
17925 self.generate_expression(&subquery.this)?;
17926
17927 if subquery.modifiers_inside {
17929 if let Some(order_by) = &subquery.order_by {
17931 self.write_space();
17932 self.write_keyword("ORDER BY");
17933 self.write_space();
17934 for (i, ord) in order_by.expressions.iter().enumerate() {
17935 if i > 0 {
17936 self.write(", ");
17937 }
17938 self.generate_ordered(ord)?;
17939 }
17940 }
17941
17942 if let Some(limit) = &subquery.limit {
17943 self.write_space();
17944 self.write_keyword("LIMIT");
17945 self.write_space();
17946 self.generate_expression(&limit.this)?;
17947 if limit.percent {
17948 self.write_space();
17949 self.write_keyword("PERCENT");
17950 }
17951 }
17952
17953 if let Some(offset) = &subquery.offset {
17954 self.write_space();
17955 self.write_keyword("OFFSET");
17956 self.write_space();
17957 self.generate_expression(&offset.this)?;
17958 }
17959 }
17960
17961 if !skip_outer_parens {
17962 if self.config.pretty && is_statement {
17963 self.write_newline();
17964 self.indent_level -= 1;
17965 self.write_indent();
17966 }
17967 self.write(")");
17968 }
17969
17970 if !subquery.modifiers_inside {
17972 if let Some(order_by) = &subquery.order_by {
17973 self.write_space();
17974 self.write_keyword("ORDER BY");
17975 self.write_space();
17976 for (i, ord) in order_by.expressions.iter().enumerate() {
17977 if i > 0 {
17978 self.write(", ");
17979 }
17980 self.generate_ordered(ord)?;
17981 }
17982 }
17983
17984 if let Some(limit) = &subquery.limit {
17985 self.write_space();
17986 self.write_keyword("LIMIT");
17987 self.write_space();
17988 self.generate_expression(&limit.this)?;
17989 if limit.percent {
17990 self.write_space();
17991 self.write_keyword("PERCENT");
17992 }
17993 }
17994
17995 if let Some(offset) = &subquery.offset {
17996 self.write_space();
17997 self.write_keyword("OFFSET");
17998 self.write_space();
17999 self.generate_expression(&offset.this)?;
18000 }
18001
18002 if let Some(distribute_by) = &subquery.distribute_by {
18004 self.write_space();
18005 self.write_keyword("DISTRIBUTE BY");
18006 self.write_space();
18007 for (i, expr) in distribute_by.expressions.iter().enumerate() {
18008 if i > 0 {
18009 self.write(", ");
18010 }
18011 self.generate_expression(expr)?;
18012 }
18013 }
18014
18015 if let Some(sort_by) = &subquery.sort_by {
18017 self.write_space();
18018 self.write_keyword("SORT BY");
18019 self.write_space();
18020 for (i, ord) in sort_by.expressions.iter().enumerate() {
18021 if i > 0 {
18022 self.write(", ");
18023 }
18024 self.generate_ordered(ord)?;
18025 }
18026 }
18027
18028 if let Some(cluster_by) = &subquery.cluster_by {
18030 self.write_space();
18031 self.write_keyword("CLUSTER BY");
18032 self.write_space();
18033 for (i, ord) in cluster_by.expressions.iter().enumerate() {
18034 if i > 0 {
18035 self.write(", ");
18036 }
18037 self.generate_ordered(ord)?;
18038 }
18039 }
18040 }
18041
18042 if let Some(alias) = &subquery.alias {
18043 self.write_space();
18044 let skip_as = matches!(self.config.dialect, Some(crate::dialects::DialectType::Oracle));
18046 if !skip_as {
18047 self.write_keyword("AS");
18048 self.write_space();
18049 }
18050 self.generate_identifier(alias)?;
18051 if !subquery.column_aliases.is_empty() {
18052 self.write("(");
18053 for (i, col) in subquery.column_aliases.iter().enumerate() {
18054 if i > 0 {
18055 self.write(", ");
18056 }
18057 self.generate_identifier(col)?;
18058 }
18059 self.write(")");
18060 }
18061 }
18062 for comment in &subquery.trailing_comments {
18064 self.write(" ");
18065 self.write(comment);
18066 }
18067 Ok(())
18068 }
18069
18070 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
18071 if let Some(ref with) = pivot.with {
18073 self.generate_with(with)?;
18074 self.write_space();
18075 }
18076
18077 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
18078
18079 let is_redshift_unpivot = pivot.unpivot
18083 && pivot.expressions.is_empty()
18084 && pivot.fields.is_empty()
18085 && pivot.using.is_empty()
18086 && pivot.into.is_none()
18087 && !matches!(&pivot.this, Expression::Null(_));
18088
18089 if is_redshift_unpivot {
18090 self.write_keyword("UNPIVOT");
18092 self.write_space();
18093 self.generate_expression(&pivot.this)?;
18094 if let Some(alias) = &pivot.alias {
18096 self.write_space();
18097 self.write_keyword("AS");
18098 self.write_space();
18099 self.write(&alias.name);
18101 }
18102 return Ok(());
18103 }
18104
18105 let is_simplified = !pivot.using.is_empty() || pivot.into.is_some()
18107 || (pivot.fields.is_empty() && !pivot.expressions.is_empty()
18108 && !matches!(&pivot.this, Expression::Null(_)));
18109
18110 if is_simplified {
18111 self.write_keyword(direction);
18115 self.write_space();
18116 self.generate_expression(&pivot.this)?;
18117
18118 if !pivot.expressions.is_empty() {
18119 self.write_space();
18120 self.write_keyword("ON");
18121 self.write_space();
18122 for (i, expr) in pivot.expressions.iter().enumerate() {
18123 if i > 0 {
18124 self.write(", ");
18125 }
18126 self.generate_expression(expr)?;
18127 }
18128 }
18129
18130 if let Some(into) = &pivot.into {
18132 self.write_space();
18133 self.write_keyword("INTO");
18134 self.write_space();
18135 self.generate_expression(into)?;
18136 }
18137
18138 if !pivot.using.is_empty() {
18140 self.write_space();
18141 self.write_keyword("USING");
18142 self.write_space();
18143 for (i, expr) in pivot.using.iter().enumerate() {
18144 if i > 0 {
18145 self.write(", ");
18146 }
18147 self.generate_expression(expr)?;
18148 }
18149 }
18150
18151 if let Some(group) = &pivot.group {
18153 self.write_space();
18154 self.generate_expression(group)?;
18155 }
18156 } else {
18157 if !matches!(&pivot.this, Expression::Null(_)) {
18162 self.generate_expression(&pivot.this)?;
18163 self.write_space();
18164 }
18165 self.write_keyword(direction);
18166 self.write("(");
18167
18168 for (i, expr) in pivot.expressions.iter().enumerate() {
18170 if i > 0 {
18171 self.write(", ");
18172 }
18173 self.generate_expression(expr)?;
18174 }
18175
18176 if !pivot.fields.is_empty() {
18178 if !pivot.expressions.is_empty() {
18179 self.write_space();
18180 }
18181 self.write_keyword("FOR");
18182 self.write_space();
18183 for (i, field) in pivot.fields.iter().enumerate() {
18184 if i > 0 {
18185 self.write_space();
18186 }
18187 self.generate_expression(field)?;
18189 }
18190 }
18191
18192 if let Some(default_val) = &pivot.default_on_null {
18194 self.write_space();
18195 self.write_keyword("DEFAULT ON NULL");
18196 self.write(" (");
18197 self.generate_expression(default_val)?;
18198 self.write(")");
18199 }
18200
18201 if let Some(group) = &pivot.group {
18203 self.write_space();
18204 self.generate_expression(group)?;
18205 }
18206
18207 self.write(")");
18208 }
18209
18210 if let Some(alias) = &pivot.alias {
18212 self.write_space();
18213 self.write_keyword("AS");
18214 self.write_space();
18215 self.generate_identifier(alias)?;
18216 }
18217
18218 Ok(())
18219 }
18220
18221 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
18222 self.generate_expression(&unpivot.this)?;
18223 self.write_space();
18224 self.write_keyword("UNPIVOT");
18225 if let Some(include) = unpivot.include_nulls {
18227 self.write_space();
18228 if include {
18229 self.write_keyword("INCLUDE NULLS");
18230 } else {
18231 self.write_keyword("EXCLUDE NULLS");
18232 }
18233 self.write_space();
18234 }
18235 self.write("(");
18236 if unpivot.value_column_parenthesized {
18237 self.write("(");
18238 }
18239 self.generate_identifier(&unpivot.value_column)?;
18240 for extra_col in &unpivot.extra_value_columns {
18242 self.write(", ");
18243 self.generate_identifier(extra_col)?;
18244 }
18245 if unpivot.value_column_parenthesized {
18246 self.write(")");
18247 }
18248 self.write_space();
18249 self.write_keyword("FOR");
18250 self.write_space();
18251 self.generate_identifier(&unpivot.name_column)?;
18252 self.write_space();
18253 self.write_keyword("IN");
18254 self.write(" (");
18255 for (i, col) in unpivot.columns.iter().enumerate() {
18256 if i > 0 {
18257 self.write(", ");
18258 }
18259 self.generate_expression(col)?;
18260 }
18261 self.write("))");
18262 if let Some(alias) = &unpivot.alias {
18263 self.write_space();
18264 self.write_keyword("AS");
18265 self.write_space();
18266 self.generate_identifier(alias)?;
18267 }
18268 Ok(())
18269 }
18270
18271 fn generate_values(&mut self, values: &Values) -> Result<()> {
18272 self.write_keyword("VALUES");
18273 for (i, row) in values.expressions.iter().enumerate() {
18274 if i > 0 {
18275 self.write(",");
18276 }
18277 self.write(" (");
18278 for (j, expr) in row.expressions.iter().enumerate() {
18279 if j > 0 {
18280 self.write(", ");
18281 }
18282 self.generate_expression(expr)?;
18283 }
18284 self.write(")");
18285 }
18286 if let Some(alias) = &values.alias {
18287 self.write_space();
18288 self.write_keyword("AS");
18289 self.write_space();
18290 self.generate_identifier(alias)?;
18291 if !values.column_aliases.is_empty() {
18292 self.write("(");
18293 for (i, col) in values.column_aliases.iter().enumerate() {
18294 if i > 0 {
18295 self.write(", ");
18296 }
18297 self.generate_identifier(col)?;
18298 }
18299 self.write(")");
18300 }
18301 }
18302 Ok(())
18303 }
18304
18305 fn generate_array(&mut self, arr: &Array) -> Result<()> {
18306 let needs_inheritance = matches!(self.config.dialect,
18308 Some(DialectType::DuckDB) | Some(DialectType::Spark)
18309 | Some(DialectType::Databricks) | Some(DialectType::Hive)
18310 | Some(DialectType::Snowflake) | Some(DialectType::Presto) | Some(DialectType::Trino)
18311 );
18312 let propagated: Vec<Expression>;
18313 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
18314 propagated = Self::inherit_struct_field_names(&arr.expressions);
18315 &propagated
18316 } else {
18317 &arr.expressions
18318 };
18319
18320 if !self.config.array_bracket_only {
18321 self.write_keyword("ARRAY");
18322 }
18323 self.write("[");
18324 for (i, expr) in expressions.iter().enumerate() {
18325 if i > 0 {
18326 self.write(", ");
18327 }
18328 self.generate_expression(expr)?;
18329 }
18330 self.write("]");
18331 Ok(())
18332 }
18333
18334 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
18335 if tuple.expressions.len() == 2 {
18338 if let Expression::TableAlias(_) = &tuple.expressions[1] {
18339 self.generate_expression(&tuple.expressions[0])?;
18341 self.write_space();
18342 self.write_keyword("AS");
18343 self.write_space();
18344 self.generate_expression(&tuple.expressions[1])?;
18345 return Ok(());
18346 }
18347 }
18348
18349 if self.config.pretty && tuple.expressions.len() > 1 {
18351 self.write("(");
18352 self.write_newline();
18353 self.indent_level += 1;
18354 for (i, expr) in tuple.expressions.iter().enumerate() {
18355 if i > 0 {
18356 self.write(",");
18357 self.write_newline();
18358 }
18359 self.write_indent();
18360 self.generate_expression(expr)?;
18361 }
18362 self.indent_level -= 1;
18363 self.write_newline();
18364 self.write(")");
18365 } else {
18366 self.write("(");
18367 for (i, expr) in tuple.expressions.iter().enumerate() {
18368 if i > 0 {
18369 self.write(", ");
18370 }
18371 self.generate_expression(expr)?;
18372 }
18373 self.write(")");
18374 }
18375 Ok(())
18376 }
18377
18378 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
18379 self.generate_expression(&ordered.this)?;
18380 if ordered.desc {
18381 self.write_space();
18382 self.write_keyword("DESC");
18383 } else if ordered.explicit_asc {
18384 self.write_space();
18385 self.write_keyword("ASC");
18386 }
18387 if let Some(nulls_first) = ordered.nulls_first {
18388 let is_asc = !ordered.desc;
18402 let is_nulls_are_large = matches!(
18403 self.config.dialect,
18404 Some(DialectType::Oracle) | Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
18405 | Some(DialectType::Snowflake)
18406 );
18407 let is_nulls_are_last = matches!(
18408 self.config.dialect,
18409 Some(DialectType::Dremio) | Some(DialectType::DuckDB) | Some(DialectType::Presto)
18410 | Some(DialectType::Trino) | Some(DialectType::Athena) | Some(DialectType::ClickHouse)
18411 | Some(DialectType::Drill) | Some(DialectType::Exasol)
18412 );
18413
18414 let is_default_nulls = if is_nulls_are_large {
18416 (is_asc && !nulls_first) || (!is_asc && nulls_first)
18418 } else if is_nulls_are_last {
18419 !nulls_first
18421 } else {
18422 false
18423 };
18424
18425 if !is_default_nulls {
18426 self.write_space();
18427 self.write_keyword("NULLS");
18428 self.write_space();
18429 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
18430 }
18431 }
18432 if let Some(ref with_fill) = ordered.with_fill {
18434 self.write_space();
18435 self.generate_with_fill(with_fill)?;
18436 }
18437 Ok(())
18438 }
18439
18440 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
18441 use crate::dialects::DialectType;
18442
18443 match dt {
18444 DataType::Boolean => {
18445 match self.config.dialect {
18447 Some(DialectType::TSQL) => self.write_keyword("BIT"),
18448 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
18450 self.write_keyword("NUMBER(1)")
18452 }
18453 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
18455 }
18456 }
18457 DataType::TinyInt { length } => {
18458 match self.config.dialect {
18461 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) | Some(DialectType::Oracle) | Some(DialectType::Exasol) => {
18462 self.write_keyword("SMALLINT");
18463 }
18464 Some(DialectType::Teradata) => {
18465 self.write_keyword("BYTEINT");
18467 }
18468 Some(DialectType::Dremio) => {
18469 self.write_keyword("INT");
18471 }
18472 _ => {
18473 self.write_keyword("TINYINT");
18474 }
18475 }
18476 if let Some(n) = length {
18477 if !matches!(self.config.dialect, Some(DialectType::Dremio)) {
18478 self.write(&format!("({})", n));
18479 }
18480 }
18481 }
18482 DataType::SmallInt { length } => {
18483 match self.config.dialect {
18485 Some(DialectType::Dremio) => {
18486 self.write_keyword("INT");
18487 }
18488 Some(DialectType::SQLite) => {
18489 self.write_keyword("INTEGER");
18490 }
18491 _ => {
18492 self.write_keyword("SMALLINT");
18493 if let Some(n) = length {
18494 self.write(&format!("({})", n));
18495 }
18496 }
18497 }
18498 }
18499 DataType::Int { length, integer_spelling } => {
18500 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
18502 self.write_keyword("INT64");
18503 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
18504 self.write("Int32");
18505 } else {
18506 let use_integer = match self.config.dialect {
18508 Some(DialectType::TSQL) | Some(DialectType::Fabric)
18509 | Some(DialectType::Presto) | Some(DialectType::Trino)
18510 | Some(DialectType::SQLite) | Some(DialectType::Redshift) => true,
18511 Some(DialectType::Databricks) => *integer_spelling,
18513 _ => false,
18514 };
18515 if use_integer {
18516 self.write_keyword("INTEGER");
18517 } else {
18518 self.write_keyword("INT");
18519 }
18520 if let Some(n) = length {
18521 self.write(&format!("({})", n));
18522 }
18523 }
18524 }
18525 DataType::BigInt { length } => {
18526 match self.config.dialect {
18528 Some(DialectType::Oracle) => {
18529 self.write_keyword("NUMBER(19)");
18531 }
18532 _ => {
18533 self.write_keyword("BIGINT");
18534 if let Some(n) = length {
18535 self.write(&format!("({})", n));
18536 }
18537 }
18538 }
18539 }
18540 DataType::Float { precision, scale, real_spelling } => {
18541 if *real_spelling && !matches!(self.config.dialect, Some(DialectType::Spark)
18545 | Some(DialectType::Databricks) | Some(DialectType::Hive)
18546 | Some(DialectType::Snowflake) | Some(DialectType::MySQL)
18547 | Some(DialectType::BigQuery)) {
18548 self.write_keyword("REAL")
18549 } else {
18550 match self.config.dialect {
18551 Some(DialectType::PostgreSQL) => {
18552 self.write_keyword("REAL")
18553 }
18554 Some(DialectType::BigQuery) => {
18555 self.write_keyword("FLOAT64")
18556 }
18557 _ => self.write_keyword("FLOAT"),
18558 }
18559 }
18560 if !matches!(self.config.dialect, Some(DialectType::Spark)
18563 | Some(DialectType::Databricks) | Some(DialectType::Hive)
18564 | Some(DialectType::Presto) | Some(DialectType::Trino)) {
18565 if let Some(p) = precision {
18566 self.write(&format!("({}", p));
18567 if let Some(s) = scale {
18568 self.write(&format!(", {})", s));
18569 } else {
18570 self.write(")");
18571 }
18572 }
18573 }
18574 }
18575 DataType::Double { precision, scale } => {
18576 match self.config.dialect {
18578 Some(DialectType::TSQL) | Some(DialectType::Fabric) => self.write_keyword("FLOAT"), Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
18580 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) | Some(DialectType::Teradata) => {
18581 self.write_keyword("DOUBLE PRECISION")
18582 }
18583 _ => self.write_keyword("DOUBLE"),
18584 }
18585 if let Some(p) = precision {
18587 self.write(&format!("({}", p));
18588 if let Some(s) = scale {
18589 self.write(&format!(", {})", s));
18590 } else {
18591 self.write(")");
18592 }
18593 }
18594 }
18595 DataType::Decimal { precision, scale } => {
18596 match self.config.dialect {
18598 Some(DialectType::ClickHouse) => {
18599 self.write("Decimal");
18600 if let Some(p) = precision {
18601 self.write(&format!("({}", p));
18602 if let Some(s) = scale {
18603 self.write(&format!(", {}", s));
18604 }
18605 self.write(")");
18606 }
18607 }
18608 Some(DialectType::Oracle) => {
18609 self.write_keyword("NUMBER");
18611 if let Some(p) = precision {
18612 self.write(&format!("({}", p));
18613 if let Some(s) = scale {
18614 self.write(&format!(", {}", s));
18615 }
18616 self.write(")");
18617 }
18618 }
18619 Some(DialectType::BigQuery) => {
18620 self.write_keyword("NUMERIC");
18622 if let Some(p) = precision {
18623 self.write(&format!("({}", p));
18624 if let Some(s) = scale {
18625 self.write(&format!(", {}", s));
18626 }
18627 self.write(")");
18628 }
18629 }
18630 _ => {
18631 self.write_keyword("DECIMAL");
18632 if let Some(p) = precision {
18633 self.write(&format!("({}", p));
18634 if let Some(s) = scale {
18635 self.write(&format!(", {}", s));
18636 }
18637 self.write(")");
18638 }
18639 }
18640 }
18641 }
18642 DataType::Char { length } => {
18643 match self.config.dialect {
18645 Some(DialectType::DuckDB) => {
18646 self.write_keyword("TEXT");
18648 }
18649 Some(DialectType::Dremio) => {
18650 self.write_keyword("VARCHAR");
18652 if let Some(n) = length {
18653 self.write(&format!("({})", n));
18654 }
18655 }
18656 _ => {
18657 self.write_keyword("CHAR");
18658 if let Some(n) = length {
18659 self.write(&format!("({})", n));
18660 }
18661 }
18662 }
18663 }
18664 DataType::VarChar { length, parenthesized_length } => {
18665 match self.config.dialect {
18667 Some(DialectType::Oracle) => {
18668 self.write_keyword("VARCHAR2");
18669 if let Some(n) = length {
18670 self.write(&format!("({})", n));
18671 }
18672 }
18673 Some(DialectType::DuckDB) => {
18674 self.write_keyword("TEXT");
18676 }
18677 Some(DialectType::SQLite) => {
18678 self.write_keyword("TEXT");
18680 if let Some(n) = length {
18681 self.write(&format!("({})", n));
18682 }
18683 }
18684 Some(DialectType::MySQL) if length.is_none() => {
18685 self.write_keyword("TEXT");
18687 }
18688 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) if length.is_none() => {
18689 self.write_keyword("STRING");
18691 }
18692 _ => {
18693 self.write_keyword("VARCHAR");
18694 if let Some(n) = length {
18695 if *parenthesized_length {
18697 self.write(&format!("(({}))", n));
18698 } else {
18699 self.write(&format!("({})", n));
18700 }
18701 }
18702 }
18703 }
18704 }
18705 DataType::Text => {
18706 match self.config.dialect {
18708 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
18709 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
18710 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
18711 Some(DialectType::Snowflake) | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
18712 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
18713 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
18714 Some(DialectType::Spark) | Some(DialectType::Databricks)
18715 | Some(DialectType::Hive) => self.write_keyword("STRING"),
18716 Some(DialectType::Redshift) => self.write_keyword("VARCHAR"),
18717 Some(DialectType::StarRocks) => self.write_keyword("STRING"),
18718 _ => self.write_keyword("TEXT"),
18719 }
18720 }
18721 DataType::String { length } => {
18722 match self.config.dialect {
18724 Some(DialectType::ClickHouse) => {
18725 self.write("String");
18727 if let Some(n) = length {
18728 self.write(&format!("({})", n));
18729 }
18730 }
18731 Some(DialectType::BigQuery) => {
18732 self.write_keyword("STRING");
18733 if let Some(n) = length {
18734 self.write(&format!("({})", n));
18735 }
18736 }
18737 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
18738 if let Some(n) = length {
18740 self.write_keyword("VARCHAR");
18741 self.write(&format!("({})", n));
18742 } else {
18743 self.write_keyword("TEXT");
18744 }
18745 }
18746 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
18747 if let Some(n) = length {
18749 self.write_keyword("VARCHAR");
18750 self.write(&format!("({})", n));
18751 } else {
18752 self.write_keyword("TEXT");
18753 }
18754 }
18755 Some(DialectType::TSQL) => {
18756 if let Some(n) = length {
18758 self.write_keyword("VARCHAR");
18759 self.write(&format!("({})", n));
18760 } else {
18761 self.write_keyword("NVARCHAR(MAX)");
18762 }
18763 }
18764 Some(DialectType::DuckDB) => {
18765 self.write_keyword("TEXT");
18767 if let Some(n) = length {
18768 self.write(&format!("({})", n));
18769 }
18770 }
18771 Some(DialectType::Presto) | Some(DialectType::Trino) => {
18772 self.write_keyword("VARCHAR");
18774 if let Some(n) = length {
18775 self.write(&format!("({})", n));
18776 }
18777 }
18778 _ => {
18779 self.write_keyword("STRING");
18781 if let Some(n) = length {
18782 self.write(&format!("({})", n));
18783 }
18784 }
18785 }
18786 }
18787 DataType::Binary { length } => {
18788 match self.config.dialect {
18790 Some(DialectType::PostgreSQL) => {
18791 self.write_keyword("BYTEA");
18792 }
18793 Some(DialectType::Redshift) => {
18794 self.write_keyword("VARBYTE");
18795 }
18796 Some(DialectType::DuckDB) => {
18797 self.write_keyword("BLOB");
18799 }
18800 Some(DialectType::Dremio) => {
18801 self.write_keyword("VARBINARY");
18803 if let Some(n) = length {
18804 self.write(&format!("({})", n));
18805 }
18806 }
18807 _ => {
18808 self.write_keyword("BINARY");
18809 if let Some(n) = length {
18810 self.write(&format!("({})", n));
18811 }
18812 }
18813 }
18814 }
18815 DataType::VarBinary { length } => {
18816 match self.config.dialect {
18818 Some(DialectType::PostgreSQL) => {
18819 self.write_keyword("BYTEA");
18820 }
18821 Some(DialectType::Redshift) => {
18822 self.write_keyword("VARBYTE");
18823 if let Some(n) = length {
18824 self.write(&format!("({})", n));
18825 }
18826 }
18827 Some(DialectType::DuckDB) => {
18828 self.write_keyword("BLOB");
18830 }
18831 Some(DialectType::Exasol) => {
18832 self.write_keyword("VARCHAR");
18834 }
18835 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks) => {
18836 self.write_keyword("BINARY");
18838 }
18839 _ => {
18840 self.write_keyword("VARBINARY");
18841 if let Some(n) = length {
18842 self.write(&format!("({})", n));
18843 }
18844 }
18845 }
18846 }
18847 DataType::Blob => {
18848 match self.config.dialect {
18850 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
18851 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
18852 Some(DialectType::TSQL) | Some(DialectType::Fabric) => self.write_keyword("VARBINARY"),
18853 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
18854 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
18855 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
18856 Some(DialectType::DuckDB) => {
18857 self.write_keyword("VARBINARY");
18860 }
18861 Some(DialectType::Spark) | Some(DialectType::Databricks)
18862 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
18863 Some(DialectType::ClickHouse) => self.write("Nullable(String)"),
18864 _ => self.write_keyword("BLOB"),
18865 }
18866 }
18867 DataType::Bit { length } => {
18868 match self.config.dialect {
18870 Some(DialectType::Dremio) | Some(DialectType::Spark)
18871 | Some(DialectType::Databricks) | Some(DialectType::Hive)
18872 | Some(DialectType::Snowflake) | Some(DialectType::BigQuery)
18873 | Some(DialectType::Presto) | Some(DialectType::Trino)
18874 | Some(DialectType::ClickHouse) | Some(DialectType::Redshift) => {
18875 self.write_keyword("BOOLEAN");
18877 }
18878 _ => {
18879 self.write_keyword("BIT");
18880 if let Some(n) = length {
18881 self.write(&format!("({})", n));
18882 }
18883 }
18884 }
18885 }
18886 DataType::VarBit { length } => {
18887 self.write_keyword("VARBIT");
18888 if let Some(n) = length {
18889 self.write(&format!("({})", n));
18890 }
18891 }
18892 DataType::Date => self.write_keyword("DATE"),
18893 DataType::Time { precision, timezone } => {
18894 if *timezone {
18895 match self.config.dialect {
18897 Some(DialectType::DuckDB) => {
18898 self.write_keyword("TIMETZ");
18900 }
18901 Some(DialectType::PostgreSQL) => {
18902 self.write_keyword("TIMETZ");
18904 if let Some(p) = precision {
18905 self.write(&format!("({})", p));
18906 }
18907 }
18908 _ => {
18909 self.write_keyword("TIME");
18911 if let Some(p) = precision {
18912 self.write(&format!("({})", p));
18913 }
18914 self.write_keyword(" WITH TIME ZONE");
18915 }
18916 }
18917 } else {
18918 if matches!(self.config.dialect, Some(DialectType::Spark)
18920 | Some(DialectType::Databricks) | Some(DialectType::Hive)) {
18921 self.write_keyword("TIMESTAMP");
18922 } else {
18923 self.write_keyword("TIME");
18924 if let Some(p) = precision {
18925 self.write(&format!("({})", p));
18926 }
18927 }
18928 }
18929 }
18930 DataType::Timestamp { precision, timezone } => {
18931 match self.config.dialect {
18933 Some(DialectType::ClickHouse) => {
18934 self.write("DateTime");
18935 if let Some(p) = precision {
18936 self.write(&format!("({})", p));
18937 }
18938 }
18939 Some(DialectType::TSQL) => {
18940 if *timezone {
18941 self.write_keyword("DATETIMEOFFSET");
18942 } else {
18943 self.write_keyword("DATETIME2");
18944 }
18945 if let Some(p) = precision {
18946 self.write(&format!("({})", p));
18947 }
18948 }
18949 Some(DialectType::MySQL) => {
18950 self.write_keyword("TIMESTAMP");
18953 if let Some(p) = precision {
18954 self.write(&format!("({})", p));
18955 }
18956 }
18957 Some(DialectType::BigQuery) => {
18958 if *timezone {
18960 self.write_keyword("TIMESTAMP");
18961 } else {
18962 self.write_keyword("DATETIME");
18963 }
18964 }
18965 Some(DialectType::DuckDB) => {
18966 if *timezone {
18968 self.write_keyword("TIMESTAMPTZ");
18969 } else {
18970 self.write_keyword("TIMESTAMP");
18971 if let Some(p) = precision {
18972 self.write(&format!("({})", p));
18973 }
18974 }
18975 }
18976 _ => {
18977 if *timezone && !self.config.tz_to_with_time_zone {
18978 self.write_keyword("TIMESTAMPTZ");
18980 if let Some(p) = precision {
18981 self.write(&format!("({})", p));
18982 }
18983 } else {
18984 self.write_keyword("TIMESTAMP");
18985 if let Some(p) = precision {
18986 self.write(&format!("({})", p));
18987 }
18988 if *timezone {
18989 self.write_space();
18990 self.write_keyword("WITH TIME ZONE");
18991 }
18992 }
18993 }
18994 }
18995 }
18996 DataType::Interval { unit, to } => {
18997 self.write_keyword("INTERVAL");
18998 if let Some(u) = unit {
18999 self.write_space();
19000 self.write_keyword(u);
19001 }
19002 if let Some(t) = to {
19004 self.write_space();
19005 self.write_keyword("TO");
19006 self.write_space();
19007 self.write_keyword(t);
19008 }
19009 }
19010 DataType::Json => {
19011 match self.config.dialect {
19013 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
19016 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
19017 _ => self.write_keyword("JSON"),
19018 }
19019 }
19020 DataType::JsonB => {
19021 match self.config.dialect {
19023 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
19024 Some(DialectType::Doris) => self.write_keyword("JSONB"),
19025 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
19026 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
19027 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
19030 }
19031 DataType::Uuid => {
19032 match self.config.dialect {
19034 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
19035 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
19036 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
19037 Some(DialectType::BigQuery) | Some(DialectType::Spark) | Some(DialectType::Databricks) => self.write_keyword("STRING"),
19038 _ => self.write_keyword("UUID"),
19039 }
19040 }
19041 DataType::Array { element_type, dimension } => {
19042 match self.config.dialect {
19044 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) | Some(DialectType::DuckDB) => {
19045 self.generate_data_type(element_type)?;
19047 if let Some(dim) = dimension {
19048 self.write(&format!("[{}]", dim));
19049 } else {
19050 self.write("[]");
19051 }
19052 }
19053 Some(DialectType::BigQuery) => {
19054 self.write_keyword("ARRAY<");
19055 self.generate_data_type(element_type)?;
19056 self.write(">");
19057 }
19058 Some(DialectType::Snowflake) | Some(DialectType::Presto) | Some(DialectType::Trino)
19059 | Some(DialectType::ClickHouse) => {
19060 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
19062 self.write("Array(");
19063 } else {
19064 self.write_keyword("ARRAY(");
19065 }
19066 self.generate_data_type(element_type)?;
19067 self.write(")");
19068 }
19069 Some(DialectType::TSQL) | Some(DialectType::MySQL) | Some(DialectType::Oracle) => {
19070 match self.config.dialect {
19073 Some(DialectType::MySQL) => self.write_keyword("JSON"),
19074 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
19075 _ => self.write_keyword("JSON"),
19076 }
19077 }
19078 _ => {
19079 self.write_keyword("ARRAY<");
19081 self.generate_data_type(element_type)?;
19082 self.write(">");
19083 }
19084 }
19085 }
19086 DataType::List { element_type } => {
19087 self.generate_data_type(element_type)?;
19089 self.write_keyword(" LIST");
19090 }
19091 DataType::Map { key_type, value_type } => {
19092 match self.config.dialect {
19094 Some(DialectType::Materialize) => {
19095 self.write_keyword("MAP[");
19097 self.generate_data_type(key_type)?;
19098 self.write(" => ");
19099 self.generate_data_type(value_type)?;
19100 self.write("]");
19101 }
19102 Some(DialectType::Snowflake) | Some(DialectType::RisingWave) | Some(DialectType::DuckDB)
19103 | Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
19104 self.write_keyword("MAP(");
19105 self.generate_data_type(key_type)?;
19106 self.write(", ");
19107 self.generate_data_type(value_type)?;
19108 self.write(")");
19109 }
19110 _ => {
19111 self.write_keyword("MAP<");
19112 self.generate_data_type(key_type)?;
19113 self.write(", ");
19114 self.generate_data_type(value_type)?;
19115 self.write(">");
19116 }
19117 }
19118 }
19119 DataType::Vector { element_type, dimension } => {
19120 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
19121 self.write_keyword("VECTOR(");
19123 if let Some(dim) = dimension {
19124 self.write(&dim.to_string());
19125 }
19126 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
19128 DataType::TinyInt { .. } => Some("I8"),
19129 DataType::SmallInt { .. } => Some("I16"),
19130 DataType::Int { .. } => Some("I32"),
19131 DataType::BigInt { .. } => Some("I64"),
19132 DataType::Float { .. } => Some("F32"),
19133 DataType::Double { .. } => Some("F64"),
19134 _ => None,
19135 });
19136 if let Some(alias) = type_alias {
19137 if dimension.is_some() {
19138 self.write(", ");
19139 }
19140 self.write(alias);
19141 }
19142 self.write(")");
19143 } else {
19144 self.write_keyword("VECTOR(");
19146 if let Some(ref et) = element_type {
19147 self.generate_data_type(et)?;
19148 if dimension.is_some() {
19149 self.write(", ");
19150 }
19151 }
19152 if let Some(dim) = dimension {
19153 self.write(&dim.to_string());
19154 }
19155 self.write(")");
19156 }
19157 }
19158 DataType::Object { fields, modifier } => {
19159 self.write_keyword("OBJECT(");
19160 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
19161 if i > 0 {
19162 self.write(", ");
19163 }
19164 self.write(name);
19165 self.write(" ");
19166 self.generate_data_type(dt)?;
19167 if *not_null {
19168 self.write_keyword(" NOT NULL");
19169 }
19170 }
19171 self.write(")");
19172 if let Some(mod_str) = modifier {
19173 self.write(" ");
19174 self.write_keyword(mod_str);
19175 }
19176 }
19177 DataType::Struct { fields, nested } => {
19178 match self.config.dialect {
19180 Some(DialectType::Snowflake) => {
19181 self.write_keyword("OBJECT(");
19183 for (i, field) in fields.iter().enumerate() {
19184 if i > 0 {
19185 self.write(", ");
19186 }
19187 if !field.name.is_empty() {
19188 self.write(&field.name);
19189 self.write(" ");
19190 }
19191 self.generate_data_type(&field.data_type)?;
19192 }
19193 self.write(")");
19194 }
19195 Some(DialectType::Presto) | Some(DialectType::Trino) => {
19196 self.write_keyword("ROW(");
19198 for (i, field) in fields.iter().enumerate() {
19199 if i > 0 {
19200 self.write(", ");
19201 }
19202 if !field.name.is_empty() {
19203 self.write(&field.name);
19204 self.write(" ");
19205 }
19206 self.generate_data_type(&field.data_type)?;
19207 }
19208 self.write(")");
19209 }
19210 Some(DialectType::DuckDB) => {
19211 self.write_keyword("STRUCT(");
19213 for (i, field) in fields.iter().enumerate() {
19214 if i > 0 {
19215 self.write(", ");
19216 }
19217 if !field.name.is_empty() {
19218 self.write(&field.name);
19219 self.write(" ");
19220 }
19221 self.generate_data_type(&field.data_type)?;
19222 }
19223 self.write(")");
19224 }
19225 Some(DialectType::SingleStore) => {
19226 self.write_keyword("RECORD(");
19228 for (i, field) in fields.iter().enumerate() {
19229 if i > 0 {
19230 self.write(", ");
19231 }
19232 if !field.name.is_empty() {
19233 self.write(&field.name);
19234 self.write(" ");
19235 }
19236 self.generate_data_type(&field.data_type)?;
19237 }
19238 self.write(")");
19239 }
19240 _ => {
19241 let force_angle_brackets = matches!(
19243 self.config.dialect,
19244 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
19245 );
19246 if *nested && !force_angle_brackets {
19247 self.write_keyword("STRUCT(");
19248 for (i, field) in fields.iter().enumerate() {
19249 if i > 0 {
19250 self.write(", ");
19251 }
19252 if !field.name.is_empty() {
19253 self.write(&field.name);
19254 self.write(" ");
19255 }
19256 self.generate_data_type(&field.data_type)?;
19257 }
19258 self.write(")");
19259 } else {
19260 self.write_keyword("STRUCT<");
19261 for (i, field) in fields.iter().enumerate() {
19262 if i > 0 {
19263 self.write(", ");
19264 }
19265 if !field.name.is_empty() {
19266 self.write(&field.name);
19268 self.write(self.config.struct_field_sep);
19269 }
19270 self.generate_data_type(&field.data_type)?;
19272 if let Some(comment) = &field.comment {
19274 self.write(" COMMENT '");
19275 self.write(comment);
19276 self.write("'");
19277 }
19278 if !field.options.is_empty() {
19280 self.write(" ");
19281 self.generate_options_clause(&field.options)?;
19282 }
19283 }
19284 self.write(">");
19285 }
19286 }
19287 }
19288 }
19289 DataType::Enum { values, assignments } => {
19290 if self.config.dialect == Some(DialectType::ClickHouse) {
19293 self.write("Enum(");
19294 } else {
19295 self.write_keyword("ENUM(");
19296 }
19297 for (i, val) in values.iter().enumerate() {
19298 if i > 0 {
19299 self.write(", ");
19300 }
19301 self.write("'");
19302 self.write(val);
19303 self.write("'");
19304 if let Some(Some(assignment)) = assignments.get(i) {
19305 self.write(" = ");
19306 self.write(assignment);
19307 }
19308 }
19309 self.write(")");
19310 }
19311 DataType::Set { values } => {
19312 self.write_keyword("SET(");
19314 for (i, val) in values.iter().enumerate() {
19315 if i > 0 {
19316 self.write(", ");
19317 }
19318 self.write("'");
19319 self.write(val);
19320 self.write("'");
19321 }
19322 self.write(")");
19323 }
19324 DataType::Union { fields } => {
19325 self.write_keyword("UNION(");
19327 for (i, (name, dt)) in fields.iter().enumerate() {
19328 if i > 0 {
19329 self.write(", ");
19330 }
19331 if !name.is_empty() {
19332 self.write(name);
19333 self.write(" ");
19334 }
19335 self.generate_data_type(dt)?;
19336 }
19337 self.write(")");
19338 }
19339 DataType::Custom { name } => {
19340 let name_upper = name.to_uppercase();
19342 match self.config.dialect {
19343 Some(DialectType::ClickHouse) => {
19344 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
19345 (name_upper[..idx].to_string(), &name[idx..])
19346 } else {
19347 (name_upper.clone(), "")
19348 };
19349 let mapped = match base_upper.as_str() {
19350 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ" | "SMALLDATETIME" | "DATETIME2" => "DateTime",
19351 "DATETIME64" => "DateTime64",
19352 "DATE32" => "Date32",
19353 "INT" => "Int32",
19354 "MEDIUMINT" => "Int32",
19355 "INT8" => "Int8",
19356 "INT16" => "Int16",
19357 "INT32" => "Int32",
19358 "INT64" => "Int64",
19359 "INT128" => "Int128",
19360 "INT256" => "Int256",
19361 "UINT8" => "UInt8",
19362 "UINT16" => "UInt16",
19363 "UINT32" => "UInt32",
19364 "UINT64" => "UInt64",
19365 "UINT128" => "UInt128",
19366 "UINT256" => "UInt256",
19367 "FLOAT32" => "Float32",
19368 "FLOAT64" => "Float64",
19369 "DECIMAL32" => "Decimal32",
19370 "DECIMAL64" => "Decimal64",
19371 "DECIMAL128" => "Decimal128",
19372 "DECIMAL256" => "Decimal256",
19373 "ENUM" => "Enum",
19374 "ENUM8" => "Enum8",
19375 "ENUM16" => "Enum16",
19376 "FIXEDSTRING" => "FixedString",
19377 "NESTED" => "Nested",
19378 "LOWCARDINALITY" => "LowCardinality",
19379 "NULLABLE" => "Nullable",
19380 "IPV4" => "IPv4",
19381 "IPV6" => "IPv6",
19382 "POINT" => "Point",
19383 "RING" => "Ring",
19384 "LINESTRING" => "LineString",
19385 "MULTILINESTRING" => "MultiLineString",
19386 "POLYGON" => "Polygon",
19387 "MULTIPOLYGON" => "MultiPolygon",
19388 "AGGREGATEFUNCTION" => "AggregateFunction",
19389 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
19390 "DYNAMIC" => "Dynamic",
19391 _ => "",
19392 };
19393 if mapped.is_empty() {
19394 self.write(name);
19395 } else {
19396 self.write(mapped);
19397 self.write(suffix);
19398 }
19399 }
19400 Some(DialectType::MySQL) if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" => {
19401 self.write_keyword("TIMESTAMP");
19403 }
19404 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
19405 self.write_keyword("SQL_VARIANT");
19406 }
19407 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
19408 self.write_keyword("DECIMAL(38, 5)");
19409 }
19410 Some(DialectType::Exasol) => {
19411 match name_upper.as_str() {
19413 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
19415 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
19417 "MEDIUMINT" => self.write_keyword("INT"),
19419 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => self.write_keyword("DECIMAL"),
19421 "DATETIME" => self.write_keyword("TIMESTAMP"),
19423 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
19424 _ => self.write(name),
19425 }
19426 }
19427 Some(DialectType::Dremio) => {
19428 match name_upper.as_str() {
19430 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
19431 "ARRAY" => self.write_keyword("LIST"),
19432 "NCHAR" => self.write_keyword("VARCHAR"),
19433 _ => self.write(name),
19434 }
19435 }
19436 _ => {
19438 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
19440 (name_upper[..idx].to_string(), Some(&name[idx..]))
19441 } else {
19442 (name_upper.clone(), None)
19443 };
19444
19445 match base_upper.as_str() {
19446 "INT64" if !matches!(self.config.dialect, Some(DialectType::BigQuery)) => {
19447 self.write_keyword("BIGINT");
19448 }
19449 "FLOAT64" if !matches!(self.config.dialect, Some(DialectType::BigQuery)) => {
19450 self.write_keyword("DOUBLE");
19451 }
19452 "BOOL" if !matches!(self.config.dialect, Some(DialectType::BigQuery)) => {
19453 self.write_keyword("BOOLEAN");
19454 }
19455 "BYTES" if matches!(self.config.dialect, Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)) => {
19456 self.write_keyword("BINARY");
19457 }
19458 "BYTES" if !matches!(self.config.dialect, Some(DialectType::BigQuery)) => {
19459 self.write_keyword("VARBINARY");
19460 }
19461 "DATETIME2" | "SMALLDATETIME" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) => {
19463 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) {
19465 self.write_keyword("TIMESTAMP");
19466 if let Some(args) = _args_str {
19467 self.write(args);
19468 }
19469 } else {
19470 self.write_keyword("TIMESTAMP");
19471 }
19472 }
19473 "DATETIMEOFFSET" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) => {
19475 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) {
19476 self.write_keyword("TIMESTAMPTZ");
19477 if let Some(args) = _args_str {
19478 self.write(args);
19479 }
19480 } else {
19481 self.write_keyword("TIMESTAMPTZ");
19482 }
19483 }
19484 "UNIQUEIDENTIFIER" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) => {
19486 match self.config.dialect {
19487 Some(DialectType::Spark) | Some(DialectType::Databricks)
19488 | Some(DialectType::Hive) => self.write_keyword("STRING"),
19489 _ => self.write_keyword("UUID"),
19490 }
19491 }
19492 "BIT" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)
19494 | Some(DialectType::PostgreSQL) | Some(DialectType::MySQL) | Some(DialectType::DuckDB)) => {
19495 self.write_keyword("BOOLEAN");
19496 }
19497 "NVARCHAR" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) => {
19499 match self.config.dialect {
19500 Some(DialectType::SQLite) => {
19501 self.write_keyword("TEXT");
19502 if let Some(args) = _args_str {
19503 self.write(args);
19504 }
19505 }
19506 Some(DialectType::Spark) | Some(DialectType::Databricks)
19507 | Some(DialectType::Hive) => {
19508 if _args_str.is_some() {
19509 self.write_keyword("VARCHAR");
19510 self.write(_args_str.unwrap());
19511 } else {
19512 self.write_keyword("VARCHAR(30)");
19513 }
19514 }
19515 _ => {
19516 self.write_keyword("VARCHAR");
19517 if let Some(args) = _args_str {
19518 self.write(args);
19519 }
19520 }
19521 }
19522 }
19523 "NCHAR" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) => {
19525 match self.config.dialect {
19526 Some(DialectType::Spark) | Some(DialectType::Databricks)
19527 | Some(DialectType::Hive) => {
19528 if _args_str.is_some() {
19529 self.write_keyword("CHAR");
19530 self.write(_args_str.unwrap());
19531 } else {
19532 self.write_keyword("CHAR(30)");
19533 }
19534 }
19535 _ => {
19536 self.write_keyword("CHAR");
19537 if let Some(args) = _args_str {
19538 self.write(args);
19539 }
19540 }
19541 }
19542 }
19543 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => {
19546 match self.config.dialect {
19547 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
19548 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => self.write_keyword("TEXT"),
19549 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
19550 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
19551 Some(DialectType::Snowflake) | Some(DialectType::Redshift) | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
19552 _ => self.write_keyword("TEXT"),
19553 }
19554 }
19555 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => {
19558 match self.config.dialect {
19559 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
19560 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => self.write_keyword("BLOB"),
19561 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
19562 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
19563 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
19564 Some(DialectType::Snowflake) | Some(DialectType::Redshift) | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
19565 _ => self.write_keyword("BLOB"),
19566 }
19567 }
19568 "LONGVARCHAR" => {
19570 match self.config.dialect {
19571 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
19572 _ => self.write_keyword("VARCHAR"),
19573 }
19574 }
19575 _ => self.write(name),
19576 }
19577 }
19578 }
19579 }
19580 DataType::Geometry { subtype, srid } => {
19581 match self.config.dialect {
19583 Some(DialectType::MySQL) => {
19584 if let Some(sub) = subtype {
19586 self.write_keyword(sub);
19587 if let Some(s) = srid {
19588 self.write(" SRID ");
19589 self.write(&s.to_string());
19590 }
19591 } else {
19592 self.write_keyword("GEOMETRY");
19593 }
19594 }
19595 Some(DialectType::BigQuery) => {
19596 self.write_keyword("GEOGRAPHY");
19598 }
19599 Some(DialectType::Teradata) => {
19600 self.write_keyword("ST_GEOMETRY");
19602 if subtype.is_some() || srid.is_some() {
19603 self.write("(");
19604 if let Some(sub) = subtype {
19605 self.write_keyword(sub);
19606 }
19607 if let Some(s) = srid {
19608 if subtype.is_some() {
19609 self.write(", ");
19610 }
19611 self.write(&s.to_string());
19612 }
19613 self.write(")");
19614 }
19615 }
19616 _ => {
19617 self.write_keyword("GEOMETRY");
19619 if subtype.is_some() || srid.is_some() {
19620 self.write("(");
19621 if let Some(sub) = subtype {
19622 self.write_keyword(sub);
19623 }
19624 if let Some(s) = srid {
19625 if subtype.is_some() {
19626 self.write(", ");
19627 }
19628 self.write(&s.to_string());
19629 }
19630 self.write(")");
19631 }
19632 }
19633 }
19634 }
19635 DataType::Geography { subtype, srid } => {
19636 match self.config.dialect {
19638 Some(DialectType::MySQL) => {
19639 if let Some(sub) = subtype {
19641 self.write_keyword(sub);
19642 } else {
19643 self.write_keyword("GEOMETRY");
19644 }
19645 let effective_srid = srid.unwrap_or(4326);
19647 self.write(" SRID ");
19648 self.write(&effective_srid.to_string());
19649 }
19650 Some(DialectType::BigQuery) => {
19651 self.write_keyword("GEOGRAPHY");
19653 }
19654 Some(DialectType::Snowflake) => {
19655 self.write_keyword("GEOGRAPHY");
19657 }
19658 _ => {
19659 self.write_keyword("GEOGRAPHY");
19661 if subtype.is_some() || srid.is_some() {
19662 self.write("(");
19663 if let Some(sub) = subtype {
19664 self.write_keyword(sub);
19665 }
19666 if let Some(s) = srid {
19667 if subtype.is_some() {
19668 self.write(", ");
19669 }
19670 self.write(&s.to_string());
19671 }
19672 self.write(")");
19673 }
19674 }
19675 }
19676 }
19677 DataType::CharacterSet { name } => {
19678 self.write_keyword("CHAR CHARACTER SET ");
19680 self.write(name);
19681 }
19682 _ => self.write("UNKNOWN"),
19683 }
19684 Ok(())
19685 }
19686
19687 fn write(&mut self, s: &str) {
19690 self.output.push_str(s);
19691 }
19692
19693 fn write_space(&mut self) {
19694 self.output.push(' ');
19695 }
19696
19697 fn write_keyword(&mut self, keyword: &str) {
19698 if self.config.uppercase_keywords {
19699 self.output.push_str(keyword);
19700 } else {
19701 self.output.push_str(&keyword.to_lowercase());
19702 }
19703 }
19704
19705 fn convert_strptime_to_exasol_format(format: &str) -> String {
19709 let mut result = String::new();
19710 let chars: Vec<char> = format.chars().collect();
19711 let mut i = 0;
19712 while i < chars.len() {
19713 if chars[i] == '%' && i + 1 < chars.len() {
19714 let spec = chars[i + 1];
19715 let exasol_spec = match spec {
19716 'Y' => "YYYY",
19717 'y' => "YY",
19718 'm' => "MM",
19719 'd' => "DD",
19720 'H' => "HH",
19721 'M' => "MI",
19722 'S' => "SS",
19723 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
19735 result.push('%');
19737 result.push(spec);
19738 i += 2;
19739 continue;
19740 }
19741 };
19742 result.push_str(exasol_spec);
19743 i += 2;
19744 } else {
19745 result.push(chars[i]);
19746 i += 1;
19747 }
19748 }
19749 result
19750 }
19751
19752 fn convert_strptime_to_postgres_format(format: &str) -> String {
19756 let mut result = String::new();
19757 let chars: Vec<char> = format.chars().collect();
19758 let mut i = 0;
19759 while i < chars.len() {
19760 if chars[i] == '%' && i + 1 < chars.len() {
19761 let spec = chars[i + 1];
19762 let pg_spec = match spec {
19763 'Y' => "YYYY",
19764 'y' => "YY",
19765 'm' => "MM",
19766 'd' => "DD",
19767 'H' => "HH24",
19768 'I' => "HH12",
19769 'M' => "MI",
19770 'S' => "SS",
19771 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
19782 result.push('%');
19784 result.push(spec);
19785 i += 2;
19786 continue;
19787 }
19788 };
19789 result.push_str(pg_spec);
19790 i += 2;
19791 } else {
19792 result.push(chars[i]);
19793 i += 1;
19794 }
19795 }
19796 result
19797 }
19798
19799 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
19801 if self.config.limit_only_literals {
19802 if let Some(value) = Self::try_evaluate_constant(expr) {
19803 self.write(&value.to_string());
19804 return Ok(());
19805 }
19806 }
19807 self.generate_expression(expr)
19808 }
19809
19810 fn write_formatted_comment(&mut self, comment: &str) {
19814 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
19817 comment[2..comment.len() - 2].trim()
19819 } else if comment.starts_with("--") {
19820 comment[2..].trim()
19822 } else {
19823 comment.trim()
19825 };
19826 self.output.push_str("/* ");
19827 self.output.push_str(content);
19828 self.output.push_str(" */");
19829 }
19830
19831 fn escape_block_for_single_quote(&self, block: &str) -> String {
19834 let escape_backslash = matches!(
19835 self.config.dialect,
19836 Some(crate::dialects::DialectType::Snowflake)
19837 );
19838 let mut escaped = String::with_capacity(block.len() + 4);
19839 for ch in block.chars() {
19840 if ch == '\'' {
19841 escaped.push('\\');
19842 escaped.push('\'');
19843 } else if escape_backslash && ch == '\\' {
19844 escaped.push('\\');
19845 escaped.push('\\');
19846 } else {
19847 escaped.push(ch);
19848 }
19849 }
19850 escaped
19851 }
19852
19853 fn write_newline(&mut self) {
19854 self.output.push('\n');
19855 }
19856
19857 fn write_indent(&mut self) {
19858 for _ in 0..self.indent_level {
19859 self.output.push_str(&self.config.indent);
19860 }
19861 }
19862
19863 fn too_wide(&self, args: &[String]) -> bool {
19869 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
19870 }
19871
19872 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
19875 if self.config.pretty {
19876 self.write_newline();
19877 self.write_indent();
19878 self.write_keyword(keyword);
19879 self.write_newline();
19880 self.indent_level += 1;
19881 self.write_indent();
19882 self.generate_expression(condition)?;
19883 self.indent_level -= 1;
19884 } else {
19885 self.write_space();
19886 self.write_keyword(keyword);
19887 self.write_space();
19888 self.generate_expression(condition)?;
19889 }
19890 Ok(())
19891 }
19892
19893 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
19896 if exprs.is_empty() {
19897 return Ok(());
19898 }
19899
19900 if self.config.pretty {
19901 self.write_newline();
19902 self.write_indent();
19903 self.write_keyword(keyword);
19904 self.write_newline();
19905 self.indent_level += 1;
19906 for (i, expr) in exprs.iter().enumerate() {
19907 if i > 0 {
19908 self.write(",");
19909 self.write_newline();
19910 }
19911 self.write_indent();
19912 self.generate_expression(expr)?;
19913 }
19914 self.indent_level -= 1;
19915 } else {
19916 self.write_space();
19917 self.write_keyword(keyword);
19918 self.write_space();
19919 for (i, expr) in exprs.iter().enumerate() {
19920 if i > 0 {
19921 self.write(", ");
19922 }
19923 self.generate_expression(expr)?;
19924 }
19925 }
19926 Ok(())
19927 }
19928
19929 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
19931 if orderings.is_empty() {
19932 return Ok(());
19933 }
19934
19935 if self.config.pretty {
19936 self.write_newline();
19937 self.write_indent();
19938 self.write_keyword(keyword);
19939 self.write_newline();
19940 self.indent_level += 1;
19941 for (i, ordered) in orderings.iter().enumerate() {
19942 if i > 0 {
19943 self.write(",");
19944 self.write_newline();
19945 }
19946 self.write_indent();
19947 self.generate_ordered(ordered)?;
19948 }
19949 self.indent_level -= 1;
19950 } else {
19951 self.write_space();
19952 self.write_keyword(keyword);
19953 self.write_space();
19954 for (i, ordered) in orderings.iter().enumerate() {
19955 if i > 0 {
19956 self.write(", ");
19957 }
19958 self.generate_ordered(ordered)?;
19959 }
19960 }
19961 Ok(())
19962 }
19963
19964 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
19966 if windows.is_empty() {
19967 return Ok(());
19968 }
19969
19970 if self.config.pretty {
19971 self.write_newline();
19972 self.write_indent();
19973 self.write_keyword("WINDOW");
19974 self.write_newline();
19975 self.indent_level += 1;
19976 for (i, named_window) in windows.iter().enumerate() {
19977 if i > 0 {
19978 self.write(",");
19979 self.write_newline();
19980 }
19981 self.write_indent();
19982 self.generate_identifier(&named_window.name)?;
19983 self.write_space();
19984 self.write_keyword("AS");
19985 self.write(" (");
19986 self.generate_over(&named_window.spec)?;
19987 self.write(")");
19988 }
19989 self.indent_level -= 1;
19990 } else {
19991 self.write_space();
19992 self.write_keyword("WINDOW");
19993 self.write_space();
19994 for (i, named_window) in windows.iter().enumerate() {
19995 if i > 0 {
19996 self.write(", ");
19997 }
19998 self.generate_identifier(&named_window.name)?;
19999 self.write_space();
20000 self.write_keyword("AS");
20001 self.write(" (");
20002 self.generate_over(&named_window.spec)?;
20003 self.write(")");
20004 }
20005 }
20006 Ok(())
20007 }
20008
20009 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
20011 self.write_keyword("AI_AGG");
20013 self.write("(");
20014 self.generate_expression(&e.this)?;
20015 self.write(", ");
20016 self.generate_expression(&e.expression)?;
20017 self.write(")");
20018 Ok(())
20019 }
20020
20021 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
20022 self.write_keyword("AI_CLASSIFY");
20024 self.write("(");
20025 self.generate_expression(&e.this)?;
20026 if let Some(categories) = &e.categories {
20027 self.write(", ");
20028 self.generate_expression(categories)?;
20029 }
20030 if let Some(config) = &e.config {
20031 self.write(", ");
20032 self.generate_expression(config)?;
20033 }
20034 self.write(")");
20035 Ok(())
20036 }
20037
20038 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
20039 self.write_keyword("ADD");
20041 self.write_space();
20042 if e.exists {
20043 self.write_keyword("IF NOT EXISTS");
20044 self.write_space();
20045 }
20046 self.generate_expression(&e.this)?;
20047 if let Some(location) = &e.location {
20048 self.write_space();
20049 self.generate_expression(location)?;
20050 }
20051 Ok(())
20052 }
20053
20054 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
20055 self.write_keyword("ALGORITHM");
20057 self.write("=");
20058 self.generate_expression(&e.this)?;
20059 Ok(())
20060 }
20061
20062 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
20063 self.generate_expression(&e.this)?;
20065 self.write_space();
20066 self.write_keyword("AS");
20067 self.write(" (");
20068 for (i, expr) in e.expressions.iter().enumerate() {
20069 if i > 0 {
20070 self.write(", ");
20071 }
20072 self.generate_expression(expr)?;
20073 }
20074 self.write(")");
20075 Ok(())
20076 }
20077
20078 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
20079 self.write_keyword("ALLOWED_VALUES");
20081 self.write_space();
20082 for (i, expr) in e.expressions.iter().enumerate() {
20083 if i > 0 {
20084 self.write(", ");
20085 }
20086 self.generate_expression(expr)?;
20087 }
20088 Ok(())
20089 }
20090
20091 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
20092 self.write_keyword("ALTER COLUMN");
20094 self.write_space();
20095 self.generate_expression(&e.this)?;
20096
20097 if let Some(dtype) = &e.dtype {
20098 self.write_space();
20099 self.write_keyword("SET DATA TYPE");
20100 self.write_space();
20101 self.generate_expression(dtype)?;
20102 if let Some(collate) = &e.collate {
20103 self.write_space();
20104 self.write_keyword("COLLATE");
20105 self.write_space();
20106 self.generate_expression(collate)?;
20107 }
20108 if let Some(using) = &e.using {
20109 self.write_space();
20110 self.write_keyword("USING");
20111 self.write_space();
20112 self.generate_expression(using)?;
20113 }
20114 } else if let Some(default) = &e.default {
20115 self.write_space();
20116 self.write_keyword("SET DEFAULT");
20117 self.write_space();
20118 self.generate_expression(default)?;
20119 } else if let Some(comment) = &e.comment {
20120 self.write_space();
20121 self.write_keyword("COMMENT");
20122 self.write_space();
20123 self.generate_expression(comment)?;
20124 } else if let Some(drop) = &e.drop {
20125 self.write_space();
20126 self.write_keyword("DROP");
20127 self.write_space();
20128 self.generate_expression(drop)?;
20129 } else if let Some(visible) = &e.visible {
20130 self.write_space();
20131 self.generate_expression(visible)?;
20132 } else if let Some(rename_to) = &e.rename_to {
20133 self.write_space();
20134 self.write_keyword("RENAME TO");
20135 self.write_space();
20136 self.generate_expression(rename_to)?;
20137 } else if let Some(allow_null) = &e.allow_null {
20138 self.write_space();
20139 self.generate_expression(allow_null)?;
20140 }
20141 Ok(())
20142 }
20143
20144 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
20145 self.write_keyword("ALTER SESSION");
20147 self.write_space();
20148 if e.unset.is_some() {
20149 self.write_keyword("UNSET");
20150 } else {
20151 self.write_keyword("SET");
20152 }
20153 self.write_space();
20154 for (i, expr) in e.expressions.iter().enumerate() {
20155 if i > 0 {
20156 self.write(", ");
20157 }
20158 self.generate_expression(expr)?;
20159 }
20160 Ok(())
20161 }
20162
20163 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
20164 self.write_keyword("SET");
20166
20167 if let Some(opt) = &e.option {
20169 self.write_space();
20170 self.generate_expression(opt)?;
20171 }
20172
20173 if !e.expressions.is_empty() {
20176 let is_properties = e.expressions.iter().any(|expr| matches!(expr, Expression::Eq(_)));
20178 if is_properties && e.option.is_none() {
20179 self.write_space();
20180 self.write_keyword("PROPERTIES");
20181 }
20182 self.write_space();
20183 for (i, expr) in e.expressions.iter().enumerate() {
20184 if i > 0 {
20185 self.write(", ");
20186 }
20187 self.generate_expression(expr)?;
20188 }
20189 }
20190
20191 if let Some(file_format) = &e.file_format {
20193 self.write(" ");
20194 self.write_keyword("STAGE_FILE_FORMAT");
20195 self.write(" = (");
20196 self.generate_space_separated_properties(file_format)?;
20197 self.write(")");
20198 }
20199
20200 if let Some(copy_options) = &e.copy_options {
20202 self.write(" ");
20203 self.write_keyword("STAGE_COPY_OPTIONS");
20204 self.write(" = (");
20205 self.generate_space_separated_properties(copy_options)?;
20206 self.write(")");
20207 }
20208
20209 if let Some(tag) = &e.tag {
20211 self.write(" ");
20212 self.write_keyword("TAG");
20213 self.write(" ");
20214 self.generate_expression(tag)?;
20215 }
20216
20217 Ok(())
20218 }
20219
20220 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
20222 match expr {
20223 Expression::Tuple(t) => {
20224 for (i, prop) in t.expressions.iter().enumerate() {
20225 if i > 0 {
20226 self.write(" ");
20227 }
20228 self.generate_expression(prop)?;
20229 }
20230 }
20231 _ => {
20232 self.generate_expression(expr)?;
20233 }
20234 }
20235 Ok(())
20236 }
20237
20238 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
20239 self.write_keyword("ALTER");
20241 if e.compound.is_some() {
20242 self.write_space();
20243 self.write_keyword("COMPOUND");
20244 }
20245 self.write_space();
20246 self.write_keyword("SORTKEY");
20247 self.write_space();
20248 if let Some(this) = &e.this {
20249 self.generate_expression(this)?;
20250 } else if !e.expressions.is_empty() {
20251 self.write("(");
20252 for (i, expr) in e.expressions.iter().enumerate() {
20253 if i > 0 {
20254 self.write(", ");
20255 }
20256 self.generate_expression(expr)?;
20257 }
20258 self.write(")");
20259 }
20260 Ok(())
20261 }
20262
20263 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
20264 self.write_keyword("ANALYZE");
20266 if !e.options.is_empty() {
20267 self.write_space();
20268 for (i, opt) in e.options.iter().enumerate() {
20269 if i > 0 {
20270 self.write_space();
20271 }
20272 if let Expression::Identifier(id) = opt {
20274 self.write_keyword(&id.name);
20275 } else {
20276 self.generate_expression(opt)?;
20277 }
20278 }
20279 }
20280 if let Some(kind) = &e.kind {
20281 self.write_space();
20282 self.write_keyword(kind);
20283 }
20284 if let Some(this) = &e.this {
20285 self.write_space();
20286 self.generate_expression(this)?;
20287 }
20288 if !e.columns.is_empty() {
20290 self.write("(");
20291 for (i, col) in e.columns.iter().enumerate() {
20292 if i > 0 {
20293 self.write(", ");
20294 }
20295 self.write(col);
20296 }
20297 self.write(")");
20298 }
20299 if let Some(partition) = &e.partition {
20300 self.write_space();
20301 self.generate_expression(partition)?;
20302 }
20303 if let Some(mode) = &e.mode {
20304 self.write_space();
20305 self.generate_expression(mode)?;
20306 }
20307 if let Some(expression) = &e.expression {
20308 self.write_space();
20309 self.generate_expression(expression)?;
20310 }
20311 if !e.properties.is_empty() {
20312 self.write_space();
20313 self.write_keyword(self.config.with_properties_prefix);
20314 self.write(" (");
20315 for (i, prop) in e.properties.iter().enumerate() {
20316 if i > 0 {
20317 self.write(", ");
20318 }
20319 self.generate_expression(prop)?;
20320 }
20321 self.write(")");
20322 }
20323 Ok(())
20324 }
20325
20326 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
20327 self.write_keyword("DELETE");
20329 if let Some(kind) = &e.kind {
20330 self.write_space();
20331 self.write_keyword(kind);
20332 }
20333 self.write_space();
20334 self.write_keyword("STATISTICS");
20335 Ok(())
20336 }
20337
20338 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
20339 if let Expression::Identifier(id) = e.this.as_ref() {
20342 self.write_keyword(&id.name);
20343 } else {
20344 self.generate_expression(&e.this)?;
20345 }
20346 self.write_space();
20347 self.write_keyword("HISTOGRAM ON");
20348 self.write_space();
20349 for (i, expr) in e.expressions.iter().enumerate() {
20350 if i > 0 {
20351 self.write(", ");
20352 }
20353 self.generate_expression(expr)?;
20354 }
20355 if let Some(expression) = &e.expression {
20356 self.write_space();
20357 self.generate_expression(expression)?;
20358 }
20359 if let Some(update_options) = &e.update_options {
20360 self.write_space();
20361 self.generate_expression(update_options)?;
20362 self.write_space();
20363 self.write_keyword("UPDATE");
20364 }
20365 Ok(())
20366 }
20367
20368 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
20369 self.write_keyword("LIST CHAINED ROWS");
20371 if let Some(expression) = &e.expression {
20372 self.write_space();
20373 self.write_keyword("INTO");
20374 self.write_space();
20375 self.generate_expression(expression)?;
20376 }
20377 Ok(())
20378 }
20379
20380 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
20381 self.write_keyword("SAMPLE");
20383 self.write_space();
20384 if let Some(sample) = &e.sample {
20385 self.generate_expression(sample)?;
20386 self.write_space();
20387 }
20388 self.write_keyword(&e.kind);
20389 Ok(())
20390 }
20391
20392 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
20393 self.write_keyword(&e.kind);
20395 if let Some(option) = &e.option {
20396 self.write_space();
20397 self.generate_expression(option)?;
20398 }
20399 self.write_space();
20400 self.write_keyword("STATISTICS");
20401 if let Some(this) = &e.this {
20402 self.write_space();
20403 self.generate_expression(this)?;
20404 }
20405 if !e.expressions.is_empty() {
20406 self.write_space();
20407 for (i, expr) in e.expressions.iter().enumerate() {
20408 if i > 0 {
20409 self.write(", ");
20410 }
20411 self.generate_expression(expr)?;
20412 }
20413 }
20414 Ok(())
20415 }
20416
20417 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
20418 self.write_keyword("VALIDATE");
20420 self.write_space();
20421 self.write_keyword(&e.kind);
20422 if let Some(this) = &e.this {
20423 self.write_space();
20424 if let Expression::Identifier(id) = this.as_ref() {
20426 self.write_keyword(&id.name);
20427 } else {
20428 self.generate_expression(this)?;
20429 }
20430 }
20431 if let Some(expression) = &e.expression {
20432 self.write_space();
20433 self.write_keyword("INTO");
20434 self.write_space();
20435 self.generate_expression(expression)?;
20436 }
20437 Ok(())
20438 }
20439
20440 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
20441 self.write_keyword("WITH");
20443 self.write_space();
20444 for (i, expr) in e.expressions.iter().enumerate() {
20445 if i > 0 {
20446 self.write(", ");
20447 }
20448 self.generate_expression(expr)?;
20449 }
20450 Ok(())
20451 }
20452
20453 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
20454 self.generate_expression(&e.this)?;
20457 self.write("(");
20458 for (i, arg) in e.expressions.iter().enumerate() {
20459 if i > 0 {
20460 self.write(", ");
20461 }
20462 self.generate_expression(arg)?;
20463 }
20464 self.write(")");
20465 Ok(())
20466 }
20467
20468 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
20469 self.generate_expression(&e.this)?;
20471 self.write("(");
20472 for (i, arg) in e.expressions.iter().enumerate() {
20473 if i > 0 {
20474 self.write(", ");
20475 }
20476 self.generate_expression(arg)?;
20477 }
20478 self.write(")");
20479 Ok(())
20480 }
20481
20482 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
20483 self.generate_expression(&e.this)?;
20485 self.write_space();
20486 self.write_keyword("APPLY");
20487 self.write("(");
20488 self.generate_expression(&e.expression)?;
20489 self.write(")");
20490 Ok(())
20491 }
20492
20493 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
20494 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
20496 self.write("(");
20497 self.generate_expression(&e.this)?;
20498 if let Some(percentile) = &e.percentile {
20499 self.write(", ");
20500 self.generate_expression(percentile)?;
20501 }
20502 self.write(")");
20503 Ok(())
20504 }
20505
20506 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
20507 self.write_keyword("APPROX_QUANTILE");
20509 self.write("(");
20510 self.generate_expression(&e.this)?;
20511 if let Some(quantile) = &e.quantile {
20512 self.write(", ");
20513 self.generate_expression(quantile)?;
20514 }
20515 if let Some(accuracy) = &e.accuracy {
20516 self.write(", ");
20517 self.generate_expression(accuracy)?;
20518 }
20519 if let Some(weight) = &e.weight {
20520 self.write(", ");
20521 self.generate_expression(weight)?;
20522 }
20523 self.write(")");
20524 Ok(())
20525 }
20526
20527 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
20528 self.write_keyword("APPROX_QUANTILES");
20530 self.write("(");
20531 self.generate_expression(&e.this)?;
20532 if let Some(expression) = &e.expression {
20533 self.write(", ");
20534 self.generate_expression(expression)?;
20535 }
20536 self.write(")");
20537 Ok(())
20538 }
20539
20540 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
20541 self.write_keyword("APPROX_TOP_K");
20543 self.write("(");
20544 self.generate_expression(&e.this)?;
20545 if let Some(expression) = &e.expression {
20546 self.write(", ");
20547 self.generate_expression(expression)?;
20548 }
20549 if let Some(counters) = &e.counters {
20550 self.write(", ");
20551 self.generate_expression(counters)?;
20552 }
20553 self.write(")");
20554 Ok(())
20555 }
20556
20557 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
20558 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
20560 self.write("(");
20561 self.generate_expression(&e.this)?;
20562 if let Some(expression) = &e.expression {
20563 self.write(", ");
20564 self.generate_expression(expression)?;
20565 }
20566 self.write(")");
20567 Ok(())
20568 }
20569
20570 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
20571 self.write_keyword("APPROX_TOP_K_COMBINE");
20573 self.write("(");
20574 self.generate_expression(&e.this)?;
20575 if let Some(expression) = &e.expression {
20576 self.write(", ");
20577 self.generate_expression(expression)?;
20578 }
20579 self.write(")");
20580 Ok(())
20581 }
20582
20583 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
20584 self.write_keyword("APPROX_TOP_K_ESTIMATE");
20586 self.write("(");
20587 self.generate_expression(&e.this)?;
20588 if let Some(expression) = &e.expression {
20589 self.write(", ");
20590 self.generate_expression(expression)?;
20591 }
20592 self.write(")");
20593 Ok(())
20594 }
20595
20596 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
20597 self.write_keyword("APPROX_TOP_SUM");
20599 self.write("(");
20600 self.generate_expression(&e.this)?;
20601 self.write(", ");
20602 self.generate_expression(&e.expression)?;
20603 if let Some(count) = &e.count {
20604 self.write(", ");
20605 self.generate_expression(count)?;
20606 }
20607 self.write(")");
20608 Ok(())
20609 }
20610
20611 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
20612 self.write_keyword("ARG_MAX");
20614 self.write("(");
20615 self.generate_expression(&e.this)?;
20616 self.write(", ");
20617 self.generate_expression(&e.expression)?;
20618 if let Some(count) = &e.count {
20619 self.write(", ");
20620 self.generate_expression(count)?;
20621 }
20622 self.write(")");
20623 Ok(())
20624 }
20625
20626 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
20627 self.write_keyword("ARG_MIN");
20629 self.write("(");
20630 self.generate_expression(&e.this)?;
20631 self.write(", ");
20632 self.generate_expression(&e.expression)?;
20633 if let Some(count) = &e.count {
20634 self.write(", ");
20635 self.generate_expression(count)?;
20636 }
20637 self.write(")");
20638 Ok(())
20639 }
20640
20641 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
20642 self.write_keyword("ARRAY_ALL");
20644 self.write("(");
20645 self.generate_expression(&e.this)?;
20646 self.write(", ");
20647 self.generate_expression(&e.expression)?;
20648 self.write(")");
20649 Ok(())
20650 }
20651
20652 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
20653 self.write_keyword("ARRAY_ANY");
20655 self.write("(");
20656 self.generate_expression(&e.this)?;
20657 self.write(", ");
20658 self.generate_expression(&e.expression)?;
20659 self.write(")");
20660 Ok(())
20661 }
20662
20663 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
20664 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
20666 self.write("(");
20667 for (i, expr) in e.expressions.iter().enumerate() {
20668 if i > 0 {
20669 self.write(", ");
20670 }
20671 self.generate_expression(expr)?;
20672 }
20673 self.write(")");
20674 Ok(())
20675 }
20676
20677 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
20678 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
20680 self.write("arraySum");
20681 } else {
20682 self.write_keyword("ARRAY_SUM");
20683 }
20684 self.write("(");
20685 self.generate_expression(&e.this)?;
20686 if let Some(expression) = &e.expression {
20687 self.write(", ");
20688 self.generate_expression(expression)?;
20689 }
20690 self.write(")");
20691 Ok(())
20692 }
20693
20694 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
20695 self.generate_expression(&e.this)?;
20697 self.write_space();
20698 self.write_keyword("AT");
20699 self.write_space();
20700 self.generate_expression(&e.expression)?;
20701 Ok(())
20702 }
20703
20704 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
20705 self.write_keyword("ATTACH");
20707 if e.exists {
20708 self.write_space();
20709 self.write_keyword("IF NOT EXISTS");
20710 }
20711 self.write_space();
20712 self.generate_expression(&e.this)?;
20713 if !e.expressions.is_empty() {
20714 self.write(" (");
20715 for (i, expr) in e.expressions.iter().enumerate() {
20716 if i > 0 {
20717 self.write(", ");
20718 }
20719 self.generate_expression(expr)?;
20720 }
20721 self.write(")");
20722 }
20723 Ok(())
20724 }
20725
20726 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
20727 self.generate_expression(&e.this)?;
20730 if let Some(expression) = &e.expression {
20731 self.write_space();
20732 self.generate_expression(expression)?;
20733 }
20734 Ok(())
20735 }
20736
20737 fn generate_auto_increment_keyword(&mut self, col: &crate::expressions::ColumnDef) -> Result<()> {
20741 use crate::dialects::DialectType;
20742 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
20743 self.write_keyword("IDENTITY");
20744 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
20745 self.write("(");
20746 if let Some(ref start) = col.auto_increment_start {
20747 self.generate_expression(start)?;
20748 } else {
20749 self.write("0");
20750 }
20751 self.write(", ");
20752 if let Some(ref inc) = col.auto_increment_increment {
20753 self.generate_expression(inc)?;
20754 } else {
20755 self.write("1");
20756 }
20757 self.write(")");
20758 }
20759 } else if matches!(self.config.dialect, Some(DialectType::Snowflake) | Some(DialectType::SQLite)) {
20760 self.write_keyword("AUTOINCREMENT");
20761 if let Some(ref start) = col.auto_increment_start {
20762 self.write_space();
20763 self.write_keyword("START");
20764 self.write_space();
20765 self.generate_expression(start)?;
20766 }
20767 if let Some(ref inc) = col.auto_increment_increment {
20768 self.write_space();
20769 self.write_keyword("INCREMENT");
20770 self.write_space();
20771 self.generate_expression(inc)?;
20772 }
20773 if let Some(order) = col.auto_increment_order {
20774 self.write_space();
20775 if order {
20776 self.write_keyword("ORDER");
20777 } else {
20778 self.write_keyword("NOORDER");
20779 }
20780 }
20781 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
20782 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
20783 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
20784 self.write(" (");
20785 let mut first = true;
20786 if let Some(ref start) = col.auto_increment_start {
20787 self.write_keyword("START WITH");
20788 self.write_space();
20789 self.generate_expression(start)?;
20790 first = false;
20791 }
20792 if let Some(ref inc) = col.auto_increment_increment {
20793 if !first { self.write_space(); }
20794 self.write_keyword("INCREMENT BY");
20795 self.write_space();
20796 self.generate_expression(inc)?;
20797 }
20798 self.write(")");
20799 }
20800 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
20801 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
20802 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
20803 self.write(" (");
20804 let mut first = true;
20805 if let Some(ref start) = col.auto_increment_start {
20806 self.write_keyword("START WITH");
20807 self.write_space();
20808 self.generate_expression(start)?;
20809 first = false;
20810 }
20811 if let Some(ref inc) = col.auto_increment_increment {
20812 if !first { self.write_space(); }
20813 self.write_keyword("INCREMENT BY");
20814 self.write_space();
20815 self.generate_expression(inc)?;
20816 }
20817 self.write(")");
20818 }
20819 } else if matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) {
20820 self.write_keyword("IDENTITY");
20821 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
20822 self.write("(");
20823 if let Some(ref start) = col.auto_increment_start {
20824 self.generate_expression(start)?;
20825 } else {
20826 self.write("0");
20827 }
20828 self.write(", ");
20829 if let Some(ref inc) = col.auto_increment_increment {
20830 self.generate_expression(inc)?;
20831 } else {
20832 self.write("1");
20833 }
20834 self.write(")");
20835 }
20836 } else {
20837 self.write_keyword("AUTO_INCREMENT");
20838 if let Some(ref start) = col.auto_increment_start {
20839 self.write_space();
20840 self.write_keyword("START");
20841 self.write_space();
20842 self.generate_expression(start)?;
20843 }
20844 if let Some(ref inc) = col.auto_increment_increment {
20845 self.write_space();
20846 self.write_keyword("INCREMENT");
20847 self.write_space();
20848 self.generate_expression(inc)?;
20849 }
20850 if let Some(order) = col.auto_increment_order {
20851 self.write_space();
20852 if order {
20853 self.write_keyword("ORDER");
20854 } else {
20855 self.write_keyword("NOORDER");
20856 }
20857 }
20858 }
20859 Ok(())
20860 }
20861
20862 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
20863 self.write_keyword("AUTO_INCREMENT");
20865 self.write("=");
20866 self.generate_expression(&e.this)?;
20867 Ok(())
20868 }
20869
20870 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
20871 self.write_keyword("AUTO_REFRESH");
20873 self.write("=");
20874 self.generate_expression(&e.this)?;
20875 Ok(())
20876 }
20877
20878 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
20879 self.write_keyword("BACKUP");
20881 self.write_space();
20882 self.generate_expression(&e.this)?;
20883 Ok(())
20884 }
20885
20886 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
20887 self.write_keyword("BASE64_DECODE_BINARY");
20889 self.write("(");
20890 self.generate_expression(&e.this)?;
20891 if let Some(alphabet) = &e.alphabet {
20892 self.write(", ");
20893 self.generate_expression(alphabet)?;
20894 }
20895 self.write(")");
20896 Ok(())
20897 }
20898
20899 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
20900 self.write_keyword("BASE64_DECODE_STRING");
20902 self.write("(");
20903 self.generate_expression(&e.this)?;
20904 if let Some(alphabet) = &e.alphabet {
20905 self.write(", ");
20906 self.generate_expression(alphabet)?;
20907 }
20908 self.write(")");
20909 Ok(())
20910 }
20911
20912 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
20913 self.write_keyword("BASE64_ENCODE");
20915 self.write("(");
20916 self.generate_expression(&e.this)?;
20917 if let Some(max_line_length) = &e.max_line_length {
20918 self.write(", ");
20919 self.generate_expression(max_line_length)?;
20920 }
20921 if let Some(alphabet) = &e.alphabet {
20922 self.write(", ");
20923 self.generate_expression(alphabet)?;
20924 }
20925 self.write(")");
20926 Ok(())
20927 }
20928
20929 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
20930 self.write_keyword("BLOCKCOMPRESSION");
20932 self.write("=");
20933 if let Some(autotemp) = &e.autotemp {
20934 self.write_keyword("AUTOTEMP");
20935 self.write("(");
20936 self.generate_expression(autotemp)?;
20937 self.write(")");
20938 }
20939 if let Some(always) = &e.always {
20940 self.generate_expression(always)?;
20941 }
20942 if let Some(default) = &e.default {
20943 self.generate_expression(default)?;
20944 }
20945 if let Some(manual) = &e.manual {
20946 self.generate_expression(manual)?;
20947 }
20948 if let Some(never) = &e.never {
20949 self.generate_expression(never)?;
20950 }
20951 Ok(())
20952 }
20953
20954 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
20955 self.write("((");
20957 self.generate_expression(&e.this)?;
20958 self.write(") ");
20959 self.write_keyword("AND");
20960 self.write(" (");
20961 self.generate_expression(&e.expression)?;
20962 self.write("))");
20963 Ok(())
20964 }
20965
20966 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
20967 self.write("((");
20969 self.generate_expression(&e.this)?;
20970 self.write(") ");
20971 self.write_keyword("OR");
20972 self.write(" (");
20973 self.generate_expression(&e.expression)?;
20974 self.write("))");
20975 Ok(())
20976 }
20977
20978 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
20979 self.write_keyword("BUILD");
20981 self.write_space();
20982 self.generate_expression(&e.this)?;
20983 Ok(())
20984 }
20985
20986 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
20987 self.generate_expression(&e.this)?;
20989 Ok(())
20990 }
20991
20992 fn generate_case_specific_column_constraint(&mut self, e: &CaseSpecificColumnConstraint) -> Result<()> {
20993 if e.not_.is_some() {
20995 self.write_keyword("NOT");
20996 self.write_space();
20997 }
20998 self.write_keyword("CASESPECIFIC");
20999 Ok(())
21000 }
21001
21002 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
21003 self.write_keyword("CAST");
21005 self.write("(");
21006 self.generate_expression(&e.this)?;
21007 if self.config.dialect == Some(DialectType::ClickHouse) {
21008 self.write(", ");
21010 } else {
21011 self.write_space();
21012 self.write_keyword("AS");
21013 self.write_space();
21014 }
21015 if let Some(to) = &e.to {
21016 self.generate_expression(to)?;
21017 }
21018 self.write(")");
21019 Ok(())
21020 }
21021
21022 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
21023 self.write_keyword("CHANGES");
21026 self.write(" (");
21027 if let Some(information) = &e.information {
21028 self.write_keyword("INFORMATION");
21029 self.write(" => ");
21030 self.generate_expression(information)?;
21031 }
21032 self.write(")");
21033 if let Some(at_before) = &e.at_before {
21035 self.write(" ");
21036 self.generate_expression(at_before)?;
21037 }
21038 if let Some(end) = &e.end {
21039 self.write(" ");
21040 self.generate_expression(end)?;
21041 }
21042 Ok(())
21043 }
21044
21045 fn generate_character_set_column_constraint(&mut self, e: &CharacterSetColumnConstraint) -> Result<()> {
21046 self.write_keyword("CHARACTER SET");
21048 self.write_space();
21049 self.generate_expression(&e.this)?;
21050 Ok(())
21051 }
21052
21053 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
21054 if e.default.is_some() {
21056 self.write_keyword("DEFAULT");
21057 self.write_space();
21058 }
21059 self.write_keyword("CHARACTER SET");
21060 self.write("=");
21061 self.generate_expression(&e.this)?;
21062 Ok(())
21063 }
21064
21065 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
21066 self.write_keyword("CHECK");
21068 self.write(" (");
21069 self.generate_expression(&e.this)?;
21070 self.write(")");
21071 if e.enforced.is_some() {
21072 self.write_space();
21073 self.write_keyword("ENFORCED");
21074 }
21075 Ok(())
21076 }
21077
21078 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
21079 self.write_keyword("CHECK_JSON");
21081 self.write("(");
21082 self.generate_expression(&e.this)?;
21083 self.write(")");
21084 Ok(())
21085 }
21086
21087 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
21088 self.write_keyword("CHECK_XML");
21090 self.write("(");
21091 self.generate_expression(&e.this)?;
21092 self.write(")");
21093 Ok(())
21094 }
21095
21096 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
21097 self.write_keyword("CHECKSUM");
21099 self.write("=");
21100 if e.on.is_some() {
21101 self.write_keyword("ON");
21102 } else if e.default.is_some() {
21103 self.write_keyword("DEFAULT");
21104 } else {
21105 self.write_keyword("OFF");
21106 }
21107 Ok(())
21108 }
21109
21110 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
21111 if e.shallow.is_some() {
21113 self.write_keyword("SHALLOW");
21114 self.write_space();
21115 }
21116 if e.copy.is_some() {
21117 self.write_keyword("COPY");
21118 } else {
21119 self.write_keyword("CLONE");
21120 }
21121 self.write_space();
21122 self.generate_expression(&e.this)?;
21123 Ok(())
21124 }
21125
21126 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
21127 self.write_keyword("CLUSTER BY");
21129 self.write(" (");
21130 for (i, ord) in e.expressions.iter().enumerate() {
21131 if i > 0 {
21132 self.write(", ");
21133 }
21134 self.generate_ordered(ord)?;
21135 }
21136 self.write(")");
21137 Ok(())
21138 }
21139
21140 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
21141 self.write_keyword("CLUSTERED BY");
21143 self.write(" (");
21144 for (i, expr) in e.expressions.iter().enumerate() {
21145 if i > 0 {
21146 self.write(", ");
21147 }
21148 self.generate_expression(expr)?;
21149 }
21150 self.write(")");
21151 if let Some(sorted_by) = &e.sorted_by {
21152 self.write_space();
21153 self.write_keyword("SORTED BY");
21154 self.write(" (");
21155 if let Expression::Tuple(t) = sorted_by.as_ref() {
21157 for (i, expr) in t.expressions.iter().enumerate() {
21158 if i > 0 {
21159 self.write(", ");
21160 }
21161 self.generate_expression(expr)?;
21162 }
21163 } else {
21164 self.generate_expression(sorted_by)?;
21165 }
21166 self.write(")");
21167 }
21168 if let Some(buckets) = &e.buckets {
21169 self.write_space();
21170 self.write_keyword("INTO");
21171 self.write_space();
21172 self.generate_expression(buckets)?;
21173 self.write_space();
21174 self.write_keyword("BUCKETS");
21175 }
21176 Ok(())
21177 }
21178
21179 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
21180 if e.default.is_some() {
21184 self.write_keyword("DEFAULT");
21185 self.write_space();
21186 }
21187 self.write_keyword("COLLATE");
21188 match self.config.dialect {
21190 Some(DialectType::BigQuery) => self.write_space(),
21191 _ => self.write("="),
21192 }
21193 self.generate_expression(&e.this)?;
21194 Ok(())
21195 }
21196
21197 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
21198 match e {
21200 ColumnConstraint::NotNull => {
21201 self.write_keyword("NOT NULL");
21202 }
21203 ColumnConstraint::Null => {
21204 self.write_keyword("NULL");
21205 }
21206 ColumnConstraint::Unique => {
21207 self.write_keyword("UNIQUE");
21208 }
21209 ColumnConstraint::PrimaryKey => {
21210 self.write_keyword("PRIMARY KEY");
21211 }
21212 ColumnConstraint::Default(expr) => {
21213 self.write_keyword("DEFAULT");
21214 self.write_space();
21215 self.generate_expression(expr)?;
21216 }
21217 ColumnConstraint::Check(expr) => {
21218 self.write_keyword("CHECK");
21219 self.write(" (");
21220 self.generate_expression(expr)?;
21221 self.write(")");
21222 }
21223 ColumnConstraint::References(fk_ref) => {
21224 if fk_ref.has_foreign_key_keywords {
21225 self.write_keyword("FOREIGN KEY");
21226 self.write_space();
21227 }
21228 self.write_keyword("REFERENCES");
21229 self.write_space();
21230 self.generate_table(&fk_ref.table)?;
21231 if !fk_ref.columns.is_empty() {
21232 self.write(" (");
21233 for (i, col) in fk_ref.columns.iter().enumerate() {
21234 if i > 0 {
21235 self.write(", ");
21236 }
21237 self.generate_identifier(col)?;
21238 }
21239 self.write(")");
21240 }
21241 }
21242 ColumnConstraint::GeneratedAsIdentity(gen) => {
21243 self.write_keyword("GENERATED");
21244 self.write_space();
21245 if gen.always {
21246 self.write_keyword("ALWAYS");
21247 } else {
21248 self.write_keyword("BY DEFAULT");
21249 if gen.on_null {
21250 self.write_space();
21251 self.write_keyword("ON NULL");
21252 }
21253 }
21254 self.write_space();
21255 self.write_keyword("AS IDENTITY");
21256 }
21257 ColumnConstraint::Collate(collation) => {
21258 self.write_keyword("COLLATE");
21259 self.write_space();
21260 self.generate_identifier(collation)?;
21261 }
21262 ColumnConstraint::Comment(comment) => {
21263 self.write_keyword("COMMENT");
21264 self.write(" '");
21265 self.write(comment);
21266 self.write("'");
21267 }
21268 ColumnConstraint::ComputedColumn(cc) => {
21269 self.generate_computed_column_inline(cc)?;
21270 }
21271 ColumnConstraint::GeneratedAsRow(gar) => {
21272 self.generate_generated_as_row_inline(gar)?;
21273 }
21274 ColumnConstraint::Tags(tags) => {
21275 self.write_keyword("TAG");
21276 self.write(" (");
21277 for (i, expr) in tags.expressions.iter().enumerate() {
21278 if i > 0 {
21279 self.write(", ");
21280 }
21281 self.generate_expression(expr)?;
21282 }
21283 self.write(")");
21284 }
21285 ColumnConstraint::Path(path_expr) => {
21286 self.write_keyword("PATH");
21287 self.write_space();
21288 self.generate_expression(path_expr)?;
21289 }
21290 }
21291 Ok(())
21292 }
21293
21294 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
21295 match e {
21297 ColumnPosition::First => {
21298 self.write_keyword("FIRST");
21299 }
21300 ColumnPosition::After(ident) => {
21301 self.write_keyword("AFTER");
21302 self.write_space();
21303 self.generate_identifier(ident)?;
21304 }
21305 }
21306 Ok(())
21307 }
21308
21309 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
21310 self.generate_expression(&e.this)?;
21312 self.write("(");
21313 self.generate_expression(&e.expression)?;
21314 self.write(")");
21315 Ok(())
21316 }
21317
21318 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
21319 if let Some(ref unpack) = e.unpack {
21322 if let Expression::Boolean(b) = unpack.as_ref() {
21323 if b.value {
21324 self.write("*");
21325 }
21326 }
21327 }
21328 self.write_keyword("COLUMNS");
21329 self.write("(");
21330 self.generate_expression(&e.this)?;
21331 self.write(")");
21332 Ok(())
21333 }
21334
21335 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
21336 self.generate_expression(&e.this)?;
21338 self.write("(");
21339 for (i, expr) in e.expressions.iter().enumerate() {
21340 if i > 0 {
21341 self.write(", ");
21342 }
21343 self.generate_expression(expr)?;
21344 }
21345 self.write(")");
21346 Ok(())
21347 }
21348
21349 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
21350 self.generate_expression(&e.this)?;
21352 self.write("(");
21353 for (i, param) in e.params.iter().enumerate() {
21354 if i > 0 {
21355 self.write(", ");
21356 }
21357 self.generate_expression(param)?;
21358 }
21359 self.write(")(");
21360 for (i, expr) in e.expressions.iter().enumerate() {
21361 if i > 0 {
21362 self.write(", ");
21363 }
21364 self.generate_expression(expr)?;
21365 }
21366 self.write(")");
21367 Ok(())
21368 }
21369
21370 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
21371 self.write_keyword("COMMIT");
21373
21374 if e.this.is_none() && matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) {
21376 self.write_space();
21377 self.write_keyword("TRANSACTION");
21378 }
21379
21380 if let Some(this) = &e.this {
21382 let is_transaction_marker = matches!(
21384 this.as_ref(),
21385 Expression::Identifier(id) if id.name == "TRANSACTION"
21386 );
21387
21388 self.write_space();
21389 self.write_keyword("TRANSACTION");
21390
21391 if !is_transaction_marker {
21393 self.write_space();
21394 self.generate_expression(this)?;
21395 }
21396 }
21397
21398 if let Some(durability) = &e.durability {
21400 self.write_space();
21401 self.write_keyword("WITH");
21402 self.write(" (");
21403 self.write_keyword("DELAYED_DURABILITY");
21404 self.write(" = ");
21405 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
21406 self.write_keyword("ON");
21407 } else {
21408 self.write_keyword("OFF");
21409 }
21410 self.write(")");
21411 }
21412
21413 if let Some(chain) = &e.chain {
21415 self.write_space();
21416 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
21417 self.write_keyword("AND NO CHAIN");
21418 } else {
21419 self.write_keyword("AND CHAIN");
21420 }
21421 }
21422 Ok(())
21423 }
21424
21425 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
21426 self.write("[");
21428 self.generate_expression(&e.this)?;
21429 self.write_space();
21430 self.write_keyword("FOR");
21431 self.write_space();
21432 self.generate_expression(&e.expression)?;
21433 if let Some(pos) = &e.position {
21435 self.write(", ");
21436 self.generate_expression(pos)?;
21437 }
21438 if let Some(iterator) = &e.iterator {
21439 self.write_space();
21440 self.write_keyword("IN");
21441 self.write_space();
21442 self.generate_expression(iterator)?;
21443 }
21444 if let Some(condition) = &e.condition {
21445 self.write_space();
21446 self.write_keyword("IF");
21447 self.write_space();
21448 self.generate_expression(condition)?;
21449 }
21450 self.write("]");
21451 Ok(())
21452 }
21453
21454 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
21455 self.write_keyword("COMPRESS");
21457 self.write("(");
21458 self.generate_expression(&e.this)?;
21459 if let Some(method) = &e.method {
21460 self.write(", '");
21461 self.write(method);
21462 self.write("'");
21463 }
21464 self.write(")");
21465 Ok(())
21466 }
21467
21468 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
21469 self.write_keyword("COMPRESS");
21471 if let Some(this) = &e.this {
21472 self.write_space();
21473 self.generate_expression(this)?;
21474 }
21475 Ok(())
21476 }
21477
21478 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
21479 self.write_keyword("AS");
21481 self.write_space();
21482 self.generate_expression(&e.this)?;
21483 if e.not_null.is_some() {
21484 self.write_space();
21485 self.write_keyword("PERSISTED NOT NULL");
21486 } else if e.persisted.is_some() {
21487 self.write_space();
21488 self.write_keyword("PERSISTED");
21489 }
21490 Ok(())
21491 }
21492
21493 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
21497 let computed_expr = if matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) {
21498 match &*cc.expression {
21499 Expression::Year(y)
21500 if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
21501 {
21502 let wrapped = Expression::Cast(Box::new(Cast {
21503 this: y.this.clone(),
21504 to: DataType::Date,
21505 trailing_comments: Vec::new(),
21506 double_colon_syntax: false,
21507 format: None,
21508 default: None,
21509 }));
21510 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
21511 }
21512 Expression::Function(f)
21513 if f.name.eq_ignore_ascii_case("YEAR")
21514 && f.args.len() == 1
21515 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
21516 {
21517 let wrapped = Expression::Cast(Box::new(Cast {
21518 this: f.args[0].clone(),
21519 to: DataType::Date,
21520 trailing_comments: Vec::new(),
21521 double_colon_syntax: false,
21522 format: None,
21523 default: None,
21524 }));
21525 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
21526 }
21527 _ => *cc.expression.clone(),
21528 }
21529 } else {
21530 *cc.expression.clone()
21531 };
21532
21533 match cc.persistence_kind.as_deref() {
21534 Some("STORED") | Some("VIRTUAL") => {
21535 self.write_keyword("GENERATED ALWAYS AS");
21537 self.write(" (");
21538 self.generate_expression(&computed_expr)?;
21539 self.write(")");
21540 self.write_space();
21541 if cc.persisted {
21542 self.write_keyword("STORED");
21543 } else {
21544 self.write_keyword("VIRTUAL");
21545 }
21546 }
21547 Some("PERSISTED") => {
21548 self.write_keyword("AS");
21550 self.write(" (");
21551 self.generate_expression(&computed_expr)?;
21552 self.write(")");
21553 self.write_space();
21554 self.write_keyword("PERSISTED");
21555 if let Some(ref dt) = cc.data_type {
21557 self.write_space();
21558 self.generate_data_type(dt)?;
21559 }
21560 if cc.not_null {
21561 self.write_space();
21562 self.write_keyword("NOT NULL");
21563 }
21564 }
21565 _ => {
21566 if matches!(
21569 self.config.dialect,
21570 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
21571 ) {
21572 self.write_keyword("GENERATED ALWAYS AS");
21573 self.write(" (");
21574 self.generate_expression(&computed_expr)?;
21575 self.write(")");
21576 } else if matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) {
21577 self.write_keyword("AS");
21578 let omit_parens = matches!(computed_expr, Expression::Year(_))
21579 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
21580 if omit_parens {
21581 self.write_space();
21582 self.generate_expression(&computed_expr)?;
21583 } else {
21584 self.write(" (");
21585 self.generate_expression(&computed_expr)?;
21586 self.write(")");
21587 }
21588 } else {
21589 self.write_keyword("AS");
21590 self.write(" (");
21591 self.generate_expression(&computed_expr)?;
21592 self.write(")");
21593 }
21594 }
21595 }
21596 Ok(())
21597 }
21598
21599 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
21602 self.write_keyword("GENERATED ALWAYS AS ROW ");
21603 if gar.start {
21604 self.write_keyword("START");
21605 } else {
21606 self.write_keyword("END");
21607 }
21608 if gar.hidden {
21609 self.write_space();
21610 self.write_keyword("HIDDEN");
21611 }
21612 Ok(())
21613 }
21614
21615 fn generate_system_versioning_content(&mut self, e: &WithSystemVersioningProperty) -> Result<()> {
21617 let mut parts = Vec::new();
21618
21619 if let Some(this) = &e.this {
21620 let mut s = String::from("HISTORY_TABLE=");
21621 let mut gen = Generator::new();
21622 gen.config = self.config.clone();
21623 gen.generate_expression(this)?;
21624 s.push_str(&gen.output);
21625 parts.push(s);
21626 }
21627
21628 if let Some(data_consistency) = &e.data_consistency {
21629 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
21630 let mut gen = Generator::new();
21631 gen.config = self.config.clone();
21632 gen.generate_expression(data_consistency)?;
21633 s.push_str(&gen.output);
21634 parts.push(s);
21635 }
21636
21637 if let Some(retention_period) = &e.retention_period {
21638 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
21639 let mut gen = Generator::new();
21640 gen.config = self.config.clone();
21641 gen.generate_expression(retention_period)?;
21642 s.push_str(&gen.output);
21643 parts.push(s);
21644 }
21645
21646 self.write_keyword("SYSTEM_VERSIONING");
21647 self.write("=");
21648
21649 if !parts.is_empty() {
21650 self.write_keyword("ON");
21651 self.write("(");
21652 self.write(&parts.join(", "));
21653 self.write(")");
21654 } else if e.on.is_some() {
21655 self.write_keyword("ON");
21656 } else {
21657 self.write_keyword("OFF");
21658 }
21659
21660 Ok(())
21661 }
21662
21663 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
21664 if e.else_.is_some() {
21667 self.write_keyword("ELSE");
21668 self.write_space();
21669 } else if let Some(expression) = &e.expression {
21670 self.write_keyword("WHEN");
21671 self.write_space();
21672 self.generate_expression(expression)?;
21673 self.write_space();
21674 self.write_keyword("THEN");
21675 self.write_space();
21676 }
21677
21678 if let Expression::Insert(insert) = e.this.as_ref() {
21681 self.write_keyword("INTO");
21682 self.write_space();
21683 self.generate_table(&insert.table)?;
21684
21685 if !insert.columns.is_empty() {
21687 self.write(" (");
21688 for (i, col) in insert.columns.iter().enumerate() {
21689 if i > 0 {
21690 self.write(", ");
21691 }
21692 self.generate_identifier(col)?;
21693 }
21694 self.write(")");
21695 }
21696
21697 if !insert.values.is_empty() {
21699 self.write_space();
21700 self.write_keyword("VALUES");
21701 for (row_idx, row) in insert.values.iter().enumerate() {
21702 if row_idx > 0 {
21703 self.write(", ");
21704 }
21705 self.write(" (");
21706 for (i, val) in row.iter().enumerate() {
21707 if i > 0 {
21708 self.write(", ");
21709 }
21710 self.generate_expression(val)?;
21711 }
21712 self.write(")");
21713 }
21714 }
21715 } else {
21716 self.generate_expression(&e.this)?;
21718 }
21719 Ok(())
21720 }
21721
21722 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
21723 self.write_keyword("CONSTRAINT");
21725 self.write_space();
21726 self.generate_expression(&e.this)?;
21727 if !e.expressions.is_empty() {
21728 self.write_space();
21729 for (i, expr) in e.expressions.iter().enumerate() {
21730 if i > 0 {
21731 self.write_space();
21732 }
21733 self.generate_expression(expr)?;
21734 }
21735 }
21736 Ok(())
21737 }
21738
21739 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
21740 self.write_keyword("CONVERT_TIMEZONE");
21742 self.write("(");
21743 let mut first = true;
21744 if let Some(source_tz) = &e.source_tz {
21745 self.generate_expression(source_tz)?;
21746 first = false;
21747 }
21748 if let Some(target_tz) = &e.target_tz {
21749 if !first {
21750 self.write(", ");
21751 }
21752 self.generate_expression(target_tz)?;
21753 first = false;
21754 }
21755 if let Some(timestamp) = &e.timestamp {
21756 if !first {
21757 self.write(", ");
21758 }
21759 self.generate_expression(timestamp)?;
21760 }
21761 self.write(")");
21762 Ok(())
21763 }
21764
21765 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
21766 self.write_keyword("CONVERT");
21768 self.write("(");
21769 self.generate_expression(&e.this)?;
21770 if let Some(dest) = &e.dest {
21771 self.write_space();
21772 self.write_keyword("USING");
21773 self.write_space();
21774 self.generate_expression(dest)?;
21775 }
21776 self.write(")");
21777 Ok(())
21778 }
21779
21780 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
21781 self.write_keyword("COPY");
21782 if e.is_into {
21783 self.write_space();
21784 self.write_keyword("INTO");
21785 }
21786 self.write_space();
21787
21788 if let Expression::Literal(Literal::String(s)) = &e.this {
21790 if s.starts_with('@') {
21791 self.write(s);
21792 } else {
21793 self.generate_expression(&e.this)?;
21794 }
21795 } else {
21796 self.generate_expression(&e.this)?;
21797 }
21798
21799 if e.kind {
21801 if self.config.pretty {
21803 self.write_newline();
21804 } else {
21805 self.write_space();
21806 }
21807 self.write_keyword("FROM");
21808 self.write_space();
21809 } else if !e.files.is_empty() {
21810 if self.config.pretty {
21812 self.write_newline();
21813 } else {
21814 self.write_space();
21815 }
21816 self.write_keyword("TO");
21817 self.write_space();
21818 }
21819
21820 for (i, file) in e.files.iter().enumerate() {
21822 if i > 0 {
21823 self.write_space();
21824 }
21825 if let Expression::Literal(Literal::String(s)) = file {
21827 if s.starts_with('@') {
21828 self.write(s);
21829 } else {
21830 self.generate_expression(file)?;
21831 }
21832 } else if let Expression::Identifier(id) = file {
21833 if id.quoted {
21835 self.write("`");
21836 self.write(&id.name);
21837 self.write("`");
21838 } else {
21839 self.generate_expression(file)?;
21840 }
21841 } else {
21842 self.generate_expression(file)?;
21843 }
21844 }
21845
21846 if !e.with_wrapped {
21848 if let Some(ref creds) = e.credentials {
21849 if let Some(ref storage) = creds.storage {
21850 if self.config.pretty { self.write_newline(); } else { self.write_space(); }
21851 self.write_keyword("STORAGE_INTEGRATION");
21852 self.write(" = ");
21853 self.write(storage);
21854 }
21855 if creds.credentials.is_empty() {
21856 if self.config.pretty { self.write_newline(); } else { self.write_space(); }
21858 self.write_keyword("CREDENTIALS");
21859 self.write(" = ()");
21860 } else {
21861 if self.config.pretty { self.write_newline(); } else { self.write_space(); }
21862 self.write_keyword("CREDENTIALS");
21863 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
21866 self.write(" '");
21868 self.write(&creds.credentials[0].1);
21869 self.write("'");
21870 } else {
21871 self.write(" = (");
21873 for (i, (k, v)) in creds.credentials.iter().enumerate() {
21874 if i > 0 {
21875 self.write_space();
21876 }
21877 self.write(k);
21878 self.write("='");
21879 self.write(v);
21880 self.write("'");
21881 }
21882 self.write(")");
21883 }
21884 }
21885 if let Some(ref encryption) = creds.encryption {
21886 self.write_space();
21887 self.write_keyword("ENCRYPTION");
21888 self.write(" = ");
21889 self.write(encryption);
21890 }
21891 }
21892 }
21893
21894 if !e.params.is_empty() {
21896 if e.with_wrapped {
21897 self.write_space();
21899 self.write_keyword("WITH");
21900 self.write(" (");
21901 for (i, param) in e.params.iter().enumerate() {
21902 if i > 0 {
21903 self.write(", ");
21904 }
21905 self.generate_copy_param_with_format(param)?;
21906 }
21907 self.write(")");
21908 } else {
21909 for param in &e.params {
21913 if self.config.pretty { self.write_newline(); } else { self.write_space(); }
21914 self.write(¶m.name);
21916 if let Some(ref value) = param.value {
21917 if param.eq {
21919 self.write(" = ");
21920 } else {
21921 self.write(" ");
21922 }
21923 if !param.values.is_empty() {
21924 self.write("(");
21925 for (i, v) in param.values.iter().enumerate() {
21926 if i > 0 {
21927 self.write_space();
21928 }
21929 self.generate_copy_nested_param(v)?;
21930 }
21931 self.write(")");
21932 } else {
21933 self.generate_copy_param_value(value)?;
21935 }
21936 } else if !param.values.is_empty() {
21937 if param.eq {
21939 self.write(" = (");
21940 } else {
21941 self.write(" (");
21942 }
21943 let is_key_value_pairs = param.values.first().map_or(false, |v| matches!(v, Expression::Eq(_)));
21948 let sep = if is_key_value_pairs && param.eq { " " } else { ", " };
21949 for (i, v) in param.values.iter().enumerate() {
21950 if i > 0 {
21951 self.write(sep);
21952 }
21953 self.generate_copy_nested_param(v)?;
21954 }
21955 self.write(")");
21956 }
21957 }
21958 }
21959 }
21960
21961 Ok(())
21962 }
21963
21964 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
21967 self.write_keyword(¶m.name);
21968 if !param.values.is_empty() {
21969 self.write(" = (");
21971 for (i, v) in param.values.iter().enumerate() {
21972 if i > 0 {
21973 self.write(", ");
21974 }
21975 self.generate_copy_nested_param(v)?;
21976 }
21977 self.write(")");
21978 } else if let Some(ref value) = param.value {
21979 if param.eq {
21980 self.write(" = ");
21981 } else {
21982 self.write(" ");
21983 }
21984 self.generate_expression(value)?;
21985 }
21986 Ok(())
21987 }
21988
21989 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
21991 match expr {
21992 Expression::Eq(eq) => {
21993 match &eq.left {
21995 Expression::Column(c) => self.write(&c.name.name),
21996 _ => self.generate_expression(&eq.left)?,
21997 }
21998 self.write("=");
21999 match &eq.right {
22001 Expression::Literal(Literal::String(s)) => {
22002 self.write("'");
22003 self.write(s);
22004 self.write("'");
22005 }
22006 Expression::Tuple(t) => {
22007 self.write("(");
22009 if self.config.pretty {
22010 self.write_newline();
22011 self.indent_level += 1;
22012 for (i, item) in t.expressions.iter().enumerate() {
22013 if i > 0 {
22014 self.write(", ");
22015 }
22016 self.write_indent();
22017 self.generate_expression(item)?;
22018 }
22019 self.write_newline();
22020 self.indent_level -= 1;
22021 } else {
22022 for (i, item) in t.expressions.iter().enumerate() {
22023 if i > 0 {
22024 self.write(", ");
22025 }
22026 self.generate_expression(item)?;
22027 }
22028 }
22029 self.write(")");
22030 }
22031 _ => self.generate_expression(&eq.right)?,
22032 }
22033 Ok(())
22034 }
22035 Expression::Column(c) => {
22036 self.write(&c.name.name);
22038 Ok(())
22039 }
22040 _ => self.generate_expression(expr),
22041 }
22042 }
22043
22044 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
22047 match expr {
22048 Expression::Column(c) => {
22049 if c.name.quoted {
22051 self.write("\"");
22052 self.write(&c.name.name);
22053 self.write("\"");
22054 } else {
22055 self.write(&c.name.name);
22056 }
22057 Ok(())
22058 }
22059 Expression::Identifier(id) => {
22060 if id.quoted {
22062 self.write("\"");
22063 self.write(&id.name);
22064 self.write("\"");
22065 } else {
22066 self.write(&id.name);
22067 }
22068 Ok(())
22069 }
22070 Expression::Literal(Literal::String(s)) => {
22071 self.write("'");
22073 self.write(s);
22074 self.write("'");
22075 Ok(())
22076 }
22077 _ => self.generate_expression(expr),
22078 }
22079 }
22080
22081 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
22082 self.write_keyword(&e.name);
22083 if let Some(ref value) = e.value {
22084 if e.eq {
22085 self.write(" = ");
22086 } else {
22087 self.write(" ");
22088 }
22089 self.generate_expression(value)?;
22090 }
22091 if !e.values.is_empty() {
22092 if e.eq {
22093 self.write(" = ");
22094 } else {
22095 self.write(" ");
22096 }
22097 self.write("(");
22098 for (i, v) in e.values.iter().enumerate() {
22099 if i > 0 {
22100 self.write(", ");
22101 }
22102 self.generate_expression(v)?;
22103 }
22104 self.write(")");
22105 }
22106 Ok(())
22107 }
22108
22109 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
22110 self.write_keyword("CORR");
22112 self.write("(");
22113 self.generate_expression(&e.this)?;
22114 self.write(", ");
22115 self.generate_expression(&e.expression)?;
22116 self.write(")");
22117 Ok(())
22118 }
22119
22120 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
22121 self.write_keyword("COSINE_DISTANCE");
22123 self.write("(");
22124 self.generate_expression(&e.this)?;
22125 self.write(", ");
22126 self.generate_expression(&e.expression)?;
22127 self.write(")");
22128 Ok(())
22129 }
22130
22131 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
22132 self.write_keyword("COVAR_POP");
22134 self.write("(");
22135 self.generate_expression(&e.this)?;
22136 self.write(", ");
22137 self.generate_expression(&e.expression)?;
22138 self.write(")");
22139 Ok(())
22140 }
22141
22142 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
22143 self.write_keyword("COVAR_SAMP");
22145 self.write("(");
22146 self.generate_expression(&e.this)?;
22147 self.write(", ");
22148 self.generate_expression(&e.expression)?;
22149 self.write(")");
22150 Ok(())
22151 }
22152
22153 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
22154 self.write_keyword("CREDENTIALS");
22156 self.write(" (");
22157 for (i, (key, value)) in e.credentials.iter().enumerate() {
22158 if i > 0 {
22159 self.write(", ");
22160 }
22161 self.write(key);
22162 self.write("='");
22163 self.write(value);
22164 self.write("'");
22165 }
22166 self.write(")");
22167 Ok(())
22168 }
22169
22170 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
22171 self.write_keyword("CREDENTIALS");
22173 self.write("=(");
22174 for (i, expr) in e.expressions.iter().enumerate() {
22175 if i > 0 {
22176 self.write(", ");
22177 }
22178 self.generate_expression(expr)?;
22179 }
22180 self.write(")");
22181 Ok(())
22182 }
22183
22184 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
22185 use crate::dialects::DialectType;
22186
22187 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
22190 self.generate_expression(&e.this)?;
22191 self.write_space();
22192 self.write_keyword("AS");
22193 self.write_space();
22194 self.generate_identifier(&e.alias)?;
22195 return Ok(());
22196 }
22197 self.write(&e.alias.name);
22198
22199 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
22201
22202 if !e.columns.is_empty() && !skip_cte_columns {
22203 self.write("(");
22204 for (i, col) in e.columns.iter().enumerate() {
22205 if i > 0 {
22206 self.write(", ");
22207 }
22208 self.write(&col.name);
22209 }
22210 self.write(")");
22211 }
22212 if !e.key_expressions.is_empty() {
22214 self.write_space();
22215 self.write_keyword("USING KEY");
22216 self.write(" (");
22217 for (i, key) in e.key_expressions.iter().enumerate() {
22218 if i > 0 {
22219 self.write(", ");
22220 }
22221 self.write(&key.name);
22222 }
22223 self.write(")");
22224 }
22225 self.write_space();
22226 self.write_keyword("AS");
22227 self.write_space();
22228 if let Some(materialized) = e.materialized {
22229 if materialized {
22230 self.write_keyword("MATERIALIZED");
22231 } else {
22232 self.write_keyword("NOT MATERIALIZED");
22233 }
22234 self.write_space();
22235 }
22236 self.write("(");
22237 self.generate_expression(&e.this)?;
22238 self.write(")");
22239 Ok(())
22240 }
22241
22242 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
22243 if e.expressions.is_empty() {
22245 self.write_keyword("WITH CUBE");
22246 } else {
22247 self.write_keyword("CUBE");
22248 self.write("(");
22249 for (i, expr) in e.expressions.iter().enumerate() {
22250 if i > 0 {
22251 self.write(", ");
22252 }
22253 self.generate_expression(expr)?;
22254 }
22255 self.write(")");
22256 }
22257 Ok(())
22258 }
22259
22260 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
22261 self.write_keyword("CURRENT_DATETIME");
22263 if let Some(this) = &e.this {
22264 self.write("(");
22265 self.generate_expression(this)?;
22266 self.write(")");
22267 }
22268 Ok(())
22269 }
22270
22271 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
22272 self.write_keyword("CURRENT_SCHEMA");
22274 Ok(())
22275 }
22276
22277 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
22278 self.write_keyword("CURRENT_SCHEMAS");
22280 self.write("(");
22281 if let Some(this) = &e.this {
22282 self.generate_expression(this)?;
22283 }
22284 self.write(")");
22285 Ok(())
22286 }
22287
22288 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
22289 self.write_keyword("CURRENT_USER");
22291 let needs_parens = e.this.is_some() || matches!(
22293 self.config.dialect,
22294 Some(DialectType::Snowflake) | Some(DialectType::Spark)
22295 | Some(DialectType::Hive) | Some(DialectType::DuckDB) | Some(DialectType::BigQuery)
22296 | Some(DialectType::MySQL) | Some(DialectType::Databricks)
22297 );
22298 if needs_parens {
22299 self.write("()");
22300 }
22301 Ok(())
22302 }
22303
22304 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
22305 if self.config.dialect == Some(DialectType::Solr) {
22307 self.generate_expression(&e.this)?;
22308 self.write(" ");
22309 self.write_keyword("OR");
22310 self.write(" ");
22311 self.generate_expression(&e.expression)?;
22312 } else {
22313 self.generate_expression(&e.this)?;
22315 self.write(" || ");
22316 self.generate_expression(&e.expression)?;
22317 }
22318 Ok(())
22319 }
22320
22321 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
22322 self.write_keyword("DATABLOCKSIZE");
22324 self.write("=");
22325 if let Some(size) = e.size {
22326 self.write(&size.to_string());
22327 if let Some(units) = &e.units {
22328 self.write_space();
22329 self.generate_expression(units)?;
22330 }
22331 } else if e.minimum.is_some() {
22332 self.write_keyword("MINIMUM");
22333 } else if e.maximum.is_some() {
22334 self.write_keyword("MAXIMUM");
22335 } else if e.default.is_some() {
22336 self.write_keyword("DEFAULT");
22337 }
22338 Ok(())
22339 }
22340
22341 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
22342 self.write_keyword("DATA_DELETION");
22344 self.write("=");
22345
22346 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
22347 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
22348
22349 if is_on {
22350 self.write_keyword("ON");
22351 if has_options {
22352 self.write("(");
22353 let mut first = true;
22354 if let Some(filter_column) = &e.filter_column {
22355 self.write_keyword("FILTER_COLUMN");
22356 self.write("=");
22357 self.generate_expression(filter_column)?;
22358 first = false;
22359 }
22360 if let Some(retention_period) = &e.retention_period {
22361 if !first {
22362 self.write(", ");
22363 }
22364 self.write_keyword("RETENTION_PERIOD");
22365 self.write("=");
22366 self.generate_expression(retention_period)?;
22367 }
22368 self.write(")");
22369 }
22370 } else {
22371 self.write_keyword("OFF");
22372 }
22373 Ok(())
22374 }
22375
22376 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
22380 use crate::dialects::DialectType;
22381 use crate::expressions::Literal;
22382
22383 match self.config.dialect {
22384 Some(DialectType::Exasol) => {
22386 self.write_keyword("TO_DATE");
22387 self.write("(");
22388 match &e.this {
22390 Expression::Literal(Literal::String(s)) => {
22391 self.write("'");
22392 self.write(s);
22393 self.write("'");
22394 }
22395 _ => {
22396 self.generate_expression(&e.this)?;
22397 }
22398 }
22399 self.write(")");
22400 }
22401 _ => {
22403 self.write_keyword("DATE");
22404 self.write("(");
22405 self.generate_expression(&e.this)?;
22406 self.write(")");
22407 }
22408 }
22409 Ok(())
22410 }
22411
22412 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
22413 self.write_keyword("DATE_BIN");
22415 self.write("(");
22416 self.generate_expression(&e.this)?;
22417 self.write(", ");
22418 self.generate_expression(&e.expression)?;
22419 if let Some(origin) = &e.origin {
22420 self.write(", ");
22421 self.generate_expression(origin)?;
22422 }
22423 self.write(")");
22424 Ok(())
22425 }
22426
22427 fn generate_date_format_column_constraint(&mut self, e: &DateFormatColumnConstraint) -> Result<()> {
22428 self.write_keyword("FORMAT");
22430 self.write_space();
22431 self.generate_expression(&e.this)?;
22432 Ok(())
22433 }
22434
22435 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
22436 self.write_keyword("DATE_FROM_PARTS");
22438 self.write("(");
22439 let mut first = true;
22440 if let Some(year) = &e.year {
22441 self.generate_expression(year)?;
22442 first = false;
22443 }
22444 if let Some(month) = &e.month {
22445 if !first {
22446 self.write(", ");
22447 }
22448 self.generate_expression(month)?;
22449 first = false;
22450 }
22451 if let Some(day) = &e.day {
22452 if !first {
22453 self.write(", ");
22454 }
22455 self.generate_expression(day)?;
22456 }
22457 self.write(")");
22458 Ok(())
22459 }
22460
22461 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
22462 self.write_keyword("DATETIME");
22464 self.write("(");
22465 self.generate_expression(&e.this)?;
22466 if let Some(expr) = &e.expression {
22467 self.write(", ");
22468 self.generate_expression(expr)?;
22469 }
22470 self.write(")");
22471 Ok(())
22472 }
22473
22474 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
22475 self.write_keyword("DATETIME_ADD");
22477 self.write("(");
22478 self.generate_expression(&e.this)?;
22479 self.write(", ");
22480 self.generate_expression(&e.expression)?;
22481 if let Some(unit) = &e.unit {
22482 self.write(", ");
22483 self.write_keyword(unit);
22484 }
22485 self.write(")");
22486 Ok(())
22487 }
22488
22489 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
22490 self.write_keyword("DATETIME_DIFF");
22492 self.write("(");
22493 self.generate_expression(&e.this)?;
22494 self.write(", ");
22495 self.generate_expression(&e.expression)?;
22496 if let Some(unit) = &e.unit {
22497 self.write(", ");
22498 self.write_keyword(unit);
22499 }
22500 self.write(")");
22501 Ok(())
22502 }
22503
22504 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
22505 self.write_keyword("DATETIME_SUB");
22507 self.write("(");
22508 self.generate_expression(&e.this)?;
22509 self.write(", ");
22510 self.generate_expression(&e.expression)?;
22511 if let Some(unit) = &e.unit {
22512 self.write(", ");
22513 self.write_keyword(unit);
22514 }
22515 self.write(")");
22516 Ok(())
22517 }
22518
22519 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
22520 self.write_keyword("DATETIME_TRUNC");
22522 self.write("(");
22523 self.generate_expression(&e.this)?;
22524 self.write(", ");
22525 self.write_keyword(&e.unit);
22526 if let Some(zone) = &e.zone {
22527 self.write(", ");
22528 self.generate_expression(zone)?;
22529 }
22530 self.write(")");
22531 Ok(())
22532 }
22533
22534 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
22535 self.write_keyword("DAYNAME");
22537 self.write("(");
22538 self.generate_expression(&e.this)?;
22539 self.write(")");
22540 Ok(())
22541 }
22542
22543 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
22544 self.write_keyword("DECLARE");
22546 self.write_space();
22547 for (i, expr) in e.expressions.iter().enumerate() {
22548 if i > 0 {
22549 self.write(", ");
22550 }
22551 self.generate_expression(expr)?;
22552 }
22553 Ok(())
22554 }
22555
22556 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
22557 use crate::dialects::DialectType;
22558
22559 self.generate_expression(&e.this)?;
22561 for name in &e.additional_names {
22563 self.write(", ");
22564 self.generate_expression(name)?;
22565 }
22566 if let Some(kind) = &e.kind {
22567 self.write_space();
22568 match self.config.dialect {
22572 Some(DialectType::BigQuery) => {
22573 self.write(kind);
22574 }
22575 Some(DialectType::TSQL) => {
22576 let is_complex_table = kind.starts_with("TABLE") &&
22580 (kind.contains("CLUSTERED") || kind.contains("INDEX"));
22581
22582 if is_complex_table {
22583 self.write(kind);
22585 } else {
22586 if !kind.starts_with("CURSOR") {
22588 self.write_keyword("AS");
22589 self.write_space();
22590 }
22591 if kind == "INT" {
22593 self.write("INTEGER");
22594 } else if kind.starts_with("TABLE") {
22595 let normalized = kind
22597 .replace(" INT ", " INTEGER ")
22598 .replace(" INT,", " INTEGER,")
22599 .replace(" INT)", " INTEGER)")
22600 .replace("(INT ", "(INTEGER ");
22601 self.write(&normalized);
22602 } else {
22603 self.write(kind);
22604 }
22605 }
22606 }
22607 _ => {
22608 if e.has_as {
22609 self.write_keyword("AS");
22610 self.write_space();
22611 }
22612 self.write(kind);
22613 }
22614 }
22615 }
22616 if let Some(default) = &e.default {
22617 match self.config.dialect {
22619 Some(DialectType::BigQuery) => {
22620 self.write_space();
22621 self.write_keyword("DEFAULT");
22622 self.write_space();
22623 }
22624 _ => {
22625 self.write(" = ");
22626 }
22627 }
22628 self.generate_expression(default)?;
22629 }
22630 Ok(())
22631 }
22632
22633 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
22634 self.write_keyword("DECODE");
22636 self.write("(");
22637 for (i, expr) in e.expressions.iter().enumerate() {
22638 if i > 0 {
22639 self.write(", ");
22640 }
22641 self.generate_expression(expr)?;
22642 }
22643 self.write(")");
22644 Ok(())
22645 }
22646
22647 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
22648 self.write_keyword("DECOMPRESS");
22650 self.write("(");
22651 self.generate_expression(&e.this)?;
22652 self.write(", '");
22653 self.write(&e.method);
22654 self.write("')");
22655 Ok(())
22656 }
22657
22658 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
22659 self.write_keyword("DECOMPRESS");
22661 self.write("(");
22662 self.generate_expression(&e.this)?;
22663 self.write(", '");
22664 self.write(&e.method);
22665 self.write("')");
22666 Ok(())
22667 }
22668
22669 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
22670 self.write_keyword("DECRYPT");
22672 self.write("(");
22673 self.generate_expression(&e.this)?;
22674 if let Some(passphrase) = &e.passphrase {
22675 self.write(", ");
22676 self.generate_expression(passphrase)?;
22677 }
22678 if let Some(aad) = &e.aad {
22679 self.write(", ");
22680 self.generate_expression(aad)?;
22681 }
22682 if let Some(method) = &e.encryption_method {
22683 self.write(", ");
22684 self.generate_expression(method)?;
22685 }
22686 self.write(")");
22687 Ok(())
22688 }
22689
22690 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
22691 self.write_keyword("DECRYPT_RAW");
22693 self.write("(");
22694 self.generate_expression(&e.this)?;
22695 if let Some(key) = &e.key {
22696 self.write(", ");
22697 self.generate_expression(key)?;
22698 }
22699 if let Some(iv) = &e.iv {
22700 self.write(", ");
22701 self.generate_expression(iv)?;
22702 }
22703 if let Some(aad) = &e.aad {
22704 self.write(", ");
22705 self.generate_expression(aad)?;
22706 }
22707 if let Some(method) = &e.encryption_method {
22708 self.write(", ");
22709 self.generate_expression(method)?;
22710 }
22711 self.write(")");
22712 Ok(())
22713 }
22714
22715 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
22716 self.write_keyword("DEFINER");
22718 self.write(" = ");
22719 self.generate_expression(&e.this)?;
22720 Ok(())
22721 }
22722
22723 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
22724 self.write_keyword("DETACH");
22726 if e.exists {
22727 self.write_keyword(" DATABASE IF EXISTS");
22728 }
22729 self.write_space();
22730 self.generate_expression(&e.this)?;
22731 Ok(())
22732 }
22733
22734 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
22735 let property_name = match e.this.as_ref() {
22736 Expression::Identifier(id) => id.name.as_str(),
22737 Expression::Var(v) => v.this.as_str(),
22738 _ => "DICTIONARY",
22739 };
22740 self.write_keyword(property_name);
22741 self.write("(");
22742 self.write(&e.kind);
22743 if let Some(settings) = &e.settings {
22744 self.write("(");
22745 if let Expression::Tuple(t) = settings.as_ref() {
22746 if self.config.pretty && !t.expressions.is_empty() {
22747 self.write_newline();
22748 self.indent_level += 1;
22749 for (i, pair) in t.expressions.iter().enumerate() {
22750 if i > 0 {
22751 self.write(",");
22752 self.write_newline();
22753 }
22754 self.write_indent();
22755 if let Expression::Tuple(pair_tuple) = pair {
22756 if let Some(k) = pair_tuple.expressions.first() {
22757 self.generate_expression(k)?;
22758 }
22759 if let Some(v) = pair_tuple.expressions.get(1) {
22760 self.write(" ");
22761 self.generate_expression(v)?;
22762 }
22763 } else {
22764 self.generate_expression(pair)?;
22765 }
22766 }
22767 self.indent_level -= 1;
22768 self.write_newline();
22769 self.write_indent();
22770 } else {
22771 for (i, pair) in t.expressions.iter().enumerate() {
22772 if i > 0 {
22773 self.write(", ");
22774 }
22775 if let Expression::Tuple(pair_tuple) = pair {
22776 if let Some(k) = pair_tuple.expressions.first() {
22777 self.generate_expression(k)?;
22778 }
22779 if let Some(v) = pair_tuple.expressions.get(1) {
22780 self.write(" ");
22781 self.generate_expression(v)?;
22782 }
22783 } else {
22784 self.generate_expression(pair)?;
22785 }
22786 }
22787 }
22788 } else {
22789 self.generate_expression(settings)?;
22790 }
22791 self.write(")");
22792 } else if property_name.eq_ignore_ascii_case("LAYOUT") {
22793 self.write("()");
22794 }
22795 self.write(")");
22796 Ok(())
22797 }
22798
22799 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
22800 let property_name = match e.this.as_ref() {
22801 Expression::Identifier(id) => id.name.as_str(),
22802 Expression::Var(v) => v.this.as_str(),
22803 _ => "RANGE",
22804 };
22805 self.write_keyword(property_name);
22806 self.write("(");
22807 if let Some(min) = &e.min {
22808 self.write_keyword("MIN");
22809 self.write_space();
22810 self.generate_expression(min)?;
22811 }
22812 if let Some(max) = &e.max {
22813 self.write_space();
22814 self.write_keyword("MAX");
22815 self.write_space();
22816 self.generate_expression(max)?;
22817 }
22818 self.write(")");
22819 Ok(())
22820 }
22821
22822 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
22823 if e.local.is_some() {
22825 self.write_keyword("LOCAL ");
22826 }
22827 self.write_keyword("DIRECTORY");
22828 self.write_space();
22829 self.generate_expression(&e.this)?;
22830 if let Some(row_format) = &e.row_format {
22831 self.write_space();
22832 self.generate_expression(row_format)?;
22833 }
22834 Ok(())
22835 }
22836
22837 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
22838 self.write_keyword("DISTKEY");
22840 self.write("(");
22841 self.generate_expression(&e.this)?;
22842 self.write(")");
22843 Ok(())
22844 }
22845
22846 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
22847 self.write_keyword("DISTSTYLE");
22849 self.write_space();
22850 self.generate_expression(&e.this)?;
22851 Ok(())
22852 }
22853
22854 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
22855 self.write_keyword("DISTRIBUTE BY");
22857 self.write_space();
22858 for (i, expr) in e.expressions.iter().enumerate() {
22859 if i > 0 {
22860 self.write(", ");
22861 }
22862 self.generate_expression(expr)?;
22863 }
22864 Ok(())
22865 }
22866
22867 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
22868 self.write_keyword("DISTRIBUTED BY");
22870 self.write_space();
22871 self.write(&e.kind);
22872 if !e.expressions.is_empty() {
22873 self.write(" (");
22874 for (i, expr) in e.expressions.iter().enumerate() {
22875 if i > 0 {
22876 self.write(", ");
22877 }
22878 self.generate_expression(expr)?;
22879 }
22880 self.write(")");
22881 }
22882 if let Some(buckets) = &e.buckets {
22883 self.write_space();
22884 self.write_keyword("BUCKETS");
22885 self.write_space();
22886 self.generate_expression(buckets)?;
22887 }
22888 if let Some(order) = &e.order {
22889 self.write_space();
22890 self.generate_expression(order)?;
22891 }
22892 Ok(())
22893 }
22894
22895 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
22896 self.write_keyword("DOT_PRODUCT");
22898 self.write("(");
22899 self.generate_expression(&e.this)?;
22900 self.write(", ");
22901 self.generate_expression(&e.expression)?;
22902 self.write(")");
22903 Ok(())
22904 }
22905
22906 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
22907 self.write_keyword("DROP");
22909 if e.exists {
22910 self.write_keyword(" IF EXISTS ");
22911 } else {
22912 self.write_space();
22913 }
22914 for (i, expr) in e.expressions.iter().enumerate() {
22915 if i > 0 {
22916 self.write(", ");
22917 }
22918 self.generate_expression(expr)?;
22919 }
22920 Ok(())
22921 }
22922
22923 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
22924 self.write_keyword("DUPLICATE KEY");
22926 self.write(" (");
22927 for (i, expr) in e.expressions.iter().enumerate() {
22928 if i > 0 {
22929 self.write(", ");
22930 }
22931 self.generate_expression(expr)?;
22932 }
22933 self.write(")");
22934 Ok(())
22935 }
22936
22937 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
22938 self.write_keyword("ELT");
22940 self.write("(");
22941 self.generate_expression(&e.this)?;
22942 for expr in &e.expressions {
22943 self.write(", ");
22944 self.generate_expression(expr)?;
22945 }
22946 self.write(")");
22947 Ok(())
22948 }
22949
22950 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
22951 self.write_keyword("ENCODE");
22953 self.write("(");
22954 self.generate_expression(&e.this)?;
22955 if let Some(charset) = &e.charset {
22956 self.write(", ");
22957 self.generate_expression(charset)?;
22958 }
22959 self.write(")");
22960 Ok(())
22961 }
22962
22963 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
22964 if e.key.is_some() {
22966 self.write_keyword("KEY ");
22967 }
22968 self.write_keyword("ENCODE");
22969 self.write_space();
22970 self.generate_expression(&e.this)?;
22971 if !e.properties.is_empty() {
22972 self.write(" (");
22973 for (i, prop) in e.properties.iter().enumerate() {
22974 if i > 0 {
22975 self.write(", ");
22976 }
22977 self.generate_expression(prop)?;
22978 }
22979 self.write(")");
22980 }
22981 Ok(())
22982 }
22983
22984 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
22985 self.write_keyword("ENCRYPT");
22987 self.write("(");
22988 self.generate_expression(&e.this)?;
22989 if let Some(passphrase) = &e.passphrase {
22990 self.write(", ");
22991 self.generate_expression(passphrase)?;
22992 }
22993 if let Some(aad) = &e.aad {
22994 self.write(", ");
22995 self.generate_expression(aad)?;
22996 }
22997 if let Some(method) = &e.encryption_method {
22998 self.write(", ");
22999 self.generate_expression(method)?;
23000 }
23001 self.write(")");
23002 Ok(())
23003 }
23004
23005 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
23006 self.write_keyword("ENCRYPT_RAW");
23008 self.write("(");
23009 self.generate_expression(&e.this)?;
23010 if let Some(key) = &e.key {
23011 self.write(", ");
23012 self.generate_expression(key)?;
23013 }
23014 if let Some(iv) = &e.iv {
23015 self.write(", ");
23016 self.generate_expression(iv)?;
23017 }
23018 if let Some(aad) = &e.aad {
23019 self.write(", ");
23020 self.generate_expression(aad)?;
23021 }
23022 if let Some(method) = &e.encryption_method {
23023 self.write(", ");
23024 self.generate_expression(method)?;
23025 }
23026 self.write(")");
23027 Ok(())
23028 }
23029
23030 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
23031 self.write_keyword("ENGINE");
23033 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23034 self.write("=");
23035 } else {
23036 self.write(" = ");
23037 }
23038 self.generate_expression(&e.this)?;
23039 Ok(())
23040 }
23041
23042 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
23043 self.write_keyword("ENVIRONMENT");
23045 self.write(" (");
23046 for (i, expr) in e.expressions.iter().enumerate() {
23047 if i > 0 {
23048 self.write(", ");
23049 }
23050 self.generate_expression(expr)?;
23051 }
23052 self.write(")");
23053 Ok(())
23054 }
23055
23056 fn generate_ephemeral_column_constraint(&mut self, e: &EphemeralColumnConstraint) -> Result<()> {
23057 self.write_keyword("EPHEMERAL");
23059 if let Some(this) = &e.this {
23060 self.write_space();
23061 self.generate_expression(this)?;
23062 }
23063 Ok(())
23064 }
23065
23066 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
23067 self.write_keyword("EQUAL_NULL");
23069 self.write("(");
23070 self.generate_expression(&e.this)?;
23071 self.write(", ");
23072 self.generate_expression(&e.expression)?;
23073 self.write(")");
23074 Ok(())
23075 }
23076
23077 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
23078 use crate::dialects::DialectType;
23079
23080 match self.config.dialect {
23082 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
23083 self.generate_expression(&e.this)?;
23084 self.write(" <-> ");
23085 self.generate_expression(&e.expression)?;
23086 }
23087 _ => {
23088 self.write_keyword("EUCLIDEAN_DISTANCE");
23090 self.write("(");
23091 self.generate_expression(&e.this)?;
23092 self.write(", ");
23093 self.generate_expression(&e.expression)?;
23094 self.write(")");
23095 }
23096 }
23097 Ok(())
23098 }
23099
23100 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
23101 self.write_keyword("EXECUTE AS");
23103 self.write_space();
23104 self.generate_expression(&e.this)?;
23105 Ok(())
23106 }
23107
23108 fn generate_export(&mut self, e: &Export) -> Result<()> {
23109 self.write_keyword("EXPORT DATA");
23111 if let Some(connection) = &e.connection {
23112 self.write_space();
23113 self.write_keyword("WITH CONNECTION");
23114 self.write_space();
23115 self.generate_expression(connection)?;
23116 }
23117 if !e.options.is_empty() {
23118 self.write_space();
23119 self.generate_options_clause(&e.options)?;
23120 }
23121 self.write_space();
23122 self.write_keyword("AS");
23123 self.write_space();
23124 self.generate_expression(&e.this)?;
23125 Ok(())
23126 }
23127
23128 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
23129 self.write_keyword("EXTERNAL");
23131 if let Some(this) = &e.this {
23132 self.write_space();
23133 self.generate_expression(this)?;
23134 }
23135 Ok(())
23136 }
23137
23138 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
23139 if e.no.is_some() {
23141 self.write_keyword("NO ");
23142 }
23143 self.write_keyword("FALLBACK");
23144 if e.protection.is_some() {
23145 self.write_keyword(" PROTECTION");
23146 }
23147 Ok(())
23148 }
23149
23150 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
23151 self.write_keyword("FARM_FINGERPRINT");
23153 self.write("(");
23154 for (i, expr) in e.expressions.iter().enumerate() {
23155 if i > 0 {
23156 self.write(", ");
23157 }
23158 self.generate_expression(expr)?;
23159 }
23160 self.write(")");
23161 Ok(())
23162 }
23163
23164 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
23165 self.write_keyword("FEATURES_AT_TIME");
23167 self.write("(");
23168 self.generate_expression(&e.this)?;
23169 if let Some(time) = &e.time {
23170 self.write(", ");
23171 self.generate_expression(time)?;
23172 }
23173 if let Some(num_rows) = &e.num_rows {
23174 self.write(", ");
23175 self.generate_expression(num_rows)?;
23176 }
23177 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
23178 self.write(", ");
23179 self.generate_expression(ignore_nulls)?;
23180 }
23181 self.write(")");
23182 Ok(())
23183 }
23184
23185 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
23186 let use_limit = !e.percent && !e.with_ties && e.count.is_some() && matches!(
23188 self.config.dialect,
23189 Some(DialectType::Spark) | Some(DialectType::Hive)
23190 | Some(DialectType::DuckDB) | Some(DialectType::SQLite) | Some(DialectType::MySQL)
23191 | Some(DialectType::BigQuery) | Some(DialectType::Databricks) | Some(DialectType::StarRocks)
23192 | Some(DialectType::Doris) | Some(DialectType::Athena) | Some(DialectType::ClickHouse)
23193 );
23194
23195 if use_limit {
23196 self.write_keyword("LIMIT");
23197 self.write_space();
23198 self.generate_expression(e.count.as_ref().unwrap())?;
23199 return Ok(());
23200 }
23201
23202 self.write_keyword("FETCH");
23204 if !e.direction.is_empty() {
23205 self.write_space();
23206 self.write_keyword(&e.direction);
23207 }
23208 if let Some(count) = &e.count {
23209 self.write_space();
23210 self.generate_expression(count)?;
23211 }
23212 if e.percent {
23214 self.write_keyword(" PERCENT");
23215 }
23216 if e.rows {
23217 self.write_keyword(" ROWS");
23218 }
23219 if e.with_ties {
23220 self.write_keyword(" WITH TIES");
23221 } else if e.rows {
23222 self.write_keyword(" ONLY");
23223 } else {
23224 self.write_keyword(" ROWS ONLY");
23225 }
23226 Ok(())
23227 }
23228
23229 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
23230 if e.hive_format.is_some() {
23234 self.write_keyword("STORED AS");
23236 self.write_space();
23237 if let Some(this) = &e.this {
23238 if let Expression::Identifier(id) = this.as_ref() {
23240 self.write_keyword(&id.name.to_uppercase());
23241 } else {
23242 self.generate_expression(this)?;
23243 }
23244 }
23245 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
23246 self.write_keyword("STORED AS");
23248 self.write_space();
23249 if let Some(this) = &e.this {
23250 if let Expression::Identifier(id) = this.as_ref() {
23251 self.write_keyword(&id.name.to_uppercase());
23252 } else {
23253 self.generate_expression(this)?;
23254 }
23255 }
23256 } else if matches!(self.config.dialect, Some(DialectType::Spark) | Some(DialectType::Databricks)) {
23257 self.write_keyword("USING");
23259 self.write_space();
23260 if let Some(this) = &e.this {
23261 self.generate_expression(this)?;
23262 }
23263 } else {
23264 self.write_keyword("FILE_FORMAT");
23266 self.write(" = ");
23267 if let Some(this) = &e.this {
23268 self.generate_expression(this)?;
23269 } else if !e.expressions.is_empty() {
23270 self.write("(");
23271 for (i, expr) in e.expressions.iter().enumerate() {
23272 if i > 0 {
23273 self.write(", ");
23274 }
23275 self.generate_expression(expr)?;
23276 }
23277 self.write(")");
23278 }
23279 }
23280 Ok(())
23281 }
23282
23283 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
23284 self.generate_expression(&e.this)?;
23286 self.write_space();
23287 self.write_keyword("FILTER");
23288 self.write("(");
23289 self.write_keyword("WHERE");
23290 self.write_space();
23291 self.generate_expression(&e.expression)?;
23292 self.write(")");
23293 Ok(())
23294 }
23295
23296 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
23297 self.write_keyword("FLOAT64");
23299 self.write("(");
23300 self.generate_expression(&e.this)?;
23301 if let Some(expr) = &e.expression {
23302 self.write(", ");
23303 self.generate_expression(expr)?;
23304 }
23305 self.write(")");
23306 Ok(())
23307 }
23308
23309 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
23310 self.write_keyword("FOR");
23312 self.write_space();
23313 self.generate_expression(&e.this)?;
23314 self.write_space();
23315 self.write_keyword("DO");
23316 self.write_space();
23317 self.generate_expression(&e.expression)?;
23318 Ok(())
23319 }
23320
23321 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
23322 self.write_keyword("FOREIGN KEY");
23324 if !e.expressions.is_empty() {
23325 self.write(" (");
23326 for (i, expr) in e.expressions.iter().enumerate() {
23327 if i > 0 {
23328 self.write(", ");
23329 }
23330 self.generate_expression(expr)?;
23331 }
23332 self.write(")");
23333 }
23334 if let Some(reference) = &e.reference {
23335 self.write_space();
23336 self.generate_expression(reference)?;
23337 }
23338 if let Some(delete) = &e.delete {
23339 self.write_space();
23340 self.write_keyword("ON DELETE");
23341 self.write_space();
23342 self.generate_expression(delete)?;
23343 }
23344 if let Some(update) = &e.update {
23345 self.write_space();
23346 self.write_keyword("ON UPDATE");
23347 self.write_space();
23348 self.generate_expression(update)?;
23349 }
23350 if !e.options.is_empty() {
23351 self.write_space();
23352 for (i, opt) in e.options.iter().enumerate() {
23353 if i > 0 {
23354 self.write_space();
23355 }
23356 self.generate_expression(opt)?;
23357 }
23358 }
23359 Ok(())
23360 }
23361
23362 fn generate_format(&mut self, e: &Format) -> Result<()> {
23363 self.write_keyword("FORMAT");
23365 self.write("(");
23366 self.generate_expression(&e.this)?;
23367 for expr in &e.expressions {
23368 self.write(", ");
23369 self.generate_expression(expr)?;
23370 }
23371 self.write(")");
23372 Ok(())
23373 }
23374
23375 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
23376 self.generate_expression(&e.this)?;
23378 self.write(" (");
23379 self.write_keyword("FORMAT");
23380 self.write(" '");
23381 self.write(&e.format);
23382 self.write("')");
23383 Ok(())
23384 }
23385
23386 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
23387 self.write_keyword("FREESPACE");
23389 self.write("=");
23390 self.generate_expression(&e.this)?;
23391 if e.percent.is_some() {
23392 self.write_keyword(" PERCENT");
23393 }
23394 Ok(())
23395 }
23396
23397 fn generate_from(&mut self, e: &From) -> Result<()> {
23398 self.write_keyword("FROM");
23400 self.write_space();
23401
23402 use crate::dialects::DialectType;
23405 let has_tablesample = e.expressions.iter().any(|expr| matches!(expr, Expression::TableSample(_)));
23406 let use_cross_join = !has_tablesample && matches!(
23407 self.config.dialect,
23408 Some(DialectType::BigQuery)
23409 | Some(DialectType::Hive)
23410 | Some(DialectType::Spark)
23411 | Some(DialectType::Databricks)
23412 | Some(DialectType::SQLite)
23413 | Some(DialectType::ClickHouse)
23414 );
23415
23416 let wrap_values_in_parens = matches!(
23418 self.config.dialect,
23419 Some(DialectType::Snowflake)
23420 );
23421
23422 for (i, expr) in e.expressions.iter().enumerate() {
23423 if i > 0 {
23424 if use_cross_join {
23425 self.write(" CROSS JOIN ");
23426 } else {
23427 self.write(", ");
23428 }
23429 }
23430 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
23431 self.write("(");
23432 self.generate_expression(expr)?;
23433 self.write(")");
23434 } else {
23435 self.generate_expression(expr)?;
23436 }
23437 }
23438 Ok(())
23439 }
23440
23441 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
23442 self.write_keyword("FROM_BASE");
23444 self.write("(");
23445 self.generate_expression(&e.this)?;
23446 self.write(", ");
23447 self.generate_expression(&e.expression)?;
23448 self.write(")");
23449 Ok(())
23450 }
23451
23452 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
23453 self.generate_expression(&e.this)?;
23455 if let Some(zone) = &e.zone {
23456 self.write_space();
23457 self.write_keyword("AT TIME ZONE");
23458 self.write_space();
23459 self.generate_expression(zone)?;
23460 self.write_space();
23461 self.write_keyword("AT TIME ZONE");
23462 self.write(" 'UTC'");
23463 }
23464 Ok(())
23465 }
23466
23467 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
23468 self.write_keyword("GAP_FILL");
23470 self.write("(");
23471 self.generate_expression(&e.this)?;
23472 if let Some(ts_column) = &e.ts_column {
23473 self.write(", ");
23474 self.generate_expression(ts_column)?;
23475 }
23476 if let Some(bucket_width) = &e.bucket_width {
23477 self.write(", ");
23478 self.generate_expression(bucket_width)?;
23479 }
23480 if let Some(partitioning_columns) = &e.partitioning_columns {
23481 self.write(", ");
23482 self.generate_expression(partitioning_columns)?;
23483 }
23484 if let Some(value_columns) = &e.value_columns {
23485 self.write(", ");
23486 self.generate_expression(value_columns)?;
23487 }
23488 self.write(")");
23489 Ok(())
23490 }
23491
23492 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
23493 self.write_keyword("GENERATE_DATE_ARRAY");
23495 self.write("(");
23496 let mut first = true;
23497 if let Some(start) = &e.start {
23498 self.generate_expression(start)?;
23499 first = false;
23500 }
23501 if let Some(end) = &e.end {
23502 if !first {
23503 self.write(", ");
23504 }
23505 self.generate_expression(end)?;
23506 first = false;
23507 }
23508 if let Some(step) = &e.step {
23509 if !first {
23510 self.write(", ");
23511 }
23512 self.generate_expression(step)?;
23513 }
23514 self.write(")");
23515 Ok(())
23516 }
23517
23518 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
23519 self.write_keyword("ML.GENERATE_EMBEDDING");
23521 self.write("(");
23522 self.generate_expression(&e.this)?;
23523 self.write(", ");
23524 self.generate_expression(&e.expression)?;
23525 if let Some(params) = &e.params_struct {
23526 self.write(", ");
23527 self.generate_expression(params)?;
23528 }
23529 self.write(")");
23530 Ok(())
23531 }
23532
23533 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
23534 self.write_keyword("GENERATE_SERIES");
23536 self.write("(");
23537 let mut first = true;
23538 if let Some(start) = &e.start {
23539 self.generate_expression(start)?;
23540 first = false;
23541 }
23542 if let Some(end) = &e.end {
23543 if !first {
23544 self.write(", ");
23545 }
23546 self.generate_expression(end)?;
23547 first = false;
23548 }
23549 if let Some(step) = &e.step {
23550 if !first {
23551 self.write(", ");
23552 }
23553 self.generate_expression(step)?;
23554 }
23555 self.write(")");
23556 Ok(())
23557 }
23558
23559 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
23560 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
23562 self.write("(");
23563 let mut first = true;
23564 if let Some(start) = &e.start {
23565 self.generate_expression(start)?;
23566 first = false;
23567 }
23568 if let Some(end) = &e.end {
23569 if !first {
23570 self.write(", ");
23571 }
23572 self.generate_expression(end)?;
23573 first = false;
23574 }
23575 if let Some(step) = &e.step {
23576 if !first {
23577 self.write(", ");
23578 }
23579 self.generate_expression(step)?;
23580 }
23581 self.write(")");
23582 Ok(())
23583 }
23584
23585 fn generate_generated_as_identity_column_constraint(&mut self, e: &GeneratedAsIdentityColumnConstraint) -> Result<()> {
23586 use crate::dialects::DialectType;
23587
23588 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
23590 self.write_keyword("AUTOINCREMENT");
23591 if let Some(start) = &e.start {
23592 self.write_keyword(" START ");
23593 self.generate_expression(start)?;
23594 }
23595 if let Some(increment) = &e.increment {
23596 self.write_keyword(" INCREMENT ");
23597 self.generate_expression(increment)?;
23598 }
23599 return Ok(());
23600 }
23601
23602 self.write_keyword("GENERATED");
23604 if let Some(this) = &e.this {
23605 if let Expression::Boolean(b) = this.as_ref() {
23607 if b.value {
23608 self.write_keyword(" ALWAYS");
23609 } else {
23610 self.write_keyword(" BY DEFAULT");
23611 if e.on_null.is_some() {
23612 self.write_keyword(" ON NULL");
23613 }
23614 }
23615 } else {
23616 self.write_keyword(" ALWAYS");
23617 }
23618 }
23619 self.write_keyword(" AS IDENTITY");
23620 let has_options = e.start.is_some() || e.increment.is_some() || e.minvalue.is_some() || e.maxvalue.is_some();
23622 if has_options {
23623 self.write(" (");
23624 let mut first = true;
23625 if let Some(start) = &e.start {
23626 self.write_keyword("START WITH ");
23627 self.generate_expression(start)?;
23628 first = false;
23629 }
23630 if let Some(increment) = &e.increment {
23631 if !first { self.write(" "); }
23632 self.write_keyword("INCREMENT BY ");
23633 self.generate_expression(increment)?;
23634 first = false;
23635 }
23636 if let Some(minvalue) = &e.minvalue {
23637 if !first { self.write(" "); }
23638 self.write_keyword("MINVALUE ");
23639 self.generate_expression(minvalue)?;
23640 first = false;
23641 }
23642 if let Some(maxvalue) = &e.maxvalue {
23643 if !first { self.write(" "); }
23644 self.write_keyword("MAXVALUE ");
23645 self.generate_expression(maxvalue)?;
23646 }
23647 self.write(")");
23648 }
23649 Ok(())
23650 }
23651
23652 fn generate_generated_as_row_column_constraint(&mut self, e: &GeneratedAsRowColumnConstraint) -> Result<()> {
23653 self.write_keyword("GENERATED ALWAYS AS ROW ");
23655 if e.start.is_some() {
23656 self.write_keyword("START");
23657 } else {
23658 self.write_keyword("END");
23659 }
23660 if e.hidden.is_some() {
23661 self.write_keyword(" HIDDEN");
23662 }
23663 Ok(())
23664 }
23665
23666 fn generate_get(&mut self, e: &Get) -> Result<()> {
23667 self.write_keyword("GET");
23669 self.write_space();
23670 self.generate_expression(&e.this)?;
23671 if let Some(target) = &e.target {
23672 self.write_space();
23673 self.generate_expression(target)?;
23674 }
23675 for prop in &e.properties {
23676 self.write_space();
23677 self.generate_expression(prop)?;
23678 }
23679 Ok(())
23680 }
23681
23682 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
23683 self.generate_expression(&e.this)?;
23685 self.write("[");
23686 self.generate_expression(&e.expression)?;
23687 self.write("]");
23688 Ok(())
23689 }
23690
23691 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
23692 self.write_keyword("GETBIT");
23694 self.write("(");
23695 self.generate_expression(&e.this)?;
23696 self.write(", ");
23697 self.generate_expression(&e.expression)?;
23698 self.write(")");
23699 Ok(())
23700 }
23701
23702 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
23703 if e.is_role {
23705 self.write_keyword("ROLE");
23706 self.write_space();
23707 } else if e.is_group {
23708 self.write_keyword("GROUP");
23709 self.write_space();
23710 }
23711 self.write(&e.name.name);
23712 Ok(())
23713 }
23714
23715 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
23716 self.generate_expression(&e.this)?;
23718 if !e.expressions.is_empty() {
23719 self.write("(");
23720 for (i, expr) in e.expressions.iter().enumerate() {
23721 if i > 0 {
23722 self.write(", ");
23723 }
23724 self.generate_expression(expr)?;
23725 }
23726 self.write(")");
23727 }
23728 Ok(())
23729 }
23730
23731 fn generate_group(&mut self, e: &Group) -> Result<()> {
23732 self.write_keyword("GROUP BY");
23734 match e.all {
23736 Some(true) => {
23737 self.write_space();
23738 self.write_keyword("ALL");
23739 }
23740 Some(false) => {
23741 self.write_space();
23742 self.write_keyword("DISTINCT");
23743 }
23744 None => {}
23745 }
23746 if !e.expressions.is_empty() {
23747 self.write_space();
23748 for (i, expr) in e.expressions.iter().enumerate() {
23749 if i > 0 {
23750 self.write(", ");
23751 }
23752 self.generate_expression(expr)?;
23753 }
23754 }
23755 if let Some(cube) = &e.cube {
23757 if !e.expressions.is_empty() {
23758 self.write(", ");
23759 } else {
23760 self.write_space();
23761 }
23762 self.generate_expression(cube)?;
23763 }
23764 if let Some(rollup) = &e.rollup {
23765 if !e.expressions.is_empty() || e.cube.is_some() {
23766 self.write(", ");
23767 } else {
23768 self.write_space();
23769 }
23770 self.generate_expression(rollup)?;
23771 }
23772 if let Some(grouping_sets) = &e.grouping_sets {
23773 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
23774 self.write(", ");
23775 } else {
23776 self.write_space();
23777 }
23778 self.generate_expression(grouping_sets)?;
23779 }
23780 if let Some(totals) = &e.totals {
23781 self.write_space();
23782 self.write_keyword("WITH TOTALS");
23783 self.generate_expression(totals)?;
23784 }
23785 Ok(())
23786 }
23787
23788 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
23789 self.write_keyword("GROUP BY");
23791 match e.all {
23793 Some(true) => {
23794 self.write_space();
23795 self.write_keyword("ALL");
23796 }
23797 Some(false) => {
23798 self.write_space();
23799 self.write_keyword("DISTINCT");
23800 }
23801 None => {}
23802 }
23803
23804 let mut trailing_cube = false;
23807 let mut trailing_rollup = false;
23808 let mut regular_expressions: Vec<&Expression> = Vec::new();
23809
23810 for expr in &e.expressions {
23811 match expr {
23812 Expression::Cube(c) if c.expressions.is_empty() => {
23813 trailing_cube = true;
23814 }
23815 Expression::Rollup(r) if r.expressions.is_empty() => {
23816 trailing_rollup = true;
23817 }
23818 _ => {
23819 regular_expressions.push(expr);
23820 }
23821 }
23822 }
23823
23824 if self.config.pretty {
23826 self.write_newline();
23827 self.indent_level += 1;
23828 for (i, expr) in regular_expressions.iter().enumerate() {
23829 if i > 0 {
23830 self.write(",");
23831 self.write_newline();
23832 }
23833 self.write_indent();
23834 self.generate_expression(expr)?;
23835 }
23836 self.indent_level -= 1;
23837 } else {
23838 self.write_space();
23839 for (i, expr) in regular_expressions.iter().enumerate() {
23840 if i > 0 {
23841 self.write(", ");
23842 }
23843 self.generate_expression(expr)?;
23844 }
23845 }
23846
23847 if trailing_cube {
23849 self.write_space();
23850 self.write_keyword("WITH CUBE");
23851 } else if trailing_rollup {
23852 self.write_space();
23853 self.write_keyword("WITH ROLLUP");
23854 }
23855
23856 if e.totals {
23858 self.write_space();
23859 self.write_keyword("WITH TOTALS");
23860 }
23861
23862 Ok(())
23863 }
23864
23865 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
23866 self.write_keyword("GROUPING");
23868 self.write("(");
23869 for (i, expr) in e.expressions.iter().enumerate() {
23870 if i > 0 {
23871 self.write(", ");
23872 }
23873 self.generate_expression(expr)?;
23874 }
23875 self.write(")");
23876 Ok(())
23877 }
23878
23879 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
23880 self.write_keyword("GROUPING_ID");
23882 self.write("(");
23883 for (i, expr) in e.expressions.iter().enumerate() {
23884 if i > 0 {
23885 self.write(", ");
23886 }
23887 self.generate_expression(expr)?;
23888 }
23889 self.write(")");
23890 Ok(())
23891 }
23892
23893 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
23894 self.write_keyword("GROUPING SETS");
23896 self.write(" (");
23897 for (i, expr) in e.expressions.iter().enumerate() {
23898 if i > 0 {
23899 self.write(", ");
23900 }
23901 self.generate_expression(expr)?;
23902 }
23903 self.write(")");
23904 Ok(())
23905 }
23906
23907 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
23908 self.write_keyword("HASH_AGG");
23910 self.write("(");
23911 self.generate_expression(&e.this)?;
23912 for expr in &e.expressions {
23913 self.write(", ");
23914 self.generate_expression(expr)?;
23915 }
23916 self.write(")");
23917 Ok(())
23918 }
23919
23920 fn generate_having(&mut self, e: &Having) -> Result<()> {
23921 self.write_keyword("HAVING");
23923 self.write_space();
23924 self.generate_expression(&e.this)?;
23925 Ok(())
23926 }
23927
23928 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
23929 self.generate_expression(&e.this)?;
23931 self.write_space();
23932 self.write_keyword("HAVING");
23933 self.write_space();
23934 if e.max.is_some() {
23935 self.write_keyword("MAX");
23936 } else {
23937 self.write_keyword("MIN");
23938 }
23939 self.write_space();
23940 self.generate_expression(&e.expression)?;
23941 Ok(())
23942 }
23943
23944 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
23945 use crate::dialects::DialectType;
23946 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
23948 if let Expression::Literal(Literal::String(ref s)) = *e.this {
23950 return self.generate_string_literal(s);
23951 }
23952 }
23953 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) {
23955 self.write("$");
23956 if let Some(tag) = &e.tag {
23957 self.generate_expression(tag)?;
23958 }
23959 self.write("$");
23960 self.generate_expression(&e.this)?;
23961 self.write("$");
23962 if let Some(tag) = &e.tag {
23963 self.generate_expression(tag)?;
23964 }
23965 self.write("$");
23966 return Ok(());
23967 }
23968 self.write("$");
23970 if let Some(tag) = &e.tag {
23971 self.generate_expression(tag)?;
23972 }
23973 self.write("$");
23974 self.generate_expression(&e.this)?;
23975 self.write("$");
23976 if let Some(tag) = &e.tag {
23977 self.generate_expression(tag)?;
23978 }
23979 self.write("$");
23980 Ok(())
23981 }
23982
23983 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
23984 self.write_keyword("HEX_ENCODE");
23986 self.write("(");
23987 self.generate_expression(&e.this)?;
23988 self.write(")");
23989 Ok(())
23990 }
23991
23992 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
23993 match e.this.as_ref() {
23996 Expression::Identifier(id) => self.write(&id.name),
23997 other => self.generate_expression(other)?,
23998 }
23999 self.write(" (");
24000 self.write(&e.kind);
24001 self.write(" => ");
24002 self.generate_expression(&e.expression)?;
24003 self.write(")");
24004 Ok(())
24005 }
24006
24007 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
24008 self.write_keyword("HLL");
24010 self.write("(");
24011 self.generate_expression(&e.this)?;
24012 for expr in &e.expressions {
24013 self.write(", ");
24014 self.generate_expression(expr)?;
24015 }
24016 self.write(")");
24017 Ok(())
24018 }
24019
24020 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
24021 if e.input_.is_some() && e.output.is_some() {
24023 self.write_keyword("IN OUT");
24024 } else if e.input_.is_some() {
24025 self.write_keyword("IN");
24026 } else if e.output.is_some() {
24027 self.write_keyword("OUT");
24028 }
24029 Ok(())
24030 }
24031
24032 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
24033 self.write_keyword("INCLUDE");
24035 self.write_space();
24036 self.generate_expression(&e.this)?;
24037 if let Some(column_def) = &e.column_def {
24038 self.write_space();
24039 self.generate_expression(column_def)?;
24040 }
24041 if let Some(alias) = &e.alias {
24042 self.write_space();
24043 self.write_keyword("AS");
24044 self.write_space();
24045 self.write(alias);
24046 }
24047 Ok(())
24048 }
24049
24050 fn generate_index(&mut self, e: &Index) -> Result<()> {
24051 if e.unique {
24053 self.write_keyword("UNIQUE");
24054 self.write_space();
24055 }
24056 if e.primary.is_some() {
24057 self.write_keyword("PRIMARY");
24058 self.write_space();
24059 }
24060 if e.amp.is_some() {
24061 self.write_keyword("AMP");
24062 self.write_space();
24063 }
24064 if e.table.is_none() {
24065 self.write_keyword("INDEX");
24066 self.write_space();
24067 }
24068 if let Some(name) = &e.this {
24069 self.generate_expression(name)?;
24070 self.write_space();
24071 }
24072 if let Some(table) = &e.table {
24073 self.write_keyword("ON");
24074 self.write_space();
24075 self.generate_expression(table)?;
24076 }
24077 if !e.params.is_empty() {
24078 self.write("(");
24079 for (i, param) in e.params.iter().enumerate() {
24080 if i > 0 {
24081 self.write(", ");
24082 }
24083 self.generate_expression(param)?;
24084 }
24085 self.write(")");
24086 }
24087 Ok(())
24088 }
24089
24090 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
24091 if let Some(kind) = &e.kind {
24093 self.write(kind);
24094 self.write_space();
24095 }
24096 self.write_keyword("INDEX");
24097 if let Some(this) = &e.this {
24098 self.write_space();
24099 self.generate_expression(this)?;
24100 }
24101 if let Some(index_type) = &e.index_type {
24102 self.write_space();
24103 self.write_keyword("USING");
24104 self.write_space();
24105 self.generate_expression(index_type)?;
24106 }
24107 if !e.expressions.is_empty() {
24108 self.write(" (");
24109 for (i, expr) in e.expressions.iter().enumerate() {
24110 if i > 0 {
24111 self.write(", ");
24112 }
24113 self.generate_expression(expr)?;
24114 }
24115 self.write(")");
24116 }
24117 for opt in &e.options {
24118 self.write_space();
24119 self.generate_expression(opt)?;
24120 }
24121 Ok(())
24122 }
24123
24124 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
24125 if let Some(key_block_size) = &e.key_block_size {
24127 self.write_keyword("KEY_BLOCK_SIZE");
24128 self.write(" = ");
24129 self.generate_expression(key_block_size)?;
24130 } else if let Some(using) = &e.using {
24131 self.write_keyword("USING");
24132 self.write_space();
24133 self.generate_expression(using)?;
24134 } else if let Some(parser) = &e.parser {
24135 self.write_keyword("WITH PARSER");
24136 self.write_space();
24137 self.generate_expression(parser)?;
24138 } else if let Some(comment) = &e.comment {
24139 self.write_keyword("COMMENT");
24140 self.write_space();
24141 self.generate_expression(comment)?;
24142 } else if let Some(visible) = &e.visible {
24143 self.generate_expression(visible)?;
24144 } else if let Some(engine_attr) = &e.engine_attr {
24145 self.write_keyword("ENGINE_ATTRIBUTE");
24146 self.write(" = ");
24147 self.generate_expression(engine_attr)?;
24148 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
24149 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
24150 self.write(" = ");
24151 self.generate_expression(secondary_engine_attr)?;
24152 }
24153 Ok(())
24154 }
24155
24156 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
24157 if let Some(using) = &e.using {
24159 self.write_keyword("USING");
24160 self.write_space();
24161 self.generate_expression(using)?;
24162 }
24163 if !e.columns.is_empty() {
24164 self.write("(");
24165 for (i, col) in e.columns.iter().enumerate() {
24166 if i > 0 {
24167 self.write(", ");
24168 }
24169 self.generate_expression(col)?;
24170 }
24171 self.write(")");
24172 }
24173 if let Some(partition_by) = &e.partition_by {
24174 self.write_space();
24175 self.write_keyword("PARTITION BY");
24176 self.write_space();
24177 self.generate_expression(partition_by)?;
24178 }
24179 if let Some(where_) = &e.where_ {
24180 self.write_space();
24181 self.generate_expression(where_)?;
24182 }
24183 if let Some(include) = &e.include {
24184 self.write_space();
24185 self.write_keyword("INCLUDE");
24186 self.write(" (");
24187 self.generate_expression(include)?;
24188 self.write(")");
24189 }
24190 if let Some(with_storage) = &e.with_storage {
24191 self.write_space();
24192 self.write_keyword("WITH");
24193 self.write(" (");
24194 self.generate_expression(with_storage)?;
24195 self.write(")");
24196 }
24197 if let Some(tablespace) = &e.tablespace {
24198 self.write_space();
24199 self.write_keyword("USING INDEX TABLESPACE");
24200 self.write_space();
24201 self.generate_expression(tablespace)?;
24202 }
24203 Ok(())
24204 }
24205
24206 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
24207 if let Expression::Identifier(id) = &*e.this {
24211 self.write_keyword(&id.name);
24212 } else {
24213 self.generate_expression(&e.this)?;
24214 }
24215 self.write_space();
24216 self.write_keyword("INDEX");
24217 if let Some(target) = &e.target {
24218 self.write_space();
24219 self.write_keyword("FOR");
24220 self.write_space();
24221 if let Expression::Identifier(id) = &**target {
24222 self.write_keyword(&id.name);
24223 } else {
24224 self.generate_expression(target)?;
24225 }
24226 }
24227 self.write(" (");
24229 for (i, expr) in e.expressions.iter().enumerate() {
24230 if i > 0 {
24231 self.write(", ");
24232 }
24233 self.generate_expression(expr)?;
24234 }
24235 self.write(")");
24236 Ok(())
24237 }
24238
24239 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
24240 self.write_keyword("INHERITS");
24242 self.write(" (");
24243 for (i, expr) in e.expressions.iter().enumerate() {
24244 if i > 0 {
24245 self.write(", ");
24246 }
24247 self.generate_expression(expr)?;
24248 }
24249 self.write(")");
24250 Ok(())
24251 }
24252
24253 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
24254 self.write_keyword("INPUT");
24256 self.write("(");
24257 self.generate_expression(&e.this)?;
24258 self.write(")");
24259 Ok(())
24260 }
24261
24262 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
24263 if let Some(input_format) = &e.input_format {
24265 self.write_keyword("INPUTFORMAT");
24266 self.write_space();
24267 self.generate_expression(input_format)?;
24268 }
24269 if let Some(output_format) = &e.output_format {
24270 if e.input_format.is_some() {
24271 self.write(" ");
24272 }
24273 self.write_keyword("OUTPUTFORMAT");
24274 self.write_space();
24275 self.generate_expression(output_format)?;
24276 }
24277 Ok(())
24278 }
24279
24280 fn generate_install(&mut self, e: &Install) -> Result<()> {
24281 if e.force.is_some() {
24283 self.write_keyword("FORCE");
24284 self.write_space();
24285 }
24286 self.write_keyword("INSTALL");
24287 self.write_space();
24288 self.generate_expression(&e.this)?;
24289 if let Some(from) = &e.from_ {
24290 self.write_space();
24291 self.write_keyword("FROM");
24292 self.write_space();
24293 self.generate_expression(from)?;
24294 }
24295 Ok(())
24296 }
24297
24298 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
24299 self.write_keyword("INTERVAL");
24301 self.write_space();
24302 self.generate_expression(&e.expression)?;
24304 if let Some(unit) = &e.unit {
24305 self.write_space();
24306 self.write(unit);
24307 }
24308 Ok(())
24309 }
24310
24311 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
24312 self.write(&format!("{:?}", e.this).to_uppercase());
24314 self.write_space();
24315 self.write_keyword("TO");
24316 self.write_space();
24317 self.write(&format!("{:?}", e.expression).to_uppercase());
24318 Ok(())
24319 }
24320
24321 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
24322 self.write_keyword("INTO");
24324 if e.temporary {
24325 self.write_keyword(" TEMPORARY");
24326 }
24327 if e.unlogged.is_some() {
24328 self.write_keyword(" UNLOGGED");
24329 }
24330 if let Some(this) = &e.this {
24331 self.write_space();
24332 self.generate_expression(this)?;
24333 }
24334 if !e.expressions.is_empty() {
24335 self.write(" (");
24336 for (i, expr) in e.expressions.iter().enumerate() {
24337 if i > 0 {
24338 self.write(", ");
24339 }
24340 self.generate_expression(expr)?;
24341 }
24342 self.write(")");
24343 }
24344 Ok(())
24345 }
24346
24347 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
24348 self.generate_expression(&e.this)?;
24350 self.write_space();
24351 self.generate_expression(&e.expression)?;
24352 Ok(())
24353 }
24354
24355 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
24356 self.write_keyword("WITH");
24358 if e.no.is_some() {
24359 self.write_keyword(" NO");
24360 }
24361 if e.concurrent.is_some() {
24362 self.write_keyword(" CONCURRENT");
24363 }
24364 self.write_keyword(" ISOLATED LOADING");
24365 if let Some(target) = &e.target {
24366 self.write_space();
24367 self.generate_expression(target)?;
24368 }
24369 Ok(())
24370 }
24371
24372 fn generate_json(&mut self, e: &JSON) -> Result<()> {
24373 self.write_keyword("JSON");
24375 if let Some(this) = &e.this {
24376 self.write_space();
24377 self.generate_expression(this)?;
24378 }
24379 if let Some(with_) = &e.with_ {
24380 if let Expression::Boolean(b) = with_.as_ref() {
24382 if b.value {
24383 self.write_keyword(" WITH");
24384 } else {
24385 self.write_keyword(" WITHOUT");
24386 }
24387 }
24388 }
24389 if e.unique {
24390 self.write_keyword(" UNIQUE KEYS");
24391 }
24392 Ok(())
24393 }
24394
24395 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
24396 self.write_keyword("JSON_ARRAY");
24398 self.write("(");
24399 for (i, expr) in e.expressions.iter().enumerate() {
24400 if i > 0 {
24401 self.write(", ");
24402 }
24403 self.generate_expression(expr)?;
24404 }
24405 if let Some(null_handling) = &e.null_handling {
24406 self.write_space();
24407 self.generate_expression(null_handling)?;
24408 }
24409 if let Some(return_type) = &e.return_type {
24410 self.write_space();
24411 self.write_keyword("RETURNING");
24412 self.write_space();
24413 self.generate_expression(return_type)?;
24414 }
24415 if e.strict.is_some() {
24416 self.write_space();
24417 self.write_keyword("STRICT");
24418 }
24419 self.write(")");
24420 Ok(())
24421 }
24422
24423 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
24424 self.write_keyword("JSON_ARRAYAGG");
24426 self.write("(");
24427 self.generate_expression(&e.this)?;
24428 if let Some(order) = &e.order {
24429 self.write_space();
24430 if let Expression::OrderBy(ob) = order.as_ref() {
24432 self.write_keyword("ORDER BY");
24433 self.write_space();
24434 for (i, ord) in ob.expressions.iter().enumerate() {
24435 if i > 0 {
24436 self.write(", ");
24437 }
24438 self.generate_ordered(ord)?;
24439 }
24440 } else {
24441 self.generate_expression(order)?;
24443 }
24444 }
24445 if let Some(null_handling) = &e.null_handling {
24446 self.write_space();
24447 self.generate_expression(null_handling)?;
24448 }
24449 if let Some(return_type) = &e.return_type {
24450 self.write_space();
24451 self.write_keyword("RETURNING");
24452 self.write_space();
24453 self.generate_expression(return_type)?;
24454 }
24455 if e.strict.is_some() {
24456 self.write_space();
24457 self.write_keyword("STRICT");
24458 }
24459 self.write(")");
24460 Ok(())
24461 }
24462
24463 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
24464 self.write_keyword("JSON_OBJECTAGG");
24466 self.write("(");
24467 for (i, expr) in e.expressions.iter().enumerate() {
24468 if i > 0 {
24469 self.write(", ");
24470 }
24471 self.generate_expression(expr)?;
24472 }
24473 if let Some(null_handling) = &e.null_handling {
24474 self.write_space();
24475 self.generate_expression(null_handling)?;
24476 }
24477 if let Some(unique_keys) = &e.unique_keys {
24478 self.write_space();
24479 if let Expression::Boolean(b) = unique_keys.as_ref() {
24480 if b.value {
24481 self.write_keyword("WITH UNIQUE KEYS");
24482 } else {
24483 self.write_keyword("WITHOUT UNIQUE KEYS");
24484 }
24485 }
24486 }
24487 if let Some(return_type) = &e.return_type {
24488 self.write_space();
24489 self.write_keyword("RETURNING");
24490 self.write_space();
24491 self.generate_expression(return_type)?;
24492 }
24493 self.write(")");
24494 Ok(())
24495 }
24496
24497 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
24498 self.write_keyword("JSON_ARRAY_APPEND");
24500 self.write("(");
24501 self.generate_expression(&e.this)?;
24502 for expr in &e.expressions {
24503 self.write(", ");
24504 self.generate_expression(expr)?;
24505 }
24506 self.write(")");
24507 Ok(())
24508 }
24509
24510 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
24511 self.write_keyword("JSON_ARRAY_CONTAINS");
24513 self.write("(");
24514 self.generate_expression(&e.this)?;
24515 self.write(", ");
24516 self.generate_expression(&e.expression)?;
24517 self.write(")");
24518 Ok(())
24519 }
24520
24521 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
24522 self.write_keyword("JSON_ARRAY_INSERT");
24524 self.write("(");
24525 self.generate_expression(&e.this)?;
24526 for expr in &e.expressions {
24527 self.write(", ");
24528 self.generate_expression(expr)?;
24529 }
24530 self.write(")");
24531 Ok(())
24532 }
24533
24534 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
24535 self.write_keyword("JSONB_EXISTS");
24537 self.write("(");
24538 self.generate_expression(&e.this)?;
24539 if let Some(path) = &e.path {
24540 self.write(", ");
24541 self.generate_expression(path)?;
24542 }
24543 self.write(")");
24544 Ok(())
24545 }
24546
24547 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
24548 self.write_keyword("JSONB_EXTRACT_SCALAR");
24550 self.write("(");
24551 self.generate_expression(&e.this)?;
24552 self.write(", ");
24553 self.generate_expression(&e.expression)?;
24554 self.write(")");
24555 Ok(())
24556 }
24557
24558 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
24559 self.write_keyword("JSONB_OBJECT_AGG");
24561 self.write("(");
24562 self.generate_expression(&e.this)?;
24563 self.write(", ");
24564 self.generate_expression(&e.expression)?;
24565 self.write(")");
24566 Ok(())
24567 }
24568
24569 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
24570 if let Some(nested_schema) = &e.nested_schema {
24572 self.write_keyword("NESTED");
24573 if let Some(path) = &e.path {
24574 self.write_space();
24575 self.write_keyword("PATH");
24576 self.write_space();
24577 self.generate_expression(path)?;
24578 }
24579 self.write_space();
24580 self.generate_expression(nested_schema)?;
24581 } else {
24582 if let Some(this) = &e.this {
24583 self.generate_expression(this)?;
24584 }
24585 if let Some(kind) = &e.kind {
24586 self.write_space();
24587 self.write(kind);
24588 }
24589 if let Some(path) = &e.path {
24590 self.write_space();
24591 self.write_keyword("PATH");
24592 self.write_space();
24593 self.generate_expression(path)?;
24594 }
24595 if e.ordinality.is_some() {
24596 self.write_keyword(" FOR ORDINALITY");
24597 }
24598 }
24599 Ok(())
24600 }
24601
24602 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
24603 self.write_keyword("JSON_EXISTS");
24605 self.write("(");
24606 self.generate_expression(&e.this)?;
24607 if let Some(path) = &e.path {
24608 self.write(", ");
24609 self.generate_expression(path)?;
24610 }
24611 if let Some(passing) = &e.passing {
24612 self.write_space();
24613 self.write_keyword("PASSING");
24614 self.write_space();
24615 self.generate_expression(passing)?;
24616 }
24617 if let Some(on_condition) = &e.on_condition {
24618 self.write_space();
24619 self.generate_expression(on_condition)?;
24620 }
24621 self.write(")");
24622 Ok(())
24623 }
24624
24625 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
24626 self.generate_expression(&e.this)?;
24627 self.write(".:");
24628 self.generate_data_type(&e.to)?;
24629 Ok(())
24630 }
24631
24632 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
24633 self.write_keyword("JSON_EXTRACT_ARRAY");
24635 self.write("(");
24636 self.generate_expression(&e.this)?;
24637 if let Some(expr) = &e.expression {
24638 self.write(", ");
24639 self.generate_expression(expr)?;
24640 }
24641 self.write(")");
24642 Ok(())
24643 }
24644
24645 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
24646 if let Some(option) = &e.option {
24648 self.generate_expression(option)?;
24649 self.write_space();
24650 }
24651 self.write_keyword("QUOTES");
24652 if e.scalar.is_some() {
24653 self.write_keyword(" SCALAR_ONLY");
24654 }
24655 Ok(())
24656 }
24657
24658 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
24659 self.write_keyword("JSON_EXTRACT_SCALAR");
24661 self.write("(");
24662 self.generate_expression(&e.this)?;
24663 self.write(", ");
24664 self.generate_expression(&e.expression)?;
24665 self.write(")");
24666 Ok(())
24667 }
24668
24669 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
24670 if e.variant_extract.is_some() {
24674 use crate::dialects::DialectType;
24675 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
24676 self.generate_expression(&e.this)?;
24678 self.write(":");
24679 match e.expression.as_ref() {
24682 Expression::Literal(Literal::String(s)) => {
24683 self.write(s);
24684 }
24685 _ => {
24686 self.generate_expression(&e.expression)?;
24688 }
24689 }
24690 } else {
24691 self.write_keyword("GET_PATH");
24693 self.write("(");
24694 self.generate_expression(&e.this)?;
24695 self.write(", ");
24696 self.generate_expression(&e.expression)?;
24697 self.write(")");
24698 }
24699 } else {
24700 self.write_keyword("JSON_EXTRACT");
24701 self.write("(");
24702 self.generate_expression(&e.this)?;
24703 self.write(", ");
24704 self.generate_expression(&e.expression)?;
24705 for expr in &e.expressions {
24706 self.write(", ");
24707 self.generate_expression(expr)?;
24708 }
24709 self.write(")");
24710 }
24711 Ok(())
24712 }
24713
24714 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
24715 if let Some(this) = &e.this {
24718 self.generate_expression(this)?;
24719 self.write_space();
24720 }
24721 self.write_keyword("FORMAT JSON");
24722 Ok(())
24723 }
24724
24725 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
24726 self.generate_expression(&e.this)?;
24728 self.write(": ");
24729 self.generate_expression(&e.expression)?;
24730 Ok(())
24731 }
24732
24733 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
24734 self.write_keyword("JSON_KEYS");
24736 self.write("(");
24737 self.generate_expression(&e.this)?;
24738 if let Some(expr) = &e.expression {
24739 self.write(", ");
24740 self.generate_expression(expr)?;
24741 }
24742 for expr in &e.expressions {
24743 self.write(", ");
24744 self.generate_expression(expr)?;
24745 }
24746 self.write(")");
24747 Ok(())
24748 }
24749
24750 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
24751 self.write_keyword("JSON_KEYS");
24753 self.write("(");
24754 self.generate_expression(&e.this)?;
24755 if let Some(expr) = &e.expression {
24756 self.write(", ");
24757 self.generate_expression(expr)?;
24758 }
24759 self.write(")");
24760 Ok(())
24761 }
24762
24763 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
24764 let mut path_str = String::new();
24767 for expr in &e.expressions {
24768 match expr {
24769 Expression::JSONPathRoot(_) => {
24770 path_str.push('$');
24771 }
24772 Expression::JSONPathKey(k) => {
24773 if let Expression::Literal(crate::expressions::Literal::String(s)) = k.this.as_ref() {
24775 path_str.push('.');
24776 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
24778 if needs_quoting {
24779 path_str.push('"');
24780 path_str.push_str(s);
24781 path_str.push('"');
24782 } else {
24783 path_str.push_str(s);
24784 }
24785 }
24786 }
24787 Expression::JSONPathSubscript(s) => {
24788 if let Expression::Literal(crate::expressions::Literal::Number(n)) = s.this.as_ref() {
24790 path_str.push('[');
24791 path_str.push_str(n);
24792 path_str.push(']');
24793 }
24794 }
24795 _ => {
24796 let mut temp_gen = Self::with_config(self.config.clone());
24798 temp_gen.generate_expression(expr)?;
24799 path_str.push_str(&temp_gen.output);
24800 }
24801 }
24802 }
24803 self.write("'");
24805 self.write(&path_str);
24806 self.write("'");
24807 Ok(())
24808 }
24809
24810 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
24811 self.write("?(");
24813 self.generate_expression(&e.this)?;
24814 self.write(")");
24815 Ok(())
24816 }
24817
24818 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
24819 self.write(".");
24821 self.generate_expression(&e.this)?;
24822 Ok(())
24823 }
24824
24825 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
24826 self.write("..");
24828 if let Some(this) = &e.this {
24829 self.generate_expression(this)?;
24830 }
24831 Ok(())
24832 }
24833
24834 fn generate_json_path_root(&mut self) -> Result<()> {
24835 self.write("$");
24837 Ok(())
24838 }
24839
24840 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
24841 self.write("(");
24843 self.generate_expression(&e.this)?;
24844 self.write(")");
24845 Ok(())
24846 }
24847
24848 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
24849 self.generate_expression(&e.this)?;
24851 Ok(())
24852 }
24853
24854 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
24855 self.write("[");
24857 if let Some(start) = &e.start {
24858 self.generate_expression(start)?;
24859 }
24860 self.write(":");
24861 if let Some(end) = &e.end {
24862 self.generate_expression(end)?;
24863 }
24864 if let Some(step) = &e.step {
24865 self.write(":");
24866 self.generate_expression(step)?;
24867 }
24868 self.write("]");
24869 Ok(())
24870 }
24871
24872 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
24873 self.write("[");
24875 self.generate_expression(&e.this)?;
24876 self.write("]");
24877 Ok(())
24878 }
24879
24880 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
24881 self.write("[");
24883 for (i, expr) in e.expressions.iter().enumerate() {
24884 if i > 0 {
24885 self.write(", ");
24886 }
24887 self.generate_expression(expr)?;
24888 }
24889 self.write("]");
24890 Ok(())
24891 }
24892
24893 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
24894 self.write_keyword("JSON_REMOVE");
24896 self.write("(");
24897 self.generate_expression(&e.this)?;
24898 for expr in &e.expressions {
24899 self.write(", ");
24900 self.generate_expression(expr)?;
24901 }
24902 self.write(")");
24903 Ok(())
24904 }
24905
24906 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
24907 self.write_keyword("COLUMNS");
24910 self.write("(");
24911
24912 if self.config.pretty && !e.expressions.is_empty() {
24913 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
24915 for expr in &e.expressions {
24916 let mut temp_gen = Generator::with_config(self.config.clone());
24917 temp_gen.generate_expression(expr)?;
24918 expr_strings.push(temp_gen.output);
24919 }
24920
24921 if self.too_wide(&expr_strings) {
24923 self.write_newline();
24925 self.indent_level += 1;
24926 for (i, expr_str) in expr_strings.iter().enumerate() {
24927 if i > 0 {
24928 self.write(",");
24929 self.write_newline();
24930 }
24931 self.write_indent();
24932 self.write(expr_str);
24933 }
24934 self.write_newline();
24935 self.indent_level -= 1;
24936 self.write_indent();
24937 } else {
24938 for (i, expr_str) in expr_strings.iter().enumerate() {
24940 if i > 0 {
24941 self.write(", ");
24942 }
24943 self.write(expr_str);
24944 }
24945 }
24946 } else {
24947 for (i, expr) in e.expressions.iter().enumerate() {
24949 if i > 0 {
24950 self.write(", ");
24951 }
24952 self.generate_expression(expr)?;
24953 }
24954 }
24955 self.write(")");
24956 Ok(())
24957 }
24958
24959 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
24960 self.write_keyword("JSON_SET");
24962 self.write("(");
24963 self.generate_expression(&e.this)?;
24964 for expr in &e.expressions {
24965 self.write(", ");
24966 self.generate_expression(expr)?;
24967 }
24968 self.write(")");
24969 Ok(())
24970 }
24971
24972 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
24973 self.write_keyword("JSON_STRIP_NULLS");
24975 self.write("(");
24976 self.generate_expression(&e.this)?;
24977 if let Some(expr) = &e.expression {
24978 self.write(", ");
24979 self.generate_expression(expr)?;
24980 }
24981 self.write(")");
24982 Ok(())
24983 }
24984
24985 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
24986 self.write_keyword("JSON_TABLE");
24988 self.write("(");
24989 self.generate_expression(&e.this)?;
24990 if let Some(path) = &e.path {
24991 self.write(", ");
24992 self.generate_expression(path)?;
24993 }
24994 if let Some(error_handling) = &e.error_handling {
24995 self.write_space();
24996 self.generate_expression(error_handling)?;
24997 }
24998 if let Some(empty_handling) = &e.empty_handling {
24999 self.write_space();
25000 self.generate_expression(empty_handling)?;
25001 }
25002 if let Some(schema) = &e.schema {
25003 self.write_space();
25004 self.generate_expression(schema)?;
25005 }
25006 self.write(")");
25007 Ok(())
25008 }
25009
25010 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
25011 self.write_keyword("JSON_TYPE");
25013 self.write("(");
25014 self.generate_expression(&e.this)?;
25015 self.write(")");
25016 Ok(())
25017 }
25018
25019 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
25020 self.write_keyword("JSON_VALUE");
25022 self.write("(");
25023 self.generate_expression(&e.this)?;
25024 if let Some(path) = &e.path {
25025 self.write(", ");
25026 self.generate_expression(path)?;
25027 }
25028 if let Some(returning) = &e.returning {
25029 self.write_space();
25030 self.write_keyword("RETURNING");
25031 self.write_space();
25032 self.generate_expression(returning)?;
25033 }
25034 if let Some(on_condition) = &e.on_condition {
25035 self.write_space();
25036 self.generate_expression(on_condition)?;
25037 }
25038 self.write(")");
25039 Ok(())
25040 }
25041
25042 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
25043 self.write_keyword("JSON_VALUE_ARRAY");
25045 self.write("(");
25046 self.generate_expression(&e.this)?;
25047 self.write(")");
25048 Ok(())
25049 }
25050
25051 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
25052 self.write_keyword("JAROWINKLER_SIMILARITY");
25054 self.write("(");
25055 self.generate_expression(&e.this)?;
25056 self.write(", ");
25057 self.generate_expression(&e.expression)?;
25058 self.write(")");
25059 Ok(())
25060 }
25061
25062 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
25063 self.generate_expression(&e.this)?;
25065 self.write("(");
25066 for (i, expr) in e.expressions.iter().enumerate() {
25067 if i > 0 {
25068 self.write(", ");
25069 }
25070 self.generate_expression(expr)?;
25071 }
25072 self.write(")");
25073 Ok(())
25074 }
25075
25076 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
25077 if e.no.is_some() {
25079 self.write_keyword("NO ");
25080 }
25081 if let Some(local) = &e.local {
25082 self.generate_expression(local)?;
25083 self.write_space();
25084 }
25085 if e.dual.is_some() {
25086 self.write_keyword("DUAL ");
25087 }
25088 if e.before.is_some() {
25089 self.write_keyword("BEFORE ");
25090 }
25091 if e.after.is_some() {
25092 self.write_keyword("AFTER ");
25093 }
25094 self.write_keyword("JOURNAL");
25095 Ok(())
25096 }
25097
25098 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
25099 self.write_keyword("LANGUAGE");
25101 self.write_space();
25102 self.generate_expression(&e.this)?;
25103 Ok(())
25104 }
25105
25106 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
25107 if e.view.is_some() {
25109 self.write_keyword("LATERAL VIEW");
25111 if e.outer.is_some() {
25112 self.write_space();
25113 self.write_keyword("OUTER");
25114 }
25115 self.write_space();
25116 self.generate_expression(&e.this)?;
25117 if let Some(alias) = &e.alias {
25118 self.write_space();
25119 self.write(alias);
25120 }
25121 } else {
25122 self.write_keyword("LATERAL");
25124 self.write_space();
25125 self.generate_expression(&e.this)?;
25126 if e.ordinality.is_some() {
25127 self.write_space();
25128 self.write_keyword("WITH ORDINALITY");
25129 }
25130 if let Some(alias) = &e.alias {
25131 self.write_space();
25132 self.write_keyword("AS");
25133 self.write_space();
25134 self.write(alias);
25135 if !e.column_aliases.is_empty() {
25136 self.write("(");
25137 for (i, col) in e.column_aliases.iter().enumerate() {
25138 if i > 0 {
25139 self.write(", ");
25140 }
25141 self.write(col);
25142 }
25143 self.write(")");
25144 }
25145 }
25146 }
25147 Ok(())
25148 }
25149
25150 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
25151 self.write_keyword("LIKE");
25153 self.write_space();
25154 self.generate_expression(&e.this)?;
25155 for expr in &e.expressions {
25156 self.write_space();
25157 self.generate_expression(expr)?;
25158 }
25159 Ok(())
25160 }
25161
25162 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
25163 self.write_keyword("LIMIT");
25164 self.write_space();
25165 self.write_limit_expr(&e.this)?;
25166 if e.percent {
25167 self.write_space();
25168 self.write_keyword("PERCENT");
25169 }
25170 Ok(())
25171 }
25172
25173 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
25174 if e.percent.is_some() {
25176 self.write_keyword(" PERCENT");
25177 }
25178 if e.rows.is_some() {
25179 self.write_keyword(" ROWS");
25180 }
25181 if e.with_ties.is_some() {
25182 self.write_keyword(" WITH TIES");
25183 } else if e.rows.is_some() {
25184 self.write_keyword(" ONLY");
25185 }
25186 Ok(())
25187 }
25188
25189 fn generate_list(&mut self, e: &List) -> Result<()> {
25190 use crate::dialects::DialectType;
25191 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
25192
25193 if e.expressions.len() == 1 {
25195 if let Expression::Select(_) = &e.expressions[0] {
25196 self.write_keyword("LIST");
25197 self.write("(");
25198 self.generate_expression(&e.expressions[0])?;
25199 self.write(")");
25200 return Ok(());
25201 }
25202 }
25203
25204 if is_materialize {
25206 self.write_keyword("LIST");
25207 self.write("[");
25208 for (i, expr) in e.expressions.iter().enumerate() {
25209 if i > 0 {
25210 self.write(", ");
25211 }
25212 self.generate_expression(expr)?;
25213 }
25214 self.write("]");
25215 } else {
25216 self.write_keyword("LIST");
25218 self.write("(");
25219 for (i, expr) in e.expressions.iter().enumerate() {
25220 if i > 0 {
25221 self.write(", ");
25222 }
25223 self.generate_expression(expr)?;
25224 }
25225 self.write(")");
25226 }
25227 Ok(())
25228 }
25229
25230 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
25231 if let Expression::Select(_) = &*e.this {
25233 self.write_keyword("MAP");
25234 self.write("(");
25235 self.generate_expression(&e.this)?;
25236 self.write(")");
25237 return Ok(());
25238 }
25239
25240 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
25241
25242 self.write_keyword("MAP");
25244 if is_duckdb {
25245 self.write(" {");
25246 } else {
25247 self.write("[");
25248 }
25249 if let Expression::Struct(s) = &*e.this {
25250 for (i, (_, expr)) in s.fields.iter().enumerate() {
25251 if i > 0 {
25252 self.write(", ");
25253 }
25254 if let Expression::PropertyEQ(op) = expr {
25255 self.generate_expression(&op.left)?;
25256 if is_duckdb {
25257 self.write(": ");
25258 } else {
25259 self.write(" => ");
25260 }
25261 self.generate_expression(&op.right)?;
25262 } else {
25263 self.generate_expression(expr)?;
25264 }
25265 }
25266 }
25267 if is_duckdb {
25268 self.write("}");
25269 } else {
25270 self.write("]");
25271 }
25272 Ok(())
25273 }
25274
25275 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
25276 self.write_keyword("LOCALTIME");
25278 if let Some(precision) = &e.this {
25279 self.write("(");
25280 self.generate_expression(precision)?;
25281 self.write(")");
25282 }
25283 Ok(())
25284 }
25285
25286 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
25287 self.write_keyword("LOCALTIMESTAMP");
25289 if let Some(precision) = &e.this {
25290 self.write("(");
25291 self.generate_expression(precision)?;
25292 self.write(")");
25293 }
25294 Ok(())
25295 }
25296
25297 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
25298 self.write_keyword("LOCATION");
25300 self.write_space();
25301 self.generate_expression(&e.this)?;
25302 Ok(())
25303 }
25304
25305 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
25306 if e.update.is_some() {
25308 if e.key.is_some() {
25309 self.write_keyword("FOR NO KEY UPDATE");
25310 } else {
25311 self.write_keyword("FOR UPDATE");
25312 }
25313 } else {
25314 if e.key.is_some() {
25315 self.write_keyword("FOR KEY SHARE");
25316 } else {
25317 self.write_keyword("FOR SHARE");
25318 }
25319 }
25320 if !e.expressions.is_empty() {
25321 self.write_keyword(" OF ");
25322 for (i, expr) in e.expressions.iter().enumerate() {
25323 if i > 0 {
25324 self.write(", ");
25325 }
25326 self.generate_expression(expr)?;
25327 }
25328 }
25329 if let Some(wait) = &e.wait {
25334 match wait.as_ref() {
25335 Expression::Boolean(b) => {
25336 if b.value {
25337 self.write_keyword(" NOWAIT");
25338 } else {
25339 self.write_keyword(" SKIP LOCKED");
25340 }
25341 }
25342 _ => {
25343 self.write_keyword(" WAIT ");
25345 self.generate_expression(wait)?;
25346 }
25347 }
25348 }
25349 Ok(())
25350 }
25351
25352 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
25353 self.write_keyword("LOCK");
25355 self.write_space();
25356 self.generate_expression(&e.this)?;
25357 Ok(())
25358 }
25359
25360 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
25361 self.write_keyword("LOCKING");
25363 self.write_space();
25364 self.write(&e.kind);
25365 if let Some(this) = &e.this {
25366 self.write_space();
25367 self.generate_expression(this)?;
25368 }
25369 if let Some(for_or_in) = &e.for_or_in {
25370 self.write_space();
25371 self.generate_expression(for_or_in)?;
25372 }
25373 if let Some(lock_type) = &e.lock_type {
25374 self.write_space();
25375 self.generate_expression(lock_type)?;
25376 }
25377 if e.override_.is_some() {
25378 self.write_keyword(" OVERRIDE");
25379 }
25380 Ok(())
25381 }
25382
25383 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
25384 self.generate_expression(&e.this)?;
25386 self.write_space();
25387 self.generate_expression(&e.expression)?;
25388 Ok(())
25389 }
25390
25391 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
25392 if e.no.is_some() {
25394 self.write_keyword("NO ");
25395 }
25396 self.write_keyword("LOG");
25397 Ok(())
25398 }
25399
25400 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
25401 self.write_keyword("MD5");
25403 self.write("(");
25404 self.generate_expression(&e.this)?;
25405 for expr in &e.expressions {
25406 self.write(", ");
25407 self.generate_expression(expr)?;
25408 }
25409 self.write(")");
25410 Ok(())
25411 }
25412
25413 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
25414 self.write_keyword("ML.FORECAST");
25416 self.write("(");
25417 self.generate_expression(&e.this)?;
25418 if let Some(expression) = &e.expression {
25419 self.write(", ");
25420 self.generate_expression(expression)?;
25421 }
25422 if let Some(params) = &e.params_struct {
25423 self.write(", ");
25424 self.generate_expression(params)?;
25425 }
25426 self.write(")");
25427 Ok(())
25428 }
25429
25430 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
25431 self.write_keyword("ML.TRANSLATE");
25433 self.write("(");
25434 self.generate_expression(&e.this)?;
25435 self.write(", ");
25436 self.generate_expression(&e.expression)?;
25437 if let Some(params) = &e.params_struct {
25438 self.write(", ");
25439 self.generate_expression(params)?;
25440 }
25441 self.write(")");
25442 Ok(())
25443 }
25444
25445 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
25446 self.write_keyword("MAKE_INTERVAL");
25448 self.write("(");
25449 let mut first = true;
25450 if let Some(year) = &e.year {
25451 self.write("years => ");
25452 self.generate_expression(year)?;
25453 first = false;
25454 }
25455 if let Some(month) = &e.month {
25456 if !first { self.write(", "); }
25457 self.write("months => ");
25458 self.generate_expression(month)?;
25459 first = false;
25460 }
25461 if let Some(week) = &e.week {
25462 if !first { self.write(", "); }
25463 self.write("weeks => ");
25464 self.generate_expression(week)?;
25465 first = false;
25466 }
25467 if let Some(day) = &e.day {
25468 if !first { self.write(", "); }
25469 self.write("days => ");
25470 self.generate_expression(day)?;
25471 first = false;
25472 }
25473 if let Some(hour) = &e.hour {
25474 if !first { self.write(", "); }
25475 self.write("hours => ");
25476 self.generate_expression(hour)?;
25477 first = false;
25478 }
25479 if let Some(minute) = &e.minute {
25480 if !first { self.write(", "); }
25481 self.write("mins => ");
25482 self.generate_expression(minute)?;
25483 first = false;
25484 }
25485 if let Some(second) = &e.second {
25486 if !first { self.write(", "); }
25487 self.write("secs => ");
25488 self.generate_expression(second)?;
25489 }
25490 self.write(")");
25491 Ok(())
25492 }
25493
25494 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
25495 self.write_keyword("MANHATTAN_DISTANCE");
25497 self.write("(");
25498 self.generate_expression(&e.this)?;
25499 self.write(", ");
25500 self.generate_expression(&e.expression)?;
25501 self.write(")");
25502 Ok(())
25503 }
25504
25505 fn generate_map(&mut self, e: &Map) -> Result<()> {
25506 self.write_keyword("MAP");
25508 self.write("(");
25509 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
25510 if i > 0 {
25511 self.write(", ");
25512 }
25513 self.generate_expression(key)?;
25514 self.write(", ");
25515 self.generate_expression(value)?;
25516 }
25517 self.write(")");
25518 Ok(())
25519 }
25520
25521 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
25522 self.write_keyword("MAP_CAT");
25524 self.write("(");
25525 self.generate_expression(&e.this)?;
25526 self.write(", ");
25527 self.generate_expression(&e.expression)?;
25528 self.write(")");
25529 Ok(())
25530 }
25531
25532 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
25533 self.write_keyword("MAP_DELETE");
25535 self.write("(");
25536 self.generate_expression(&e.this)?;
25537 for expr in &e.expressions {
25538 self.write(", ");
25539 self.generate_expression(expr)?;
25540 }
25541 self.write(")");
25542 Ok(())
25543 }
25544
25545 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
25546 self.write_keyword("MAP_INSERT");
25548 self.write("(");
25549 self.generate_expression(&e.this)?;
25550 if let Some(key) = &e.key {
25551 self.write(", ");
25552 self.generate_expression(key)?;
25553 }
25554 if let Some(value) = &e.value {
25555 self.write(", ");
25556 self.generate_expression(value)?;
25557 }
25558 if let Some(update_flag) = &e.update_flag {
25559 self.write(", ");
25560 self.generate_expression(update_flag)?;
25561 }
25562 self.write(")");
25563 Ok(())
25564 }
25565
25566 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
25567 self.write_keyword("MAP_PICK");
25569 self.write("(");
25570 self.generate_expression(&e.this)?;
25571 for expr in &e.expressions {
25572 self.write(", ");
25573 self.generate_expression(expr)?;
25574 }
25575 self.write(")");
25576 Ok(())
25577 }
25578
25579 fn generate_masking_policy_column_constraint(&mut self, e: &MaskingPolicyColumnConstraint) -> Result<()> {
25580 self.write_keyword("MASKING POLICY");
25582 self.write_space();
25583 self.generate_expression(&e.this)?;
25584 if !e.expressions.is_empty() {
25585 self.write_keyword(" USING");
25586 self.write(" (");
25587 for (i, expr) in e.expressions.iter().enumerate() {
25588 if i > 0 {
25589 self.write(", ");
25590 }
25591 self.generate_expression(expr)?;
25592 }
25593 self.write(")");
25594 }
25595 Ok(())
25596 }
25597
25598 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
25599 if matches!(
25600 self.config.dialect,
25601 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
25602 ) {
25603 if e.expressions.len() > 1 {
25604 self.write("(");
25605 }
25606 for (i, expr) in e.expressions.iter().enumerate() {
25607 if i > 0 {
25608 self.write_keyword(" OR ");
25609 }
25610 self.generate_expression(expr)?;
25611 self.write_space();
25612 self.write("@@");
25613 self.write_space();
25614 self.generate_expression(&e.this)?;
25615 }
25616 if e.expressions.len() > 1 {
25617 self.write(")");
25618 }
25619 return Ok(());
25620 }
25621
25622 self.write_keyword("MATCH");
25624 self.write("(");
25625 for (i, expr) in e.expressions.iter().enumerate() {
25626 if i > 0 {
25627 self.write(", ");
25628 }
25629 self.generate_expression(expr)?;
25630 }
25631 self.write(")");
25632 self.write_keyword(" AGAINST");
25633 self.write("(");
25634 self.generate_expression(&e.this)?;
25635 if let Some(modifier) = &e.modifier {
25636 self.write_space();
25637 self.generate_expression(modifier)?;
25638 }
25639 self.write(")");
25640 Ok(())
25641 }
25642
25643 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
25644 if let Some(window_frame) = &e.window_frame {
25646 self.write(&format!("{:?}", window_frame).to_uppercase());
25647 self.write_space();
25648 }
25649 self.generate_expression(&e.this)?;
25650 Ok(())
25651 }
25652
25653 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
25654 self.write_keyword("MATERIALIZED");
25656 if let Some(this) = &e.this {
25657 self.write_space();
25658 self.generate_expression(this)?;
25659 }
25660 Ok(())
25661 }
25662
25663 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
25664 if let Some(with_) = &e.with_ {
25667 self.generate_expression(with_)?;
25668 self.write_space();
25669 }
25670 self.write_keyword("MERGE INTO");
25671 self.write_space();
25672 self.generate_expression(&e.this)?;
25673
25674 if self.config.pretty {
25676 self.write_newline();
25677 self.write_indent();
25678 } else {
25679 self.write_space();
25680 }
25681 self.write_keyword("USING");
25682 self.write_space();
25683 self.generate_expression(&e.using)?;
25684
25685 if let Some(on) = &e.on {
25687 if self.config.pretty {
25688 self.write_newline();
25689 self.write_indent();
25690 } else {
25691 self.write_space();
25692 }
25693 self.write_keyword("ON");
25694 self.write_space();
25695 self.generate_expression(on)?;
25696 }
25697 if let Some(using_cond) = &e.using_cond {
25699 self.write_space();
25700 self.write_keyword("USING");
25701 self.write_space();
25702 self.write("(");
25703 if let Expression::Tuple(tuple) = using_cond.as_ref() {
25705 for (i, col) in tuple.expressions.iter().enumerate() {
25706 if i > 0 {
25707 self.write(", ");
25708 }
25709 self.generate_expression(col)?;
25710 }
25711 } else {
25712 self.generate_expression(using_cond)?;
25713 }
25714 self.write(")");
25715 }
25716 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
25718 if matches!(self.config.dialect, Some(crate::DialectType::PostgreSQL) | Some(crate::DialectType::Redshift) | Some(crate::DialectType::Trino) | Some(crate::DialectType::Presto) | Some(crate::DialectType::Athena)) {
25719 let mut names = Vec::new();
25720 match e.this.as_ref() {
25721 Expression::Alias(a) => {
25722 if let Expression::Table(t) = &a.this {
25724 names.push(t.name.name.clone());
25725 } else if let Expression::Identifier(id) = &a.this {
25726 names.push(id.name.clone());
25727 }
25728 names.push(a.alias.name.clone());
25729 }
25730 Expression::Table(t) => {
25731 names.push(t.name.name.clone());
25732 }
25733 Expression::Identifier(id) => {
25734 names.push(id.name.clone());
25735 }
25736 _ => {}
25737 }
25738 self.merge_strip_qualifiers = names;
25739 }
25740
25741 if let Some(whens) = &e.whens {
25743 if self.config.pretty {
25744 self.write_newline();
25745 self.write_indent();
25746 } else {
25747 self.write_space();
25748 }
25749 self.generate_expression(whens)?;
25750 }
25751
25752 self.merge_strip_qualifiers = saved_merge_strip;
25754
25755 if let Some(returning) = &e.returning {
25757 if self.config.pretty {
25758 self.write_newline();
25759 self.write_indent();
25760 } else {
25761 self.write_space();
25762 }
25763 self.generate_expression(returning)?;
25764 }
25765 Ok(())
25766 }
25767
25768 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
25769 if e.no.is_some() {
25771 self.write_keyword("NO MERGEBLOCKRATIO");
25772 } else if e.default.is_some() {
25773 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
25774 } else {
25775 self.write_keyword("MERGEBLOCKRATIO");
25776 self.write("=");
25777 if let Some(this) = &e.this {
25778 self.generate_expression(this)?;
25779 }
25780 if e.percent.is_some() {
25781 self.write_keyword(" PERCENT");
25782 }
25783 }
25784 Ok(())
25785 }
25786
25787 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
25788 self.write_keyword("TTL");
25790 let pretty_clickhouse = self.config.pretty
25791 && matches!(self.config.dialect, Some(crate::dialects::DialectType::ClickHouse));
25792
25793 if pretty_clickhouse {
25794 self.write_newline();
25795 self.indent_level += 1;
25796 for (i, expr) in e.expressions.iter().enumerate() {
25797 if i > 0 {
25798 self.write(",");
25799 self.write_newline();
25800 }
25801 self.write_indent();
25802 self.generate_expression(expr)?;
25803 }
25804 self.indent_level -= 1;
25805 } else {
25806 self.write_space();
25807 for (i, expr) in e.expressions.iter().enumerate() {
25808 if i > 0 {
25809 self.write(", ");
25810 }
25811 self.generate_expression(expr)?;
25812 }
25813 }
25814
25815 if let Some(where_) = &e.where_ {
25816 if pretty_clickhouse {
25817 self.write_newline();
25818 if let Expression::Where(w) = where_.as_ref() {
25819 self.write_indent();
25820 self.write_keyword("WHERE");
25821 self.write_newline();
25822 self.indent_level += 1;
25823 self.write_indent();
25824 self.generate_expression(&w.this)?;
25825 self.indent_level -= 1;
25826 } else {
25827 self.write_indent();
25828 self.generate_expression(where_)?;
25829 }
25830 } else {
25831 self.write_space();
25832 self.generate_expression(where_)?;
25833 }
25834 }
25835 if let Some(group) = &e.group {
25836 if pretty_clickhouse {
25837 self.write_newline();
25838 if let Expression::Group(g) = group.as_ref() {
25839 self.write_indent();
25840 self.write_keyword("GROUP BY");
25841 self.write_newline();
25842 self.indent_level += 1;
25843 for (i, expr) in g.expressions.iter().enumerate() {
25844 if i > 0 {
25845 self.write(",");
25846 self.write_newline();
25847 }
25848 self.write_indent();
25849 self.generate_expression(expr)?;
25850 }
25851 self.indent_level -= 1;
25852 } else {
25853 self.write_indent();
25854 self.generate_expression(group)?;
25855 }
25856 } else {
25857 self.write_space();
25858 self.generate_expression(group)?;
25859 }
25860 }
25861 if let Some(aggregates) = &e.aggregates {
25862 if pretty_clickhouse {
25863 self.write_newline();
25864 self.write_indent();
25865 self.write_keyword("SET");
25866 self.write_newline();
25867 self.indent_level += 1;
25868 if let Expression::Tuple(t) = aggregates.as_ref() {
25869 for (i, agg) in t.expressions.iter().enumerate() {
25870 if i > 0 {
25871 self.write(",");
25872 self.write_newline();
25873 }
25874 self.write_indent();
25875 self.generate_expression(agg)?;
25876 }
25877 } else {
25878 self.write_indent();
25879 self.generate_expression(aggregates)?;
25880 }
25881 self.indent_level -= 1;
25882 } else {
25883 self.write_space();
25884 self.write_keyword("SET");
25885 self.write_space();
25886 self.generate_expression(aggregates)?;
25887 }
25888 }
25889 Ok(())
25890 }
25891
25892 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
25893 self.generate_expression(&e.this)?;
25895 if e.delete.is_some() {
25896 self.write_keyword(" DELETE");
25897 }
25898 if let Some(recompress) = &e.recompress {
25899 self.write_keyword(" RECOMPRESS ");
25900 self.generate_expression(recompress)?;
25901 }
25902 if let Some(to_disk) = &e.to_disk {
25903 self.write_keyword(" TO DISK ");
25904 self.generate_expression(to_disk)?;
25905 }
25906 if let Some(to_volume) = &e.to_volume {
25907 self.write_keyword(" TO VOLUME ");
25908 self.generate_expression(to_volume)?;
25909 }
25910 Ok(())
25911 }
25912
25913 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
25914 self.write_keyword("MINHASH");
25916 self.write("(");
25917 self.generate_expression(&e.this)?;
25918 for expr in &e.expressions {
25919 self.write(", ");
25920 self.generate_expression(expr)?;
25921 }
25922 self.write(")");
25923 Ok(())
25924 }
25925
25926 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
25927 self.generate_expression(&e.this)?;
25929 self.write("!");
25930 self.generate_expression(&e.expression)?;
25931 Ok(())
25932 }
25933
25934 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
25935 self.write_keyword("MONTHNAME");
25937 self.write("(");
25938 self.generate_expression(&e.this)?;
25939 self.write(")");
25940 Ok(())
25941 }
25942
25943 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
25944 for comment in &e.leading_comments {
25946 self.write_formatted_comment(comment);
25947 self.write_space();
25948 }
25949 self.write_keyword("INSERT");
25951 self.write_space();
25952 self.write(&e.kind);
25953 for expr in &e.expressions {
25954 self.write_space();
25955 self.generate_expression(expr)?;
25956 }
25957 if let Some(source) = &e.source {
25958 self.write_space();
25959 self.generate_expression(source)?;
25960 }
25961 Ok(())
25962 }
25963
25964 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
25965 self.write_keyword("NEXT VALUE FOR");
25967 self.write_space();
25968 self.generate_expression(&e.this)?;
25969 if let Some(order) = &e.order {
25970 self.write_space();
25971 self.write_keyword("OVER");
25972 self.write(" (");
25973 self.generate_expression(order)?;
25974 self.write(")");
25975 }
25976 Ok(())
25977 }
25978
25979 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
25980 self.write_keyword("NORMAL");
25982 self.write("(");
25983 self.generate_expression(&e.this)?;
25984 if let Some(stddev) = &e.stddev {
25985 self.write(", ");
25986 self.generate_expression(stddev)?;
25987 }
25988 if let Some(gen) = &e.gen {
25989 self.write(", ");
25990 self.generate_expression(gen)?;
25991 }
25992 self.write(")");
25993 Ok(())
25994 }
25995
25996 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
25997 if e.is_casefold.is_some() {
25999 self.write_keyword("NORMALIZE_AND_CASEFOLD");
26000 } else {
26001 self.write_keyword("NORMALIZE");
26002 }
26003 self.write("(");
26004 self.generate_expression(&e.this)?;
26005 if let Some(form) = &e.form {
26006 self.write(", ");
26007 self.generate_expression(form)?;
26008 }
26009 self.write(")");
26010 Ok(())
26011 }
26012
26013 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
26014 if e.allow_null.is_none() {
26016 self.write_keyword("NOT ");
26017 }
26018 self.write_keyword("NULL");
26019 Ok(())
26020 }
26021
26022 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
26023 self.write_keyword("NULLIF");
26025 self.write("(");
26026 self.generate_expression(&e.this)?;
26027 self.write(", ");
26028 self.generate_expression(&e.expression)?;
26029 self.write(")");
26030 Ok(())
26031 }
26032
26033 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
26034 self.write_keyword("FORMAT");
26036 self.write("(");
26037 self.generate_expression(&e.this)?;
26038 self.write(", '");
26039 self.write(&e.format);
26040 self.write("'");
26041 if let Some(culture) = &e.culture {
26042 self.write(", ");
26043 self.generate_expression(culture)?;
26044 }
26045 self.write(")");
26046 Ok(())
26047 }
26048
26049 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
26050 self.write_keyword("OBJECT_AGG");
26052 self.write("(");
26053 self.generate_expression(&e.this)?;
26054 self.write(", ");
26055 self.generate_expression(&e.expression)?;
26056 self.write(")");
26057 Ok(())
26058 }
26059
26060 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
26061 self.generate_expression(&e.this)?;
26063 Ok(())
26064 }
26065
26066 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
26067 self.write_keyword("OBJECT_INSERT");
26069 self.write("(");
26070 self.generate_expression(&e.this)?;
26071 if let Some(key) = &e.key {
26072 self.write(", ");
26073 self.generate_expression(key)?;
26074 }
26075 if let Some(value) = &e.value {
26076 self.write(", ");
26077 self.generate_expression(value)?;
26078 }
26079 if let Some(update_flag) = &e.update_flag {
26080 self.write(", ");
26081 self.generate_expression(update_flag)?;
26082 }
26083 self.write(")");
26084 Ok(())
26085 }
26086
26087 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
26088 self.write_keyword("OFFSET");
26090 self.write_space();
26091 self.generate_expression(&e.this)?;
26092 if e.rows == Some(true) && matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL) | Some(crate::dialects::DialectType::Oracle)) {
26094 self.write_space();
26095 self.write_keyword("ROWS");
26096 }
26097 Ok(())
26098 }
26099
26100 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
26101 self.write_keyword("QUALIFY");
26103 self.write_space();
26104 self.generate_expression(&e.this)?;
26105 Ok(())
26106 }
26107
26108 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
26109 self.write_keyword("ON CLUSTER");
26111 self.write_space();
26112 self.generate_expression(&e.this)?;
26113 Ok(())
26114 }
26115
26116 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
26117 self.write_keyword("ON COMMIT");
26119 if e.delete.is_some() {
26120 self.write_keyword(" DELETE ROWS");
26121 } else {
26122 self.write_keyword(" PRESERVE ROWS");
26123 }
26124 Ok(())
26125 }
26126
26127 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
26128 if let Some(empty) = &e.empty {
26130 self.generate_expression(empty)?;
26131 self.write_keyword(" ON EMPTY");
26132 }
26133 if let Some(error) = &e.error {
26134 if e.empty.is_some() {
26135 self.write_space();
26136 }
26137 self.generate_expression(error)?;
26138 self.write_keyword(" ON ERROR");
26139 }
26140 if let Some(null) = &e.null {
26141 if e.empty.is_some() || e.error.is_some() {
26142 self.write_space();
26143 }
26144 self.generate_expression(null)?;
26145 self.write_keyword(" ON NULL");
26146 }
26147 Ok(())
26148 }
26149
26150 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
26151 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
26153 return Ok(());
26154 }
26155 if e.duplicate.is_some() {
26157 self.write_keyword("ON DUPLICATE KEY UPDATE");
26159 for (i, expr) in e.expressions.iter().enumerate() {
26160 if i > 0 {
26161 self.write(",");
26162 }
26163 self.write_space();
26164 self.generate_expression(expr)?;
26165 }
26166 return Ok(());
26167 } else {
26168 self.write_keyword("ON CONFLICT");
26169 }
26170 if let Some(constraint) = &e.constraint {
26171 self.write_keyword(" ON CONSTRAINT ");
26172 self.generate_expression(constraint)?;
26173 }
26174 if let Some(conflict_keys) = &e.conflict_keys {
26175 if let Expression::Tuple(t) = conflict_keys.as_ref() {
26177 self.write("(");
26178 for (i, expr) in t.expressions.iter().enumerate() {
26179 if i > 0 {
26180 self.write(", ");
26181 }
26182 self.generate_expression(expr)?;
26183 }
26184 self.write(")");
26185 } else {
26186 self.write("(");
26187 self.generate_expression(conflict_keys)?;
26188 self.write(")");
26189 }
26190 }
26191 if let Some(index_predicate) = &e.index_predicate {
26192 self.write_keyword(" WHERE ");
26193 self.generate_expression(index_predicate)?;
26194 }
26195 if let Some(action) = &e.action {
26196 if let Expression::Identifier(id) = action.as_ref() {
26198 if id.name == "NOTHING" || id.name.to_uppercase() == "NOTHING" {
26199 self.write_keyword(" DO NOTHING");
26200 } else {
26201 self.write_keyword(" DO ");
26202 self.generate_expression(action)?;
26203 }
26204 } else if let Expression::Tuple(t) = action.as_ref() {
26205 self.write_keyword(" DO UPDATE SET ");
26207 for (i, expr) in t.expressions.iter().enumerate() {
26208 if i > 0 {
26209 self.write(", ");
26210 }
26211 self.generate_expression(expr)?;
26212 }
26213 } else {
26214 self.write_keyword(" DO ");
26215 self.generate_expression(action)?;
26216 }
26217 }
26218 if let Some(where_) = &e.where_ {
26220 self.write_keyword(" WHERE ");
26221 self.generate_expression(where_)?;
26222 }
26223 Ok(())
26224 }
26225
26226 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
26227 self.write_keyword("ON");
26229 self.write_space();
26230 self.generate_expression(&e.this)?;
26231 Ok(())
26232 }
26233
26234 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
26235 self.generate_expression(&e.this)?;
26237 self.write_space();
26238 self.generate_expression(&e.expression)?;
26239 Ok(())
26240 }
26241
26242 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
26243 self.write_keyword("OPENJSON");
26245 self.write("(");
26246 self.generate_expression(&e.this)?;
26247 if let Some(path) = &e.path {
26248 self.write(", ");
26249 self.generate_expression(path)?;
26250 }
26251 self.write(")");
26252 if !e.expressions.is_empty() {
26253 self.write_keyword(" WITH");
26254 if self.config.pretty {
26255 self.write(" (\n");
26256 self.indent_level += 2;
26257 for (i, expr) in e.expressions.iter().enumerate() {
26258 if i > 0 {
26259 self.write(",\n");
26260 }
26261 self.write_indent();
26262 self.generate_expression(expr)?;
26263 }
26264 self.write("\n");
26265 self.indent_level -= 2;
26266 self.write(")");
26267 } else {
26268 self.write(" (");
26269 for (i, expr) in e.expressions.iter().enumerate() {
26270 if i > 0 {
26271 self.write(", ");
26272 }
26273 self.generate_expression(expr)?;
26274 }
26275 self.write(")");
26276 }
26277 }
26278 Ok(())
26279 }
26280
26281 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
26282 self.generate_expression(&e.this)?;
26284 self.write_space();
26285 if let Some(ref dt) = e.data_type {
26287 self.generate_data_type(dt)?;
26288 } else if !e.kind.is_empty() {
26289 self.write(&e.kind);
26290 }
26291 if let Some(path) = &e.path {
26292 self.write_space();
26293 self.generate_expression(path)?;
26294 }
26295 if e.as_json.is_some() {
26296 self.write_keyword(" AS JSON");
26297 }
26298 Ok(())
26299 }
26300
26301 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
26302 self.generate_expression(&e.this)?;
26304 self.write_space();
26305 if let Some(op) = &e.operator {
26306 self.write_keyword("OPERATOR");
26307 self.write("(");
26308 self.generate_expression(op)?;
26309 self.write(")");
26310 }
26311 self.write_space();
26312 self.generate_expression(&e.expression)?;
26313 Ok(())
26314 }
26315
26316 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
26317 self.write_keyword("ORDER BY");
26319 let pretty_clickhouse_single_paren = self.config.pretty
26320 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
26321 && e.expressions.len() == 1
26322 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
26323 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
26324 && e.expressions.len() == 1
26325 && matches!(e.expressions[0].this, Expression::Tuple(_))
26326 && !e.expressions[0].desc
26327 && e.expressions[0].nulls_first.is_none();
26328
26329 if pretty_clickhouse_single_paren {
26330 self.write_space();
26331 if let Expression::Paren(p) = &e.expressions[0].this {
26332 self.write("(");
26333 self.write_newline();
26334 self.indent_level += 1;
26335 self.write_indent();
26336 self.generate_expression(&p.this)?;
26337 self.indent_level -= 1;
26338 self.write_newline();
26339 self.write(")");
26340 }
26341 return Ok(());
26342 }
26343
26344 if clickhouse_single_tuple {
26345 self.write_space();
26346 if let Expression::Tuple(t) = &e.expressions[0].this {
26347 self.write("(");
26348 for (i, expr) in t.expressions.iter().enumerate() {
26349 if i > 0 {
26350 self.write(", ");
26351 }
26352 self.generate_expression(expr)?;
26353 }
26354 self.write(")");
26355 }
26356 return Ok(());
26357 }
26358
26359 self.write_space();
26360 for (i, ordered) in e.expressions.iter().enumerate() {
26361 if i > 0 {
26362 self.write(", ");
26363 }
26364 self.generate_expression(&ordered.this)?;
26365 if ordered.desc {
26366 self.write_space();
26367 self.write_keyword("DESC");
26368 } else if ordered.explicit_asc {
26369 self.write_space();
26370 self.write_keyword("ASC");
26371 }
26372 if let Some(nulls_first) = ordered.nulls_first {
26373 let skip_nulls_last = !nulls_first
26375 && matches!(self.config.dialect, Some(DialectType::Dremio));
26376 if !skip_nulls_last {
26377 self.write_space();
26378 self.write_keyword("NULLS");
26379 self.write_space();
26380 if nulls_first {
26381 self.write_keyword("FIRST");
26382 } else {
26383 self.write_keyword("LAST");
26384 }
26385 }
26386 }
26387 }
26388 Ok(())
26389 }
26390
26391 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
26392 self.write_keyword("OUTPUT");
26394 self.write("(");
26395 if self.config.pretty {
26396 self.indent_level += 1;
26397 self.write_newline();
26398 self.write_indent();
26399 self.generate_expression(&e.this)?;
26400 self.indent_level -= 1;
26401 self.write_newline();
26402 } else {
26403 self.generate_expression(&e.this)?;
26404 }
26405 self.write(")");
26406 Ok(())
26407 }
26408
26409 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
26410 self.write_keyword("TRUNCATE");
26412 if let Some(this) = &e.this {
26413 self.write_space();
26414 self.generate_expression(this)?;
26415 }
26416 if e.with_count.is_some() {
26417 self.write_keyword(" WITH COUNT");
26418 } else {
26419 self.write_keyword(" WITHOUT COUNT");
26420 }
26421 Ok(())
26422 }
26423
26424 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
26425 self.generate_expression(&e.this)?;
26427 self.write("(");
26428 for (i, expr) in e.expressions.iter().enumerate() {
26429 if i > 0 {
26430 self.write(", ");
26431 }
26432 self.generate_expression(expr)?;
26433 }
26434 self.write(")(");
26435 for (i, param) in e.params.iter().enumerate() {
26436 if i > 0 {
26437 self.write(", ");
26438 }
26439 self.generate_expression(param)?;
26440 }
26441 self.write(")");
26442 Ok(())
26443 }
26444
26445 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
26446 self.write_keyword("PARSE_DATETIME");
26448 self.write("(");
26449 if let Some(format) = &e.format {
26450 self.write("'");
26451 self.write(format);
26452 self.write("', ");
26453 }
26454 self.generate_expression(&e.this)?;
26455 if let Some(zone) = &e.zone {
26456 self.write(", ");
26457 self.generate_expression(zone)?;
26458 }
26459 self.write(")");
26460 Ok(())
26461 }
26462
26463 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
26464 self.write_keyword("PARSE_IP");
26466 self.write("(");
26467 self.generate_expression(&e.this)?;
26468 if let Some(type_) = &e.type_ {
26469 self.write(", ");
26470 self.generate_expression(type_)?;
26471 }
26472 if let Some(permissive) = &e.permissive {
26473 self.write(", ");
26474 self.generate_expression(permissive)?;
26475 }
26476 self.write(")");
26477 Ok(())
26478 }
26479
26480 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
26481 self.write_keyword("PARSE_JSON");
26483 self.write("(");
26484 self.generate_expression(&e.this)?;
26485 if let Some(expression) = &e.expression {
26486 self.write(", ");
26487 self.generate_expression(expression)?;
26488 }
26489 self.write(")");
26490 Ok(())
26491 }
26492
26493 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
26494 self.write_keyword("PARSE_TIME");
26496 self.write("(");
26497 self.write(&format!("'{}'", e.format));
26498 self.write(", ");
26499 self.generate_expression(&e.this)?;
26500 self.write(")");
26501 Ok(())
26502 }
26503
26504 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
26505 self.write_keyword("PARSE_URL");
26507 self.write("(");
26508 self.generate_expression(&e.this)?;
26509 if let Some(part) = &e.part_to_extract {
26510 self.write(", ");
26511 self.generate_expression(part)?;
26512 }
26513 if let Some(key) = &e.key {
26514 self.write(", ");
26515 self.generate_expression(key)?;
26516 }
26517 if let Some(permissive) = &e.permissive {
26518 self.write(", ");
26519 self.generate_expression(permissive)?;
26520 }
26521 self.write(")");
26522 Ok(())
26523 }
26524
26525 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
26526 if e.subpartition {
26528 self.write_keyword("SUBPARTITION");
26529 } else {
26530 self.write_keyword("PARTITION");
26531 }
26532 self.write("(");
26533 for (i, expr) in e.expressions.iter().enumerate() {
26534 if i > 0 {
26535 self.write(", ");
26536 }
26537 self.generate_expression(expr)?;
26538 }
26539 self.write(")");
26540 Ok(())
26541 }
26542
26543 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
26544 if let Some(this) = &e.this {
26546 if let Some(expression) = &e.expression {
26547 self.write_keyword("WITH");
26549 self.write(" (");
26550 self.write_keyword("MODULUS");
26551 self.write_space();
26552 self.generate_expression(this)?;
26553 self.write(", ");
26554 self.write_keyword("REMAINDER");
26555 self.write_space();
26556 self.generate_expression(expression)?;
26557 self.write(")");
26558 } else {
26559 self.write_keyword("IN");
26561 self.write(" (");
26562 self.generate_partition_bound_values(this)?;
26563 self.write(")");
26564 }
26565 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
26566 self.write_keyword("FROM");
26568 self.write(" (");
26569 self.generate_partition_bound_values(from)?;
26570 self.write(") ");
26571 self.write_keyword("TO");
26572 self.write(" (");
26573 self.generate_partition_bound_values(to)?;
26574 self.write(")");
26575 }
26576 Ok(())
26577 }
26578
26579 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
26582 if let Expression::Tuple(t) = expr {
26583 for (i, e) in t.expressions.iter().enumerate() {
26584 if i > 0 {
26585 self.write(", ");
26586 }
26587 self.generate_expression(e)?;
26588 }
26589 Ok(())
26590 } else {
26591 self.generate_expression(expr)
26592 }
26593 }
26594
26595 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
26596 self.write_keyword("PARTITION BY LIST");
26598 if let Some(partition_exprs) = &e.partition_expressions {
26599 self.write(" (");
26600 self.generate_doris_partition_expressions(partition_exprs)?;
26602 self.write(")");
26603 }
26604 if let Some(create_exprs) = &e.create_expressions {
26605 self.write(" (");
26606 self.generate_doris_partition_definitions(create_exprs)?;
26608 self.write(")");
26609 }
26610 Ok(())
26611 }
26612
26613 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
26614 self.write_keyword("PARTITION BY RANGE");
26616 if let Some(partition_exprs) = &e.partition_expressions {
26617 self.write(" (");
26618 self.generate_doris_partition_expressions(partition_exprs)?;
26620 self.write(")");
26621 }
26622 if let Some(create_exprs) = &e.create_expressions {
26623 self.write(" (");
26624 self.generate_doris_partition_definitions(create_exprs)?;
26626 self.write(")");
26627 }
26628 Ok(())
26629 }
26630
26631 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
26633 if let Expression::Tuple(t) = expr {
26634 for (i, e) in t.expressions.iter().enumerate() {
26635 if i > 0 {
26636 self.write(", ");
26637 }
26638 self.generate_expression(e)?;
26639 }
26640 } else {
26641 self.generate_expression(expr)?;
26642 }
26643 Ok(())
26644 }
26645
26646 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
26648 match expr {
26649 Expression::Tuple(t) => {
26650 for (i, part) in t.expressions.iter().enumerate() {
26652 if i > 0 {
26653 self.write(", ");
26654 }
26655 if let Expression::Partition(p) = part {
26657 for (j, inner) in p.expressions.iter().enumerate() {
26658 if j > 0 {
26659 self.write(", ");
26660 }
26661 self.generate_expression(inner)?;
26662 }
26663 } else {
26664 self.generate_expression(part)?;
26665 }
26666 }
26667 }
26668 Expression::PartitionByRangePropertyDynamic(_) => {
26669 self.generate_expression(expr)?;
26671 }
26672 _ => {
26673 self.generate_expression(expr)?;
26674 }
26675 }
26676 Ok(())
26677 }
26678
26679 fn generate_partition_by_range_property_dynamic(&mut self, e: &PartitionByRangePropertyDynamic) -> Result<()> {
26680 if let Some(start) = &e.start {
26682 self.write_keyword("FROM");
26683 self.write(" (");
26684 self.generate_expression(start)?;
26685 self.write(")");
26686 }
26687 if let Some(end) = &e.end {
26688 self.write_space();
26689 self.write_keyword("TO");
26690 self.write(" (");
26691 self.generate_expression(end)?;
26692 self.write(")");
26693 }
26694 if let Some(every) = &e.every {
26695 self.write_space();
26696 self.generate_doris_interval(every)?;
26698 }
26699 Ok(())
26700 }
26701
26702 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
26704 if let Expression::Interval(interval) = expr {
26705 self.write_keyword("INTERVAL");
26706 if let Some(ref value) = interval.this {
26707 self.write_space();
26708 self.generate_expression(value)?;
26710 }
26711 if let Some(ref unit_spec) = interval.unit {
26712 self.write_space();
26713 self.write_interval_unit_spec(unit_spec)?;
26714 }
26715 Ok(())
26716 } else {
26717 self.generate_expression(expr)
26718 }
26719 }
26720
26721 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
26722 self.write_keyword("TRUNCATE");
26724 self.write("(");
26725 self.generate_expression(&e.expression)?;
26726 self.write(", ");
26727 self.generate_expression(&e.this)?;
26728 self.write(")");
26729 Ok(())
26730 }
26731
26732 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
26733 self.write_keyword("PARTITION");
26735 self.write_space();
26736 self.generate_expression(&e.this)?;
26737 self.write_space();
26738 self.write_keyword("VALUES IN");
26739 self.write(" (");
26740 for (i, expr) in e.expressions.iter().enumerate() {
26741 if i > 0 {
26742 self.write(", ");
26743 }
26744 self.generate_expression(expr)?;
26745 }
26746 self.write(")");
26747 Ok(())
26748 }
26749
26750 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
26751 if e.expressions.is_empty() && e.expression.is_some() {
26754 self.generate_expression(&e.this)?;
26756 self.write_space();
26757 self.write_keyword("TO");
26758 self.write_space();
26759 self.generate_expression(e.expression.as_ref().unwrap())?;
26760 return Ok(());
26761 }
26762
26763 self.write_keyword("PARTITION");
26765 self.write_space();
26766 self.generate_expression(&e.this)?;
26767 self.write_space();
26768
26769 if e.expressions.len() == 1 {
26771 self.write_keyword("VALUES LESS THAN");
26773 self.write(" (");
26774 self.generate_expression(&e.expressions[0])?;
26775 self.write(")");
26776 } else if !e.expressions.is_empty() {
26777 self.write_keyword("VALUES");
26779 self.write(" [");
26780 for (i, expr) in e.expressions.iter().enumerate() {
26781 if i > 0 {
26782 self.write(", ");
26783 }
26784 if let Expression::Tuple(t) = expr {
26786 self.write("(");
26787 for (j, inner) in t.expressions.iter().enumerate() {
26788 if j > 0 {
26789 self.write(", ");
26790 }
26791 self.generate_expression(inner)?;
26792 }
26793 self.write(")");
26794 } else {
26795 self.write("(");
26796 self.generate_expression(expr)?;
26797 self.write(")");
26798 }
26799 }
26800 self.write(")");
26801 }
26802 Ok(())
26803 }
26804
26805 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
26806 self.write_keyword("BUCKET");
26808 self.write("(");
26809 self.generate_expression(&e.this)?;
26810 self.write(", ");
26811 self.generate_expression(&e.expression)?;
26812 self.write(")");
26813 Ok(())
26814 }
26815
26816 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
26817 if matches!(
26819 self.config.dialect,
26820 Some(crate::dialects::DialectType::Teradata) | Some(crate::dialects::DialectType::ClickHouse)
26821 ) {
26822 self.write_keyword("PARTITION BY");
26823 } else {
26824 self.write_keyword("PARTITIONED BY");
26825 }
26826 self.write_space();
26827 if self.config.pretty {
26829 if let Expression::Tuple(ref tuple) = *e.this {
26830 self.write("(");
26831 self.write_newline();
26832 self.indent_level += 1;
26833 for (i, expr) in tuple.expressions.iter().enumerate() {
26834 if i > 0 {
26835 self.write(",");
26836 self.write_newline();
26837 }
26838 self.write_indent();
26839 self.generate_expression(expr)?;
26840 }
26841 self.indent_level -= 1;
26842 self.write_newline();
26843 self.write(")");
26844 } else {
26845 self.generate_expression(&e.this)?;
26846 }
26847 } else {
26848 self.generate_expression(&e.this)?;
26849 }
26850 Ok(())
26851 }
26852
26853 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
26854 self.write_keyword("PARTITION OF");
26856 self.write_space();
26857 self.generate_expression(&e.this)?;
26858 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
26860 self.write_space();
26861 self.write_keyword("FOR VALUES");
26862 self.write_space();
26863 self.generate_expression(&e.expression)?;
26864 } else {
26865 self.write_space();
26866 self.write_keyword("DEFAULT");
26867 }
26868 Ok(())
26869 }
26870
26871 fn generate_period_for_system_time_constraint(&mut self, e: &PeriodForSystemTimeConstraint) -> Result<()> {
26872 self.write_keyword("PERIOD FOR SYSTEM_TIME");
26874 self.write(" (");
26875 self.generate_expression(&e.this)?;
26876 self.write(", ");
26877 self.generate_expression(&e.expression)?;
26878 self.write(")");
26879 Ok(())
26880 }
26881
26882 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
26883 self.generate_expression(&e.this)?;
26886 self.write_space();
26887 self.write_keyword("AS");
26888 self.write_space();
26889 if self.config.unpivot_aliases_are_identifiers {
26891 match &e.alias {
26892 Expression::Literal(Literal::String(s)) => {
26893 self.generate_identifier(&Identifier::new(s.clone()))?;
26895 }
26896 Expression::Literal(Literal::Number(n)) => {
26897 let mut id = Identifier::new(n.clone());
26899 id.quoted = true;
26900 self.generate_identifier(&id)?;
26901 }
26902 other => {
26903 self.generate_expression(other)?;
26904 }
26905 }
26906 } else {
26907 self.generate_expression(&e.alias)?;
26908 }
26909 Ok(())
26910 }
26911
26912 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
26913 self.write_keyword("ANY");
26915 if let Some(this) = &e.this {
26916 self.write_space();
26917 self.generate_expression(this)?;
26918 }
26919 Ok(())
26920 }
26921
26922 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
26923 self.write_keyword("ML.PREDICT");
26925 self.write("(");
26926 self.write_keyword("MODEL");
26927 self.write_space();
26928 self.generate_expression(&e.this)?;
26929 self.write(", ");
26930 self.generate_expression(&e.expression)?;
26931 if let Some(params) = &e.params_struct {
26932 self.write(", ");
26933 self.generate_expression(params)?;
26934 }
26935 self.write(")");
26936 Ok(())
26937 }
26938
26939 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
26940 self.write_keyword("PREVIOUS_DAY");
26942 self.write("(");
26943 self.generate_expression(&e.this)?;
26944 self.write(", ");
26945 self.generate_expression(&e.expression)?;
26946 self.write(")");
26947 Ok(())
26948 }
26949
26950 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
26951 self.write_keyword("PRIMARY KEY");
26953 if let Some(name) = &e.this {
26954 self.write_space();
26955 self.generate_expression(name)?;
26956 }
26957 if !e.expressions.is_empty() {
26958 self.write(" (");
26959 for (i, expr) in e.expressions.iter().enumerate() {
26960 if i > 0 {
26961 self.write(", ");
26962 }
26963 self.generate_expression(expr)?;
26964 }
26965 self.write(")");
26966 }
26967 if let Some(include) = &e.include {
26968 self.write_space();
26969 self.generate_expression(include)?;
26970 }
26971 if !e.options.is_empty() {
26972 self.write_space();
26973 for (i, opt) in e.options.iter().enumerate() {
26974 if i > 0 {
26975 self.write_space();
26976 }
26977 self.generate_expression(opt)?;
26978 }
26979 }
26980 Ok(())
26981 }
26982
26983 fn generate_primary_key_column_constraint(&mut self, _e: &PrimaryKeyColumnConstraint) -> Result<()> {
26984 self.write_keyword("PRIMARY KEY");
26986 Ok(())
26987 }
26988
26989 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
26990 self.write_keyword("PATH");
26992 self.write_space();
26993 self.generate_expression(&e.this)?;
26994 Ok(())
26995 }
26996
26997 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
26998 self.write_keyword("PROJECTION");
27000 self.write_space();
27001 self.generate_expression(&e.this)?;
27002 self.write(" (");
27003 self.generate_expression(&e.expression)?;
27004 self.write(")");
27005 Ok(())
27006 }
27007
27008 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
27009 for (i, prop) in e.expressions.iter().enumerate() {
27011 if i > 0 {
27012 self.write(", ");
27013 }
27014 self.generate_expression(prop)?;
27015 }
27016 Ok(())
27017 }
27018
27019 fn generate_property(&mut self, e: &Property) -> Result<()> {
27020 self.generate_expression(&e.this)?;
27022 if let Some(value) = &e.value {
27023 self.write("=");
27024 self.generate_expression(value)?;
27025 }
27026 Ok(())
27027 }
27028
27029 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
27031 self.write_keyword("OPTIONS");
27032 self.write(" (");
27033 for (i, opt) in options.iter().enumerate() {
27034 if i > 0 {
27035 self.write(", ");
27036 }
27037 self.generate_option_expression(opt)?;
27038 }
27039 self.write(")");
27040 Ok(())
27041 }
27042
27043 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
27045 self.write_keyword("PROPERTIES");
27046 self.write(" (");
27047 for (i, prop) in properties.iter().enumerate() {
27048 if i > 0 {
27049 self.write(", ");
27050 }
27051 self.generate_option_expression(prop)?;
27052 }
27053 self.write(")");
27054 Ok(())
27055 }
27056
27057 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
27059 self.write_keyword("ENVIRONMENT");
27060 self.write(" (");
27061 for (i, env_item) in environment.iter().enumerate() {
27062 if i > 0 {
27063 self.write(", ");
27064 }
27065 self.generate_environment_expression(env_item)?;
27066 }
27067 self.write(")");
27068 Ok(())
27069 }
27070
27071 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
27073 match expr {
27074 Expression::Eq(eq) => {
27075 self.generate_expression(&eq.left)?;
27077 self.write(" = ");
27078 self.generate_expression(&eq.right)?;
27079 Ok(())
27080 }
27081 _ => self.generate_expression(expr),
27082 }
27083 }
27084
27085 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
27087 self.write_keyword("TBLPROPERTIES");
27088 if self.config.pretty {
27089 self.write(" (");
27090 self.write_newline();
27091 self.indent_level += 1;
27092 for (i, opt) in options.iter().enumerate() {
27093 if i > 0 {
27094 self.write(",");
27095 self.write_newline();
27096 }
27097 self.write_indent();
27098 self.generate_option_expression(opt)?;
27099 }
27100 self.indent_level -= 1;
27101 self.write_newline();
27102 self.write(")");
27103 } else {
27104 self.write(" (");
27105 for (i, opt) in options.iter().enumerate() {
27106 if i > 0 {
27107 self.write(", ");
27108 }
27109 self.generate_option_expression(opt)?;
27110 }
27111 self.write(")");
27112 }
27113 Ok(())
27114 }
27115
27116 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
27118 match expr {
27119 Expression::Eq(eq) => {
27120 self.generate_expression(&eq.left)?;
27122 self.write("=");
27123 self.generate_expression(&eq.right)?;
27124 Ok(())
27125 }
27126 _ => self.generate_expression(expr),
27127 }
27128 }
27129
27130 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
27131 self.generate_expression(&e.this)?;
27133 Ok(())
27134 }
27135
27136 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
27137 self.write_keyword("PUT");
27139 self.write_space();
27140
27141 if e.source_quoted {
27143 self.write("'");
27144 self.write(&e.source);
27145 self.write("'");
27146 } else {
27147 self.write(&e.source);
27148 }
27149
27150 self.write_space();
27151
27152 if let Expression::Literal(Literal::String(s)) = &e.target {
27154 self.write(s);
27155 } else {
27156 self.generate_expression(&e.target)?;
27157 }
27158
27159 for param in &e.params {
27161 self.write_space();
27162 self.write(¶m.name);
27163 if let Some(ref value) = param.value {
27164 self.write("=");
27165 self.generate_expression(value)?;
27166 }
27167 }
27168
27169 Ok(())
27170 }
27171
27172 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
27173 self.write_keyword("QUANTILE");
27175 self.write("(");
27176 self.generate_expression(&e.this)?;
27177 if let Some(quantile) = &e.quantile {
27178 self.write(", ");
27179 self.generate_expression(quantile)?;
27180 }
27181 self.write(")");
27182 Ok(())
27183 }
27184
27185 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
27186 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Teradata)) {
27188 self.write_keyword("SET");
27189 self.write_space();
27190 }
27191 self.write_keyword("QUERY_BAND");
27192 self.write(" = ");
27193 self.generate_expression(&e.this)?;
27194 if e.update.is_some() {
27195 self.write_space();
27196 self.write_keyword("UPDATE");
27197 }
27198 if let Some(scope) = &e.scope {
27199 self.write_space();
27200 self.write_keyword("FOR");
27201 self.write_space();
27202 self.generate_expression(scope)?;
27203 }
27204 Ok(())
27205 }
27206
27207 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
27208 self.generate_expression(&e.this)?;
27210 if let Some(expression) = &e.expression {
27211 self.write(" = ");
27212 self.generate_expression(expression)?;
27213 }
27214 Ok(())
27215 }
27216
27217 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
27218 self.write_keyword("TRANSFORM");
27220 self.write("(");
27221 for (i, expr) in e.expressions.iter().enumerate() {
27222 if i > 0 {
27223 self.write(", ");
27224 }
27225 self.generate_expression(expr)?;
27226 }
27227 self.write(")");
27228 if let Some(row_format_before) = &e.row_format_before {
27229 self.write_space();
27230 self.generate_expression(row_format_before)?;
27231 }
27232 if let Some(record_writer) = &e.record_writer {
27233 self.write_space();
27234 self.write_keyword("RECORDWRITER");
27235 self.write_space();
27236 self.generate_expression(record_writer)?;
27237 }
27238 if let Some(command_script) = &e.command_script {
27239 self.write_space();
27240 self.write_keyword("USING");
27241 self.write_space();
27242 self.generate_expression(command_script)?;
27243 }
27244 if let Some(schema) = &e.schema {
27245 self.write_space();
27246 self.write_keyword("AS");
27247 self.write_space();
27248 self.generate_expression(schema)?;
27249 }
27250 if let Some(row_format_after) = &e.row_format_after {
27251 self.write_space();
27252 self.generate_expression(row_format_after)?;
27253 }
27254 if let Some(record_reader) = &e.record_reader {
27255 self.write_space();
27256 self.write_keyword("RECORDREADER");
27257 self.write_space();
27258 self.generate_expression(record_reader)?;
27259 }
27260 Ok(())
27261 }
27262
27263 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
27264 self.write_keyword("RANDN");
27266 self.write("(");
27267 if let Some(this) = &e.this {
27268 self.generate_expression(this)?;
27269 }
27270 self.write(")");
27271 Ok(())
27272 }
27273
27274 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
27275 self.write_keyword("RANDSTR");
27277 self.write("(");
27278 self.generate_expression(&e.this)?;
27279 if let Some(generator) = &e.generator {
27280 self.write(", ");
27281 self.generate_expression(generator)?;
27282 }
27283 self.write(")");
27284 Ok(())
27285 }
27286
27287 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
27288 self.write_keyword("RANGE_BUCKET");
27290 self.write("(");
27291 self.generate_expression(&e.this)?;
27292 self.write(", ");
27293 self.generate_expression(&e.expression)?;
27294 self.write(")");
27295 Ok(())
27296 }
27297
27298 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
27299 self.write_keyword("RANGE_N");
27301 self.write("(");
27302 self.generate_expression(&e.this)?;
27303 self.write_space();
27304 self.write_keyword("BETWEEN");
27305 self.write_space();
27306 for (i, expr) in e.expressions.iter().enumerate() {
27307 if i > 0 {
27308 self.write(", ");
27309 }
27310 self.generate_expression(expr)?;
27311 }
27312 if let Some(each) = &e.each {
27313 self.write_space();
27314 self.write_keyword("EACH");
27315 self.write_space();
27316 self.generate_expression(each)?;
27317 }
27318 self.write(")");
27319 Ok(())
27320 }
27321
27322 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
27323 self.write_keyword("READ_CSV");
27325 self.write("(");
27326 self.generate_expression(&e.this)?;
27327 for expr in &e.expressions {
27328 self.write(", ");
27329 self.generate_expression(expr)?;
27330 }
27331 self.write(")");
27332 Ok(())
27333 }
27334
27335 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
27336 self.write_keyword("READ_PARQUET");
27338 self.write("(");
27339 for (i, expr) in e.expressions.iter().enumerate() {
27340 if i > 0 {
27341 self.write(", ");
27342 }
27343 self.generate_expression(expr)?;
27344 }
27345 self.write(")");
27346 Ok(())
27347 }
27348
27349 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
27350 if e.kind == "CYCLE" {
27353 self.write_keyword("CYCLE");
27354 } else {
27355 self.write_keyword("SEARCH");
27356 self.write_space();
27357 self.write(&e.kind);
27358 self.write_space();
27359 self.write_keyword("FIRST BY");
27360 }
27361 self.write_space();
27362 self.generate_expression(&e.this)?;
27363 self.write_space();
27364 self.write_keyword("SET");
27365 self.write_space();
27366 self.generate_expression(&e.expression)?;
27367 if let Some(using) = &e.using {
27368 self.write_space();
27369 self.write_keyword("USING");
27370 self.write_space();
27371 self.generate_expression(using)?;
27372 }
27373 Ok(())
27374 }
27375
27376 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
27377 self.write_keyword("REDUCE");
27379 self.write("(");
27380 self.generate_expression(&e.this)?;
27381 if let Some(initial) = &e.initial {
27382 self.write(", ");
27383 self.generate_expression(initial)?;
27384 }
27385 if let Some(merge) = &e.merge {
27386 self.write(", ");
27387 self.generate_expression(merge)?;
27388 }
27389 if let Some(finish) = &e.finish {
27390 self.write(", ");
27391 self.generate_expression(finish)?;
27392 }
27393 self.write(")");
27394 Ok(())
27395 }
27396
27397 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
27398 self.write_keyword("REFERENCES");
27400 self.write_space();
27401 self.generate_expression(&e.this)?;
27402 if !e.expressions.is_empty() {
27403 self.write(" (");
27404 for (i, expr) in e.expressions.iter().enumerate() {
27405 if i > 0 {
27406 self.write(", ");
27407 }
27408 self.generate_expression(expr)?;
27409 }
27410 self.write(")");
27411 }
27412 for opt in &e.options {
27413 self.write_space();
27414 self.generate_expression(opt)?;
27415 }
27416 Ok(())
27417 }
27418
27419 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
27420 self.write_keyword("REFRESH");
27422 if !e.kind.is_empty() {
27423 self.write_space();
27424 self.write_keyword(&e.kind);
27425 }
27426 self.write_space();
27427 self.generate_expression(&e.this)?;
27428 Ok(())
27429 }
27430
27431 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
27432 self.write_keyword("REFRESH");
27434 self.write_space();
27435 self.write_keyword(&e.method);
27436
27437 if let Some(ref kind) = e.kind {
27438 self.write_space();
27439 self.write_keyword("ON");
27440 self.write_space();
27441 self.write_keyword(kind);
27442
27443 if let Some(ref every) = e.every {
27445 self.write_space();
27446 self.write_keyword("EVERY");
27447 self.write_space();
27448 self.generate_expression(every)?;
27449 if let Some(ref unit) = e.unit {
27450 self.write_space();
27451 self.write_keyword(unit);
27452 }
27453 }
27454
27455 if let Some(ref starts) = e.starts {
27457 self.write_space();
27458 self.write_keyword("STARTS");
27459 self.write_space();
27460 self.generate_expression(starts)?;
27461 }
27462 }
27463 Ok(())
27464 }
27465
27466 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
27467 self.write_keyword("REGEXP_COUNT");
27469 self.write("(");
27470 self.generate_expression(&e.this)?;
27471 self.write(", ");
27472 self.generate_expression(&e.expression)?;
27473 if let Some(position) = &e.position {
27474 self.write(", ");
27475 self.generate_expression(position)?;
27476 }
27477 if let Some(parameters) = &e.parameters {
27478 self.write(", ");
27479 self.generate_expression(parameters)?;
27480 }
27481 self.write(")");
27482 Ok(())
27483 }
27484
27485 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
27486 self.write_keyword("REGEXP_EXTRACT_ALL");
27488 self.write("(");
27489 self.generate_expression(&e.this)?;
27490 self.write(", ");
27491 self.generate_expression(&e.expression)?;
27492 if let Some(group) = &e.group {
27493 self.write(", ");
27494 self.generate_expression(group)?;
27495 }
27496 self.write(")");
27497 Ok(())
27498 }
27499
27500 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
27501 self.write_keyword("REGEXP_FULL_MATCH");
27503 self.write("(");
27504 self.generate_expression(&e.this)?;
27505 self.write(", ");
27506 self.generate_expression(&e.expression)?;
27507 self.write(")");
27508 Ok(())
27509 }
27510
27511 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
27512 use crate::dialects::DialectType;
27513 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) && e.flag.is_none() {
27515 self.generate_expression(&e.this)?;
27516 self.write(" ~* ");
27517 self.generate_expression(&e.expression)?;
27518 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
27519 self.write_keyword("REGEXP_LIKE");
27521 self.write("(");
27522 self.generate_expression(&e.this)?;
27523 self.write(", ");
27524 self.generate_expression(&e.expression)?;
27525 self.write(", ");
27526 if let Some(flag) = &e.flag {
27527 self.generate_expression(flag)?;
27528 } else {
27529 self.write("'i'");
27530 }
27531 self.write(")");
27532 } else {
27533 self.generate_expression(&e.this)?;
27535 self.write_space();
27536 self.write_keyword("REGEXP_ILIKE");
27537 self.write_space();
27538 self.generate_expression(&e.expression)?;
27539 if let Some(flag) = &e.flag {
27540 self.write(", ");
27541 self.generate_expression(flag)?;
27542 }
27543 }
27544 Ok(())
27545 }
27546
27547 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
27548 self.write_keyword("REGEXP_INSTR");
27550 self.write("(");
27551 self.generate_expression(&e.this)?;
27552 self.write(", ");
27553 self.generate_expression(&e.expression)?;
27554 if let Some(position) = &e.position {
27555 self.write(", ");
27556 self.generate_expression(position)?;
27557 }
27558 if let Some(occurrence) = &e.occurrence {
27559 self.write(", ");
27560 self.generate_expression(occurrence)?;
27561 }
27562 if let Some(option) = &e.option {
27563 self.write(", ");
27564 self.generate_expression(option)?;
27565 }
27566 if let Some(parameters) = &e.parameters {
27567 self.write(", ");
27568 self.generate_expression(parameters)?;
27569 }
27570 if let Some(group) = &e.group {
27571 self.write(", ");
27572 self.generate_expression(group)?;
27573 }
27574 self.write(")");
27575 Ok(())
27576 }
27577
27578 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
27579 self.write_keyword("REGEXP_SPLIT");
27581 self.write("(");
27582 self.generate_expression(&e.this)?;
27583 self.write(", ");
27584 self.generate_expression(&e.expression)?;
27585 if let Some(limit) = &e.limit {
27586 self.write(", ");
27587 self.generate_expression(limit)?;
27588 }
27589 self.write(")");
27590 Ok(())
27591 }
27592
27593 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
27594 self.write_keyword("REGR_AVGX");
27596 self.write("(");
27597 self.generate_expression(&e.this)?;
27598 self.write(", ");
27599 self.generate_expression(&e.expression)?;
27600 self.write(")");
27601 Ok(())
27602 }
27603
27604 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
27605 self.write_keyword("REGR_AVGY");
27607 self.write("(");
27608 self.generate_expression(&e.this)?;
27609 self.write(", ");
27610 self.generate_expression(&e.expression)?;
27611 self.write(")");
27612 Ok(())
27613 }
27614
27615 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
27616 self.write_keyword("REGR_COUNT");
27618 self.write("(");
27619 self.generate_expression(&e.this)?;
27620 self.write(", ");
27621 self.generate_expression(&e.expression)?;
27622 self.write(")");
27623 Ok(())
27624 }
27625
27626 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
27627 self.write_keyword("REGR_INTERCEPT");
27629 self.write("(");
27630 self.generate_expression(&e.this)?;
27631 self.write(", ");
27632 self.generate_expression(&e.expression)?;
27633 self.write(")");
27634 Ok(())
27635 }
27636
27637 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
27638 self.write_keyword("REGR_R2");
27640 self.write("(");
27641 self.generate_expression(&e.this)?;
27642 self.write(", ");
27643 self.generate_expression(&e.expression)?;
27644 self.write(")");
27645 Ok(())
27646 }
27647
27648 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
27649 self.write_keyword("REGR_SLOPE");
27651 self.write("(");
27652 self.generate_expression(&e.this)?;
27653 self.write(", ");
27654 self.generate_expression(&e.expression)?;
27655 self.write(")");
27656 Ok(())
27657 }
27658
27659 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
27660 self.write_keyword("REGR_SXX");
27662 self.write("(");
27663 self.generate_expression(&e.this)?;
27664 self.write(", ");
27665 self.generate_expression(&e.expression)?;
27666 self.write(")");
27667 Ok(())
27668 }
27669
27670 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
27671 self.write_keyword("REGR_SXY");
27673 self.write("(");
27674 self.generate_expression(&e.this)?;
27675 self.write(", ");
27676 self.generate_expression(&e.expression)?;
27677 self.write(")");
27678 Ok(())
27679 }
27680
27681 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
27682 self.write_keyword("REGR_SYY");
27684 self.write("(");
27685 self.generate_expression(&e.this)?;
27686 self.write(", ");
27687 self.generate_expression(&e.expression)?;
27688 self.write(")");
27689 Ok(())
27690 }
27691
27692 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
27693 self.write_keyword("REGR_VALX");
27695 self.write("(");
27696 self.generate_expression(&e.this)?;
27697 self.write(", ");
27698 self.generate_expression(&e.expression)?;
27699 self.write(")");
27700 Ok(())
27701 }
27702
27703 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
27704 self.write_keyword("REGR_VALY");
27706 self.write("(");
27707 self.generate_expression(&e.this)?;
27708 self.write(", ");
27709 self.generate_expression(&e.expression)?;
27710 self.write(")");
27711 Ok(())
27712 }
27713
27714 fn generate_remote_with_connection_model_property(&mut self, e: &RemoteWithConnectionModelProperty) -> Result<()> {
27715 self.write_keyword("REMOTE WITH CONNECTION");
27717 self.write_space();
27718 self.generate_expression(&e.this)?;
27719 Ok(())
27720 }
27721
27722 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
27723 self.write_keyword("RENAME COLUMN");
27725 if e.exists {
27726 self.write_space();
27727 self.write_keyword("IF EXISTS");
27728 }
27729 self.write_space();
27730 self.generate_expression(&e.this)?;
27731 if let Some(to) = &e.to {
27732 self.write_space();
27733 self.write_keyword("TO");
27734 self.write_space();
27735 self.generate_expression(to)?;
27736 }
27737 Ok(())
27738 }
27739
27740 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
27741 self.write_keyword("REPLACE PARTITION");
27743 self.write_space();
27744 self.generate_expression(&e.expression)?;
27745 if let Some(source) = &e.source {
27746 self.write_space();
27747 self.write_keyword("FROM");
27748 self.write_space();
27749 self.generate_expression(source)?;
27750 }
27751 Ok(())
27752 }
27753
27754 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
27755 let keyword = match self.config.dialect {
27758 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
27759 _ => "RETURNING",
27760 };
27761 self.write_keyword(keyword);
27762 self.write_space();
27763 for (i, expr) in e.expressions.iter().enumerate() {
27764 if i > 0 {
27765 self.write(", ");
27766 }
27767 self.generate_expression(expr)?;
27768 }
27769 if let Some(into) = &e.into {
27770 self.write_space();
27771 self.write_keyword("INTO");
27772 self.write_space();
27773 self.generate_expression(into)?;
27774 }
27775 Ok(())
27776 }
27777
27778 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
27779 self.write_space();
27781 self.write_keyword("OUTPUT");
27782 self.write_space();
27783 for (i, expr) in output.columns.iter().enumerate() {
27784 if i > 0 {
27785 self.write(", ");
27786 }
27787 self.generate_expression(expr)?;
27788 }
27789 if let Some(into_table) = &output.into_table {
27790 self.write_space();
27791 self.write_keyword("INTO");
27792 self.write_space();
27793 self.generate_expression(into_table)?;
27794 }
27795 Ok(())
27796 }
27797
27798 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
27799 self.write_keyword("RETURNS");
27801 if e.is_table.is_some() {
27802 self.write_space();
27803 self.write_keyword("TABLE");
27804 }
27805 if let Some(table) = &e.table {
27806 self.write_space();
27807 self.generate_expression(table)?;
27808 } else if let Some(this) = &e.this {
27809 self.write_space();
27810 self.generate_expression(this)?;
27811 }
27812 if e.null.is_some() {
27813 self.write_space();
27814 self.write_keyword("NULL ON NULL INPUT");
27815 }
27816 Ok(())
27817 }
27818
27819 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
27820 self.write_keyword("ROLLBACK");
27822
27823 if e.this.is_none() && matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) {
27825 self.write_space();
27826 self.write_keyword("TRANSACTION");
27827 }
27828
27829 if let Some(this) = &e.this {
27831 let is_transaction_marker = matches!(
27833 this.as_ref(),
27834 Expression::Identifier(id) if id.name == "TRANSACTION"
27835 );
27836
27837 self.write_space();
27838 self.write_keyword("TRANSACTION");
27839
27840 if !is_transaction_marker {
27842 self.write_space();
27843 self.generate_expression(this)?;
27844 }
27845 }
27846
27847 if let Some(savepoint) = &e.savepoint {
27849 self.write_space();
27850 self.write_keyword("TO");
27851 self.write_space();
27852 self.generate_expression(savepoint)?;
27853 }
27854 Ok(())
27855 }
27856
27857 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
27858 if e.expressions.is_empty() {
27860 self.write_keyword("WITH ROLLUP");
27861 } else {
27862 self.write_keyword("ROLLUP");
27863 self.write("(");
27864 for (i, expr) in e.expressions.iter().enumerate() {
27865 if i > 0 {
27866 self.write(", ");
27867 }
27868 self.generate_expression(expr)?;
27869 }
27870 self.write(")");
27871 }
27872 Ok(())
27873 }
27874
27875 fn generate_row_format_delimited_property(&mut self, e: &RowFormatDelimitedProperty) -> Result<()> {
27876 self.write_keyword("ROW FORMAT DELIMITED");
27878 if let Some(fields) = &e.fields {
27879 self.write_space();
27880 self.write_keyword("FIELDS TERMINATED BY");
27881 self.write_space();
27882 self.generate_expression(fields)?;
27883 }
27884 if let Some(escaped) = &e.escaped {
27885 self.write_space();
27886 self.write_keyword("ESCAPED BY");
27887 self.write_space();
27888 self.generate_expression(escaped)?;
27889 }
27890 if let Some(items) = &e.collection_items {
27891 self.write_space();
27892 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
27893 self.write_space();
27894 self.generate_expression(items)?;
27895 }
27896 if let Some(keys) = &e.map_keys {
27897 self.write_space();
27898 self.write_keyword("MAP KEYS TERMINATED BY");
27899 self.write_space();
27900 self.generate_expression(keys)?;
27901 }
27902 if let Some(lines) = &e.lines {
27903 self.write_space();
27904 self.write_keyword("LINES TERMINATED BY");
27905 self.write_space();
27906 self.generate_expression(lines)?;
27907 }
27908 if let Some(null) = &e.null {
27909 self.write_space();
27910 self.write_keyword("NULL DEFINED AS");
27911 self.write_space();
27912 self.generate_expression(null)?;
27913 }
27914 if let Some(serde) = &e.serde {
27915 self.write_space();
27916 self.generate_expression(serde)?;
27917 }
27918 Ok(())
27919 }
27920
27921 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
27922 self.write_keyword("ROW FORMAT");
27924 self.write_space();
27925 self.generate_expression(&e.this)?;
27926 Ok(())
27927 }
27928
27929 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
27930 self.write_keyword("ROW FORMAT SERDE");
27932 self.write_space();
27933 self.generate_expression(&e.this)?;
27934 if let Some(props) = &e.serde_properties {
27935 self.write_space();
27936 self.generate_expression(props)?;
27938 }
27939 Ok(())
27940 }
27941
27942 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
27943 self.write_keyword("SHA2");
27945 self.write("(");
27946 self.generate_expression(&e.this)?;
27947 if let Some(length) = e.length {
27948 self.write(", ");
27949 self.write(&length.to_string());
27950 }
27951 self.write(")");
27952 Ok(())
27953 }
27954
27955 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
27956 self.write_keyword("SHA2_DIGEST");
27958 self.write("(");
27959 self.generate_expression(&e.this)?;
27960 if let Some(length) = e.length {
27961 self.write(", ");
27962 self.write(&length.to_string());
27963 }
27964 self.write(")");
27965 Ok(())
27966 }
27967
27968 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
27969 let name = if matches!(self.config.dialect, Some(crate::dialects::DialectType::Spark) | Some(crate::dialects::DialectType::Databricks)) {
27970 "TRY_ADD"
27971 } else {
27972 "SAFE_ADD"
27973 };
27974 self.write_keyword(name);
27975 self.write("(");
27976 self.generate_expression(&e.this)?;
27977 self.write(", ");
27978 self.generate_expression(&e.expression)?;
27979 self.write(")");
27980 Ok(())
27981 }
27982
27983 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
27984 self.write_keyword("SAFE_DIVIDE");
27986 self.write("(");
27987 self.generate_expression(&e.this)?;
27988 self.write(", ");
27989 self.generate_expression(&e.expression)?;
27990 self.write(")");
27991 Ok(())
27992 }
27993
27994 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
27995 let name = if matches!(self.config.dialect, Some(crate::dialects::DialectType::Spark) | Some(crate::dialects::DialectType::Databricks)) {
27996 "TRY_MULTIPLY"
27997 } else {
27998 "SAFE_MULTIPLY"
27999 };
28000 self.write_keyword(name);
28001 self.write("(");
28002 self.generate_expression(&e.this)?;
28003 self.write(", ");
28004 self.generate_expression(&e.expression)?;
28005 self.write(")");
28006 Ok(())
28007 }
28008
28009 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
28010 let name = if matches!(self.config.dialect, Some(crate::dialects::DialectType::Spark) | Some(crate::dialects::DialectType::Databricks)) {
28011 "TRY_SUBTRACT"
28012 } else {
28013 "SAFE_SUBTRACT"
28014 };
28015 self.write_keyword(name);
28016 self.write("(");
28017 self.generate_expression(&e.this)?;
28018 self.write(", ");
28019 self.generate_expression(&e.expression)?;
28020 self.write(")");
28021 Ok(())
28022 }
28023
28024 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
28027 if matches!(sample.method, SampleMethod::Bucket) {
28029 self.write(" (");
28030 self.write_keyword("BUCKET");
28031 self.write_space();
28032 if let Some(ref num) = sample.bucket_numerator {
28033 self.generate_expression(num)?;
28034 }
28035 self.write_space();
28036 self.write_keyword("OUT OF");
28037 self.write_space();
28038 if let Some(ref denom) = sample.bucket_denominator {
28039 self.generate_expression(denom)?;
28040 }
28041 if let Some(ref field) = sample.bucket_field {
28042 self.write_space();
28043 self.write_keyword("ON");
28044 self.write_space();
28045 self.generate_expression(field)?;
28046 }
28047 self.write(")");
28048 return Ok(());
28049 }
28050
28051 let is_snowflake = matches!(self.config.dialect, Some(crate::dialects::DialectType::Snowflake));
28053 let is_postgres = matches!(self.config.dialect, Some(crate::dialects::DialectType::PostgreSQL) | Some(crate::dialects::DialectType::Redshift));
28054 let is_databricks = matches!(self.config.dialect, Some(crate::dialects::DialectType::Databricks));
28056 let is_spark = matches!(self.config.dialect, Some(crate::dialects::DialectType::Spark));
28057 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
28058 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
28060 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
28061 self.write_space();
28062 if !sample.explicit_method && (is_snowflake || force_method) {
28063 self.write_keyword("BERNOULLI");
28065 } else {
28066 match sample.method {
28067 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
28068 SampleMethod::System => self.write_keyword("SYSTEM"),
28069 SampleMethod::Block => self.write_keyword("BLOCK"),
28070 SampleMethod::Row => self.write_keyword("ROW"),
28071 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
28072 SampleMethod::Percent => self.write_keyword("SYSTEM"),
28073 SampleMethod::Bucket => {} }
28075 }
28076 }
28077
28078 let emit_size_no_parens = !self.config.tablesample_requires_parens;
28080 if emit_size_no_parens {
28081 self.write_space();
28082 match &sample.size {
28083 Expression::Tuple(tuple) => {
28084 for (i, expr) in tuple.expressions.iter().enumerate() {
28085 if i > 0 {
28086 self.write(", ");
28087 }
28088 self.generate_expression(expr)?;
28089 }
28090 }
28091 expr => self.generate_expression(expr)?,
28092 }
28093 } else {
28094 self.write(" (");
28095 self.generate_expression(&sample.size)?;
28096 }
28097
28098 let is_rows_method = matches!(sample.method, SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket);
28100 let is_percent = matches!(sample.method, SampleMethod::Percent | SampleMethod::System | SampleMethod::Bernoulli | SampleMethod::Block);
28101
28102 let is_presto = matches!(self.config.dialect, Some(crate::dialects::DialectType::Presto) | Some(crate::dialects::DialectType::Trino) | Some(crate::dialects::DialectType::Athena));
28106 let should_output_unit = if is_databricks || is_spark {
28107 is_percent || is_rows_method || sample.unit_after_size
28109 } else if is_snowflake || is_postgres || is_presto {
28110 sample.unit_after_size
28111 } else {
28112 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
28113 };
28114
28115 if should_output_unit {
28116 self.write_space();
28117 if sample.is_percent {
28118 self.write_keyword("PERCENT");
28119 } else if is_rows_method && !sample.unit_after_size {
28120 self.write_keyword("ROWS");
28121 } else if sample.unit_after_size {
28122 match sample.method {
28123 SampleMethod::Percent | SampleMethod::System | SampleMethod::Bernoulli | SampleMethod::Block => {
28124 self.write_keyword("PERCENT");
28125 }
28126 SampleMethod::Row | SampleMethod::Reservoir => {
28127 self.write_keyword("ROWS");
28128 }
28129 _ => self.write_keyword("ROWS"),
28130 }
28131 } else {
28132 self.write_keyword("PERCENT");
28133 }
28134 }
28135
28136 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
28137 if let Some(ref offset) = sample.offset {
28138 self.write_space();
28139 self.write_keyword("OFFSET");
28140 self.write_space();
28141 self.generate_expression(offset)?;
28142 }
28143 }
28144 if !emit_size_no_parens {
28145 self.write(")");
28146 }
28147
28148 Ok(())
28149 }
28150
28151 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
28152 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
28154 self.write_keyword("SAMPLE BY");
28155 } else {
28156 self.write_keyword("SAMPLE");
28157 }
28158 self.write_space();
28159 self.generate_expression(&e.this)?;
28160 Ok(())
28161 }
28162
28163 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
28164 if let Some(this) = &e.this {
28166 self.generate_expression(this)?;
28167 }
28168 if !e.expressions.is_empty() {
28169 if e.this.is_some() {
28171 self.write_space();
28172 }
28173 self.write("(");
28174 for (i, expr) in e.expressions.iter().enumerate() {
28175 if i > 0 {
28176 self.write(", ");
28177 }
28178 self.generate_expression(expr)?;
28179 }
28180 self.write(")");
28181 }
28182 Ok(())
28183 }
28184
28185 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
28186 self.write_keyword("COMMENT");
28188 self.write_space();
28189 self.generate_expression(&e.this)?;
28190 Ok(())
28191 }
28192
28193 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
28194 if let Some(this) = &e.this {
28196 self.generate_expression(this)?;
28197 self.write("::");
28198 }
28199 self.generate_expression(&e.expression)?;
28200 Ok(())
28201 }
28202
28203 fn generate_search(&mut self, e: &Search) -> Result<()> {
28204 self.write_keyword("SEARCH");
28206 self.write("(");
28207 self.generate_expression(&e.this)?;
28208 self.write(", ");
28209 self.generate_expression(&e.expression)?;
28210 if let Some(json_scope) = &e.json_scope {
28211 self.write(", ");
28212 self.generate_expression(json_scope)?;
28213 }
28214 if let Some(analyzer) = &e.analyzer {
28215 self.write(", ");
28216 self.generate_expression(analyzer)?;
28217 }
28218 if let Some(analyzer_options) = &e.analyzer_options {
28219 self.write(", ");
28220 self.generate_expression(analyzer_options)?;
28221 }
28222 if let Some(search_mode) = &e.search_mode {
28223 self.write(", ");
28224 self.generate_expression(search_mode)?;
28225 }
28226 self.write(")");
28227 Ok(())
28228 }
28229
28230 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
28231 self.write_keyword("SEARCH_IP");
28233 self.write("(");
28234 self.generate_expression(&e.this)?;
28235 self.write(", ");
28236 self.generate_expression(&e.expression)?;
28237 self.write(")");
28238 Ok(())
28239 }
28240
28241 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
28242 self.write_keyword("SECURITY");
28244 self.write_space();
28245 self.generate_expression(&e.this)?;
28246 Ok(())
28247 }
28248
28249 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
28250 self.write("SEMANTIC_VIEW(");
28252
28253 if self.config.pretty {
28254 self.write_newline();
28256 self.indent_level += 1;
28257 self.write_indent();
28258 self.generate_expression(&e.this)?;
28259
28260 if let Some(metrics) = &e.metrics {
28261 self.write_newline();
28262 self.write_indent();
28263 self.write_keyword("METRICS");
28264 self.write_space();
28265 self.generate_semantic_view_tuple(metrics)?;
28266 }
28267 if let Some(dimensions) = &e.dimensions {
28268 self.write_newline();
28269 self.write_indent();
28270 self.write_keyword("DIMENSIONS");
28271 self.write_space();
28272 self.generate_semantic_view_tuple(dimensions)?;
28273 }
28274 if let Some(facts) = &e.facts {
28275 self.write_newline();
28276 self.write_indent();
28277 self.write_keyword("FACTS");
28278 self.write_space();
28279 self.generate_semantic_view_tuple(facts)?;
28280 }
28281 if let Some(where_) = &e.where_ {
28282 self.write_newline();
28283 self.write_indent();
28284 self.write_keyword("WHERE");
28285 self.write_space();
28286 self.generate_expression(where_)?;
28287 }
28288 self.write_newline();
28289 self.indent_level -= 1;
28290 self.write_indent();
28291 } else {
28292 self.generate_expression(&e.this)?;
28294 if let Some(metrics) = &e.metrics {
28295 self.write_space();
28296 self.write_keyword("METRICS");
28297 self.write_space();
28298 self.generate_semantic_view_tuple(metrics)?;
28299 }
28300 if let Some(dimensions) = &e.dimensions {
28301 self.write_space();
28302 self.write_keyword("DIMENSIONS");
28303 self.write_space();
28304 self.generate_semantic_view_tuple(dimensions)?;
28305 }
28306 if let Some(facts) = &e.facts {
28307 self.write_space();
28308 self.write_keyword("FACTS");
28309 self.write_space();
28310 self.generate_semantic_view_tuple(facts)?;
28311 }
28312 if let Some(where_) = &e.where_ {
28313 self.write_space();
28314 self.write_keyword("WHERE");
28315 self.write_space();
28316 self.generate_expression(where_)?;
28317 }
28318 }
28319 self.write(")");
28320 Ok(())
28321 }
28322
28323 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
28325 if let Expression::Tuple(t) = expr {
28326 for (i, e) in t.expressions.iter().enumerate() {
28327 if i > 0 {
28328 self.write(", ");
28329 }
28330 self.generate_expression(e)?;
28331 }
28332 } else {
28333 self.generate_expression(expr)?;
28334 }
28335 Ok(())
28336 }
28337
28338 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
28339 if let Some(start) = &e.start {
28341 self.write_keyword("START WITH");
28342 self.write_space();
28343 self.generate_expression(start)?;
28344 }
28345 if let Some(increment) = &e.increment {
28346 self.write_space();
28347 self.write_keyword("INCREMENT BY");
28348 self.write_space();
28349 self.generate_expression(increment)?;
28350 }
28351 if let Some(minvalue) = &e.minvalue {
28352 self.write_space();
28353 self.write_keyword("MINVALUE");
28354 self.write_space();
28355 self.generate_expression(minvalue)?;
28356 }
28357 if let Some(maxvalue) = &e.maxvalue {
28358 self.write_space();
28359 self.write_keyword("MAXVALUE");
28360 self.write_space();
28361 self.generate_expression(maxvalue)?;
28362 }
28363 if let Some(cache) = &e.cache {
28364 self.write_space();
28365 self.write_keyword("CACHE");
28366 self.write_space();
28367 self.generate_expression(cache)?;
28368 }
28369 if let Some(owned) = &e.owned {
28370 self.write_space();
28371 self.write_keyword("OWNED BY");
28372 self.write_space();
28373 self.generate_expression(owned)?;
28374 }
28375 for opt in &e.options {
28376 self.write_space();
28377 self.generate_expression(opt)?;
28378 }
28379 Ok(())
28380 }
28381
28382 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
28383 if e.with_.is_some() {
28385 self.write_keyword("WITH");
28386 self.write_space();
28387 }
28388 self.write_keyword("SERDEPROPERTIES");
28389 self.write(" (");
28390 for (i, expr) in e.expressions.iter().enumerate() {
28391 if i > 0 {
28392 self.write(", ");
28393 }
28394 match expr {
28396 Expression::Eq(eq) => {
28397 self.generate_expression(&eq.left)?;
28398 self.write("=");
28399 self.generate_expression(&eq.right)?;
28400 }
28401 _ => self.generate_expression(expr)?,
28402 }
28403 }
28404 self.write(")");
28405 Ok(())
28406 }
28407
28408 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
28409 self.write("@@");
28411 if let Some(kind) = &e.kind {
28412 self.write(kind);
28413 self.write(".");
28414 }
28415 self.generate_expression(&e.this)?;
28416 Ok(())
28417 }
28418
28419 fn generate_set(&mut self, e: &Set) -> Result<()> {
28420 if e.unset.is_some() {
28422 self.write_keyword("UNSET");
28423 } else {
28424 self.write_keyword("SET");
28425 }
28426 if e.tag.is_some() {
28427 self.write_space();
28428 self.write_keyword("TAG");
28429 }
28430 if !e.expressions.is_empty() {
28431 self.write_space();
28432 for (i, expr) in e.expressions.iter().enumerate() {
28433 if i > 0 {
28434 self.write(", ");
28435 }
28436 self.generate_expression(expr)?;
28437 }
28438 }
28439 Ok(())
28440 }
28441
28442 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
28443 self.write_keyword("SET");
28445 self.write_space();
28446 self.generate_expression(&e.this)?;
28447 Ok(())
28448 }
28449
28450 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
28451 if let Some(kind) = &e.kind {
28453 self.write_keyword(kind);
28454 self.write_space();
28455 }
28456 self.generate_expression(&e.name)?;
28457 self.write(" = ");
28458 self.generate_expression(&e.value)?;
28459 Ok(())
28460 }
28461
28462 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
28463 if let Some(with_) = &e.with_ {
28465 self.generate_expression(with_)?;
28466 self.write_space();
28467 }
28468 self.generate_expression(&e.this)?;
28469 self.write_space();
28470 if let Some(kind) = &e.kind {
28472 self.write_keyword(kind);
28473 }
28474 if e.distinct {
28475 self.write_space();
28476 self.write_keyword("DISTINCT");
28477 } else {
28478 self.write_space();
28479 self.write_keyword("ALL");
28480 }
28481 if e.by_name.is_some() {
28482 self.write_space();
28483 self.write_keyword("BY NAME");
28484 }
28485 self.write_space();
28486 self.generate_expression(&e.expression)?;
28487 Ok(())
28488 }
28489
28490 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
28491 if e.multi.is_some() {
28493 self.write_keyword("MULTISET");
28494 } else {
28495 self.write_keyword("SET");
28496 }
28497 Ok(())
28498 }
28499
28500 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
28501 self.write_keyword("SETTINGS");
28503 if self.config.pretty && e.expressions.len() > 1 {
28504 self.indent_level += 1;
28506 for (i, expr) in e.expressions.iter().enumerate() {
28507 if i > 0 {
28508 self.write(",");
28509 }
28510 self.write_newline();
28511 self.write_indent();
28512 self.generate_expression(expr)?;
28513 }
28514 self.indent_level -= 1;
28515 } else {
28516 self.write_space();
28517 for (i, expr) in e.expressions.iter().enumerate() {
28518 if i > 0 {
28519 self.write(", ");
28520 }
28521 self.generate_expression(expr)?;
28522 }
28523 }
28524 Ok(())
28525 }
28526
28527 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
28528 self.write_keyword("SHARING");
28530 if let Some(this) = &e.this {
28531 self.write(" = ");
28532 self.generate_expression(this)?;
28533 }
28534 Ok(())
28535 }
28536
28537 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
28538 if let Some(begin) = &e.this {
28540 self.generate_expression(begin)?;
28541 }
28542 self.write(":");
28543 if let Some(end) = &e.expression {
28544 self.generate_expression(end)?;
28545 }
28546 if let Some(step) = &e.step {
28547 self.write(":");
28548 self.generate_expression(step)?;
28549 }
28550 Ok(())
28551 }
28552
28553 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
28554 self.write_keyword("SORT_ARRAY");
28556 self.write("(");
28557 self.generate_expression(&e.this)?;
28558 if let Some(asc) = &e.asc {
28559 self.write(", ");
28560 self.generate_expression(asc)?;
28561 }
28562 self.write(")");
28563 Ok(())
28564 }
28565
28566 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
28567 self.write_keyword("SORT BY");
28569 self.write_space();
28570 for (i, expr) in e.expressions.iter().enumerate() {
28571 if i > 0 {
28572 self.write(", ");
28573 }
28574 self.generate_ordered(expr)?;
28575 }
28576 Ok(())
28577 }
28578
28579 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
28580 if e.compound.is_some() {
28582 self.write_keyword("COMPOUND");
28583 self.write_space();
28584 }
28585 self.write_keyword("SORTKEY");
28586 self.write("(");
28587 if let Expression::Tuple(t) = e.this.as_ref() {
28589 for (i, expr) in t.expressions.iter().enumerate() {
28590 if i > 0 {
28591 self.write(", ");
28592 }
28593 self.generate_expression(expr)?;
28594 }
28595 } else {
28596 self.generate_expression(&e.this)?;
28597 }
28598 self.write(")");
28599 Ok(())
28600 }
28601
28602 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
28603 self.write_keyword("SPLIT_PART");
28605 self.write("(");
28606 self.generate_expression(&e.this)?;
28607 if let Some(delimiter) = &e.delimiter {
28608 self.write(", ");
28609 self.generate_expression(delimiter)?;
28610 }
28611 if let Some(part_index) = &e.part_index {
28612 self.write(", ");
28613 self.generate_expression(part_index)?;
28614 }
28615 self.write(")");
28616 Ok(())
28617 }
28618
28619 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
28620 self.generate_expression(&e.this)?;
28622 Ok(())
28623 }
28624
28625 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
28626 self.write_keyword("SQL SECURITY");
28628 self.write_space();
28629 self.generate_expression(&e.this)?;
28630 Ok(())
28631 }
28632
28633 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
28634 self.write_keyword("ST_DISTANCE");
28636 self.write("(");
28637 self.generate_expression(&e.this)?;
28638 self.write(", ");
28639 self.generate_expression(&e.expression)?;
28640 if let Some(use_spheroid) = &e.use_spheroid {
28641 self.write(", ");
28642 self.generate_expression(use_spheroid)?;
28643 }
28644 self.write(")");
28645 Ok(())
28646 }
28647
28648 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
28649 self.write_keyword("ST_POINT");
28651 self.write("(");
28652 self.generate_expression(&e.this)?;
28653 self.write(", ");
28654 self.generate_expression(&e.expression)?;
28655 self.write(")");
28656 Ok(())
28657 }
28658
28659 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
28660 self.generate_expression(&e.this)?;
28662 Ok(())
28663 }
28664
28665 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
28666 self.write_keyword("STANDARD_HASH");
28668 self.write("(");
28669 self.generate_expression(&e.this)?;
28670 if let Some(expression) = &e.expression {
28671 self.write(", ");
28672 self.generate_expression(expression)?;
28673 }
28674 self.write(")");
28675 Ok(())
28676 }
28677
28678 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
28679 self.write_keyword("STORED BY");
28681 self.write_space();
28682 self.generate_expression(&e.this)?;
28683 Ok(())
28684 }
28685
28686 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
28687 use crate::dialects::DialectType;
28690 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
28691 self.write_keyword("CHARINDEX");
28693 self.write("(");
28694 if let Some(substr) = &e.substr {
28695 self.generate_expression(substr)?;
28696 self.write(", ");
28697 }
28698 self.generate_expression(&e.this)?;
28699 if let Some(position) = &e.position {
28700 self.write(", ");
28701 self.generate_expression(position)?;
28702 }
28703 self.write(")");
28704 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
28705 self.write_keyword("POSITION");
28706 self.write("(");
28707 self.generate_expression(&e.this)?;
28708 if let Some(substr) = &e.substr {
28709 self.write(", ");
28710 self.generate_expression(substr)?;
28711 }
28712 if let Some(position) = &e.position {
28713 self.write(", ");
28714 self.generate_expression(position)?;
28715 }
28716 if let Some(occurrence) = &e.occurrence {
28717 self.write(", ");
28718 self.generate_expression(occurrence)?;
28719 }
28720 self.write(")");
28721 } else if matches!(self.config.dialect, Some(DialectType::SQLite) | Some(DialectType::Oracle) | Some(DialectType::BigQuery) | Some(DialectType::Teradata)) {
28722 self.write_keyword("INSTR");
28723 self.write("(");
28724 self.generate_expression(&e.this)?;
28725 if let Some(substr) = &e.substr {
28726 self.write(", ");
28727 self.generate_expression(substr)?;
28728 }
28729 if let Some(position) = &e.position {
28730 self.write(", ");
28731 self.generate_expression(position)?;
28732 } else if e.occurrence.is_some() {
28733 self.write(", 1");
28736 }
28737 if let Some(occurrence) = &e.occurrence {
28738 self.write(", ");
28739 self.generate_expression(occurrence)?;
28740 }
28741 self.write(")");
28742 } else if matches!(self.config.dialect, Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::Doris) | Some(DialectType::StarRocks)
28743 | Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)) {
28744 self.write_keyword("LOCATE");
28746 self.write("(");
28747 if let Some(substr) = &e.substr {
28748 self.generate_expression(substr)?;
28749 self.write(", ");
28750 }
28751 self.generate_expression(&e.this)?;
28752 if let Some(position) = &e.position {
28753 self.write(", ");
28754 self.generate_expression(position)?;
28755 }
28756 self.write(")");
28757 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
28758 self.write_keyword("CHARINDEX");
28760 self.write("(");
28761 if let Some(substr) = &e.substr {
28762 self.generate_expression(substr)?;
28763 self.write(", ");
28764 }
28765 self.generate_expression(&e.this)?;
28766 if let Some(position) = &e.position {
28767 self.write(", ");
28768 self.generate_expression(position)?;
28769 }
28770 self.write(")");
28771 } else {
28772 self.write_keyword("STRPOS");
28773 self.write("(");
28774 self.generate_expression(&e.this)?;
28775 if let Some(substr) = &e.substr {
28776 self.write(", ");
28777 self.generate_expression(substr)?;
28778 }
28779 if let Some(position) = &e.position {
28780 self.write(", ");
28781 self.generate_expression(position)?;
28782 }
28783 if let Some(occurrence) = &e.occurrence {
28784 self.write(", ");
28785 self.generate_expression(occurrence)?;
28786 }
28787 self.write(")");
28788 }
28789 Ok(())
28790 }
28791
28792 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
28793 match self.config.dialect {
28794 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
28795 self.write_keyword("TO_DATE");
28797 self.write("(");
28798 self.generate_expression(&e.this)?;
28799 if let Some(format) = &e.format {
28800 self.write(", '");
28801 self.write(&Self::strftime_to_java_format(format));
28802 self.write("'");
28803 }
28804 self.write(")");
28805 }
28806 Some(DialectType::DuckDB) => {
28807 self.write_keyword("CAST");
28809 self.write("(");
28810 self.write_keyword("STRPTIME");
28811 self.write("(");
28812 self.generate_expression(&e.this)?;
28813 if let Some(format) = &e.format {
28814 self.write(", '");
28815 self.write(format);
28816 self.write("'");
28817 }
28818 self.write(")");
28819 self.write_keyword(" AS ");
28820 self.write_keyword("DATE");
28821 self.write(")");
28822 }
28823 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
28824 self.write_keyword("TO_DATE");
28826 self.write("(");
28827 self.generate_expression(&e.this)?;
28828 if let Some(format) = &e.format {
28829 self.write(", '");
28830 self.write(&Self::strftime_to_postgres_format(format));
28831 self.write("'");
28832 }
28833 self.write(")");
28834 }
28835 Some(DialectType::BigQuery) => {
28836 self.write_keyword("PARSE_DATE");
28838 self.write("(");
28839 if let Some(format) = &e.format {
28840 self.write("'");
28841 self.write(format);
28842 self.write("'");
28843 self.write(", ");
28844 }
28845 self.generate_expression(&e.this)?;
28846 self.write(")");
28847 }
28848 Some(DialectType::Teradata) => {
28849 self.write_keyword("CAST");
28851 self.write("(");
28852 self.generate_expression(&e.this)?;
28853 self.write_keyword(" AS ");
28854 self.write_keyword("DATE");
28855 if let Some(format) = &e.format {
28856 self.write_keyword(" FORMAT ");
28857 self.write("'");
28858 self.write(&Self::strftime_to_teradata_format(format));
28859 self.write("'");
28860 }
28861 self.write(")");
28862 }
28863 _ => {
28864 self.write_keyword("STR_TO_DATE");
28866 self.write("(");
28867 self.generate_expression(&e.this)?;
28868 if let Some(format) = &e.format {
28869 self.write(", '");
28870 self.write(format);
28871 self.write("'");
28872 }
28873 self.write(")");
28874 }
28875 }
28876 Ok(())
28877 }
28878
28879 fn strftime_to_teradata_format(fmt: &str) -> String {
28881 let mut result = fmt.to_string();
28882 result = result.replace("%Y", "YYYY");
28883 result = result.replace("%y", "YY");
28884 result = result.replace("%m", "MM");
28885 result = result.replace("%B", "MMMM");
28886 result = result.replace("%b", "MMM");
28887 result = result.replace("%d", "DD");
28888 result = result.replace("%j", "DDD");
28889 result = result.replace("%H", "HH");
28890 result = result.replace("%M", "MI");
28891 result = result.replace("%S", "SS");
28892 result = result.replace("%f", "SSSSSS");
28893 result = result.replace("%A", "EEEE");
28894 result = result.replace("%a", "EEE");
28895 result
28896 }
28897
28898 fn strftime_to_java_format(fmt: &str) -> String {
28900 let mut result = fmt.to_string();
28901 result = result.replace("%Y", "yyyy");
28902 result = result.replace("%y", "yy");
28903 result = result.replace("%m", "MM");
28904 result = result.replace("%B", "MMMM");
28905 result = result.replace("%b", "MMM");
28906 result = result.replace("%d", "dd");
28907 result = result.replace("%j", "DDD");
28908 result = result.replace("%H", "HH");
28909 result = result.replace("%M", "mm");
28910 result = result.replace("%S", "ss");
28911 result = result.replace("%f", "SSSSSS");
28912 result = result.replace("%A", "EEEE");
28913 result = result.replace("%a", "EEE");
28914 result
28915 }
28916
28917 fn strftime_to_postgres_format(fmt: &str) -> String {
28919 let mut result = fmt.to_string();
28920 result = result.replace("%Y", "YYYY");
28921 result = result.replace("%y", "YY");
28922 result = result.replace("%m", "MM");
28923 result = result.replace("%B", "Month");
28924 result = result.replace("%b", "Mon");
28925 result = result.replace("%d", "DD");
28926 result = result.replace("%j", "DDD");
28927 result = result.replace("%H", "HH24");
28928 result = result.replace("%M", "MI");
28929 result = result.replace("%S", "SS");
28930 result = result.replace("%f", "US");
28931 result = result.replace("%A", "Day");
28932 result = result.replace("%a", "Dy");
28933 result
28934 }
28935
28936 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
28937 self.write_keyword("STR_TO_MAP");
28939 self.write("(");
28940 self.generate_expression(&e.this)?;
28941 let needs_defaults = matches!(
28943 self.config.dialect,
28944 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
28945 );
28946 if let Some(pair_delim) = &e.pair_delim {
28947 self.write(", ");
28948 self.generate_expression(pair_delim)?;
28949 } else if needs_defaults {
28950 self.write(", ','");
28951 }
28952 if let Some(key_value_delim) = &e.key_value_delim {
28953 self.write(", ");
28954 self.generate_expression(key_value_delim)?;
28955 } else if needs_defaults {
28956 self.write(", ':'");
28957 }
28958 self.write(")");
28959 Ok(())
28960 }
28961
28962 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
28963 match self.config.dialect {
28964 Some(DialectType::Exasol) => {
28965 self.write_keyword("TO_DATE");
28966 self.write("(");
28967 self.generate_expression(&e.this)?;
28968 self.write(", '");
28969 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
28970 self.write("'");
28971 self.write(")");
28972 }
28973 Some(DialectType::BigQuery) => {
28974 let fmt = Self::snowflake_format_to_strftime(&e.format);
28976 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
28978 self.write_keyword("PARSE_TIMESTAMP");
28979 self.write("('");
28980 self.write(&fmt);
28981 self.write("', ");
28982 self.generate_expression(&e.this)?;
28983 self.write(")");
28984 }
28985 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
28986 let fmt = Self::snowflake_format_to_spark(&e.format);
28988 self.write_keyword("TO_TIMESTAMP");
28989 self.write("(");
28990 self.generate_expression(&e.this)?;
28991 self.write(", '");
28992 self.write(&fmt);
28993 self.write("')");
28994 }
28995 Some(DialectType::Presto) | Some(DialectType::Trino) => {
28996 let fmt = Self::snowflake_format_to_strftime(&e.format);
28998 self.write_keyword("DATE_PARSE");
28999 self.write("(");
29000 self.generate_expression(&e.this)?;
29001 self.write(", '");
29002 self.write(&fmt);
29003 self.write("')");
29004 }
29005 Some(DialectType::DuckDB) => {
29006 let fmt = Self::snowflake_format_to_strftime(&e.format);
29008 self.write_keyword("STRPTIME");
29009 self.write("(");
29010 self.generate_expression(&e.this)?;
29011 self.write(", '");
29012 self.write(&fmt);
29013 self.write("')");
29014 }
29015 Some(DialectType::Snowflake) => {
29016 self.write_keyword("TO_TIMESTAMP");
29018 self.write("(");
29019 self.generate_expression(&e.this)?;
29020 self.write(", '");
29021 self.write(&e.format);
29022 self.write("')");
29023 }
29024 _ => {
29025 self.write_keyword("STR_TO_TIME");
29027 self.write("(");
29028 self.generate_expression(&e.this)?;
29029 self.write(", '");
29030 self.write(&e.format);
29031 self.write("'");
29032 self.write(")");
29033 }
29034 }
29035 Ok(())
29036 }
29037
29038 fn snowflake_format_to_strftime(format: &str) -> String {
29040 let mut result = String::new();
29041 let chars: Vec<char> = format.chars().collect();
29042 let mut i = 0;
29043 while i < chars.len() {
29044 let remaining = &format[i..];
29045 if remaining.starts_with("yyyy") {
29046 result.push_str("%Y");
29047 i += 4;
29048 } else if remaining.starts_with("yy") {
29049 result.push_str("%y");
29050 i += 2;
29051 } else if remaining.starts_with("mmmm") {
29052 result.push_str("%B"); i += 4;
29054 } else if remaining.starts_with("mon") {
29055 result.push_str("%b"); i += 3;
29057 } else if remaining.starts_with("mm") {
29058 result.push_str("%m");
29059 i += 2;
29060 } else if remaining.starts_with("DD") {
29061 result.push_str("%d");
29062 i += 2;
29063 } else if remaining.starts_with("dy") {
29064 result.push_str("%a"); i += 2;
29066 } else if remaining.starts_with("hh24") {
29067 result.push_str("%H");
29068 i += 4;
29069 } else if remaining.starts_with("hh12") {
29070 result.push_str("%I");
29071 i += 4;
29072 } else if remaining.starts_with("hh") {
29073 result.push_str("%H");
29074 i += 2;
29075 } else if remaining.starts_with("mi") {
29076 result.push_str("%M");
29077 i += 2;
29078 } else if remaining.starts_with("ss") {
29079 result.push_str("%S");
29080 i += 2;
29081 } else if remaining.starts_with("ff") {
29082 result.push_str("%f");
29084 i += 2;
29085 while i < chars.len() && chars[i].is_ascii_digit() {
29087 i += 1;
29088 }
29089 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
29090 result.push_str("%p");
29091 i += 2;
29092 } else if remaining.starts_with("tz") {
29093 result.push_str("%Z");
29094 i += 2;
29095 } else {
29096 result.push(chars[i]);
29097 i += 1;
29098 }
29099 }
29100 result
29101 }
29102
29103 fn snowflake_format_to_spark(format: &str) -> String {
29105 let mut result = String::new();
29106 let chars: Vec<char> = format.chars().collect();
29107 let mut i = 0;
29108 while i < chars.len() {
29109 let remaining = &format[i..];
29110 if remaining.starts_with("yyyy") {
29111 result.push_str("yyyy");
29112 i += 4;
29113 } else if remaining.starts_with("yy") {
29114 result.push_str("yy");
29115 i += 2;
29116 } else if remaining.starts_with("mmmm") {
29117 result.push_str("MMMM"); i += 4;
29119 } else if remaining.starts_with("mon") {
29120 result.push_str("MMM"); i += 3;
29122 } else if remaining.starts_with("mm") {
29123 result.push_str("MM");
29124 i += 2;
29125 } else if remaining.starts_with("DD") {
29126 result.push_str("dd");
29127 i += 2;
29128 } else if remaining.starts_with("dy") {
29129 result.push_str("EEE"); i += 2;
29131 } else if remaining.starts_with("hh24") {
29132 result.push_str("HH");
29133 i += 4;
29134 } else if remaining.starts_with("hh12") {
29135 result.push_str("hh");
29136 i += 4;
29137 } else if remaining.starts_with("hh") {
29138 result.push_str("HH");
29139 i += 2;
29140 } else if remaining.starts_with("mi") {
29141 result.push_str("mm");
29142 i += 2;
29143 } else if remaining.starts_with("ss") {
29144 result.push_str("ss");
29145 i += 2;
29146 } else if remaining.starts_with("ff") {
29147 result.push_str("SSS"); i += 2;
29149 while i < chars.len() && chars[i].is_ascii_digit() {
29151 i += 1;
29152 }
29153 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
29154 result.push_str("a");
29155 i += 2;
29156 } else if remaining.starts_with("tz") {
29157 result.push_str("z");
29158 i += 2;
29159 } else {
29160 result.push(chars[i]);
29161 i += 1;
29162 }
29163 }
29164 result
29165 }
29166
29167 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
29168 self.write_keyword("STR_TO_UNIX");
29170 self.write("(");
29171 if let Some(this) = &e.this {
29172 self.generate_expression(this)?;
29173 }
29174 if let Some(format) = &e.format {
29175 self.write(", '");
29176 self.write(format);
29177 self.write("'");
29178 }
29179 self.write(")");
29180 Ok(())
29181 }
29182
29183 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
29184 self.write_keyword("STRING_TO_ARRAY");
29186 self.write("(");
29187 self.generate_expression(&e.this)?;
29188 if let Some(expression) = &e.expression {
29189 self.write(", ");
29190 self.generate_expression(expression)?;
29191 }
29192 if let Some(null_val) = &e.null {
29193 self.write(", ");
29194 self.generate_expression(null_val)?;
29195 }
29196 self.write(")");
29197 Ok(())
29198 }
29199
29200 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
29201 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
29202 self.write_keyword("OBJECT_CONSTRUCT");
29204 self.write("(");
29205 for (i, (name, expr)) in e.fields.iter().enumerate() {
29206 if i > 0 {
29207 self.write(", ");
29208 }
29209 if let Some(name) = name {
29210 self.write("'");
29211 self.write(name);
29212 self.write("'");
29213 self.write(", ");
29214 } else {
29215 self.write("'_");
29216 self.write(&i.to_string());
29217 self.write("'");
29218 self.write(", ");
29219 }
29220 self.generate_expression(expr)?;
29221 }
29222 self.write(")");
29223 } else if self.config.struct_curly_brace_notation {
29224 self.write("{");
29226 for (i, (name, expr)) in e.fields.iter().enumerate() {
29227 if i > 0 {
29228 self.write(", ");
29229 }
29230 if let Some(name) = name {
29231 self.write("'");
29233 self.write(name);
29234 self.write("'");
29235 self.write(": ");
29236 } else {
29237 self.write("'_");
29239 self.write(&i.to_string());
29240 self.write("'");
29241 self.write(": ");
29242 }
29243 self.generate_expression(expr)?;
29244 }
29245 self.write("}");
29246 } else {
29247 let value_as_name = matches!(
29251 self.config.dialect,
29252 Some(DialectType::BigQuery)
29253 | Some(DialectType::Spark)
29254
29255 | Some(DialectType::Databricks)
29256 | Some(DialectType::Hive)
29257 );
29258 self.write_keyword("STRUCT");
29259 self.write("(");
29260 for (i, (name, expr)) in e.fields.iter().enumerate() {
29261 if i > 0 {
29262 self.write(", ");
29263 }
29264 if let Some(name) = name {
29265 if value_as_name {
29266 self.generate_expression(expr)?;
29268 self.write_space();
29269 self.write_keyword("AS");
29270 self.write_space();
29271 let needs_quoting = name.contains(' ') || name.contains('-');
29273 if needs_quoting {
29274 if matches!(self.config.dialect, Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)) {
29275 self.write("`");
29276 self.write(name);
29277 self.write("`");
29278 } else {
29279 self.write(name);
29280 }
29281 } else {
29282 self.write(name);
29283 }
29284 } else {
29285 self.write(name);
29287 self.write_space();
29288 self.write_keyword("AS");
29289 self.write_space();
29290 self.generate_expression(expr)?;
29291 }
29292 } else {
29293 self.generate_expression(expr)?;
29294 }
29295 }
29296 self.write(")");
29297 }
29298 Ok(())
29299 }
29300
29301 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
29302 self.write_keyword("STUFF");
29304 self.write("(");
29305 self.generate_expression(&e.this)?;
29306 if let Some(start) = &e.start {
29307 self.write(", ");
29308 self.generate_expression(start)?;
29309 }
29310 if let Some(length) = e.length {
29311 self.write(", ");
29312 self.write(&length.to_string());
29313 }
29314 self.write(", ");
29315 self.generate_expression(&e.expression)?;
29316 self.write(")");
29317 Ok(())
29318 }
29319
29320 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
29321 self.write_keyword("SUBSTRING_INDEX");
29323 self.write("(");
29324 self.generate_expression(&e.this)?;
29325 if let Some(delimiter) = &e.delimiter {
29326 self.write(", ");
29327 self.generate_expression(delimiter)?;
29328 }
29329 if let Some(count) = &e.count {
29330 self.write(", ");
29331 self.generate_expression(count)?;
29332 }
29333 self.write(")");
29334 Ok(())
29335 }
29336
29337 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
29338 self.write_keyword("SUMMARIZE");
29340 if e.table.is_some() {
29341 self.write_space();
29342 self.write_keyword("TABLE");
29343 }
29344 self.write_space();
29345 self.generate_expression(&e.this)?;
29346 Ok(())
29347 }
29348
29349 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
29350 self.write_keyword("SYSTIMESTAMP");
29352 Ok(())
29353 }
29354
29355 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
29356 if let Some(this) = &e.this {
29358 self.generate_expression(this)?;
29359 }
29360 if !e.columns.is_empty() {
29361 self.write("(");
29362 for (i, col) in e.columns.iter().enumerate() {
29363 if i > 0 {
29364 self.write(", ");
29365 }
29366 self.generate_expression(col)?;
29367 }
29368 self.write(")");
29369 }
29370 Ok(())
29371 }
29372
29373 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
29374 self.write_keyword("TABLE");
29376 self.write("(");
29377 self.generate_expression(&e.this)?;
29378 self.write(")");
29379 if let Some(alias) = &e.alias {
29380 self.write_space();
29381 self.write_keyword("AS");
29382 self.write_space();
29383 self.write(alias);
29384 }
29385 Ok(())
29386 }
29387
29388 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
29389 self.write_keyword("ROWS FROM");
29391 self.write(" (");
29392 for (i, expr) in e.expressions.iter().enumerate() {
29393 if i > 0 {
29394 self.write(", ");
29395 }
29396 match expr {
29400 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
29401 self.generate_expression(&tuple.expressions[0])?;
29403 self.write_space();
29404 self.write_keyword("AS");
29405 self.write_space();
29406 self.generate_expression(&tuple.expressions[1])?;
29407 }
29408 _ => {
29409 self.generate_expression(expr)?;
29410 }
29411 }
29412 }
29413 self.write(")");
29414 if e.ordinality {
29415 self.write_space();
29416 self.write_keyword("WITH ORDINALITY");
29417 }
29418 if let Some(alias) = &e.alias {
29419 self.write_space();
29420 self.write_keyword("AS");
29421 self.write_space();
29422 self.generate_expression(alias)?;
29423 }
29424 Ok(())
29425 }
29426
29427 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
29428 use crate::dialects::DialectType;
29429
29430 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
29432 if self.config.alias_post_tablesample {
29434 if let Expression::Subquery(ref s) = **this {
29436 if let Some(ref alias) = s.alias {
29437 let mut subquery_no_alias = (**s).clone();
29439 subquery_no_alias.alias = None;
29440 subquery_no_alias.column_aliases = Vec::new();
29441 self.generate_expression(&Expression::Subquery(Box::new(subquery_no_alias)))?;
29442 self.write_space();
29443 self.write_keyword("TABLESAMPLE");
29444 self.generate_sample_body(sample)?;
29445 if let Some(ref seed) = sample.seed {
29446 self.write_space();
29447 let use_seed = sample.use_seed_keyword
29448 && !matches!(self.config.dialect, Some(crate::dialects::DialectType::Databricks) | Some(crate::dialects::DialectType::Spark));
29449 if use_seed { self.write_keyword("SEED"); } else { self.write_keyword("REPEATABLE"); }
29450 self.write(" (");
29451 self.generate_expression(seed)?;
29452 self.write(")");
29453 }
29454 self.write_space();
29455 self.write_keyword("AS");
29456 self.write_space();
29457 self.generate_identifier(alias)?;
29458 return Ok(());
29459 }
29460 } else if let Expression::Alias(ref a) = **this {
29461 self.generate_expression(&a.this)?;
29463 self.write_space();
29464 self.write_keyword("TABLESAMPLE");
29465 self.generate_sample_body(sample)?;
29466 if let Some(ref seed) = sample.seed {
29467 self.write_space();
29468 let use_seed = sample.use_seed_keyword
29469 && !matches!(self.config.dialect, Some(crate::dialects::DialectType::Databricks) | Some(crate::dialects::DialectType::Spark));
29470 if use_seed { self.write_keyword("SEED"); } else { self.write_keyword("REPEATABLE"); }
29471 self.write(" (");
29472 self.generate_expression(seed)?;
29473 self.write(")");
29474 }
29475 self.write_space();
29477 self.write_keyword("AS");
29478 self.write_space();
29479 self.generate_identifier(&a.alias)?;
29480 return Ok(());
29481 }
29482 }
29483 self.generate_expression(this)?;
29485 self.write_space();
29486 self.write_keyword("TABLESAMPLE");
29487 self.generate_sample_body(sample)?;
29488 if let Some(ref seed) = sample.seed {
29490 self.write_space();
29491 let use_seed = sample.use_seed_keyword
29493 && !matches!(self.config.dialect, Some(crate::dialects::DialectType::Databricks) | Some(crate::dialects::DialectType::Spark));
29494 if use_seed {
29495 self.write_keyword("SEED");
29496 } else {
29497 self.write_keyword("REPEATABLE");
29498 }
29499 self.write(" (");
29500 self.generate_expression(seed)?;
29501 self.write(")");
29502 }
29503 return Ok(());
29504 }
29505
29506 self.write_keyword("TABLESAMPLE");
29508 if let Some(method) = &e.method {
29509 self.write_space();
29510 self.write_keyword(method);
29511 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
29512 self.write_space();
29514 self.write_keyword("BERNOULLI");
29515 }
29516 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
29517 self.write_space();
29518 self.write_keyword("BUCKET");
29519 self.write_space();
29520 self.generate_expression(numerator)?;
29521 self.write_space();
29522 self.write_keyword("OUT OF");
29523 self.write_space();
29524 self.generate_expression(denominator)?;
29525 if let Some(field) = &e.bucket_field {
29526 self.write_space();
29527 self.write_keyword("ON");
29528 self.write_space();
29529 self.generate_expression(field)?;
29530 }
29531 } else if !e.expressions.is_empty() {
29532 self.write(" (");
29533 for (i, expr) in e.expressions.iter().enumerate() {
29534 if i > 0 {
29535 self.write(", ");
29536 }
29537 self.generate_expression(expr)?;
29538 }
29539 self.write(")");
29540 } else if let Some(percent) = &e.percent {
29541 self.write(" (");
29542 self.generate_expression(percent)?;
29543 self.write_space();
29544 self.write_keyword("PERCENT");
29545 self.write(")");
29546 }
29547 Ok(())
29548 }
29549
29550 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
29551 if let Some(prefix) = &e.prefix {
29553 self.generate_expression(prefix)?;
29554 }
29555 if let Some(this) = &e.this {
29556 self.generate_expression(this)?;
29557 }
29558 if let Some(postfix) = &e.postfix {
29559 self.generate_expression(postfix)?;
29560 }
29561 Ok(())
29562 }
29563
29564 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
29565 self.write_keyword("TAG");
29567 self.write(" (");
29568 for (i, expr) in e.expressions.iter().enumerate() {
29569 if i > 0 {
29570 self.write(", ");
29571 }
29572 self.generate_expression(expr)?;
29573 }
29574 self.write(")");
29575 Ok(())
29576 }
29577
29578 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
29579 if let Some(this) = &e.this {
29581 self.generate_expression(this)?;
29582 self.write_space();
29583 }
29584 self.write_keyword("TEMPORARY");
29585 Ok(())
29586 }
29587
29588 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
29591 self.write_keyword("TIME");
29593 self.write("(");
29594 self.generate_expression(&e.this)?;
29595 self.write(")");
29596 Ok(())
29597 }
29598
29599 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
29600 self.write_keyword("TIME_ADD");
29602 self.write("(");
29603 self.generate_expression(&e.this)?;
29604 self.write(", ");
29605 self.generate_expression(&e.expression)?;
29606 if let Some(unit) = &e.unit {
29607 self.write(", ");
29608 self.write_keyword(unit);
29609 }
29610 self.write(")");
29611 Ok(())
29612 }
29613
29614 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
29615 self.write_keyword("TIME_DIFF");
29617 self.write("(");
29618 self.generate_expression(&e.this)?;
29619 self.write(", ");
29620 self.generate_expression(&e.expression)?;
29621 if let Some(unit) = &e.unit {
29622 self.write(", ");
29623 self.write_keyword(unit);
29624 }
29625 self.write(")");
29626 Ok(())
29627 }
29628
29629 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
29630 self.write_keyword("TIME_FROM_PARTS");
29632 self.write("(");
29633 let mut first = true;
29634 if let Some(hour) = &e.hour {
29635 self.generate_expression(hour)?;
29636 first = false;
29637 }
29638 if let Some(minute) = &e.min {
29639 if !first { self.write(", "); }
29640 self.generate_expression(minute)?;
29641 first = false;
29642 }
29643 if let Some(second) = &e.sec {
29644 if !first { self.write(", "); }
29645 self.generate_expression(second)?;
29646 first = false;
29647 }
29648 if let Some(ns) = &e.nano {
29649 if !first { self.write(", "); }
29650 self.generate_expression(ns)?;
29651 }
29652 self.write(")");
29653 Ok(())
29654 }
29655
29656 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
29657 self.write_keyword("TIME_SLICE");
29659 self.write("(");
29660 self.generate_expression(&e.this)?;
29661 self.write(", ");
29662 self.generate_expression(&e.expression)?;
29663 self.write(", ");
29664 self.write_keyword(&e.unit);
29665 self.write(")");
29666 Ok(())
29667 }
29668
29669 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
29670 self.write_keyword("TIME_STR_TO_TIME");
29672 self.write("(");
29673 self.generate_expression(&e.this)?;
29674 self.write(")");
29675 Ok(())
29676 }
29677
29678 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
29679 self.write_keyword("TIME_SUB");
29681 self.write("(");
29682 self.generate_expression(&e.this)?;
29683 self.write(", ");
29684 self.generate_expression(&e.expression)?;
29685 if let Some(unit) = &e.unit {
29686 self.write(", ");
29687 self.write_keyword(unit);
29688 }
29689 self.write(")");
29690 Ok(())
29691 }
29692
29693 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
29694 if self.config.dialect == Some(DialectType::Exasol) {
29696 self.write_keyword("TO_CHAR");
29697 self.write("(");
29698 self.generate_expression(&e.this)?;
29699 self.write(", '");
29700 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
29701 self.write("'");
29702 self.write(")");
29703 return Ok(());
29704 }
29705
29706 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) {
29708 self.write_keyword("TO_CHAR");
29709 self.write("(");
29710 self.generate_expression(&e.this)?;
29711 self.write(", '");
29712 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
29713 self.write("'");
29714 self.write(")");
29715 return Ok(());
29716 }
29717
29718 self.write_keyword("TIME_TO_STR");
29720 self.write("(");
29721 self.generate_expression(&e.this)?;
29722 self.write(", '");
29723 self.write(&e.format);
29724 self.write("'");
29725 self.write(")");
29726 Ok(())
29727 }
29728
29729 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
29730 self.write_keyword("TIME_TRUNC");
29732 self.write("(");
29733 self.generate_expression(&e.this)?;
29734 self.write(", ");
29735 self.write_keyword(&e.unit);
29736 self.write(")");
29737 Ok(())
29738 }
29739
29740 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
29741 if let Some(unit) = &e.unit {
29743 self.write_keyword(unit);
29744 }
29745 Ok(())
29746 }
29747
29748 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
29752 use crate::dialects::DialectType;
29753 use crate::expressions::Literal;
29754
29755 match self.config.dialect {
29756 Some(DialectType::Exasol) => {
29758 self.write_keyword("TO_TIMESTAMP");
29759 self.write("(");
29760 if let Some(this) = &e.this {
29762 match this.as_ref() {
29763 Expression::Literal(Literal::String(s)) => {
29764 self.write("'");
29765 self.write(s);
29766 self.write("'");
29767 }
29768 _ => {
29769 self.generate_expression(this)?;
29770 }
29771 }
29772 }
29773 self.write(")");
29774 }
29775 _ => {
29777 self.write_keyword("TIMESTAMP");
29778 self.write("(");
29779 if let Some(this) = &e.this {
29780 self.generate_expression(this)?;
29781 }
29782 if let Some(zone) = &e.zone {
29783 self.write(", ");
29784 self.generate_expression(zone)?;
29785 }
29786 self.write(")");
29787 }
29788 }
29789 Ok(())
29790 }
29791
29792 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
29793 self.write_keyword("TIMESTAMP_ADD");
29795 self.write("(");
29796 self.generate_expression(&e.this)?;
29797 self.write(", ");
29798 self.generate_expression(&e.expression)?;
29799 if let Some(unit) = &e.unit {
29800 self.write(", ");
29801 self.write_keyword(unit);
29802 }
29803 self.write(")");
29804 Ok(())
29805 }
29806
29807 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
29808 self.write_keyword("TIMESTAMP_DIFF");
29810 self.write("(");
29811 self.generate_expression(&e.this)?;
29812 self.write(", ");
29813 self.generate_expression(&e.expression)?;
29814 if let Some(unit) = &e.unit {
29815 self.write(", ");
29816 self.write_keyword(unit);
29817 }
29818 self.write(")");
29819 Ok(())
29820 }
29821
29822 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
29823 self.write_keyword("TIMESTAMP_FROM_PARTS");
29825 self.write("(");
29826 if let Some(this) = &e.this {
29827 self.generate_expression(this)?;
29828 }
29829 if let Some(expression) = &e.expression {
29830 self.write(", ");
29831 self.generate_expression(expression)?;
29832 }
29833 if let Some(zone) = &e.zone {
29834 self.write(", ");
29835 self.generate_expression(zone)?;
29836 }
29837 if let Some(milli) = &e.milli {
29838 self.write(", ");
29839 self.generate_expression(milli)?;
29840 }
29841 self.write(")");
29842 Ok(())
29843 }
29844
29845 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
29846 self.write_keyword("TIMESTAMP_SUB");
29848 self.write("(");
29849 self.generate_expression(&e.this)?;
29850 self.write(", ");
29851 self.write_keyword("INTERVAL");
29852 self.write_space();
29853 self.generate_expression(&e.expression)?;
29854 if let Some(unit) = &e.unit {
29855 self.write_space();
29856 self.write_keyword(unit);
29857 }
29858 self.write(")");
29859 Ok(())
29860 }
29861
29862 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
29863 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
29865 self.write("(");
29866 if let Some(zone) = &e.zone {
29867 self.generate_expression(zone)?;
29868 }
29869 self.write(")");
29870 Ok(())
29871 }
29872
29873 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
29874 self.write_keyword("TO_BINARY");
29876 self.write("(");
29877 self.generate_expression(&e.this)?;
29878 if let Some(format) = &e.format {
29879 self.write(", '");
29880 self.write(format);
29881 self.write("'");
29882 }
29883 self.write(")");
29884 Ok(())
29885 }
29886
29887 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
29888 self.write_keyword("TO_BOOLEAN");
29890 self.write("(");
29891 self.generate_expression(&e.this)?;
29892 self.write(")");
29893 Ok(())
29894 }
29895
29896 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
29897 self.write_keyword("TO_CHAR");
29899 self.write("(");
29900 self.generate_expression(&e.this)?;
29901 if let Some(format) = &e.format {
29902 self.write(", '");
29903 self.write(format);
29904 self.write("'");
29905 }
29906 if let Some(nlsparam) = &e.nlsparam {
29907 self.write(", ");
29908 self.generate_expression(nlsparam)?;
29909 }
29910 self.write(")");
29911 Ok(())
29912 }
29913
29914 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
29915 self.write_keyword("TO_DECFLOAT");
29917 self.write("(");
29918 self.generate_expression(&e.this)?;
29919 if let Some(format) = &e.format {
29920 self.write(", '");
29921 self.write(format);
29922 self.write("'");
29923 }
29924 self.write(")");
29925 Ok(())
29926 }
29927
29928 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
29929 self.write_keyword("TO_DOUBLE");
29931 self.write("(");
29932 self.generate_expression(&e.this)?;
29933 if let Some(format) = &e.format {
29934 self.write(", '");
29935 self.write(format);
29936 self.write("'");
29937 }
29938 self.write(")");
29939 Ok(())
29940 }
29941
29942 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
29943 self.write_keyword("TO_FILE");
29945 self.write("(");
29946 self.generate_expression(&e.this)?;
29947 if let Some(path) = &e.path {
29948 self.write(", ");
29949 self.generate_expression(path)?;
29950 }
29951 self.write(")");
29952 Ok(())
29953 }
29954
29955 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
29956 let is_safe = e.safe.is_some();
29959 if is_safe {
29960 self.write_keyword("TRY_TO_NUMBER");
29961 } else {
29962 self.write_keyword("TO_NUMBER");
29963 }
29964 self.write("(");
29965 self.generate_expression(&e.this)?;
29966 if let Some(format) = &e.format {
29967 self.write(", ");
29968 self.generate_expression(format)?;
29969 }
29970 if let Some(nlsparam) = &e.nlsparam {
29971 self.write(", ");
29972 self.generate_expression(nlsparam)?;
29973 }
29974 if let Some(precision) = &e.precision {
29975 self.write(", ");
29976 self.generate_expression(precision)?;
29977 }
29978 if let Some(scale) = &e.scale {
29979 self.write(", ");
29980 self.generate_expression(scale)?;
29981 }
29982 self.write(")");
29983 Ok(())
29984 }
29985
29986 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
29987 self.write_keyword("TO_TABLE");
29989 self.write_space();
29990 self.generate_expression(&e.this)?;
29991 Ok(())
29992 }
29993
29994 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
29995 let mark_text = e.mark.as_ref().map(|m| {
29997 match m.as_ref() {
29998 Expression::Identifier(id) => id.name.clone(),
29999 Expression::Literal(Literal::String(s)) => s.clone(),
30000 _ => String::new(),
30001 }
30002 });
30003
30004 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
30005 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
30006 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
30007 matches!(m.as_ref(), Expression::Literal(Literal::String(_)))
30008 });
30009
30010 if is_start {
30011 self.write_keyword("START TRANSACTION");
30013 if let Some(modes) = &e.modes {
30014 self.write_space();
30015 self.generate_expression(modes)?;
30016 }
30017 } else {
30018 self.write_keyword("BEGIN");
30020
30021 if has_transaction_keyword || has_with_mark {
30023 self.write_space();
30024 self.write_keyword("TRANSACTION");
30025 }
30026
30027 if let Some(this) = &e.this {
30029 self.write_space();
30030 self.generate_expression(this)?;
30031 }
30032
30033 if has_with_mark {
30035 self.write_space();
30036 self.write_keyword("WITH MARK");
30037 if let Some(Expression::Literal(Literal::String(desc))) = e.mark.as_deref() {
30038 if !desc.is_empty() {
30039 self.write_space();
30040 self.write(&format!("'{}'", desc));
30041 }
30042 }
30043 }
30044
30045 if let Some(modes) = &e.modes {
30047 self.write_space();
30048 self.generate_expression(modes)?;
30049 }
30050 }
30051 Ok(())
30052 }
30053
30054 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
30055 self.write_keyword("TRANSFORM");
30057 self.write("(");
30058 self.generate_expression(&e.this)?;
30059 self.write(", ");
30060 self.generate_expression(&e.expression)?;
30061 self.write(")");
30062 Ok(())
30063 }
30064
30065 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
30066 self.write_keyword("TRANSFORM");
30068 self.write("(");
30069 if self.config.pretty && !e.expressions.is_empty() {
30070 self.indent_level += 1;
30071 for (i, expr) in e.expressions.iter().enumerate() {
30072 if i > 0 {
30073 self.write(",");
30074 }
30075 self.write_newline();
30076 self.write_indent();
30077 self.generate_expression(expr)?;
30078 }
30079 self.indent_level -= 1;
30080 self.write_newline();
30081 self.write(")");
30082 } else {
30083 for (i, expr) in e.expressions.iter().enumerate() {
30084 if i > 0 {
30085 self.write(", ");
30086 }
30087 self.generate_expression(expr)?;
30088 }
30089 self.write(")");
30090 }
30091 Ok(())
30092 }
30093
30094 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
30095 use crate::dialects::DialectType;
30096 if let Some(this) = &e.this {
30098 self.generate_expression(this)?;
30099 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
30100 self.write_space();
30101 }
30102 }
30103 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
30104 self.write_keyword("TRANSIENT");
30105 }
30106 Ok(())
30107 }
30108
30109 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
30110 self.write_keyword("TRANSLATE");
30112 self.write("(");
30113 self.generate_expression(&e.this)?;
30114 if let Some(from) = &e.from_ {
30115 self.write(", ");
30116 self.generate_expression(from)?;
30117 }
30118 if let Some(to) = &e.to {
30119 self.write(", ");
30120 self.generate_expression(to)?;
30121 }
30122 self.write(")");
30123 Ok(())
30124 }
30125
30126 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
30127 self.write_keyword("TRANSLATE");
30129 self.write("(");
30130 self.generate_expression(&e.this)?;
30131 self.write_space();
30132 self.write_keyword("USING");
30133 self.write_space();
30134 self.generate_expression(&e.expression)?;
30135 if e.with_error.is_some() {
30136 self.write_space();
30137 self.write_keyword("WITH ERROR");
30138 }
30139 self.write(")");
30140 Ok(())
30141 }
30142
30143 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
30144 self.write_keyword("TRUNCATE TABLE");
30146 self.write_space();
30147 for (i, expr) in e.expressions.iter().enumerate() {
30148 if i > 0 {
30149 self.write(", ");
30150 }
30151 self.generate_expression(expr)?;
30152 }
30153 Ok(())
30154 }
30155
30156 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
30157 self.write_keyword("TRY_BASE64_DECODE_BINARY");
30159 self.write("(");
30160 self.generate_expression(&e.this)?;
30161 if let Some(alphabet) = &e.alphabet {
30162 self.write(", ");
30163 self.generate_expression(alphabet)?;
30164 }
30165 self.write(")");
30166 Ok(())
30167 }
30168
30169 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
30170 self.write_keyword("TRY_BASE64_DECODE_STRING");
30172 self.write("(");
30173 self.generate_expression(&e.this)?;
30174 if let Some(alphabet) = &e.alphabet {
30175 self.write(", ");
30176 self.generate_expression(alphabet)?;
30177 }
30178 self.write(")");
30179 Ok(())
30180 }
30181
30182 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
30183 self.write_keyword("TRY_TO_DECFLOAT");
30185 self.write("(");
30186 self.generate_expression(&e.this)?;
30187 if let Some(format) = &e.format {
30188 self.write(", '");
30189 self.write(format);
30190 self.write("'");
30191 }
30192 self.write(")");
30193 Ok(())
30194 }
30195
30196 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
30197 self.write_keyword("TS_OR_DS_ADD");
30199 self.write("(");
30200 self.generate_expression(&e.this)?;
30201 self.write(", ");
30202 self.generate_expression(&e.expression)?;
30203 if let Some(unit) = &e.unit {
30204 self.write(", ");
30205 self.write_keyword(unit);
30206 }
30207 if let Some(return_type) = &e.return_type {
30208 self.write(", ");
30209 self.generate_expression(return_type)?;
30210 }
30211 self.write(")");
30212 Ok(())
30213 }
30214
30215 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
30216 self.write_keyword("TS_OR_DS_DIFF");
30218 self.write("(");
30219 self.generate_expression(&e.this)?;
30220 self.write(", ");
30221 self.generate_expression(&e.expression)?;
30222 if let Some(unit) = &e.unit {
30223 self.write(", ");
30224 self.write_keyword(unit);
30225 }
30226 self.write(")");
30227 Ok(())
30228 }
30229
30230 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
30231 self.write_keyword("TS_OR_DS_TO_DATE");
30233 self.write("(");
30234 self.generate_expression(&e.this)?;
30235 if let Some(format) = &e.format {
30236 self.write(", '");
30237 self.write(format);
30238 self.write("'");
30239 }
30240 self.write(")");
30241 Ok(())
30242 }
30243
30244 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
30245 self.write_keyword("TS_OR_DS_TO_TIME");
30247 self.write("(");
30248 self.generate_expression(&e.this)?;
30249 if let Some(format) = &e.format {
30250 self.write(", '");
30251 self.write(format);
30252 self.write("'");
30253 }
30254 self.write(")");
30255 Ok(())
30256 }
30257
30258 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
30259 self.write_keyword("UNHEX");
30261 self.write("(");
30262 self.generate_expression(&e.this)?;
30263 if let Some(expression) = &e.expression {
30264 self.write(", ");
30265 self.generate_expression(expression)?;
30266 }
30267 self.write(")");
30268 Ok(())
30269 }
30270
30271 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
30272 self.write("U&");
30274 self.generate_expression(&e.this)?;
30275 if let Some(escape) = &e.escape {
30276 self.write_space();
30277 self.write_keyword("UESCAPE");
30278 self.write_space();
30279 self.generate_expression(escape)?;
30280 }
30281 Ok(())
30282 }
30283
30284 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
30285 self.write_keyword("UNIFORM");
30287 self.write("(");
30288 self.generate_expression(&e.this)?;
30289 self.write(", ");
30290 self.generate_expression(&e.expression)?;
30291 if let Some(gen) = &e.gen {
30292 self.write(", ");
30293 self.generate_expression(gen)?;
30294 }
30295 if let Some(seed) = &e.seed {
30296 self.write(", ");
30297 self.generate_expression(seed)?;
30298 }
30299 self.write(")");
30300 Ok(())
30301 }
30302
30303 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
30304 self.write_keyword("UNIQUE");
30306 if e.nulls.is_some() {
30308 self.write(" NULLS NOT DISTINCT");
30309 }
30310 if let Some(this) = &e.this {
30311 self.write_space();
30312 self.generate_expression(this)?;
30313 }
30314 if let Some(index_type) = &e.index_type {
30315 self.write(" USING ");
30316 self.generate_expression(index_type)?;
30317 }
30318 if let Some(on_conflict) = &e.on_conflict {
30319 self.write_space();
30320 self.generate_expression(on_conflict)?;
30321 }
30322 for opt in &e.options {
30323 self.write_space();
30324 self.generate_expression(opt)?;
30325 }
30326 Ok(())
30327 }
30328
30329 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
30330 self.write_keyword("UNIQUE KEY");
30332 self.write(" (");
30333 for (i, expr) in e.expressions.iter().enumerate() {
30334 if i > 0 {
30335 self.write(", ");
30336 }
30337 self.generate_expression(expr)?;
30338 }
30339 self.write(")");
30340 Ok(())
30341 }
30342
30343 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
30344 self.write_keyword("ROLLUP");
30346 self.write(" (");
30347 for (i, index) in e.expressions.iter().enumerate() {
30348 if i > 0 {
30349 self.write(", ");
30350 }
30351 self.generate_identifier(&index.name)?;
30352 self.write("(");
30353 for (j, col) in index.expressions.iter().enumerate() {
30354 if j > 0 {
30355 self.write(", ");
30356 }
30357 self.generate_identifier(col)?;
30358 }
30359 self.write(")");
30360 }
30361 self.write(")");
30362 Ok(())
30363 }
30364
30365 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
30366 self.write_keyword("UNIX_TO_STR");
30368 self.write("(");
30369 self.generate_expression(&e.this)?;
30370 if let Some(format) = &e.format {
30371 self.write(", '");
30372 self.write(format);
30373 self.write("'");
30374 }
30375 self.write(")");
30376 Ok(())
30377 }
30378
30379 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
30380 use crate::dialects::DialectType;
30381 let scale = e.scale.unwrap_or(0); match self.config.dialect {
30384 Some(DialectType::Snowflake) => {
30385 self.write_keyword("TO_TIMESTAMP");
30387 self.write("(");
30388 self.generate_expression(&e.this)?;
30389 if let Some(s) = e.scale {
30390 if s > 0 {
30391 self.write(", ");
30392 self.write(&s.to_string());
30393 }
30394 }
30395 self.write(")");
30396 }
30397 Some(DialectType::BigQuery) => {
30398 match scale {
30401 0 => {
30402 self.write_keyword("TIMESTAMP_SECONDS");
30403 self.write("(");
30404 self.generate_expression(&e.this)?;
30405 self.write(")");
30406 }
30407 3 => {
30408 self.write_keyword("TIMESTAMP_MILLIS");
30409 self.write("(");
30410 self.generate_expression(&e.this)?;
30411 self.write(")");
30412 }
30413 6 => {
30414 self.write_keyword("TIMESTAMP_MICROS");
30415 self.write("(");
30416 self.generate_expression(&e.this)?;
30417 self.write(")");
30418 }
30419 _ => {
30420 self.write_keyword("TIMESTAMP_SECONDS");
30422 self.write("(CAST(");
30423 self.generate_expression(&e.this)?;
30424 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
30425 }
30426 }
30427 }
30428 Some(DialectType::Spark) => {
30429 match scale {
30434 0 => {
30435 self.write_keyword("CAST");
30436 self.write("(");
30437 self.write_keyword("FROM_UNIXTIME");
30438 self.write("(");
30439 self.generate_expression(&e.this)?;
30440 self.write(") ");
30441 self.write_keyword("AS TIMESTAMP");
30442 self.write(")");
30443 }
30444 3 => {
30445 self.write_keyword("TIMESTAMP_MILLIS");
30446 self.write("(");
30447 self.generate_expression(&e.this)?;
30448 self.write(")");
30449 }
30450 6 => {
30451 self.write_keyword("TIMESTAMP_MICROS");
30452 self.write("(");
30453 self.generate_expression(&e.this)?;
30454 self.write(")");
30455 }
30456 _ => {
30457 self.write_keyword("TIMESTAMP_SECONDS");
30458 self.write("(");
30459 self.generate_expression(&e.this)?;
30460 self.write(&format!(" / POWER(10, {}))", scale));
30461 }
30462 }
30463 }
30464 Some(DialectType::Databricks) => {
30465 match scale {
30469 0 => {
30470 self.write_keyword("CAST");
30471 self.write("(");
30472 self.write_keyword("FROM_UNIXTIME");
30473 self.write("(");
30474 self.generate_expression(&e.this)?;
30475 self.write(") ");
30476 self.write_keyword("AS TIMESTAMP");
30477 self.write(")");
30478 }
30479 3 => {
30480 self.write_keyword("TIMESTAMP_MILLIS");
30481 self.write("(");
30482 self.generate_expression(&e.this)?;
30483 self.write(")");
30484 }
30485 6 => {
30486 self.write_keyword("TIMESTAMP_MICROS");
30487 self.write("(");
30488 self.generate_expression(&e.this)?;
30489 self.write(")");
30490 }
30491 _ => {
30492 self.write_keyword("TIMESTAMP_SECONDS");
30493 self.write("(");
30494 self.generate_expression(&e.this)?;
30495 self.write(&format!(" / POWER(10, {}))", scale));
30496 }
30497 }
30498 }
30499 Some(DialectType::Presto) | Some(DialectType::Trino) => {
30500 if scale == 0 {
30503 self.write_keyword("FROM_UNIXTIME");
30504 self.write("(");
30505 self.generate_expression(&e.this)?;
30506 self.write(")");
30507 } else {
30508 self.write_keyword("FROM_UNIXTIME");
30509 self.write("(CAST(");
30510 self.generate_expression(&e.this)?;
30511 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
30512 }
30513 }
30514 Some(DialectType::DuckDB) => {
30515 match scale {
30519 0 => {
30520 self.write_keyword("TO_TIMESTAMP");
30521 self.write("(");
30522 self.generate_expression(&e.this)?;
30523 self.write(")");
30524 }
30525 3 => {
30526 self.write_keyword("EPOCH_MS");
30527 self.write("(");
30528 self.generate_expression(&e.this)?;
30529 self.write(")");
30530 }
30531 6 => {
30532 self.write_keyword("MAKE_TIMESTAMP");
30533 self.write("(");
30534 self.generate_expression(&e.this)?;
30535 self.write(")");
30536 }
30537 _ => {
30538 self.write_keyword("TO_TIMESTAMP");
30539 self.write("(");
30540 self.generate_expression(&e.this)?;
30541 self.write(&format!(" / POWER(10, {}))", scale));
30542 self.write_keyword(" AT TIME ZONE");
30543 self.write(" 'UTC'");
30544 }
30545 }
30546 }
30547 Some(DialectType::Redshift) => {
30548 self.write("(TIMESTAMP 'epoch' + ");
30551 if scale == 0 {
30552 self.generate_expression(&e.this)?;
30553 } else {
30554 self.write("(");
30555 self.generate_expression(&e.this)?;
30556 self.write(&format!(" / POWER(10, {}))", scale));
30557 }
30558 self.write(" * INTERVAL '1 SECOND')");
30559 }
30560 _ => {
30561 self.write_keyword("TO_TIMESTAMP");
30563 self.write("(");
30564 self.generate_expression(&e.this)?;
30565 if let Some(s) = e.scale {
30566 self.write(", ");
30567 self.write(&s.to_string());
30568 }
30569 self.write(")");
30570 }
30571 }
30572 Ok(())
30573 }
30574
30575 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
30576 if !matches!(&*e.this, Expression::Null(_)) {
30578 self.write_keyword("NAME");
30579 self.write_space();
30580 self.generate_expression(&e.this)?;
30581 }
30582 if !e.expressions.is_empty() {
30583 self.write_space();
30584 self.write_keyword("VALUE");
30585 self.write_space();
30586 for (i, expr) in e.expressions.iter().enumerate() {
30587 if i > 0 {
30588 self.write(", ");
30589 }
30590 self.generate_expression(expr)?;
30591 }
30592 }
30593 Ok(())
30594 }
30595
30596 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
30597 if e.wrapped.is_some() {
30599 self.write("(");
30600 }
30601 self.generate_expression(&e.this)?;
30602 if e.wrapped.is_some() {
30603 self.write(")");
30604 }
30605 self.write("(");
30606 for (i, expr) in e.expressions.iter().enumerate() {
30607 if i > 0 {
30608 self.write(", ");
30609 }
30610 self.generate_expression(expr)?;
30611 }
30612 self.write(")");
30613 Ok(())
30614 }
30615
30616 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
30617 self.write_keyword("USING TEMPLATE");
30619 self.write_space();
30620 self.generate_expression(&e.this)?;
30621 Ok(())
30622 }
30623
30624 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
30625 self.write_keyword("UTC_TIME");
30627 Ok(())
30628 }
30629
30630 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
30631 self.write_keyword("UTC_TIMESTAMP");
30633 Ok(())
30634 }
30635
30636 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
30637 use crate::dialects::DialectType;
30638 let func_name = match self.config.dialect {
30640 Some(DialectType::Snowflake) => "UUID_STRING",
30641 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
30642 Some(DialectType::BigQuery) => "GENERATE_UUID",
30643 _ => {
30644 if let Some(name) = &e.name {
30645 name.as_str()
30646 } else {
30647 "UUID"
30648 }
30649 }
30650 };
30651 self.write_keyword(func_name);
30652 self.write("(");
30653 if let Some(this) = &e.this {
30654 self.generate_expression(this)?;
30655 }
30656 self.write(")");
30657 Ok(())
30658 }
30659
30660 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
30661 self.write_keyword("MAP");
30663 self.write("(");
30664 let mut first = true;
30665 for (k, v) in e.keys.iter().zip(e.values.iter()) {
30666 if !first {
30667 self.write(", ");
30668 }
30669 self.generate_expression(k)?;
30670 self.write(", ");
30671 self.generate_expression(v)?;
30672 first = false;
30673 }
30674 self.write(")");
30675 Ok(())
30676 }
30677
30678 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
30679 self.write_keyword("VECTOR_SEARCH");
30681 self.write("(");
30682 self.generate_expression(&e.this)?;
30683 if let Some(col) = &e.column_to_search {
30684 self.write(", ");
30685 self.generate_expression(col)?;
30686 }
30687 if let Some(query_table) = &e.query_table {
30688 self.write(", ");
30689 self.generate_expression(query_table)?;
30690 }
30691 if let Some(query_col) = &e.query_column_to_search {
30692 self.write(", ");
30693 self.generate_expression(query_col)?;
30694 }
30695 if let Some(top_k) = &e.top_k {
30696 self.write(", ");
30697 self.generate_expression(top_k)?;
30698 }
30699 if let Some(dist_type) = &e.distance_type {
30700 self.write(", ");
30701 self.generate_expression(dist_type)?;
30702 }
30703 self.write(")");
30704 Ok(())
30705 }
30706
30707 fn generate_version(&mut self, e: &Version) -> Result<()> {
30708 use crate::dialects::DialectType;
30714 let skip_for = matches!(self.config.dialect, Some(DialectType::Hive) | Some(DialectType::Spark));
30715 if !skip_for {
30716 self.write_keyword("FOR");
30717 self.write_space();
30718 }
30719 match e.this.as_ref() {
30721 Expression::Identifier(ident) => {
30722 self.write_keyword(&ident.name);
30723 }
30724 _ => {
30725 self.generate_expression(&e.this)?;
30726 }
30727 }
30728 self.write_space();
30729 self.write_keyword(&e.kind);
30730 if let Some(expression) = &e.expression {
30731 self.write_space();
30732 self.generate_expression(expression)?;
30733 }
30734 Ok(())
30735 }
30736
30737 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
30738 self.generate_expression(&e.this)?;
30740 Ok(())
30741 }
30742
30743 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
30744 if e.this.is_some() {
30746 self.write_keyword("NOT VOLATILE");
30747 } else {
30748 self.write_keyword("VOLATILE");
30749 }
30750 Ok(())
30751 }
30752
30753 fn generate_watermark_column_constraint(&mut self, e: &WatermarkColumnConstraint) -> Result<()> {
30754 self.write_keyword("WATERMARK FOR");
30756 self.write_space();
30757 self.generate_expression(&e.this)?;
30758 self.write_space();
30759 self.write_keyword("AS");
30760 self.write_space();
30761 self.generate_expression(&e.expression)?;
30762 Ok(())
30763 }
30764
30765 fn generate_week(&mut self, e: &Week) -> Result<()> {
30766 self.write_keyword("WEEK");
30768 self.write("(");
30769 self.generate_expression(&e.this)?;
30770 if let Some(mode) = &e.mode {
30771 self.write(", ");
30772 self.generate_expression(mode)?;
30773 }
30774 self.write(")");
30775 Ok(())
30776 }
30777
30778 fn generate_when(&mut self, e: &When) -> Result<()> {
30779 self.write_keyword("WHEN");
30783 self.write_space();
30784
30785 if let Some(matched) = &e.matched {
30787 match matched.as_ref() {
30789 Expression::Boolean(b) if b.value => {
30790 self.write_keyword("MATCHED");
30791 }
30792 _ => {
30793 self.write_keyword("NOT MATCHED");
30794 }
30795 }
30796 } else {
30797 self.write_keyword("NOT MATCHED");
30798 }
30799
30800 if self.config.matched_by_source {
30805 if let Some(source) = &e.source {
30806 if let Expression::Boolean(b) = source.as_ref() {
30807 if b.value {
30808 self.write_space();
30810 self.write_keyword("BY SOURCE");
30811 }
30812 } else {
30814 self.write_space();
30816 self.write_keyword("BY SOURCE");
30817 }
30818 }
30819 }
30820
30821 if let Some(condition) = &e.condition {
30823 self.write_space();
30824 self.write_keyword("AND");
30825 self.write_space();
30826 self.generate_expression(condition)?;
30827 }
30828
30829 self.write_space();
30830 self.write_keyword("THEN");
30831 self.write_space();
30832
30833 self.generate_merge_action(&e.then)?;
30836
30837 Ok(())
30838 }
30839
30840 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
30841 match action {
30842 Expression::Tuple(tuple) => {
30843 let elements = &tuple.expressions;
30844 if elements.is_empty() {
30845 return self.generate_expression(action);
30846 }
30847 match &elements[0] {
30849 Expression::Var(v) if v.this == "INSERT" => {
30850 self.write_keyword("INSERT");
30851 let mut values_idx = 1;
30852 if elements.len() > 1 {
30854 if let Expression::Tuple(cols) = &elements[1] {
30855 if elements.len() > 2 {
30857 self.write(" (");
30859 for (i, col) in cols.expressions.iter().enumerate() {
30860 if i > 0 { self.write(", "); }
30861 self.generate_expression(col)?;
30862 }
30863 self.write(")");
30864 values_idx = 2;
30865 } else {
30866 values_idx = 1;
30868 }
30869 }
30870 }
30871 if values_idx < elements.len() {
30873 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
30875 if !is_row {
30876 self.write_space();
30877 self.write_keyword("VALUES");
30878 }
30879 self.write(" ");
30880 if let Expression::Tuple(vals) = &elements[values_idx] {
30881 self.write("(");
30882 for (i, val) in vals.expressions.iter().enumerate() {
30883 if i > 0 { self.write(", "); }
30884 self.generate_expression(val)?;
30885 }
30886 self.write(")");
30887 } else {
30888 self.generate_expression(&elements[values_idx])?;
30889 }
30890 }
30891 }
30892 Expression::Var(v) if v.this == "UPDATE" => {
30893 self.write_keyword("UPDATE");
30894 if elements.len() > 1 {
30895 self.write_space();
30896 self.write_keyword("SET");
30897 if self.config.pretty {
30899 self.write_newline();
30900 self.indent_level += 1;
30901 self.write_indent();
30902 } else {
30903 self.write_space();
30904 }
30905 if let Expression::Tuple(assignments) = &elements[1] {
30906 for (i, assignment) in assignments.expressions.iter().enumerate() {
30907 if i > 0 { self.write(", "); }
30908 if !self.merge_strip_qualifiers.is_empty() {
30910 self.generate_merge_set_assignment(assignment)?;
30911 } else {
30912 self.generate_expression(assignment)?;
30913 }
30914 }
30915 } else {
30916 self.generate_expression(&elements[1])?;
30917 }
30918 if self.config.pretty {
30919 self.indent_level -= 1;
30920 }
30921 }
30922 }
30923 _ => {
30924 self.generate_expression(action)?;
30926 }
30927 }
30928 }
30929 Expression::Var(v) if v.this == "INSERT" || v.this == "UPDATE" || v.this == "DELETE" || v.this == "DO NOTHING" => {
30930 self.write_keyword(&v.this);
30931 }
30932 _ => {
30933 self.generate_expression(action)?;
30934 }
30935 }
30936 Ok(())
30937 }
30938
30939 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
30941 match assignment {
30942 Expression::Eq(eq) => {
30943 let stripped_left = self.strip_merge_qualifier(&eq.left);
30945 self.generate_expression(&stripped_left)?;
30946 self.write(" = ");
30947 self.generate_expression(&eq.right)?;
30948 Ok(())
30949 }
30950 other => self.generate_expression(other),
30951 }
30952 }
30953
30954 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
30956 match expr {
30957 Expression::Column(col) => {
30958 if let Some(ref table_ident) = col.table {
30959 if self.merge_strip_qualifiers.iter().any(|n| n.eq_ignore_ascii_case(&table_ident.name)) {
30960 let mut col = col.clone();
30962 col.table = None;
30963 return Expression::Column(col);
30964 }
30965 }
30966 expr.clone()
30967 }
30968 Expression::Dot(dot) => {
30969 if let Expression::Identifier(id) = &dot.this {
30971 if self.merge_strip_qualifiers.iter().any(|n| n.eq_ignore_ascii_case(&id.name)) {
30972 return Expression::Identifier(dot.field.clone());
30973 }
30974 }
30975 expr.clone()
30976 }
30977 _ => expr.clone(),
30978 }
30979 }
30980
30981 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
30982 for (i, expr) in e.expressions.iter().enumerate() {
30984 if i > 0 {
30985 if self.config.pretty {
30987 self.write_newline();
30988 self.write_indent();
30989 } else {
30990 self.write_space();
30991 }
30992 }
30993 self.generate_expression(expr)?;
30994 }
30995 Ok(())
30996 }
30997
30998 fn generate_where(&mut self, e: &Where) -> Result<()> {
30999 self.write_keyword("WHERE");
31001 self.write_space();
31002 self.generate_expression(&e.this)?;
31003 Ok(())
31004 }
31005
31006 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
31007 self.write_keyword("WIDTH_BUCKET");
31009 self.write("(");
31010 self.generate_expression(&e.this)?;
31011 if let Some(min_value) = &e.min_value {
31012 self.write(", ");
31013 self.generate_expression(min_value)?;
31014 }
31015 if let Some(max_value) = &e.max_value {
31016 self.write(", ");
31017 self.generate_expression(max_value)?;
31018 }
31019 if let Some(num_buckets) = &e.num_buckets {
31020 self.write(", ");
31021 self.generate_expression(num_buckets)?;
31022 }
31023 self.write(")");
31024 Ok(())
31025 }
31026
31027 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
31028 self.generate_window_spec(e)
31030 }
31031
31032 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
31033 let mut has_content = false;
31035
31036 if !e.partition_by.is_empty() {
31038 self.write_keyword("PARTITION BY");
31039 self.write_space();
31040 for (i, expr) in e.partition_by.iter().enumerate() {
31041 if i > 0 {
31042 self.write(", ");
31043 }
31044 self.generate_expression(expr)?;
31045 }
31046 has_content = true;
31047 }
31048
31049 if !e.order_by.is_empty() {
31051 if has_content {
31052 self.write_space();
31053 }
31054 self.write_keyword("ORDER BY");
31055 self.write_space();
31056 for (i, ordered) in e.order_by.iter().enumerate() {
31057 if i > 0 {
31058 self.write(", ");
31059 }
31060 self.generate_expression(&ordered.this)?;
31061 if ordered.desc {
31062 self.write_space();
31063 self.write_keyword("DESC");
31064 } else if ordered.explicit_asc {
31065 self.write_space();
31066 self.write_keyword("ASC");
31067 }
31068 if let Some(nulls_first) = ordered.nulls_first {
31069 self.write_space();
31070 self.write_keyword("NULLS");
31071 self.write_space();
31072 if nulls_first {
31073 self.write_keyword("FIRST");
31074 } else {
31075 self.write_keyword("LAST");
31076 }
31077 }
31078 }
31079 has_content = true;
31080 }
31081
31082 if let Some(frame) = &e.frame {
31084 if has_content {
31085 self.write_space();
31086 }
31087 self.generate_window_frame(frame)?;
31088 }
31089
31090 Ok(())
31091 }
31092
31093 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
31094 self.write_keyword("WITH");
31096 self.write_space();
31097 if e.no.is_some() {
31098 self.write_keyword("NO");
31099 self.write_space();
31100 }
31101 self.write_keyword("DATA");
31102
31103 if let Some(statistics) = &e.statistics {
31105 self.write_space();
31106 self.write_keyword("AND");
31107 self.write_space();
31108 match statistics.as_ref() {
31110 Expression::Boolean(b) if !b.value => {
31111 self.write_keyword("NO");
31112 self.write_space();
31113 }
31114 _ => {}
31115 }
31116 self.write_keyword("STATISTICS");
31117 }
31118 Ok(())
31119 }
31120
31121 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
31122 self.write_keyword("WITH FILL");
31124
31125 if let Some(from_) = &e.from_ {
31126 self.write_space();
31127 self.write_keyword("FROM");
31128 self.write_space();
31129 self.generate_expression(from_)?;
31130 }
31131
31132 if let Some(to) = &e.to {
31133 self.write_space();
31134 self.write_keyword("TO");
31135 self.write_space();
31136 self.generate_expression(to)?;
31137 }
31138
31139 if let Some(step) = &e.step {
31140 self.write_space();
31141 self.write_keyword("STEP");
31142 self.write_space();
31143 self.generate_expression(step)?;
31144 }
31145
31146 if let Some(interpolate) = &e.interpolate {
31147 self.write_space();
31148 self.write_keyword("INTERPOLATE");
31149 self.write(" (");
31150 self.generate_interpolate_item(interpolate)?;
31152 self.write(")");
31153 }
31154
31155 Ok(())
31156 }
31157
31158 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
31160 match expr {
31161 Expression::Alias(alias) => {
31162 self.generate_identifier(&alias.alias)?;
31164 self.write_space();
31165 self.write_keyword("AS");
31166 self.write_space();
31167 self.generate_expression(&alias.this)?;
31168 }
31169 Expression::Tuple(tuple) => {
31170 for (i, item) in tuple.expressions.iter().enumerate() {
31171 if i > 0 { self.write(", "); }
31172 self.generate_interpolate_item(item)?;
31173 }
31174 }
31175 other => {
31176 self.generate_expression(other)?;
31177 }
31178 }
31179 Ok(())
31180 }
31181
31182 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
31183 self.write_keyword("WITH JOURNAL TABLE");
31185 self.write("=");
31186 self.generate_expression(&e.this)?;
31187 Ok(())
31188 }
31189
31190 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
31191 self.generate_expression(&e.this)?;
31193 self.write_space();
31194 self.write_keyword("WITH");
31195 self.write_space();
31196 self.write_keyword(&e.op);
31197 Ok(())
31198 }
31199
31200 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
31201 self.write_keyword("WITH");
31203 self.write_space();
31204 for (i, expr) in e.expressions.iter().enumerate() {
31205 if i > 0 {
31206 self.write(", ");
31207 }
31208 self.generate_expression(expr)?;
31209 }
31210 Ok(())
31211 }
31212
31213 fn generate_with_schema_binding_property(&mut self, e: &WithSchemaBindingProperty) -> Result<()> {
31214 self.write_keyword("WITH");
31216 self.write_space();
31217 self.generate_expression(&e.this)?;
31218 Ok(())
31219 }
31220
31221 fn generate_with_system_versioning_property(&mut self, e: &WithSystemVersioningProperty) -> Result<()> {
31222 let mut parts = Vec::new();
31228
31229 if let Some(this) = &e.this {
31230 let mut s = String::from("HISTORY_TABLE=");
31232 let mut gen = Generator::new();
31233 gen.generate_expression(this)?;
31234 s.push_str(&gen.output);
31235 parts.push(s);
31236 }
31237
31238 if let Some(data_consistency) = &e.data_consistency {
31239 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
31240 let mut gen = Generator::new();
31241 gen.generate_expression(data_consistency)?;
31242 s.push_str(&gen.output);
31243 parts.push(s);
31244 }
31245
31246 if let Some(retention_period) = &e.retention_period {
31247 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
31248 let mut gen = Generator::new();
31249 gen.generate_expression(retention_period)?;
31250 s.push_str(&gen.output);
31251 parts.push(s);
31252 }
31253
31254 self.write_keyword("SYSTEM_VERSIONING");
31255 self.write("=");
31256
31257 if !parts.is_empty() {
31258 self.write_keyword("ON");
31259 self.write("(");
31260 self.write(&parts.join(", "));
31261 self.write(")");
31262 } else if e.on.is_some() {
31263 self.write_keyword("ON");
31264 } else {
31265 self.write_keyword("OFF");
31266 }
31267
31268 if e.with_.is_some() {
31270 let inner = self.output.clone();
31271 self.output.clear();
31272 self.write("WITH(");
31273 self.write(&inner);
31274 self.write(")");
31275 }
31276
31277 Ok(())
31278 }
31279
31280 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
31281 self.write_keyword("WITH");
31283 self.write(" (");
31284 for (i, expr) in e.expressions.iter().enumerate() {
31285 if i > 0 {
31286 self.write(", ");
31287 }
31288 self.generate_expression(expr)?;
31289 }
31290 self.write(")");
31291 Ok(())
31292 }
31293
31294 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
31295 self.write_keyword("XMLELEMENT");
31298 self.write("(");
31299
31300 if e.evalname.is_some() {
31301 self.write_keyword("EVALNAME");
31302 } else {
31303 self.write_keyword("NAME");
31304 }
31305 self.write_space();
31306 self.generate_expression(&e.this)?;
31307
31308 for expr in &e.expressions {
31309 self.write(", ");
31310 self.generate_expression(expr)?;
31311 }
31312 self.write(")");
31313 Ok(())
31314 }
31315
31316 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
31317 self.write_keyword("XMLGET");
31319 self.write("(");
31320 self.generate_expression(&e.this)?;
31321 self.write(", ");
31322 self.generate_expression(&e.expression)?;
31323 if let Some(instance) = &e.instance {
31324 self.write(", ");
31325 self.generate_expression(instance)?;
31326 }
31327 self.write(")");
31328 Ok(())
31329 }
31330
31331 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
31332 self.generate_expression(&e.this)?;
31334 if let Some(expression) = &e.expression {
31335 self.write("(");
31336 self.generate_expression(expression)?;
31337 self.write(")");
31338 }
31339 Ok(())
31340 }
31341
31342 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
31343 self.write_keyword("XMLTABLE");
31345 self.write("(");
31346
31347 if self.config.pretty {
31348 self.indent_level += 1;
31349 self.write_newline();
31350 self.write_indent();
31351 self.generate_expression(&e.this)?;
31352
31353 if let Some(passing) = &e.passing {
31354 self.write_newline();
31355 self.write_indent();
31356 self.write_keyword("PASSING");
31357 if let Expression::Tuple(tuple) = passing.as_ref() {
31358 for expr in &tuple.expressions {
31359 self.write_newline();
31360 self.indent_level += 1;
31361 self.write_indent();
31362 self.generate_expression(expr)?;
31363 self.indent_level -= 1;
31364 }
31365 } else {
31366 self.write_newline();
31367 self.indent_level += 1;
31368 self.write_indent();
31369 self.generate_expression(passing)?;
31370 self.indent_level -= 1;
31371 }
31372 }
31373
31374 if e.by_ref.is_some() {
31375 self.write_newline();
31376 self.write_indent();
31377 self.write_keyword("RETURNING SEQUENCE BY REF");
31378 }
31379
31380 if !e.columns.is_empty() {
31381 self.write_newline();
31382 self.write_indent();
31383 self.write_keyword("COLUMNS");
31384 for (i, col) in e.columns.iter().enumerate() {
31385 self.write_newline();
31386 self.indent_level += 1;
31387 self.write_indent();
31388 self.generate_expression(col)?;
31389 self.indent_level -= 1;
31390 if i < e.columns.len() - 1 {
31391 self.write(",");
31392 }
31393 }
31394 }
31395
31396 self.indent_level -= 1;
31397 self.write_newline();
31398 self.write_indent();
31399 self.write(")");
31400 return Ok(());
31401 }
31402
31403 if let Some(namespaces) = &e.namespaces {
31405 self.write_keyword("XMLNAMESPACES");
31406 self.write("(");
31407 if let Expression::Tuple(tuple) = namespaces.as_ref() {
31409 for (i, expr) in tuple.expressions.iter().enumerate() {
31410 if i > 0 {
31411 self.write(", ");
31412 }
31413 if !matches!(expr, Expression::Alias(_)) {
31416 self.write_keyword("DEFAULT");
31417 self.write_space();
31418 }
31419 self.generate_expression(expr)?;
31420 }
31421 } else {
31422 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
31424 self.write_keyword("DEFAULT");
31425 self.write_space();
31426 }
31427 self.generate_expression(namespaces)?;
31428 }
31429 self.write("), ");
31430 }
31431
31432 self.generate_expression(&e.this)?;
31434
31435 if let Some(passing) = &e.passing {
31437 self.write_space();
31438 self.write_keyword("PASSING");
31439 self.write_space();
31440 if let Expression::Tuple(tuple) = passing.as_ref() {
31442 for (i, expr) in tuple.expressions.iter().enumerate() {
31443 if i > 0 {
31444 self.write(", ");
31445 }
31446 self.generate_expression(expr)?;
31447 }
31448 } else {
31449 self.generate_expression(passing)?;
31450 }
31451 }
31452
31453 if e.by_ref.is_some() {
31455 self.write_space();
31456 self.write_keyword("RETURNING SEQUENCE BY REF");
31457 }
31458
31459 if !e.columns.is_empty() {
31461 self.write_space();
31462 self.write_keyword("COLUMNS");
31463 self.write_space();
31464 for (i, col) in e.columns.iter().enumerate() {
31465 if i > 0 {
31466 self.write(", ");
31467 }
31468 self.generate_expression(col)?;
31469 }
31470 }
31471
31472 self.write(")");
31473 Ok(())
31474 }
31475
31476 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
31477 if let Some(this) = &e.this {
31480 self.generate_expression(this)?;
31481 if let Some(expression) = &e.expression {
31482 self.write_space();
31483 self.write_keyword("XOR");
31484 self.write_space();
31485 self.generate_expression(expression)?;
31486 }
31487 }
31488
31489 for (i, expr) in e.expressions.iter().enumerate() {
31491 if i > 0 || e.this.is_some() {
31492 self.write_space();
31493 self.write_keyword("XOR");
31494 self.write_space();
31495 }
31496 self.generate_expression(expr)?;
31497 }
31498 Ok(())
31499 }
31500
31501 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
31502 self.write_keyword("ZIPF");
31504 self.write("(");
31505 self.generate_expression(&e.this)?;
31506 if let Some(elementcount) = &e.elementcount {
31507 self.write(", ");
31508 self.generate_expression(elementcount)?;
31509 }
31510 if let Some(gen) = &e.gen {
31511 self.write(", ");
31512 self.generate_expression(gen)?;
31513 }
31514 self.write(")");
31515 Ok(())
31516 }
31517}
31518
31519impl Default for Generator {
31520 fn default() -> Self {
31521 Self::new()
31522 }
31523}
31524
31525#[cfg(test)]
31526mod tests {
31527 use super::*;
31528 use crate::parser::Parser;
31529
31530 fn roundtrip(sql: &str) -> String {
31531 let ast = Parser::parse_sql(sql).unwrap();
31532 Generator::sql(&ast[0]).unwrap()
31533 }
31534
31535 #[test]
31536 fn test_simple_select() {
31537 let result = roundtrip("SELECT 1");
31538 assert_eq!(result, "SELECT 1");
31539 }
31540
31541 #[test]
31542 fn test_select_from() {
31543 let result = roundtrip("SELECT a, b FROM t");
31544 assert_eq!(result, "SELECT a, b FROM t");
31545 }
31546
31547 #[test]
31548 fn test_select_where() {
31549 let result = roundtrip("SELECT * FROM t WHERE x = 1");
31550 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
31551 }
31552
31553 #[test]
31554 fn test_select_join() {
31555 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
31556 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
31557 }
31558
31559 #[test]
31560 fn test_insert() {
31561 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
31562 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
31563 }
31564
31565 #[test]
31566 fn test_pretty_print() {
31567 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
31568 let result = Generator::pretty_sql(&ast[0]).unwrap();
31569 assert!(result.contains('\n'));
31570 }
31571
31572 #[test]
31573 fn test_window_function() {
31574 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
31575 assert_eq!(result, "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
31576 }
31577
31578 #[test]
31579 fn test_window_function_with_frame() {
31580 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
31581 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
31582 }
31583
31584 #[test]
31585 fn test_aggregate_with_filter() {
31586 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
31587 assert_eq!(result, "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders");
31588 }
31589
31590 #[test]
31591 fn test_subscript() {
31592 let result = roundtrip("SELECT arr[0]");
31593 assert_eq!(result, "SELECT arr[0]");
31594 }
31595
31596 #[test]
31598 fn test_create_table() {
31599 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
31600 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
31601 }
31602
31603 #[test]
31604 fn test_create_table_with_constraints() {
31605 let result = roundtrip("CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)");
31606 assert_eq!(result, "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)");
31607 }
31608
31609 #[test]
31610 fn test_create_table_if_not_exists() {
31611 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
31612 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
31613 }
31614
31615 #[test]
31616 fn test_drop_table() {
31617 let result = roundtrip("DROP TABLE users");
31618 assert_eq!(result, "DROP TABLE users");
31619 }
31620
31621 #[test]
31622 fn test_drop_table_if_exists_cascade() {
31623 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
31624 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
31625 }
31626
31627 #[test]
31628 fn test_alter_table_add_column() {
31629 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
31630 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
31631 }
31632
31633 #[test]
31634 fn test_alter_table_drop_column() {
31635 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
31636 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
31637 }
31638
31639 #[test]
31640 fn test_create_index() {
31641 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
31642 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
31643 }
31644
31645 #[test]
31646 fn test_create_unique_index() {
31647 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
31648 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
31649 }
31650
31651 #[test]
31652 fn test_drop_index() {
31653 let result = roundtrip("DROP INDEX idx_name");
31654 assert_eq!(result, "DROP INDEX idx_name");
31655 }
31656
31657 #[test]
31658 fn test_create_view() {
31659 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
31660 assert_eq!(result, "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
31661 }
31662
31663 #[test]
31664 fn test_drop_view() {
31665 let result = roundtrip("DROP VIEW active_users");
31666 assert_eq!(result, "DROP VIEW active_users");
31667 }
31668
31669 #[test]
31670 fn test_truncate() {
31671 let result = roundtrip("TRUNCATE TABLE users");
31672 assert_eq!(result, "TRUNCATE TABLE users");
31673 }
31674
31675 #[test]
31676 fn test_string_literal_escaping_default() {
31677 let result = roundtrip("SELECT 'hello'");
31679 assert_eq!(result, "SELECT 'hello'");
31680
31681 let result = roundtrip("SELECT 'it''s a test'");
31683 assert_eq!(result, "SELECT 'it''s a test'");
31684 }
31685
31686 #[test]
31687 fn test_string_literal_escaping_mysql() {
31688 use crate::dialects::DialectType;
31689
31690 let config = GeneratorConfig {
31691 dialect: Some(DialectType::MySQL),
31692 ..Default::default()
31693 };
31694
31695 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
31696 let mut gen = Generator::with_config(config.clone());
31697 let result = gen.generate(&ast[0]).unwrap();
31698 assert_eq!(result, "SELECT 'hello'");
31699
31700 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
31702 let mut gen = Generator::with_config(config.clone());
31703 let result = gen.generate(&ast[0]).unwrap();
31704 assert_eq!(result, "SELECT 'it''s'");
31705 }
31706
31707 #[test]
31708 fn test_string_literal_escaping_postgres() {
31709 use crate::dialects::DialectType;
31710
31711 let config = GeneratorConfig {
31712 dialect: Some(DialectType::PostgreSQL),
31713 ..Default::default()
31714 };
31715
31716 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
31717 let mut gen = Generator::with_config(config.clone());
31718 let result = gen.generate(&ast[0]).unwrap();
31719 assert_eq!(result, "SELECT 'hello'");
31720
31721 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
31723 let mut gen = Generator::with_config(config.clone());
31724 let result = gen.generate(&ast[0]).unwrap();
31725 assert_eq!(result, "SELECT 'it''s'");
31726 }
31727
31728 #[test]
31729 fn test_string_literal_escaping_bigquery() {
31730 use crate::dialects::DialectType;
31731
31732 let config = GeneratorConfig {
31733 dialect: Some(DialectType::BigQuery),
31734 ..Default::default()
31735 };
31736
31737 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
31738 let mut gen = Generator::with_config(config.clone());
31739 let result = gen.generate(&ast[0]).unwrap();
31740 assert_eq!(result, "SELECT 'hello'");
31741
31742 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
31744 let mut gen = Generator::with_config(config.clone());
31745 let result = gen.generate(&ast[0]).unwrap();
31746 assert_eq!(result, "SELECT 'it\\'s'");
31747 }
31748
31749}