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::PipeOperator(pipe) => self.generate_pipe_operator(pipe),
2010 Expression::Ordered(ordered) => self.generate_ordered(ordered),
2011 Expression::DataType(dt) => self.generate_data_type(dt),
2012 Expression::Raw(raw) => {
2013 self.write(&raw.sql);
2014 Ok(())
2015 }
2016 Expression::Command(cmd) => {
2017 self.write(&cmd.this);
2018 Ok(())
2019 }
2020 Expression::Kill(kill) => {
2021 self.write_keyword("KILL");
2022 if let Some(kind) = &kill.kind {
2023 self.write_space();
2024 self.write_keyword(kind);
2025 }
2026 self.write_space();
2027 self.generate_expression(&kill.this)?;
2028 Ok(())
2029 }
2030 Expression::Execute(exec) => {
2031 self.write_keyword("EXEC");
2032 self.write_space();
2033 self.generate_expression(&exec.this)?;
2034 for (i, param) in exec.parameters.iter().enumerate() {
2035 if i == 0 {
2036 self.write_space();
2037 } else {
2038 self.write(", ");
2039 }
2040 self.write(¶m.name);
2041 self.write("=");
2042 self.generate_expression(¶m.value)?;
2043 }
2044 Ok(())
2045 }
2046 Expression::Annotated(annotated) => {
2047 self.generate_expression(&annotated.this)?;
2048 for comment in &annotated.trailing_comments {
2049 self.write(" ");
2050 self.write_formatted_comment(comment);
2051 }
2052 Ok(())
2053 }
2054
2055 Expression::CreateTable(ct) => self.generate_create_table(ct),
2057 Expression::DropTable(dt) => self.generate_drop_table(dt),
2058 Expression::AlterTable(at) => self.generate_alter_table(at),
2059 Expression::CreateIndex(ci) => self.generate_create_index(ci),
2060 Expression::DropIndex(di) => self.generate_drop_index(di),
2061 Expression::CreateView(cv) => self.generate_create_view(cv),
2062 Expression::DropView(dv) => self.generate_drop_view(dv),
2063 Expression::AlterView(av) => self.generate_alter_view(av),
2064 Expression::AlterIndex(ai) => self.generate_alter_index(ai),
2065 Expression::Truncate(tr) => self.generate_truncate(tr),
2066 Expression::Use(u) => self.generate_use(u),
2067 Expression::CreateSchema(cs) => self.generate_create_schema(cs),
2069 Expression::DropSchema(ds) => self.generate_drop_schema(ds),
2070 Expression::DropNamespace(dn) => self.generate_drop_namespace(dn),
2071 Expression::CreateDatabase(cd) => self.generate_create_database(cd),
2072 Expression::DropDatabase(dd) => self.generate_drop_database(dd),
2073 Expression::CreateFunction(cf) => self.generate_create_function(cf),
2074 Expression::DropFunction(df) => self.generate_drop_function(df),
2075 Expression::CreateProcedure(cp) => self.generate_create_procedure(cp),
2076 Expression::DropProcedure(dp) => self.generate_drop_procedure(dp),
2077 Expression::CreateSequence(cs) => self.generate_create_sequence(cs),
2078 Expression::DropSequence(ds) => self.generate_drop_sequence(ds),
2079 Expression::AlterSequence(als) => self.generate_alter_sequence(als),
2080 Expression::CreateTrigger(ct) => self.generate_create_trigger(ct),
2081 Expression::DropTrigger(dt) => self.generate_drop_trigger(dt),
2082 Expression::CreateType(ct) => self.generate_create_type(ct),
2083 Expression::DropType(dt) => self.generate_drop_type(dt),
2084 Expression::Describe(d) => self.generate_describe(d),
2085 Expression::Show(s) => self.generate_show(s),
2086
2087 Expression::Cache(c) => self.generate_cache(c),
2089 Expression::Uncache(u) => self.generate_uncache(u),
2090 Expression::LoadData(l) => self.generate_load_data(l),
2091 Expression::Pragma(p) => self.generate_pragma(p),
2092 Expression::Grant(g) => self.generate_grant(g),
2093 Expression::Revoke(r) => self.generate_revoke(r),
2094 Expression::Comment(c) => self.generate_comment(c),
2095 Expression::SetStatement(s) => self.generate_set_statement(s),
2096
2097 Expression::Pivot(pivot) => self.generate_pivot(pivot),
2099 Expression::Unpivot(unpivot) => self.generate_unpivot(unpivot),
2100
2101 Expression::Values(values) => self.generate_values(values),
2103
2104
2105 Expression::AIAgg(e) => self.generate_ai_agg(e),
2107 Expression::AIClassify(e) => self.generate_ai_classify(e),
2108 Expression::AddPartition(e) => self.generate_add_partition(e),
2109 Expression::AlgorithmProperty(e) => self.generate_algorithm_property(e),
2110 Expression::Aliases(e) => self.generate_aliases(e),
2111 Expression::AllowedValuesProperty(e) => self.generate_allowed_values_property(e),
2112 Expression::AlterColumn(e) => self.generate_alter_column(e),
2113 Expression::AlterSession(e) => self.generate_alter_session(e),
2114 Expression::AlterSet(e) => self.generate_alter_set(e),
2115 Expression::AlterSortKey(e) => self.generate_alter_sort_key(e),
2116 Expression::Analyze(e) => self.generate_analyze(e),
2117 Expression::AnalyzeDelete(e) => self.generate_analyze_delete(e),
2118 Expression::AnalyzeHistogram(e) => self.generate_analyze_histogram(e),
2119 Expression::AnalyzeListChainedRows(e) => self.generate_analyze_list_chained_rows(e),
2120 Expression::AnalyzeSample(e) => self.generate_analyze_sample(e),
2121 Expression::AnalyzeStatistics(e) => self.generate_analyze_statistics(e),
2122 Expression::AnalyzeValidate(e) => self.generate_analyze_validate(e),
2123 Expression::AnalyzeWith(e) => self.generate_analyze_with(e),
2124 Expression::Anonymous(e) => self.generate_anonymous(e),
2125 Expression::AnonymousAggFunc(e) => self.generate_anonymous_agg_func(e),
2126 Expression::Apply(e) => self.generate_apply(e),
2127 Expression::ApproxPercentileEstimate(e) => self.generate_approx_percentile_estimate(e),
2128 Expression::ApproxQuantile(e) => self.generate_approx_quantile(e),
2129 Expression::ApproxQuantiles(e) => self.generate_approx_quantiles(e),
2130 Expression::ApproxTopK(e) => self.generate_approx_top_k(e),
2131 Expression::ApproxTopKAccumulate(e) => self.generate_approx_top_k_accumulate(e),
2132 Expression::ApproxTopKCombine(e) => self.generate_approx_top_k_combine(e),
2133 Expression::ApproxTopKEstimate(e) => self.generate_approx_top_k_estimate(e),
2134 Expression::ApproxTopSum(e) => self.generate_approx_top_sum(e),
2135 Expression::ArgMax(e) => self.generate_arg_max(e),
2136 Expression::ArgMin(e) => self.generate_arg_min(e),
2137 Expression::ArrayAll(e) => self.generate_array_all(e),
2138 Expression::ArrayAny(e) => self.generate_array_any(e),
2139 Expression::ArrayConstructCompact(e) => self.generate_array_construct_compact(e),
2140 Expression::ArraySum(e) => self.generate_array_sum(e),
2141 Expression::AtIndex(e) => self.generate_at_index(e),
2142 Expression::Attach(e) => self.generate_attach(e),
2143 Expression::AttachOption(e) => self.generate_attach_option(e),
2144 Expression::AutoIncrementProperty(e) => self.generate_auto_increment_property(e),
2145 Expression::AutoRefreshProperty(e) => self.generate_auto_refresh_property(e),
2146 Expression::BackupProperty(e) => self.generate_backup_property(e),
2147 Expression::Base64DecodeBinary(e) => self.generate_base64_decode_binary(e),
2148 Expression::Base64DecodeString(e) => self.generate_base64_decode_string(e),
2149 Expression::Base64Encode(e) => self.generate_base64_encode(e),
2150 Expression::BlockCompressionProperty(e) => self.generate_block_compression_property(e),
2151 Expression::Booland(e) => self.generate_booland(e),
2152 Expression::Boolor(e) => self.generate_boolor(e),
2153 Expression::BuildProperty(e) => self.generate_build_property(e),
2154 Expression::ByteString(e) => self.generate_byte_string(e),
2155 Expression::CaseSpecificColumnConstraint(e) => self.generate_case_specific_column_constraint(e),
2156 Expression::CastToStrType(e) => self.generate_cast_to_str_type(e),
2157 Expression::Changes(e) => self.generate_changes(e),
2158 Expression::CharacterSetColumnConstraint(e) => self.generate_character_set_column_constraint(e),
2159 Expression::CharacterSetProperty(e) => self.generate_character_set_property(e),
2160 Expression::CheckColumnConstraint(e) => self.generate_check_column_constraint(e),
2161 Expression::CheckJson(e) => self.generate_check_json(e),
2162 Expression::CheckXml(e) => self.generate_check_xml(e),
2163 Expression::ChecksumProperty(e) => self.generate_checksum_property(e),
2164 Expression::Clone(e) => self.generate_clone(e),
2165 Expression::ClusterBy(e) => self.generate_cluster_by(e),
2166 Expression::ClusteredByProperty(e) => self.generate_clustered_by_property(e),
2167 Expression::CollateProperty(e) => self.generate_collate_property(e),
2168 Expression::ColumnConstraint(e) => self.generate_column_constraint(e),
2169 Expression::ColumnDef(e) => self.generate_column_def_expr(e),
2170 Expression::ColumnPosition(e) => self.generate_column_position(e),
2171 Expression::ColumnPrefix(e) => self.generate_column_prefix(e),
2172 Expression::Columns(e) => self.generate_columns(e),
2173 Expression::CombinedAggFunc(e) => self.generate_combined_agg_func(e),
2174 Expression::CombinedParameterizedAgg(e) => self.generate_combined_parameterized_agg(e),
2175 Expression::Commit(e) => self.generate_commit(e),
2176 Expression::Comprehension(e) => self.generate_comprehension(e),
2177 Expression::Compress(e) => self.generate_compress(e),
2178 Expression::CompressColumnConstraint(e) => self.generate_compress_column_constraint(e),
2179 Expression::ComputedColumnConstraint(e) => self.generate_computed_column_constraint(e),
2180 Expression::ConditionalInsert(e) => self.generate_conditional_insert(e),
2181 Expression::Constraint(e) => self.generate_constraint(e),
2182 Expression::ConvertTimezone(e) => self.generate_convert_timezone(e),
2183 Expression::ConvertToCharset(e) => self.generate_convert_to_charset(e),
2184 Expression::Copy(e) => self.generate_copy(e),
2185 Expression::CopyParameter(e) => self.generate_copy_parameter(e),
2186 Expression::Corr(e) => self.generate_corr(e),
2187 Expression::CosineDistance(e) => self.generate_cosine_distance(e),
2188 Expression::CovarPop(e) => self.generate_covar_pop(e),
2189 Expression::CovarSamp(e) => self.generate_covar_samp(e),
2190 Expression::Credentials(e) => self.generate_credentials(e),
2191 Expression::CredentialsProperty(e) => self.generate_credentials_property(e),
2192 Expression::Cte(e) => self.generate_cte(e),
2193 Expression::Cube(e) => self.generate_cube(e),
2194 Expression::CurrentDatetime(e) => self.generate_current_datetime(e),
2195 Expression::CurrentSchema(e) => self.generate_current_schema(e),
2196 Expression::CurrentSchemas(e) => self.generate_current_schemas(e),
2197 Expression::CurrentUser(e) => self.generate_current_user(e),
2198 Expression::DPipe(e) => self.generate_d_pipe(e),
2199 Expression::DataBlocksizeProperty(e) => self.generate_data_blocksize_property(e),
2200 Expression::DataDeletionProperty(e) => self.generate_data_deletion_property(e),
2201 Expression::Date(e) => self.generate_date_func(e),
2202 Expression::DateBin(e) => self.generate_date_bin(e),
2203 Expression::DateFormatColumnConstraint(e) => self.generate_date_format_column_constraint(e),
2204 Expression::DateFromParts(e) => self.generate_date_from_parts(e),
2205 Expression::Datetime(e) => self.generate_datetime(e),
2206 Expression::DatetimeAdd(e) => self.generate_datetime_add(e),
2207 Expression::DatetimeDiff(e) => self.generate_datetime_diff(e),
2208 Expression::DatetimeSub(e) => self.generate_datetime_sub(e),
2209 Expression::DatetimeTrunc(e) => self.generate_datetime_trunc(e),
2210 Expression::Dayname(e) => self.generate_dayname(e),
2211 Expression::Declare(e) => self.generate_declare(e),
2212 Expression::DeclareItem(e) => self.generate_declare_item(e),
2213 Expression::DecodeCase(e) => self.generate_decode_case(e),
2214 Expression::DecompressBinary(e) => self.generate_decompress_binary(e),
2215 Expression::DecompressString(e) => self.generate_decompress_string(e),
2216 Expression::Decrypt(e) => self.generate_decrypt(e),
2217 Expression::DecryptRaw(e) => self.generate_decrypt_raw(e),
2218 Expression::DefinerProperty(e) => self.generate_definer_property(e),
2219 Expression::Detach(e) => self.generate_detach(e),
2220 Expression::DictProperty(e) => self.generate_dict_property(e),
2221 Expression::DictRange(e) => self.generate_dict_range(e),
2222 Expression::Directory(e) => self.generate_directory(e),
2223 Expression::DistKeyProperty(e) => self.generate_dist_key_property(e),
2224 Expression::DistStyleProperty(e) => self.generate_dist_style_property(e),
2225 Expression::DistributeBy(e) => self.generate_distribute_by(e),
2226 Expression::DistributedByProperty(e) => self.generate_distributed_by_property(e),
2227 Expression::DotProduct(e) => self.generate_dot_product(e),
2228 Expression::DropPartition(e) => self.generate_drop_partition(e),
2229 Expression::DuplicateKeyProperty(e) => self.generate_duplicate_key_property(e),
2230 Expression::Elt(e) => self.generate_elt(e),
2231 Expression::Encode(e) => self.generate_encode(e),
2232 Expression::EncodeProperty(e) => self.generate_encode_property(e),
2233 Expression::Encrypt(e) => self.generate_encrypt(e),
2234 Expression::EncryptRaw(e) => self.generate_encrypt_raw(e),
2235 Expression::EngineProperty(e) => self.generate_engine_property(e),
2236 Expression::EnviromentProperty(e) => self.generate_enviroment_property(e),
2237 Expression::EphemeralColumnConstraint(e) => self.generate_ephemeral_column_constraint(e),
2238 Expression::EqualNull(e) => self.generate_equal_null(e),
2239 Expression::EuclideanDistance(e) => self.generate_euclidean_distance(e),
2240 Expression::ExecuteAsProperty(e) => self.generate_execute_as_property(e),
2241 Expression::Export(e) => self.generate_export(e),
2242 Expression::ExternalProperty(e) => self.generate_external_property(e),
2243 Expression::FallbackProperty(e) => self.generate_fallback_property(e),
2244 Expression::FarmFingerprint(e) => self.generate_farm_fingerprint(e),
2245 Expression::FeaturesAtTime(e) => self.generate_features_at_time(e),
2246 Expression::Fetch(e) => self.generate_fetch(e),
2247 Expression::FileFormatProperty(e) => self.generate_file_format_property(e),
2248 Expression::Filter(e) => self.generate_filter(e),
2249 Expression::Float64(e) => self.generate_float64(e),
2250 Expression::ForIn(e) => self.generate_for_in(e),
2251 Expression::ForeignKey(e) => self.generate_foreign_key(e),
2252 Expression::Format(e) => self.generate_format(e),
2253 Expression::FormatPhrase(e) => self.generate_format_phrase(e),
2254 Expression::FreespaceProperty(e) => self.generate_freespace_property(e),
2255 Expression::From(e) => self.generate_from(e),
2256 Expression::FromBase(e) => self.generate_from_base(e),
2257 Expression::FromTimeZone(e) => self.generate_from_time_zone(e),
2258 Expression::GapFill(e) => self.generate_gap_fill(e),
2259 Expression::GenerateDateArray(e) => self.generate_generate_date_array(e),
2260 Expression::GenerateEmbedding(e) => self.generate_generate_embedding(e),
2261 Expression::GenerateSeries(e) => self.generate_generate_series(e),
2262 Expression::GenerateTimestampArray(e) => self.generate_generate_timestamp_array(e),
2263 Expression::GeneratedAsIdentityColumnConstraint(e) => self.generate_generated_as_identity_column_constraint(e),
2264 Expression::GeneratedAsRowColumnConstraint(e) => self.generate_generated_as_row_column_constraint(e),
2265 Expression::Get(e) => self.generate_get(e),
2266 Expression::GetExtract(e) => self.generate_get_extract(e),
2267 Expression::Getbit(e) => self.generate_getbit(e),
2268 Expression::GrantPrincipal(e) => self.generate_grant_principal(e),
2269 Expression::GrantPrivilege(e) => self.generate_grant_privilege(e),
2270 Expression::Group(e) => self.generate_group(e),
2271 Expression::GroupBy(e) => self.generate_group_by(e),
2272 Expression::Grouping(e) => self.generate_grouping(e),
2273 Expression::GroupingId(e) => self.generate_grouping_id(e),
2274 Expression::GroupingSets(e) => self.generate_grouping_sets(e),
2275 Expression::HashAgg(e) => self.generate_hash_agg(e),
2276 Expression::Having(e) => self.generate_having(e),
2277 Expression::HavingMax(e) => self.generate_having_max(e),
2278 Expression::Heredoc(e) => self.generate_heredoc(e),
2279 Expression::HexEncode(e) => self.generate_hex_encode(e),
2280 Expression::Hll(e) => self.generate_hll(e),
2281 Expression::InOutColumnConstraint(e) => self.generate_in_out_column_constraint(e),
2282 Expression::IncludeProperty(e) => self.generate_include_property(e),
2283 Expression::Index(e) => self.generate_index(e),
2284 Expression::IndexColumnConstraint(e) => self.generate_index_column_constraint(e),
2285 Expression::IndexConstraintOption(e) => self.generate_index_constraint_option(e),
2286 Expression::IndexParameters(e) => self.generate_index_parameters(e),
2287 Expression::IndexTableHint(e) => self.generate_index_table_hint(e),
2288 Expression::InheritsProperty(e) => self.generate_inherits_property(e),
2289 Expression::InputModelProperty(e) => self.generate_input_model_property(e),
2290 Expression::InputOutputFormat(e) => self.generate_input_output_format(e),
2291 Expression::Install(e) => self.generate_install(e),
2292 Expression::IntervalOp(e) => self.generate_interval_op(e),
2293 Expression::IntervalSpan(e) => self.generate_interval_span(e),
2294 Expression::IntoClause(e) => self.generate_into_clause(e),
2295 Expression::Introducer(e) => self.generate_introducer(e),
2296 Expression::IsolatedLoadingProperty(e) => self.generate_isolated_loading_property(e),
2297 Expression::JSON(e) => self.generate_json(e),
2298 Expression::JSONArray(e) => self.generate_json_array(e),
2299 Expression::JSONArrayAgg(e) => self.generate_json_array_agg_struct(e),
2300 Expression::JSONArrayAppend(e) => self.generate_json_array_append(e),
2301 Expression::JSONArrayContains(e) => self.generate_json_array_contains(e),
2302 Expression::JSONArrayInsert(e) => self.generate_json_array_insert(e),
2303 Expression::JSONBExists(e) => self.generate_jsonb_exists(e),
2304 Expression::JSONBExtractScalar(e) => self.generate_jsonb_extract_scalar(e),
2305 Expression::JSONBObjectAgg(e) => self.generate_jsonb_object_agg(e),
2306 Expression::JSONObjectAgg(e) => self.generate_json_object_agg_struct(e),
2307 Expression::JSONColumnDef(e) => self.generate_json_column_def(e),
2308 Expression::JSONExists(e) => self.generate_json_exists(e),
2309 Expression::JSONCast(e) => self.generate_json_cast(e),
2310 Expression::JSONExtract(e) => self.generate_json_extract_path(e),
2311 Expression::JSONExtractArray(e) => self.generate_json_extract_array(e),
2312 Expression::JSONExtractQuote(e) => self.generate_json_extract_quote(e),
2313 Expression::JSONExtractScalar(e) => self.generate_json_extract_scalar(e),
2314 Expression::JSONFormat(e) => self.generate_json_format(e),
2315 Expression::JSONKeyValue(e) => self.generate_json_key_value(e),
2316 Expression::JSONKeys(e) => self.generate_json_keys(e),
2317 Expression::JSONKeysAtDepth(e) => self.generate_json_keys_at_depth(e),
2318 Expression::JSONPath(e) => self.generate_json_path_expr(e),
2319 Expression::JSONPathFilter(e) => self.generate_json_path_filter(e),
2320 Expression::JSONPathKey(e) => self.generate_json_path_key(e),
2321 Expression::JSONPathRecursive(e) => self.generate_json_path_recursive(e),
2322 Expression::JSONPathRoot(_) => self.generate_json_path_root(),
2323 Expression::JSONPathScript(e) => self.generate_json_path_script(e),
2324 Expression::JSONPathSelector(e) => self.generate_json_path_selector(e),
2325 Expression::JSONPathSlice(e) => self.generate_json_path_slice(e),
2326 Expression::JSONPathSubscript(e) => self.generate_json_path_subscript(e),
2327 Expression::JSONPathUnion(e) => self.generate_json_path_union(e),
2328 Expression::JSONRemove(e) => self.generate_json_remove(e),
2329 Expression::JSONSchema(e) => self.generate_json_schema(e),
2330 Expression::JSONSet(e) => self.generate_json_set(e),
2331 Expression::JSONStripNulls(e) => self.generate_json_strip_nulls(e),
2332 Expression::JSONTable(e) => self.generate_json_table(e),
2333 Expression::JSONType(e) => self.generate_json_type(e),
2334 Expression::JSONValue(e) => self.generate_json_value(e),
2335 Expression::JSONValueArray(e) => self.generate_json_value_array(e),
2336 Expression::JarowinklerSimilarity(e) => self.generate_jarowinkler_similarity(e),
2337 Expression::JoinHint(e) => self.generate_join_hint(e),
2338 Expression::JournalProperty(e) => self.generate_journal_property(e),
2339 Expression::LanguageProperty(e) => self.generate_language_property(e),
2340 Expression::Lateral(e) => self.generate_lateral(e),
2341 Expression::LikeProperty(e) => self.generate_like_property(e),
2342 Expression::Limit(e) => self.generate_limit(e),
2343 Expression::LimitOptions(e) => self.generate_limit_options(e),
2344 Expression::List(e) => self.generate_list(e),
2345 Expression::ToMap(e) => self.generate_tomap(e),
2346 Expression::Localtime(e) => self.generate_localtime(e),
2347 Expression::Localtimestamp(e) => self.generate_localtimestamp(e),
2348 Expression::LocationProperty(e) => self.generate_location_property(e),
2349 Expression::Lock(e) => self.generate_lock(e),
2350 Expression::LockProperty(e) => self.generate_lock_property(e),
2351 Expression::LockingProperty(e) => self.generate_locking_property(e),
2352 Expression::LockingStatement(e) => self.generate_locking_statement(e),
2353 Expression::LogProperty(e) => self.generate_log_property(e),
2354 Expression::MD5Digest(e) => self.generate_md5_digest(e),
2355 Expression::MLForecast(e) => self.generate_ml_forecast(e),
2356 Expression::MLTranslate(e) => self.generate_ml_translate(e),
2357 Expression::MakeInterval(e) => self.generate_make_interval(e),
2358 Expression::ManhattanDistance(e) => self.generate_manhattan_distance(e),
2359 Expression::Map(e) => self.generate_map(e),
2360 Expression::MapCat(e) => self.generate_map_cat(e),
2361 Expression::MapDelete(e) => self.generate_map_delete(e),
2362 Expression::MapInsert(e) => self.generate_map_insert(e),
2363 Expression::MapPick(e) => self.generate_map_pick(e),
2364 Expression::MaskingPolicyColumnConstraint(e) => self.generate_masking_policy_column_constraint(e),
2365 Expression::MatchAgainst(e) => self.generate_match_against(e),
2366 Expression::MatchRecognizeMeasure(e) => self.generate_match_recognize_measure(e),
2367 Expression::MaterializedProperty(e) => self.generate_materialized_property(e),
2368 Expression::Merge(e) => self.generate_merge(e),
2369 Expression::MergeBlockRatioProperty(e) => self.generate_merge_block_ratio_property(e),
2370 Expression::MergeTreeTTL(e) => self.generate_merge_tree_ttl(e),
2371 Expression::MergeTreeTTLAction(e) => self.generate_merge_tree_ttl_action(e),
2372 Expression::Minhash(e) => self.generate_minhash(e),
2373 Expression::ModelAttribute(e) => self.generate_model_attribute(e),
2374 Expression::Monthname(e) => self.generate_monthname(e),
2375 Expression::MultitableInserts(e) => self.generate_multitable_inserts(e),
2376 Expression::NextValueFor(e) => self.generate_next_value_for(e),
2377 Expression::Normal(e) => self.generate_normal(e),
2378 Expression::Normalize(e) => self.generate_normalize(e),
2379 Expression::NotNullColumnConstraint(e) => self.generate_not_null_column_constraint(e),
2380 Expression::Nullif(e) => self.generate_nullif(e),
2381 Expression::NumberToStr(e) => self.generate_number_to_str(e),
2382 Expression::ObjectAgg(e) => self.generate_object_agg(e),
2383 Expression::ObjectIdentifier(e) => self.generate_object_identifier(e),
2384 Expression::ObjectInsert(e) => self.generate_object_insert(e),
2385 Expression::Offset(e) => self.generate_offset(e),
2386 Expression::Qualify(e) => self.generate_qualify(e),
2387 Expression::OnCluster(e) => self.generate_on_cluster(e),
2388 Expression::OnCommitProperty(e) => self.generate_on_commit_property(e),
2389 Expression::OnCondition(e) => self.generate_on_condition(e),
2390 Expression::OnConflict(e) => self.generate_on_conflict(e),
2391 Expression::OnProperty(e) => self.generate_on_property(e),
2392 Expression::Opclass(e) => self.generate_opclass(e),
2393 Expression::OpenJSON(e) => self.generate_open_json(e),
2394 Expression::OpenJSONColumnDef(e) => self.generate_open_json_column_def(e),
2395 Expression::Operator(e) => self.generate_operator(e),
2396 Expression::OrderBy(e) => self.generate_order_by(e),
2397 Expression::OutputModelProperty(e) => self.generate_output_model_property(e),
2398 Expression::OverflowTruncateBehavior(e) => self.generate_overflow_truncate_behavior(e),
2399 Expression::ParameterizedAgg(e) => self.generate_parameterized_agg(e),
2400 Expression::ParseDatetime(e) => self.generate_parse_datetime(e),
2401 Expression::ParseIp(e) => self.generate_parse_ip(e),
2402 Expression::ParseJSON(e) => self.generate_parse_json(e),
2403 Expression::ParseTime(e) => self.generate_parse_time(e),
2404 Expression::ParseUrl(e) => self.generate_parse_url(e),
2405 Expression::Partition(e) => self.generate_partition_expr(e),
2406 Expression::PartitionBoundSpec(e) => self.generate_partition_bound_spec(e),
2407 Expression::PartitionByListProperty(e) => self.generate_partition_by_list_property(e),
2408 Expression::PartitionByRangeProperty(e) => self.generate_partition_by_range_property(e),
2409 Expression::PartitionByRangePropertyDynamic(e) => self.generate_partition_by_range_property_dynamic(e),
2410 Expression::PartitionByTruncate(e) => self.generate_partition_by_truncate(e),
2411 Expression::PartitionList(e) => self.generate_partition_list(e),
2412 Expression::PartitionRange(e) => self.generate_partition_range(e),
2413 Expression::PartitionedByBucket(e) => self.generate_partitioned_by_bucket(e),
2414 Expression::PartitionedByProperty(e) => self.generate_partitioned_by_property(e),
2415 Expression::PartitionedOfProperty(e) => self.generate_partitioned_of_property(e),
2416 Expression::PeriodForSystemTimeConstraint(e) => self.generate_period_for_system_time_constraint(e),
2417 Expression::PivotAlias(e) => self.generate_pivot_alias(e),
2418 Expression::PivotAny(e) => self.generate_pivot_any(e),
2419 Expression::Predict(e) => self.generate_predict(e),
2420 Expression::PreviousDay(e) => self.generate_previous_day(e),
2421 Expression::PrimaryKey(e) => self.generate_primary_key(e),
2422 Expression::PrimaryKeyColumnConstraint(e) => self.generate_primary_key_column_constraint(e),
2423 Expression::PathColumnConstraint(e) => self.generate_path_column_constraint(e),
2424 Expression::ProjectionDef(e) => self.generate_projection_def(e),
2425 Expression::Properties(e) => self.generate_properties(e),
2426 Expression::Property(e) => self.generate_property(e),
2427 Expression::PseudoType(e) => self.generate_pseudo_type(e),
2428 Expression::Put(e) => self.generate_put(e),
2429 Expression::Quantile(e) => self.generate_quantile(e),
2430 Expression::QueryBand(e) => self.generate_query_band(e),
2431 Expression::QueryOption(e) => self.generate_query_option(e),
2432 Expression::QueryTransform(e) => self.generate_query_transform(e),
2433 Expression::Randn(e) => self.generate_randn(e),
2434 Expression::Randstr(e) => self.generate_randstr(e),
2435 Expression::RangeBucket(e) => self.generate_range_bucket(e),
2436 Expression::RangeN(e) => self.generate_range_n(e),
2437 Expression::ReadCSV(e) => self.generate_read_csv(e),
2438 Expression::ReadParquet(e) => self.generate_read_parquet(e),
2439 Expression::RecursiveWithSearch(e) => self.generate_recursive_with_search(e),
2440 Expression::Reduce(e) => self.generate_reduce(e),
2441 Expression::Reference(e) => self.generate_reference(e),
2442 Expression::Refresh(e) => self.generate_refresh(e),
2443 Expression::RefreshTriggerProperty(e) => self.generate_refresh_trigger_property(e),
2444 Expression::RegexpCount(e) => self.generate_regexp_count(e),
2445 Expression::RegexpExtractAll(e) => self.generate_regexp_extract_all(e),
2446 Expression::RegexpFullMatch(e) => self.generate_regexp_full_match(e),
2447 Expression::RegexpILike(e) => self.generate_regexp_i_like(e),
2448 Expression::RegexpInstr(e) => self.generate_regexp_instr(e),
2449 Expression::RegexpSplit(e) => self.generate_regexp_split(e),
2450 Expression::RegrAvgx(e) => self.generate_regr_avgx(e),
2451 Expression::RegrAvgy(e) => self.generate_regr_avgy(e),
2452 Expression::RegrCount(e) => self.generate_regr_count(e),
2453 Expression::RegrIntercept(e) => self.generate_regr_intercept(e),
2454 Expression::RegrR2(e) => self.generate_regr_r2(e),
2455 Expression::RegrSlope(e) => self.generate_regr_slope(e),
2456 Expression::RegrSxx(e) => self.generate_regr_sxx(e),
2457 Expression::RegrSxy(e) => self.generate_regr_sxy(e),
2458 Expression::RegrSyy(e) => self.generate_regr_syy(e),
2459 Expression::RegrValx(e) => self.generate_regr_valx(e),
2460 Expression::RegrValy(e) => self.generate_regr_valy(e),
2461 Expression::RemoteWithConnectionModelProperty(e) => self.generate_remote_with_connection_model_property(e),
2462 Expression::RenameColumn(e) => self.generate_rename_column(e),
2463 Expression::ReplacePartition(e) => self.generate_replace_partition(e),
2464 Expression::Returning(e) => self.generate_returning(e),
2465 Expression::ReturnsProperty(e) => self.generate_returns_property(e),
2466 Expression::Rollback(e) => self.generate_rollback(e),
2467 Expression::Rollup(e) => self.generate_rollup(e),
2468 Expression::RowFormatDelimitedProperty(e) => self.generate_row_format_delimited_property(e),
2469 Expression::RowFormatProperty(e) => self.generate_row_format_property(e),
2470 Expression::RowFormatSerdeProperty(e) => self.generate_row_format_serde_property(e),
2471 Expression::SHA2(e) => self.generate_sha2(e),
2472 Expression::SHA2Digest(e) => self.generate_sha2_digest(e),
2473 Expression::SafeAdd(e) => self.generate_safe_add(e),
2474 Expression::SafeDivide(e) => self.generate_safe_divide(e),
2475 Expression::SafeMultiply(e) => self.generate_safe_multiply(e),
2476 Expression::SafeSubtract(e) => self.generate_safe_subtract(e),
2477 Expression::SampleProperty(e) => self.generate_sample_property(e),
2478 Expression::Schema(e) => self.generate_schema(e),
2479 Expression::SchemaCommentProperty(e) => self.generate_schema_comment_property(e),
2480 Expression::ScopeResolution(e) => self.generate_scope_resolution(e),
2481 Expression::Search(e) => self.generate_search(e),
2482 Expression::SearchIp(e) => self.generate_search_ip(e),
2483 Expression::SecurityProperty(e) => self.generate_security_property(e),
2484 Expression::SemanticView(e) => self.generate_semantic_view(e),
2485 Expression::SequenceProperties(e) => self.generate_sequence_properties(e),
2486 Expression::SerdeProperties(e) => self.generate_serde_properties(e),
2487 Expression::SessionParameter(e) => self.generate_session_parameter(e),
2488 Expression::Set(e) => self.generate_set(e),
2489 Expression::SetConfigProperty(e) => self.generate_set_config_property(e),
2490 Expression::SetItem(e) => self.generate_set_item(e),
2491 Expression::SetOperation(e) => self.generate_set_operation(e),
2492 Expression::SetProperty(e) => self.generate_set_property(e),
2493 Expression::SettingsProperty(e) => self.generate_settings_property(e),
2494 Expression::SharingProperty(e) => self.generate_sharing_property(e),
2495 Expression::Slice(e) => self.generate_slice(e),
2496 Expression::SortArray(e) => self.generate_sort_array(e),
2497 Expression::SortBy(e) => self.generate_sort_by(e),
2498 Expression::SortKeyProperty(e) => self.generate_sort_key_property(e),
2499 Expression::SplitPart(e) => self.generate_split_part(e),
2500 Expression::SqlReadWriteProperty(e) => self.generate_sql_read_write_property(e),
2501 Expression::SqlSecurityProperty(e) => self.generate_sql_security_property(e),
2502 Expression::StDistance(e) => self.generate_st_distance(e),
2503 Expression::StPoint(e) => self.generate_st_point(e),
2504 Expression::StabilityProperty(e) => self.generate_stability_property(e),
2505 Expression::StandardHash(e) => self.generate_standard_hash(e),
2506 Expression::StorageHandlerProperty(e) => self.generate_storage_handler_property(e),
2507 Expression::StrPosition(e) => self.generate_str_position(e),
2508 Expression::StrToDate(e) => self.generate_str_to_date(e),
2509 Expression::DateStrToDate(f) => self.generate_simple_func("DATE_STR_TO_DATE", &f.this),
2510 Expression::DateToDateStr(f) => self.generate_simple_func("DATE_TO_DATE_STR", &f.this),
2511 Expression::StrToMap(e) => self.generate_str_to_map(e),
2512 Expression::StrToTime(e) => self.generate_str_to_time(e),
2513 Expression::StrToUnix(e) => self.generate_str_to_unix(e),
2514 Expression::StringToArray(e) => self.generate_string_to_array(e),
2515 Expression::Struct(e) => self.generate_struct(e),
2516 Expression::Stuff(e) => self.generate_stuff(e),
2517 Expression::SubstringIndex(e) => self.generate_substring_index(e),
2518 Expression::Summarize(e) => self.generate_summarize(e),
2519 Expression::Systimestamp(e) => self.generate_systimestamp(e),
2520 Expression::TableAlias(e) => self.generate_table_alias(e),
2521 Expression::TableFromRows(e) => self.generate_table_from_rows(e),
2522 Expression::RowsFrom(e) => self.generate_rows_from(e),
2523 Expression::TableSample(e) => self.generate_table_sample(e),
2524 Expression::Tag(e) => self.generate_tag(e),
2525 Expression::Tags(e) => self.generate_tags(e),
2526 Expression::TemporaryProperty(e) => self.generate_temporary_property(e),
2527 Expression::Time(e) => self.generate_time_func(e),
2528 Expression::TimeAdd(e) => self.generate_time_add(e),
2529 Expression::TimeDiff(e) => self.generate_time_diff(e),
2530 Expression::TimeFromParts(e) => self.generate_time_from_parts(e),
2531 Expression::TimeSlice(e) => self.generate_time_slice(e),
2532 Expression::TimeStrToTime(e) => self.generate_time_str_to_time(e),
2533 Expression::TimeSub(e) => self.generate_time_sub(e),
2534 Expression::TimeToStr(e) => self.generate_time_to_str(e),
2535 Expression::TimeTrunc(e) => self.generate_time_trunc(e),
2536 Expression::TimeUnit(e) => self.generate_time_unit(e),
2537 Expression::Timestamp(e) => self.generate_timestamp_func(e),
2538 Expression::TimestampAdd(e) => self.generate_timestamp_add(e),
2539 Expression::TimestampDiff(e) => self.generate_timestamp_diff(e),
2540 Expression::TimestampFromParts(e) => self.generate_timestamp_from_parts(e),
2541 Expression::TimestampSub(e) => self.generate_timestamp_sub(e),
2542 Expression::TimestampTzFromParts(e) => self.generate_timestamp_tz_from_parts(e),
2543 Expression::ToBinary(e) => self.generate_to_binary(e),
2544 Expression::ToBoolean(e) => self.generate_to_boolean(e),
2545 Expression::ToChar(e) => self.generate_to_char(e),
2546 Expression::ToDecfloat(e) => self.generate_to_decfloat(e),
2547 Expression::ToDouble(e) => self.generate_to_double(e),
2548 Expression::ToFile(e) => self.generate_to_file(e),
2549 Expression::ToNumber(e) => self.generate_to_number(e),
2550 Expression::ToTableProperty(e) => self.generate_to_table_property(e),
2551 Expression::Transaction(e) => self.generate_transaction(e),
2552 Expression::Transform(e) => self.generate_transform(e),
2553 Expression::TransformModelProperty(e) => self.generate_transform_model_property(e),
2554 Expression::TransientProperty(e) => self.generate_transient_property(e),
2555 Expression::Translate(e) => self.generate_translate(e),
2556 Expression::TranslateCharacters(e) => self.generate_translate_characters(e),
2557 Expression::TruncateTable(e) => self.generate_truncate_table(e),
2558 Expression::TryBase64DecodeBinary(e) => self.generate_try_base64_decode_binary(e),
2559 Expression::TryBase64DecodeString(e) => self.generate_try_base64_decode_string(e),
2560 Expression::TryToDecfloat(e) => self.generate_try_to_decfloat(e),
2561 Expression::TsOrDsAdd(e) => self.generate_ts_or_ds_add(e),
2562 Expression::TsOrDsDiff(e) => self.generate_ts_or_ds_diff(e),
2563 Expression::TsOrDsToDate(e) => self.generate_ts_or_ds_to_date(e),
2564 Expression::TsOrDsToTime(e) => self.generate_ts_or_ds_to_time(e),
2565 Expression::Unhex(e) => self.generate_unhex(e),
2566 Expression::UnicodeString(e) => self.generate_unicode_string(e),
2567 Expression::Uniform(e) => self.generate_uniform(e),
2568 Expression::UniqueColumnConstraint(e) => self.generate_unique_column_constraint(e),
2569 Expression::UniqueKeyProperty(e) => self.generate_unique_key_property(e),
2570 Expression::RollupProperty(e) => self.generate_rollup_property(e),
2571 Expression::UnixToStr(e) => self.generate_unix_to_str(e),
2572 Expression::UnixToTime(e) => self.generate_unix_to_time(e),
2573 Expression::UnpivotColumns(e) => self.generate_unpivot_columns(e),
2574 Expression::UserDefinedFunction(e) => self.generate_user_defined_function(e),
2575 Expression::UsingTemplateProperty(e) => self.generate_using_template_property(e),
2576 Expression::UtcTime(e) => self.generate_utc_time(e),
2577 Expression::UtcTimestamp(e) => self.generate_utc_timestamp(e),
2578 Expression::Uuid(e) => self.generate_uuid(e),
2579 Expression::Var(v) => {
2580 if matches!(self.config.dialect, Some(DialectType::MySQL))
2581 && v.this.len() > 2
2582 && (v.this.starts_with("0x") || v.this.starts_with("0X"))
2583 && !v.this[2..].chars().all(|c| c.is_ascii_hexdigit())
2584 {
2585 return self.generate_identifier(&Identifier {
2586 name: v.this.clone(),
2587 quoted: true,
2588 trailing_comments: Vec::new(),
2589 });
2590 }
2591 self.write(&v.this);
2592 Ok(())
2593 }
2594 Expression::VarMap(e) => self.generate_var_map(e),
2595 Expression::VectorSearch(e) => self.generate_vector_search(e),
2596 Expression::Version(e) => self.generate_version(e),
2597 Expression::ViewAttributeProperty(e) => self.generate_view_attribute_property(e),
2598 Expression::VolatileProperty(e) => self.generate_volatile_property(e),
2599 Expression::WatermarkColumnConstraint(e) => self.generate_watermark_column_constraint(e),
2600 Expression::Week(e) => self.generate_week(e),
2601 Expression::When(e) => self.generate_when(e),
2602 Expression::Whens(e) => self.generate_whens(e),
2603 Expression::Where(e) => self.generate_where(e),
2604 Expression::WidthBucket(e) => self.generate_width_bucket(e),
2605 Expression::Window(e) => self.generate_window(e),
2606 Expression::WindowSpec(e) => self.generate_window_spec(e),
2607 Expression::WithDataProperty(e) => self.generate_with_data_property(e),
2608 Expression::WithFill(e) => self.generate_with_fill(e),
2609 Expression::WithJournalTableProperty(e) => self.generate_with_journal_table_property(e),
2610 Expression::WithOperator(e) => self.generate_with_operator(e),
2611 Expression::WithProcedureOptions(e) => self.generate_with_procedure_options(e),
2612 Expression::WithSchemaBindingProperty(e) => self.generate_with_schema_binding_property(e),
2613 Expression::WithSystemVersioningProperty(e) => self.generate_with_system_versioning_property(e),
2614 Expression::WithTableHint(e) => self.generate_with_table_hint(e),
2615 Expression::XMLElement(e) => self.generate_xml_element(e),
2616 Expression::XMLGet(e) => self.generate_xml_get(e),
2617 Expression::XMLKeyValueOption(e) => self.generate_xml_key_value_option(e),
2618 Expression::XMLTable(e) => self.generate_xml_table(e),
2619 Expression::Xor(e) => self.generate_xor(e),
2620 Expression::Zipf(e) => self.generate_zipf(e),
2621 _ => {
2622 self.write(&format!("/* unimplemented: {:?} */", expr));
2624 Ok(())
2625 }
2626 }
2627 }
2628
2629 fn generate_select(&mut self, select: &Select) -> Result<()> {
2630 use crate::dialects::DialectType;
2631
2632 for comment in &select.leading_comments {
2634 self.write_formatted_comment(comment);
2635 self.write(" ");
2636 }
2637
2638 if let Some(with) = &select.with {
2640 self.generate_with(with)?;
2641 if self.config.pretty {
2642 self.write_newline();
2643 self.write_indent();
2644 } else {
2645 self.write_space();
2646 }
2647 }
2648
2649 for comment in &select.post_select_comments {
2652 self.write_formatted_comment(comment);
2653 self.write(" ");
2654 }
2655
2656 self.write_keyword("SELECT");
2657
2658 if let Some(hint) = &select.hint {
2660 self.generate_hint(hint)?;
2661 }
2662
2663 let use_top_from_limit = matches!(self.config.dialect, Some(DialectType::TSQL))
2667 && select.top.is_none()
2668 && select.limit.is_some()
2669 && select.offset.is_none(); let is_top_dialect = matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Teradata) | Some(DialectType::Fabric));
2674
2675 if select.distinct && (is_top_dialect || select.top.is_some()) {
2676 self.write_space();
2677 self.write_keyword("DISTINCT");
2678 }
2679
2680 if is_top_dialect {
2681 if let Some(top) = &select.top {
2682 self.write_space();
2683 self.write_keyword("TOP");
2684 if top.parenthesized {
2685 self.write(" (");
2686 self.generate_expression(&top.this)?;
2687 self.write(")");
2688 } else {
2689 self.write_space();
2690 self.generate_expression(&top.this)?;
2691 }
2692 if top.percent {
2693 self.write_space();
2694 self.write_keyword("PERCENT");
2695 }
2696 if top.with_ties {
2697 self.write_space();
2698 self.write_keyword("WITH TIES");
2699 }
2700 } else if use_top_from_limit {
2701 if let Some(limit) = &select.limit {
2703 self.write_space();
2704 self.write_keyword("TOP");
2705 let is_simple_literal = matches!(&limit.this, Expression::Literal(Literal::Number(_)));
2707 if is_simple_literal {
2708 self.write_space();
2709 self.generate_expression(&limit.this)?;
2710 } else {
2711 self.write(" (");
2712 self.generate_expression(&limit.this)?;
2713 self.write(")");
2714 }
2715 }
2716 }
2717 }
2718
2719 if select.distinct && !is_top_dialect && select.top.is_none() {
2720 self.write_space();
2721 self.write_keyword("DISTINCT");
2722 }
2723
2724 if let Some(distinct_on) = &select.distinct_on {
2726 self.write_space();
2727 self.write_keyword("ON");
2728 self.write(" (");
2729 for (i, expr) in distinct_on.iter().enumerate() {
2730 if i > 0 {
2731 self.write(", ");
2732 }
2733 self.generate_expression(expr)?;
2734 }
2735 self.write(")");
2736 }
2737
2738 for modifier in &select.operation_modifiers {
2740 self.write_space();
2741 self.write_keyword(modifier);
2742 }
2743
2744 if let Some(kind) = &select.kind {
2746 self.write_space();
2747 self.write_keyword("AS");
2748 self.write_space();
2749 self.write_keyword(kind);
2750 }
2751
2752 if !select.expressions.is_empty() {
2754 if self.config.pretty {
2755 self.write_newline();
2756 self.indent_level += 1;
2757 } else {
2758 self.write_space();
2759 }
2760 }
2761
2762 for (i, expr) in select.expressions.iter().enumerate() {
2763 if i > 0 {
2764 self.write(",");
2765 if self.config.pretty {
2766 self.write_newline();
2767 } else {
2768 self.write_space();
2769 }
2770 }
2771 if self.config.pretty {
2772 self.write_indent();
2773 }
2774 self.generate_expression(expr)?;
2775 }
2776
2777 if self.config.pretty && !select.expressions.is_empty() {
2778 self.indent_level -= 1;
2779 }
2780
2781 if let Some(into) = &select.into {
2784 if self.config.pretty {
2785 self.write_newline();
2786 self.write_indent();
2787 } else {
2788 self.write_space();
2789 }
2790 if into.bulk_collect {
2791 self.write_keyword("BULK COLLECT INTO");
2792 } else {
2793 self.write_keyword("INTO");
2794 }
2795 if into.temporary {
2796 self.write_space();
2797 self.write_keyword("TEMPORARY");
2798 }
2799 if into.unlogged {
2800 self.write_space();
2801 self.write_keyword("UNLOGGED");
2802 }
2803 self.write_space();
2804 if !into.expressions.is_empty() {
2806 for (i, expr) in into.expressions.iter().enumerate() {
2807 if i > 0 {
2808 self.write(", ");
2809 }
2810 self.generate_expression(expr)?;
2811 }
2812 } else {
2813 self.generate_expression(&into.this)?;
2814 }
2815 }
2816
2817 if let Some(from) = &select.from {
2819 if self.config.pretty {
2820 self.write_newline();
2821 self.write_indent();
2822 } else {
2823 self.write_space();
2824 }
2825 self.write_keyword("FROM");
2826 self.write_space();
2827
2828 let has_tablesample = from.expressions.iter().any(|e| matches!(e, Expression::TableSample(_)));
2831 let use_cross_join = !has_tablesample && matches!(
2832 self.config.dialect,
2833 Some(DialectType::BigQuery)
2834 | Some(DialectType::Hive)
2835 | Some(DialectType::Spark)
2836 | Some(DialectType::Databricks)
2837 | Some(DialectType::SQLite)
2838 | Some(DialectType::ClickHouse)
2839 );
2840
2841 let wrap_values_in_parens = matches!(
2843 self.config.dialect,
2844 Some(DialectType::Snowflake)
2845 );
2846
2847 for (i, expr) in from.expressions.iter().enumerate() {
2848 if i > 0 {
2849 if use_cross_join {
2850 self.write(" CROSS JOIN ");
2851 } else {
2852 self.write(", ");
2853 }
2854 }
2855 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
2856 self.write("(");
2857 self.generate_expression(expr)?;
2858 self.write(")");
2859 } else {
2860 self.generate_expression(expr)?;
2861 }
2862 }
2863 }
2864
2865 for join in &select.joins {
2867 self.generate_join(join)?;
2868 }
2869
2870 for join in select.joins.iter().rev() {
2873 if join.deferred_condition {
2874 self.generate_join_condition(join)?;
2875 }
2876 }
2877
2878 for lateral_view in &select.lateral_views {
2880 self.generate_lateral_view(lateral_view)?;
2881 }
2882
2883 if let Some(prewhere) = &select.prewhere {
2885 self.write_clause_condition("PREWHERE", prewhere)?;
2886 }
2887
2888 if let Some(where_clause) = &select.where_clause {
2890 self.write_clause_condition("WHERE", &where_clause.this)?;
2891 }
2892
2893 if let Some(connect) = &select.connect {
2895 self.generate_connect(connect)?;
2896 }
2897
2898 if let Some(group_by) = &select.group_by {
2900 if self.config.pretty {
2901 self.write_newline();
2902 self.write_indent();
2903 } else {
2904 self.write_space();
2905 }
2906 self.write_keyword("GROUP BY");
2907 match group_by.all {
2909 Some(true) => {
2910 self.write_space();
2911 self.write_keyword("ALL");
2912 }
2913 Some(false) => {
2914 self.write_space();
2915 self.write_keyword("DISTINCT");
2916 }
2917 None => {}
2918 }
2919 if !group_by.expressions.is_empty() {
2920 let mut trailing_cube = false;
2923 let mut trailing_rollup = false;
2924 let mut plain_expressions: Vec<&Expression> = Vec::new();
2925 let mut grouping_sets_expressions: Vec<&Expression> = Vec::new();
2926 let mut cube_expressions: Vec<&Expression> = Vec::new();
2927 let mut rollup_expressions: Vec<&Expression> = Vec::new();
2928
2929 for expr in &group_by.expressions {
2930 match expr {
2931 Expression::Cube(c) if c.expressions.is_empty() => {
2932 trailing_cube = true;
2933 }
2934 Expression::Rollup(r) if r.expressions.is_empty() => {
2935 trailing_rollup = true;
2936 }
2937 Expression::Function(f) if f.name == "CUBE" => {
2938 cube_expressions.push(expr);
2939 }
2940 Expression::Function(f) if f.name == "ROLLUP" => {
2941 rollup_expressions.push(expr);
2942 }
2943 Expression::Function(f) if f.name == "GROUPING SETS" => {
2944 grouping_sets_expressions.push(expr);
2945 }
2946 _ => {
2947 plain_expressions.push(expr);
2948 }
2949 }
2950 }
2951
2952 let mut regular_expressions: Vec<&Expression> = Vec::new();
2954 regular_expressions.extend(plain_expressions);
2955 regular_expressions.extend(grouping_sets_expressions);
2956 regular_expressions.extend(cube_expressions);
2957 regular_expressions.extend(rollup_expressions);
2958
2959 if self.config.pretty {
2960 self.write_newline();
2961 self.indent_level += 1;
2962 self.write_indent();
2963 } else {
2964 self.write_space();
2965 }
2966
2967 for (i, expr) in regular_expressions.iter().enumerate() {
2968 if i > 0 {
2969 self.write(", ");
2970 }
2971 self.generate_expression(expr)?;
2972 }
2973
2974 if self.config.pretty {
2975 self.indent_level -= 1;
2976 }
2977
2978 if trailing_cube {
2980 self.write_space();
2981 self.write_keyword("WITH CUBE");
2982 } else if trailing_rollup {
2983 self.write_space();
2984 self.write_keyword("WITH ROLLUP");
2985 }
2986 }
2987
2988 if group_by.totals {
2990 self.write_space();
2991 self.write_keyword("WITH TOTALS");
2992 }
2993 }
2994
2995 if let Some(having) = &select.having {
2997 self.write_clause_condition("HAVING", &having.this)?;
2998 }
2999
3000 if select.qualify_after_window {
3002 if let Some(windows) = &select.windows {
3004 self.write_window_clause(windows)?;
3005 }
3006 if let Some(qualify) = &select.qualify {
3007 self.write_clause_condition("QUALIFY", &qualify.this)?;
3008 }
3009 } else {
3010 if let Some(qualify) = &select.qualify {
3012 self.write_clause_condition("QUALIFY", &qualify.this)?;
3013 }
3014 if let Some(windows) = &select.windows {
3015 self.write_window_clause(windows)?;
3016 }
3017 }
3018
3019 if let Some(distribute_by) = &select.distribute_by {
3021 self.write_clause_expressions("DISTRIBUTE BY", &distribute_by.expressions)?;
3022 }
3023
3024 if let Some(cluster_by) = &select.cluster_by {
3026 self.write_order_clause("CLUSTER BY", &cluster_by.expressions)?;
3027 }
3028
3029 if let Some(sort_by) = &select.sort_by {
3031 self.write_order_clause("SORT BY", &sort_by.expressions)?;
3032 }
3033
3034 if let Some(order_by) = &select.order_by {
3036 let keyword = if order_by.siblings { "ORDER SIBLINGS BY" } else { "ORDER BY" };
3037 self.write_order_clause(keyword, &order_by.expressions)?;
3038 }
3039
3040 if select.order_by.is_none() && select.fetch.is_some()
3042 && matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric))
3043 {
3044 if self.config.pretty {
3045 self.write_newline();
3046 self.write_indent();
3047 } else {
3048 self.write_space();
3049 }
3050 self.write_keyword("ORDER BY (SELECT NULL) OFFSET 0 ROWS");
3051 }
3052
3053 let is_presto_like = matches!(
3058 self.config.dialect,
3059 Some(DialectType::Presto) | Some(DialectType::Trino)
3060 );
3061
3062 if is_presto_like && select.offset.is_some() {
3063 if let Some(offset) = &select.offset {
3065 if self.config.pretty {
3066 self.write_newline();
3067 self.write_indent();
3068 } else {
3069 self.write_space();
3070 }
3071 self.write_keyword("OFFSET");
3072 self.write_space();
3073 self.write_limit_expr(&offset.this)?;
3074 if offset.rows == Some(true) {
3075 self.write_space();
3076 self.write_keyword("ROWS");
3077 }
3078 }
3079 if let Some(limit) = &select.limit {
3080 if self.config.pretty {
3081 self.write_newline();
3082 self.write_indent();
3083 } else {
3084 self.write_space();
3085 }
3086 self.write_keyword("LIMIT");
3087 self.write_space();
3088 self.write_limit_expr(&limit.this)?;
3089 if limit.percent {
3090 self.write_space();
3091 self.write_keyword("PERCENT");
3092 }
3093 }
3094 } else {
3095 let fetch_as_limit = select.fetch.as_ref().map_or(false, |fetch| {
3097 !fetch.percent && !fetch.with_ties && fetch.count.is_some() && matches!(
3098 self.config.dialect,
3099 Some(DialectType::Spark) | Some(DialectType::Hive)
3100 | Some(DialectType::DuckDB) | Some(DialectType::SQLite) | Some(DialectType::MySQL)
3101 | Some(DialectType::BigQuery) | Some(DialectType::Databricks) | Some(DialectType::StarRocks)
3102 | Some(DialectType::Doris) | Some(DialectType::Athena) | Some(DialectType::ClickHouse)
3103 | Some(DialectType::Redshift)
3104 )
3105 });
3106
3107 if let Some(limit) = &select.limit {
3109 if !matches!(self.config.dialect, Some(DialectType::TSQL)) {
3111 if self.config.pretty {
3112 self.write_newline();
3113 self.write_indent();
3114 } else {
3115 self.write_space();
3116 }
3117 self.write_keyword("LIMIT");
3118 self.write_space();
3119 self.write_limit_expr(&limit.this)?;
3120 if limit.percent {
3121 self.write_space();
3122 self.write_keyword("PERCENT");
3123 }
3124 }
3125 }
3126
3127 if select.top.is_some() && !is_top_dialect && select.limit.is_none() {
3129 if let Some(top) = &select.top {
3130 if !top.percent && !top.with_ties {
3131 if self.config.pretty {
3132 self.write_newline();
3133 self.write_indent();
3134 } else {
3135 self.write_space();
3136 }
3137 self.write_keyword("LIMIT");
3138 self.write_space();
3139 self.generate_expression(&top.this)?;
3140 }
3141 }
3142 }
3143
3144 if fetch_as_limit && select.offset.is_some() {
3147 if let Some(fetch) = &select.fetch {
3148 if self.config.pretty {
3149 self.write_newline();
3150 self.write_indent();
3151 } else {
3152 self.write_space();
3153 }
3154 self.write_keyword("LIMIT");
3155 self.write_space();
3156 self.generate_expression(fetch.count.as_ref().unwrap())?;
3157 }
3158 }
3159
3160 if let Some(offset) = &select.offset {
3164 if self.config.pretty {
3165 self.write_newline();
3166 self.write_indent();
3167 } else {
3168 self.write_space();
3169 }
3170 if matches!(self.config.dialect, Some(DialectType::TSQL)) {
3171 self.write_keyword("OFFSET");
3173 self.write_space();
3174 self.write_limit_expr(&offset.this)?;
3175 self.write_space();
3176 self.write_keyword("ROWS");
3177 if let Some(limit) = &select.limit {
3179 self.write_space();
3180 self.write_keyword("FETCH NEXT");
3181 self.write_space();
3182 self.write_limit_expr(&limit.this)?;
3183 self.write_space();
3184 self.write_keyword("ROWS ONLY");
3185 }
3186 } else {
3187 self.write_keyword("OFFSET");
3188 self.write_space();
3189 self.write_limit_expr(&offset.this)?;
3190 if offset.rows == Some(true) {
3192 self.write_space();
3193 self.write_keyword("ROWS");
3194 }
3195 }
3196 }
3197 }
3198
3199 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
3201 if let Some(limit_by) = &select.limit_by {
3202 if !limit_by.is_empty() {
3203 self.write_space();
3204 self.write_keyword("BY");
3205 self.write_space();
3206 for (i, expr) in limit_by.iter().enumerate() {
3207 if i > 0 {
3208 self.write(", ");
3209 }
3210 self.generate_expression(expr)?;
3211 }
3212 }
3213 }
3214 }
3215
3216 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
3218 if let Some(settings) = &select.settings {
3219 if self.config.pretty {
3220 self.write_newline();
3221 self.write_indent();
3222 } else {
3223 self.write_space();
3224 }
3225 self.write_keyword("SETTINGS");
3226 self.write_space();
3227 for (i, expr) in settings.iter().enumerate() {
3228 if i > 0 {
3229 self.write(", ");
3230 }
3231 self.generate_expression(expr)?;
3232 }
3233 }
3234
3235 if let Some(format_expr) = &select.format {
3236 if self.config.pretty {
3237 self.write_newline();
3238 self.write_indent();
3239 } else {
3240 self.write_space();
3241 }
3242 self.write_keyword("FORMAT");
3243 self.write_space();
3244 self.generate_expression(format_expr)?;
3245 }
3246 }
3247
3248 if let Some(fetch) = &select.fetch {
3250 let fetch_already_as_limit = select.offset.is_some() && !fetch.percent && !fetch.with_ties && fetch.count.is_some() && matches!(
3252 self.config.dialect,
3253 Some(DialectType::Spark) | Some(DialectType::Hive)
3254 | Some(DialectType::DuckDB) | Some(DialectType::SQLite) | Some(DialectType::MySQL)
3255 | Some(DialectType::BigQuery) | Some(DialectType::Databricks) | Some(DialectType::StarRocks)
3256 | Some(DialectType::Doris) | Some(DialectType::Athena) | Some(DialectType::ClickHouse)
3257 | Some(DialectType::Redshift)
3258 );
3259
3260 if fetch_already_as_limit {
3261 } else {
3263 if self.config.pretty {
3264 self.write_newline();
3265 self.write_indent();
3266 } else {
3267 self.write_space();
3268 }
3269
3270 let use_limit = !fetch.percent && !fetch.with_ties && fetch.count.is_some() && matches!(
3272 self.config.dialect,
3273 Some(DialectType::Spark) | Some(DialectType::Hive)
3274 | Some(DialectType::DuckDB) | Some(DialectType::SQLite) | Some(DialectType::MySQL)
3275 | Some(DialectType::BigQuery) | Some(DialectType::Databricks) | Some(DialectType::StarRocks)
3276 | Some(DialectType::Doris) | Some(DialectType::Athena) | Some(DialectType::ClickHouse)
3277 | Some(DialectType::Redshift)
3278 );
3279
3280 if use_limit {
3281 self.write_keyword("LIMIT");
3282 self.write_space();
3283 self.generate_expression(fetch.count.as_ref().unwrap())?;
3284 } else {
3285 self.write_keyword("FETCH");
3286 self.write_space();
3287 self.write_keyword(&fetch.direction);
3288 if let Some(ref count) = fetch.count {
3289 self.write_space();
3290 self.generate_expression(count)?;
3291 }
3292 if fetch.percent {
3293 self.write_space();
3294 self.write_keyword("PERCENT");
3295 }
3296 if fetch.rows {
3297 self.write_space();
3298 self.write_keyword("ROWS");
3299 }
3300 if fetch.with_ties {
3301 self.write_space();
3302 self.write_keyword("WITH TIES");
3303 } else {
3304 self.write_space();
3305 self.write_keyword("ONLY");
3306 }
3307 }
3308 } }
3310
3311 if let Some(sample) = &select.sample {
3313 use crate::dialects::DialectType;
3314 if self.config.pretty {
3315 self.write_newline();
3316 } else {
3317 self.write_space();
3318 }
3319
3320 if sample.is_using_sample {
3321 self.write_keyword("USING SAMPLE");
3323 self.generate_sample_body(sample)?;
3324 } else {
3325 self.write_keyword("TABLESAMPLE");
3326
3327 let snowflake_bernoulli = matches!(self.config.dialect, Some(DialectType::Snowflake)) && !sample.explicit_method;
3329 if snowflake_bernoulli {
3330 self.write_space();
3331 self.write_keyword("BERNOULLI");
3332 }
3333
3334 if matches!(sample.method, SampleMethod::Bucket) {
3336 self.write_space();
3337 self.write("(");
3338 self.write_keyword("BUCKET");
3339 self.write_space();
3340 if let Some(ref num) = sample.bucket_numerator {
3341 self.generate_expression(num)?;
3342 }
3343 self.write_space();
3344 self.write_keyword("OUT OF");
3345 self.write_space();
3346 if let Some(ref denom) = sample.bucket_denominator {
3347 self.generate_expression(denom)?;
3348 }
3349 if let Some(ref field) = sample.bucket_field {
3350 self.write_space();
3351 self.write_keyword("ON");
3352 self.write_space();
3353 self.generate_expression(field)?;
3354 }
3355 self.write(")");
3356 } else if sample.unit_after_size {
3357 if sample.explicit_method && sample.method_before_size {
3359 self.write_space();
3360 match sample.method {
3361 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
3362 SampleMethod::System => self.write_keyword("SYSTEM"),
3363 SampleMethod::Block => self.write_keyword("BLOCK"),
3364 SampleMethod::Row => self.write_keyword("ROW"),
3365 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
3366 _ => {}
3367 }
3368 }
3369 self.write(" (");
3370 self.generate_expression(&sample.size)?;
3371 self.write_space();
3372 match sample.method {
3373 SampleMethod::Percent => self.write_keyword("PERCENT"),
3374 SampleMethod::Row => self.write_keyword("ROWS"),
3375 SampleMethod::Reservoir => self.write_keyword("ROWS"),
3376 _ => {
3377 self.write_keyword("PERCENT");
3378 }
3379 }
3380 self.write(")");
3381 } else {
3382 self.write_space();
3384 match sample.method {
3385 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
3386 SampleMethod::System => self.write_keyword("SYSTEM"),
3387 SampleMethod::Block => self.write_keyword("BLOCK"),
3388 SampleMethod::Row => self.write_keyword("ROW"),
3389 SampleMethod::Percent => self.write_keyword("BERNOULLI"),
3390 SampleMethod::Bucket => {}
3391 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
3392 }
3393 self.write(" (");
3394 self.generate_expression(&sample.size)?;
3395 if matches!(sample.method, SampleMethod::Percent) {
3396 self.write_space();
3397 self.write_keyword("PERCENT");
3398 }
3399 self.write(")");
3400 }
3401 }
3402
3403 if let Some(seed) = &sample.seed {
3404 self.write_space();
3405 let use_seed = sample.use_seed_keyword
3407 && !matches!(self.config.dialect, Some(crate::dialects::DialectType::Databricks) | Some(crate::dialects::DialectType::Spark));
3408 if use_seed {
3409 self.write_keyword("SEED");
3410 } else {
3411 self.write_keyword("REPEATABLE");
3412 }
3413 self.write(" (");
3414 self.generate_expression(seed)?;
3415 self.write(")");
3416 }
3417 }
3418
3419 if self.config.locking_reads_supported {
3422 for lock in &select.locks {
3423 if self.config.pretty {
3424 self.write_newline();
3425 self.write_indent();
3426 } else {
3427 self.write_space();
3428 }
3429 self.generate_lock(lock)?;
3430 }
3431 }
3432
3433 if !select.for_xml.is_empty() {
3435 if self.config.pretty {
3436 self.write_newline();
3437 self.write_indent();
3438 } else {
3439 self.write_space();
3440 }
3441 self.write_keyword("FOR XML");
3442 for (i, opt) in select.for_xml.iter().enumerate() {
3443 if self.config.pretty {
3444 if i > 0 {
3445 self.write(",");
3446 }
3447 self.write_newline();
3448 self.write_indent();
3449 self.write(" "); } else {
3451 if i > 0 {
3452 self.write(",");
3453 }
3454 self.write_space();
3455 }
3456 self.generate_for_xml_option(opt)?;
3457 }
3458 }
3459
3460 if let Some(ref option) = select.option {
3462 if matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL) | Some(crate::dialects::DialectType::Fabric)) {
3463 self.write_space();
3464 self.write(option);
3465 }
3466 }
3467
3468 Ok(())
3469 }
3470
3471 fn generate_for_xml_option(&mut self, opt: &Expression) -> Result<()> {
3473 match opt {
3474 Expression::QueryOption(qo) => {
3475 if let Expression::Var(var) = &*qo.this {
3477 self.write(&var.this);
3478 } else {
3479 self.generate_expression(&qo.this)?;
3480 }
3481 if let Some(expr) = &qo.expression {
3483 self.write("(");
3484 self.generate_expression(expr)?;
3485 self.write(")");
3486 }
3487 }
3488 _ => {
3489 self.generate_expression(opt)?;
3490 }
3491 }
3492 Ok(())
3493 }
3494
3495 fn generate_with(&mut self, with: &With) -> Result<()> {
3496 use crate::dialects::DialectType;
3497
3498 for comment in &with.leading_comments {
3500 self.write(comment);
3501 self.write(" ");
3502 }
3503 self.write_keyword("WITH");
3504 if with.recursive {
3505 self.write_space();
3506 self.write_keyword("RECURSIVE");
3507 }
3508 self.write_space();
3509
3510 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
3512
3513 for (i, cte) in with.ctes.iter().enumerate() {
3514 if i > 0 {
3515 self.write(",");
3516 if self.config.pretty {
3517 self.write_space();
3518 } else {
3519 self.write(" ");
3520 }
3521 }
3522 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !cte.alias_first {
3523 self.generate_expression(&cte.this)?;
3524 self.write_space();
3525 self.write_keyword("AS");
3526 self.write_space();
3527 self.generate_identifier(&cte.alias)?;
3528 continue;
3529 }
3530 self.generate_identifier(&cte.alias)?;
3531 if !cte.columns.is_empty() && !skip_cte_columns {
3532 self.write("(");
3533 for (j, col) in cte.columns.iter().enumerate() {
3534 if j > 0 {
3535 self.write(", ");
3536 }
3537 self.generate_identifier(col)?;
3538 }
3539 self.write(")");
3540 }
3541 if !cte.key_expressions.is_empty() {
3543 self.write_space();
3544 self.write_keyword("USING KEY");
3545 self.write(" (");
3546 for (i, key) in cte.key_expressions.iter().enumerate() {
3547 if i > 0 {
3548 self.write(", ");
3549 }
3550 self.generate_identifier(key)?;
3551 }
3552 self.write(")");
3553 }
3554 self.write_space();
3555 self.write_keyword("AS");
3556 if let Some(materialized) = cte.materialized {
3558 self.write_space();
3559 if materialized {
3560 self.write_keyword("MATERIALIZED");
3561 } else {
3562 self.write_keyword("NOT MATERIALIZED");
3563 }
3564 }
3565 self.write(" (");
3566 if self.config.pretty {
3567 self.write_newline();
3568 self.indent_level += 1;
3569 self.write_indent();
3570 }
3571 let wrap_values_in_select = matches!(
3574 self.config.dialect,
3575 Some(DialectType::Spark) | Some(DialectType::Databricks)
3576 ) && matches!(&cte.this, Expression::Values(_));
3577
3578 if wrap_values_in_select {
3579 self.write_keyword("SELECT");
3580 self.write(" * ");
3581 self.write_keyword("FROM");
3582 self.write_space();
3583 }
3584 self.generate_expression(&cte.this)?;
3585 if self.config.pretty {
3586 self.write_newline();
3587 self.indent_level -= 1;
3588 self.write_indent();
3589 }
3590 self.write(")");
3591 }
3592
3593 if let Some(search) = &with.search {
3595 self.write_space();
3596 self.generate_expression(search)?;
3597 }
3598
3599 Ok(())
3600 }
3601
3602 fn generate_join(&mut self, join: &Join) -> Result<()> {
3603 if join.kind == JoinKind::Implicit {
3605 self.write(",");
3606 if self.config.pretty {
3607 self.write_newline();
3608 self.write_indent();
3609 } else {
3610 self.write_space();
3611 }
3612 self.generate_expression(&join.this)?;
3613 return Ok(());
3614 }
3615
3616 if self.config.pretty {
3617 self.write_newline();
3618 self.write_indent();
3619 } else {
3620 self.write_space();
3621 }
3622
3623 let hint_str = if self.config.join_hints {
3626 join.join_hint.as_ref().map(|h| format!(" {}", h)).unwrap_or_default()
3627 } else {
3628 String::new()
3629 };
3630
3631 let clickhouse_join_keyword = if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
3632 if let Some(hint) = &join.join_hint {
3633 let mut global = false;
3634 let mut strictness: Option<&'static str> = None;
3635 for part in hint.split_whitespace() {
3636 match part.to_uppercase().as_str() {
3637 "GLOBAL" => global = true,
3638 "ANY" => strictness = Some("ANY"),
3639 "ASOF" => strictness = Some("ASOF"),
3640 "SEMI" => strictness = Some("SEMI"),
3641 "ANTI" => strictness = Some("ANTI"),
3642 _ => {}
3643 }
3644 }
3645
3646 if global || strictness.is_some() {
3647 let join_type = match join.kind {
3648 JoinKind::Left => {
3649 if join.use_outer_keyword {
3650 "LEFT OUTER"
3651 } else if join.use_inner_keyword {
3652 "LEFT INNER"
3653 } else {
3654 "LEFT"
3655 }
3656 }
3657 JoinKind::Right => {
3658 if join.use_outer_keyword {
3659 "RIGHT OUTER"
3660 } else if join.use_inner_keyword {
3661 "RIGHT INNER"
3662 } else {
3663 "RIGHT"
3664 }
3665 }
3666 JoinKind::Full => {
3667 if join.use_outer_keyword {
3668 "FULL OUTER"
3669 } else {
3670 "FULL"
3671 }
3672 }
3673 JoinKind::Inner => {
3674 if join.use_inner_keyword {
3675 "INNER"
3676 } else {
3677 ""
3678 }
3679 }
3680 _ => "",
3681 };
3682
3683 let mut parts = Vec::new();
3684 if global {
3685 parts.push("GLOBAL");
3686 }
3687 if !join_type.is_empty() {
3688 parts.push(join_type);
3689 }
3690 if let Some(strict) = strictness {
3691 parts.push(strict);
3692 }
3693 parts.push("JOIN");
3694 Some(parts.join(" "))
3695 } else {
3696 None
3697 }
3698 } else {
3699 None
3700 }
3701 } else {
3702 None
3703 };
3704
3705 if let Some(keyword) = clickhouse_join_keyword {
3706 self.write_keyword(&keyword);
3707 } else {
3708 match join.kind {
3709 JoinKind::Inner => {
3710 if join.use_inner_keyword {
3711 self.write_keyword(&format!("INNER{} JOIN", hint_str));
3712 } else {
3713 self.write_keyword(&format!("{}JOIN", if hint_str.is_empty() { String::new() } else { format!("{} ", hint_str.trim()) }));
3714 }
3715 }
3716 JoinKind::Left => {
3717 if join.use_outer_keyword {
3718 self.write_keyword(&format!("LEFT OUTER{} JOIN", hint_str));
3719 } else if join.use_inner_keyword {
3720 self.write_keyword(&format!("LEFT INNER{} JOIN", hint_str));
3721 } else {
3722 self.write_keyword(&format!("LEFT{} JOIN", hint_str));
3723 }
3724 }
3725 JoinKind::Right => {
3726 if join.use_outer_keyword {
3727 self.write_keyword(&format!("RIGHT OUTER{} JOIN", hint_str));
3728 } else if join.use_inner_keyword {
3729 self.write_keyword(&format!("RIGHT INNER{} JOIN", hint_str));
3730 } else {
3731 self.write_keyword(&format!("RIGHT{} JOIN", hint_str));
3732 }
3733 }
3734 JoinKind::Full => {
3735 if join.use_outer_keyword {
3736 self.write_keyword(&format!("FULL OUTER{} JOIN", hint_str));
3737 } else {
3738 self.write_keyword(&format!("FULL{} JOIN", hint_str));
3739 }
3740 }
3741 JoinKind::Outer => self.write_keyword("OUTER JOIN"),
3742 JoinKind::Cross => self.write_keyword("CROSS JOIN"),
3743 JoinKind::Natural => self.write_keyword("NATURAL JOIN"),
3744 JoinKind::NaturalLeft => {
3745 if join.use_outer_keyword {
3746 self.write_keyword("NATURAL LEFT OUTER JOIN");
3747 } else {
3748 self.write_keyword("NATURAL LEFT JOIN");
3749 }
3750 }
3751 JoinKind::NaturalRight => {
3752 if join.use_outer_keyword {
3753 self.write_keyword("NATURAL RIGHT OUTER JOIN");
3754 } else {
3755 self.write_keyword("NATURAL RIGHT JOIN");
3756 }
3757 }
3758 JoinKind::NaturalFull => {
3759 if join.use_outer_keyword {
3760 self.write_keyword("NATURAL FULL OUTER JOIN");
3761 } else {
3762 self.write_keyword("NATURAL FULL JOIN");
3763 }
3764 }
3765 JoinKind::Semi => self.write_keyword("SEMI JOIN"),
3766 JoinKind::Anti => self.write_keyword("ANTI JOIN"),
3767 JoinKind::LeftSemi => self.write_keyword("LEFT SEMI JOIN"),
3768 JoinKind::LeftAnti => self.write_keyword("LEFT ANTI JOIN"),
3769 JoinKind::RightSemi => self.write_keyword("RIGHT SEMI JOIN"),
3770 JoinKind::RightAnti => self.write_keyword("RIGHT ANTI JOIN"),
3771 JoinKind::CrossApply => {
3772 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
3774 self.write_keyword("CROSS APPLY");
3775 } else {
3776 self.write_keyword("INNER JOIN LATERAL");
3777 }
3778 }
3779 JoinKind::OuterApply => {
3780 if matches!(self.config.dialect, Some(DialectType::TSQL) | None) {
3782 self.write_keyword("OUTER APPLY");
3783 } else {
3784 self.write_keyword("LEFT JOIN LATERAL");
3785 }
3786 }
3787 JoinKind::AsOf => self.write_keyword("ASOF JOIN"),
3788 JoinKind::AsOfLeft => {
3789 if join.use_outer_keyword {
3790 self.write_keyword("ASOF LEFT OUTER JOIN");
3791 } else {
3792 self.write_keyword("ASOF LEFT JOIN");
3793 }
3794 }
3795 JoinKind::AsOfRight => {
3796 if join.use_outer_keyword {
3797 self.write_keyword("ASOF RIGHT OUTER JOIN");
3798 } else {
3799 self.write_keyword("ASOF RIGHT JOIN");
3800 }
3801 }
3802 JoinKind::Lateral => self.write_keyword("LATERAL JOIN"),
3803 JoinKind::LeftLateral => {
3804 if join.use_outer_keyword {
3805 self.write_keyword("LEFT OUTER LATERAL JOIN");
3806 } else {
3807 self.write_keyword("LEFT LATERAL JOIN");
3808 }
3809 }
3810 JoinKind::Straight => self.write_keyword("STRAIGHT_JOIN"),
3811 JoinKind::Implicit => {
3812 use crate::dialects::DialectType;
3814 if matches!(self.config.dialect, Some(DialectType::BigQuery) | Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)) {
3815 self.write_keyword("CROSS JOIN");
3816 } else {
3817 self.output.truncate(self.output.trim_end().len());
3821 self.write(",");
3822 }
3823 }
3824 JoinKind::Array => self.write_keyword("ARRAY JOIN"),
3825 JoinKind::LeftArray => self.write_keyword("LEFT ARRAY JOIN"),
3826 }
3827 }
3828
3829 if matches!(join.kind, JoinKind::Array | JoinKind::LeftArray) {
3831 self.write_space();
3832 match &join.this {
3833 Expression::Tuple(t) => {
3834 for (i, item) in t.expressions.iter().enumerate() {
3835 if i > 0 {
3836 self.write(", ");
3837 }
3838 self.generate_expression(item)?;
3839 }
3840 }
3841 other => {
3842 self.generate_expression(other)?;
3843 }
3844 }
3845 } else {
3846 self.write_space();
3847 self.generate_expression(&join.this)?;
3848 }
3849
3850 if !join.deferred_condition {
3852 if let Some(match_cond) = &join.match_condition {
3854 self.write_space();
3855 self.write_keyword("MATCH_CONDITION");
3856 self.write(" (");
3857 self.generate_expression(match_cond)?;
3858 self.write(")");
3859 }
3860
3861 if let Some(on) = &join.on {
3862 if self.config.pretty {
3863 self.write_newline();
3864 self.indent_level += 1;
3865 self.write_indent();
3866 self.write_keyword("ON");
3867 self.write_space();
3868 self.generate_join_on_condition(on)?;
3869 self.indent_level -= 1;
3870 } else {
3871 self.write_space();
3872 self.write_keyword("ON");
3873 self.write_space();
3874 self.generate_expression(on)?;
3875 }
3876 }
3877
3878 if !join.using.is_empty() {
3879 if self.config.pretty {
3880 self.write_newline();
3881 self.indent_level += 1;
3882 self.write_indent();
3883 self.write_keyword("USING");
3884 self.write(" (");
3885 for (i, col) in join.using.iter().enumerate() {
3886 if i > 0 {
3887 self.write(", ");
3888 }
3889 self.generate_identifier(col)?;
3890 }
3891 self.write(")");
3892 self.indent_level -= 1;
3893 } else {
3894 self.write_space();
3895 self.write_keyword("USING");
3896 self.write(" (");
3897 for (i, col) in join.using.iter().enumerate() {
3898 if i > 0 {
3899 self.write(", ");
3900 }
3901 self.generate_identifier(col)?;
3902 }
3903 self.write(")");
3904 }
3905 }
3906 }
3907
3908 for pivot in &join.pivots {
3910 self.write_space();
3911 self.generate_expression(pivot)?;
3912 }
3913
3914 Ok(())
3915 }
3916
3917 fn generate_join_condition(&mut self, join: &Join) -> Result<()> {
3919 if let Some(match_cond) = &join.match_condition {
3921 self.write_space();
3922 self.write_keyword("MATCH_CONDITION");
3923 self.write(" (");
3924 self.generate_expression(match_cond)?;
3925 self.write(")");
3926 }
3927
3928 if let Some(on) = &join.on {
3929 if self.config.pretty {
3930 self.write_newline();
3931 self.indent_level += 1;
3932 self.write_indent();
3933 self.write_keyword("ON");
3934 self.write_space();
3935 self.generate_join_on_condition(on)?;
3937 self.indent_level -= 1;
3938 } else {
3939 self.write_space();
3940 self.write_keyword("ON");
3941 self.write_space();
3942 self.generate_expression(on)?;
3943 }
3944 }
3945
3946 if !join.using.is_empty() {
3947 if self.config.pretty {
3948 self.write_newline();
3949 self.indent_level += 1;
3950 self.write_indent();
3951 self.write_keyword("USING");
3952 self.write(" (");
3953 for (i, col) in join.using.iter().enumerate() {
3954 if i > 0 {
3955 self.write(", ");
3956 }
3957 self.generate_identifier(col)?;
3958 }
3959 self.write(")");
3960 self.indent_level -= 1;
3961 } else {
3962 self.write_space();
3963 self.write_keyword("USING");
3964 self.write(" (");
3965 for (i, col) in join.using.iter().enumerate() {
3966 if i > 0 {
3967 self.write(", ");
3968 }
3969 self.generate_identifier(col)?;
3970 }
3971 self.write(")");
3972 }
3973 }
3974
3975 for pivot in &join.pivots {
3977 self.write_space();
3978 self.generate_expression(pivot)?;
3979 }
3980
3981 Ok(())
3982 }
3983
3984 fn generate_join_on_condition(&mut self, expr: &Expression) -> Result<()> {
3986 if let Expression::And(and_op) = expr {
3988 self.generate_join_on_condition(&and_op.left)?;
3990 self.write_newline();
3992 self.write_indent();
3993 self.write_keyword("AND");
3994 self.write_space();
3995 self.generate_expression(&and_op.right)?;
3997 } else {
3998 self.generate_expression(expr)?;
4000 }
4001 Ok(())
4002 }
4003
4004 fn generate_joined_table(&mut self, jt: &JoinedTable) -> Result<()> {
4005 self.write("(");
4007 self.generate_expression(&jt.left)?;
4008
4009 for join in &jt.joins {
4011 self.generate_join(join)?;
4012 }
4013
4014 for lv in &jt.lateral_views {
4016 self.generate_lateral_view(lv)?;
4017 }
4018
4019 self.write(")");
4020
4021 if let Some(alias) = &jt.alias {
4023 self.write_space();
4024 self.write_keyword("AS");
4025 self.write_space();
4026 self.generate_identifier(alias)?;
4027 }
4028
4029 Ok(())
4030 }
4031
4032 fn generate_lateral_view(&mut self, lv: &LateralView) -> Result<()> {
4033 use crate::dialects::DialectType;
4034
4035 if self.config.pretty {
4036 self.write_newline();
4037 self.write_indent();
4038 } else {
4039 self.write_space();
4040 }
4041
4042 let use_lateral_join = matches!(
4045 self.config.dialect,
4046 Some(DialectType::PostgreSQL) | Some(DialectType::DuckDB) |
4047 Some(DialectType::Snowflake) | Some(DialectType::TSQL) |
4048 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
4049 );
4050
4051 let use_unnest = matches!(
4053 self.config.dialect,
4054 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)
4055 );
4056
4057 let (is_posexplode, func_args) = match &lv.this {
4059 Expression::Explode(uf) => {
4060 (false, vec![uf.this.clone()])
4062 }
4063 Expression::Function(func) => {
4064 let name = func.name.to_uppercase();
4065 if name == "POSEXPLODE" || name == "POSEXPLODE_OUTER" {
4066 (true, func.args.clone())
4067 } else if name == "EXPLODE" || name == "EXPLODE_OUTER" || name == "INLINE" {
4068 (false, func.args.clone())
4069 } else {
4070 (false, vec![])
4071 }
4072 }
4073 _ => (false, vec![]),
4074 };
4075
4076 if use_lateral_join {
4077 if lv.outer {
4079 self.write_keyword("LEFT JOIN LATERAL");
4080 } else {
4081 self.write_keyword("CROSS JOIN");
4082 }
4083 self.write_space();
4084
4085 if use_unnest && !func_args.is_empty() {
4086 let unnest_args = if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
4089 func_args.iter().map(|a| {
4091 if let Expression::Function(ref f) = a {
4092 if f.name.to_uppercase() == "ARRAY" && f.args.len() == 1 {
4093 return Expression::ArrayFunc(Box::new(crate::expressions::ArrayConstructor {
4094 expressions: f.args.clone(),
4095 bracket_notation: true,
4096 use_list_keyword: false,
4097 }));
4098 }
4099 }
4100 a.clone()
4101 }).collect::<Vec<_>>()
4102 } else if matches!(self.config.dialect, Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena)) {
4103 func_args.iter().map(|a| {
4105 if let Expression::Function(ref f) = a {
4106 if f.name.to_uppercase() == "ARRAY" && f.args.len() >= 1 {
4107 return Expression::ArrayFunc(Box::new(crate::expressions::ArrayConstructor {
4108 expressions: f.args.clone(),
4109 bracket_notation: true,
4110 use_list_keyword: false,
4111 }));
4112 }
4113 }
4114 a.clone()
4115 }).collect::<Vec<_>>()
4116 } else {
4117 func_args
4118 };
4119
4120 self.write_keyword("UNNEST");
4121 self.write("(");
4122 for (i, arg) in unnest_args.iter().enumerate() {
4123 if i > 0 { self.write(", "); }
4124 self.generate_expression(arg)?;
4125 }
4126 self.write(")");
4127
4128 if is_posexplode {
4130 self.write_space();
4131 self.write_keyword("WITH ORDINALITY");
4132 }
4133 } else {
4134 if !lv.outer {
4136 self.write_keyword("LATERAL");
4137 self.write_space();
4138 }
4139 self.generate_expression(&lv.this)?;
4140 }
4141
4142 if let Some(alias) = &lv.table_alias {
4144 self.write_space();
4145 self.write_keyword("AS");
4146 self.write_space();
4147 self.generate_identifier(alias)?;
4148 if !lv.column_aliases.is_empty() {
4149 self.write("(");
4150 for (i, col) in lv.column_aliases.iter().enumerate() {
4151 if i > 0 {
4152 self.write(", ");
4153 }
4154 self.generate_identifier(col)?;
4155 }
4156 self.write(")");
4157 }
4158 } else if !lv.column_aliases.is_empty() {
4159 self.write_space();
4161 self.write_keyword("AS");
4162 self.write(" t(");
4163 for (i, col) in lv.column_aliases.iter().enumerate() {
4164 if i > 0 {
4165 self.write(", ");
4166 }
4167 self.generate_identifier(col)?;
4168 }
4169 self.write(")");
4170 }
4171
4172 if lv.outer {
4174 self.write_space();
4175 self.write_keyword("ON TRUE");
4176 }
4177 } else {
4178 self.write_keyword("LATERAL VIEW");
4180 if lv.outer {
4181 self.write_space();
4182 self.write_keyword("OUTER");
4183 }
4184 self.write_space();
4185 self.generate_expression(&lv.this)?;
4186
4187 if let Some(alias) = &lv.table_alias {
4189 self.write_space();
4190 self.generate_identifier(alias)?;
4191 }
4192
4193 if !lv.column_aliases.is_empty() {
4195 self.write_space();
4196 self.write_keyword("AS");
4197 self.write_space();
4198 for (i, col) in lv.column_aliases.iter().enumerate() {
4199 if i > 0 {
4200 self.write(", ");
4201 }
4202 self.generate_identifier(col)?;
4203 }
4204 }
4205 }
4206
4207 Ok(())
4208 }
4209
4210 fn generate_union(&mut self, union: &Union) -> Result<()> {
4211 if let Some(with) = &union.with {
4213 self.generate_with(with)?;
4214 self.write_space();
4215 }
4216 self.generate_expression(&union.left)?;
4217 if self.config.pretty {
4218 self.write_newline();
4219 self.write_indent();
4220 } else {
4221 self.write_space();
4222 }
4223
4224 if let Some(side) = &union.side {
4226 self.write_keyword(side);
4227 self.write_space();
4228 }
4229 if let Some(kind) = &union.kind {
4230 self.write_keyword(kind);
4231 self.write_space();
4232 }
4233
4234 self.write_keyword("UNION");
4235 if union.all {
4236 self.write_space();
4237 self.write_keyword("ALL");
4238 } else if union.distinct {
4239 self.write_space();
4240 self.write_keyword("DISTINCT");
4241 }
4242
4243 if union.corresponding || union.by_name {
4246 self.write_space();
4247 self.write_keyword("BY NAME");
4248 }
4249 if !union.on_columns.is_empty() {
4250 self.write_space();
4251 self.write_keyword("ON");
4252 self.write(" (");
4253 for (i, col) in union.on_columns.iter().enumerate() {
4254 if i > 0 {
4255 self.write(", ");
4256 }
4257 self.generate_expression(col)?;
4258 }
4259 self.write(")");
4260 }
4261
4262 if self.config.pretty {
4263 self.write_newline();
4264 self.write_indent();
4265 } else {
4266 self.write_space();
4267 }
4268 self.generate_expression(&union.right)?;
4269 if let Some(order_by) = &union.order_by {
4271 if self.config.pretty {
4272 self.write_newline();
4273 } else {
4274 self.write_space();
4275 }
4276 self.write_keyword("ORDER BY");
4277 self.write_space();
4278 for (i, ordered) in order_by.expressions.iter().enumerate() {
4279 if i > 0 {
4280 self.write(", ");
4281 }
4282 self.generate_ordered(ordered)?;
4283 }
4284 }
4285 if let Some(limit) = &union.limit {
4286 if self.config.pretty {
4287 self.write_newline();
4288 } else {
4289 self.write_space();
4290 }
4291 self.write_keyword("LIMIT");
4292 self.write_space();
4293 self.generate_expression(limit)?;
4294 }
4295 if let Some(offset) = &union.offset {
4296 if self.config.pretty {
4297 self.write_newline();
4298 } else {
4299 self.write_space();
4300 }
4301 self.write_keyword("OFFSET");
4302 self.write_space();
4303 self.generate_expression(offset)?;
4304 }
4305 if let Some(distribute_by) = &union.distribute_by {
4307 self.write_space();
4308 self.write_keyword("DISTRIBUTE BY");
4309 self.write_space();
4310 for (i, expr) in distribute_by.expressions.iter().enumerate() {
4311 if i > 0 {
4312 self.write(", ");
4313 }
4314 self.generate_expression(expr)?;
4315 }
4316 }
4317 if let Some(sort_by) = &union.sort_by {
4319 self.write_space();
4320 self.write_keyword("SORT BY");
4321 self.write_space();
4322 for (i, ord) in sort_by.expressions.iter().enumerate() {
4323 if i > 0 {
4324 self.write(", ");
4325 }
4326 self.generate_ordered(ord)?;
4327 }
4328 }
4329 if let Some(cluster_by) = &union.cluster_by {
4331 self.write_space();
4332 self.write_keyword("CLUSTER BY");
4333 self.write_space();
4334 for (i, ord) in cluster_by.expressions.iter().enumerate() {
4335 if i > 0 {
4336 self.write(", ");
4337 }
4338 self.generate_ordered(ord)?;
4339 }
4340 }
4341 Ok(())
4342 }
4343
4344 fn generate_intersect(&mut self, intersect: &Intersect) -> Result<()> {
4345 if let Some(with) = &intersect.with {
4347 self.generate_with(with)?;
4348 self.write_space();
4349 }
4350 self.generate_expression(&intersect.left)?;
4351 if self.config.pretty {
4352 self.write_newline();
4353 self.write_indent();
4354 } else {
4355 self.write_space();
4356 }
4357
4358 if let Some(side) = &intersect.side {
4360 self.write_keyword(side);
4361 self.write_space();
4362 }
4363 if let Some(kind) = &intersect.kind {
4364 self.write_keyword(kind);
4365 self.write_space();
4366 }
4367
4368 self.write_keyword("INTERSECT");
4369 if intersect.all {
4370 self.write_space();
4371 self.write_keyword("ALL");
4372 } else if intersect.distinct {
4373 self.write_space();
4374 self.write_keyword("DISTINCT");
4375 }
4376
4377 if intersect.corresponding || intersect.by_name {
4380 self.write_space();
4381 self.write_keyword("BY NAME");
4382 }
4383 if !intersect.on_columns.is_empty() {
4384 self.write_space();
4385 self.write_keyword("ON");
4386 self.write(" (");
4387 for (i, col) in intersect.on_columns.iter().enumerate() {
4388 if i > 0 {
4389 self.write(", ");
4390 }
4391 self.generate_expression(col)?;
4392 }
4393 self.write(")");
4394 }
4395
4396 if self.config.pretty {
4397 self.write_newline();
4398 self.write_indent();
4399 } else {
4400 self.write_space();
4401 }
4402 self.generate_expression(&intersect.right)?;
4403 if let Some(order_by) = &intersect.order_by {
4405 if self.config.pretty {
4406 self.write_newline();
4407 } else {
4408 self.write_space();
4409 }
4410 self.write_keyword("ORDER BY");
4411 self.write_space();
4412 for (i, ordered) in order_by.expressions.iter().enumerate() {
4413 if i > 0 {
4414 self.write(", ");
4415 }
4416 self.generate_ordered(ordered)?;
4417 }
4418 }
4419 if let Some(limit) = &intersect.limit {
4420 if self.config.pretty {
4421 self.write_newline();
4422 } else {
4423 self.write_space();
4424 }
4425 self.write_keyword("LIMIT");
4426 self.write_space();
4427 self.generate_expression(limit)?;
4428 }
4429 if let Some(offset) = &intersect.offset {
4430 if self.config.pretty {
4431 self.write_newline();
4432 } else {
4433 self.write_space();
4434 }
4435 self.write_keyword("OFFSET");
4436 self.write_space();
4437 self.generate_expression(offset)?;
4438 }
4439 if let Some(distribute_by) = &intersect.distribute_by {
4441 self.write_space();
4442 self.write_keyword("DISTRIBUTE BY");
4443 self.write_space();
4444 for (i, expr) in distribute_by.expressions.iter().enumerate() {
4445 if i > 0 {
4446 self.write(", ");
4447 }
4448 self.generate_expression(expr)?;
4449 }
4450 }
4451 if let Some(sort_by) = &intersect.sort_by {
4453 self.write_space();
4454 self.write_keyword("SORT BY");
4455 self.write_space();
4456 for (i, ord) in sort_by.expressions.iter().enumerate() {
4457 if i > 0 {
4458 self.write(", ");
4459 }
4460 self.generate_ordered(ord)?;
4461 }
4462 }
4463 if let Some(cluster_by) = &intersect.cluster_by {
4465 self.write_space();
4466 self.write_keyword("CLUSTER BY");
4467 self.write_space();
4468 for (i, ord) in cluster_by.expressions.iter().enumerate() {
4469 if i > 0 {
4470 self.write(", ");
4471 }
4472 self.generate_ordered(ord)?;
4473 }
4474 }
4475 Ok(())
4476 }
4477
4478 fn generate_except(&mut self, except: &Except) -> Result<()> {
4479 use crate::dialects::DialectType;
4480
4481 if let Some(with) = &except.with {
4483 self.generate_with(with)?;
4484 self.write_space();
4485 }
4486
4487 self.generate_expression(&except.left)?;
4488 if self.config.pretty {
4489 self.write_newline();
4490 self.write_indent();
4491 } else {
4492 self.write_space();
4493 }
4494
4495 if let Some(side) = &except.side {
4497 self.write_keyword(side);
4498 self.write_space();
4499 }
4500 if let Some(kind) = &except.kind {
4501 self.write_keyword(kind);
4502 self.write_space();
4503 }
4504
4505 match self.config.dialect {
4507 Some(DialectType::Oracle) => {
4508 self.write_keyword("MINUS");
4509 }
4511 _ => {
4512 self.write_keyword("EXCEPT");
4513 if except.all {
4514 self.write_space();
4515 self.write_keyword("ALL");
4516 } else if except.distinct {
4517 self.write_space();
4518 self.write_keyword("DISTINCT");
4519 }
4520 }
4521 }
4522
4523 if except.corresponding || except.by_name {
4526 self.write_space();
4527 self.write_keyword("BY NAME");
4528 }
4529 if !except.on_columns.is_empty() {
4530 self.write_space();
4531 self.write_keyword("ON");
4532 self.write(" (");
4533 for (i, col) in except.on_columns.iter().enumerate() {
4534 if i > 0 {
4535 self.write(", ");
4536 }
4537 self.generate_expression(col)?;
4538 }
4539 self.write(")");
4540 }
4541
4542 if self.config.pretty {
4543 self.write_newline();
4544 self.write_indent();
4545 } else {
4546 self.write_space();
4547 }
4548 self.generate_expression(&except.right)?;
4549 if let Some(order_by) = &except.order_by {
4551 if self.config.pretty {
4552 self.write_newline();
4553 } else {
4554 self.write_space();
4555 }
4556 self.write_keyword("ORDER BY");
4557 self.write_space();
4558 for (i, ordered) in order_by.expressions.iter().enumerate() {
4559 if i > 0 {
4560 self.write(", ");
4561 }
4562 self.generate_ordered(ordered)?;
4563 }
4564 }
4565 if let Some(limit) = &except.limit {
4566 if self.config.pretty {
4567 self.write_newline();
4568 } else {
4569 self.write_space();
4570 }
4571 self.write_keyword("LIMIT");
4572 self.write_space();
4573 self.generate_expression(limit)?;
4574 }
4575 if let Some(offset) = &except.offset {
4576 if self.config.pretty {
4577 self.write_newline();
4578 } else {
4579 self.write_space();
4580 }
4581 self.write_keyword("OFFSET");
4582 self.write_space();
4583 self.generate_expression(offset)?;
4584 }
4585 if let Some(distribute_by) = &except.distribute_by {
4587 self.write_space();
4588 self.write_keyword("DISTRIBUTE BY");
4589 self.write_space();
4590 for (i, expr) in distribute_by.expressions.iter().enumerate() {
4591 if i > 0 {
4592 self.write(", ");
4593 }
4594 self.generate_expression(expr)?;
4595 }
4596 }
4597 if let Some(sort_by) = &except.sort_by {
4599 self.write_space();
4600 self.write_keyword("SORT BY");
4601 self.write_space();
4602 for (i, ord) in sort_by.expressions.iter().enumerate() {
4603 if i > 0 {
4604 self.write(", ");
4605 }
4606 self.generate_ordered(ord)?;
4607 }
4608 }
4609 if let Some(cluster_by) = &except.cluster_by {
4611 self.write_space();
4612 self.write_keyword("CLUSTER BY");
4613 self.write_space();
4614 for (i, ord) in cluster_by.expressions.iter().enumerate() {
4615 if i > 0 {
4616 self.write(", ");
4617 }
4618 self.generate_ordered(ord)?;
4619 }
4620 }
4621 Ok(())
4622 }
4623
4624 fn generate_insert(&mut self, insert: &Insert) -> Result<()> {
4625 let prepend_query_cte = if insert.with.is_none() {
4627 use crate::dialects::DialectType;
4628 let should_prepend = matches!(self.config.dialect,
4629 Some(DialectType::TSQL) | Some(DialectType::Fabric)
4630 | Some(DialectType::Spark)
4631 | Some(DialectType::Databricks) | Some(DialectType::Hive)
4632 );
4633 if should_prepend {
4634 if let Some(Expression::Select(select)) = &insert.query {
4635 select.with.clone()
4636 } else {
4637 None
4638 }
4639 } else {
4640 None
4641 }
4642 } else {
4643 None
4644 };
4645
4646 if let Some(with) = &insert.with {
4648 self.generate_with(with)?;
4649 self.write_space();
4650 } else if let Some(with) = &prepend_query_cte {
4651 self.generate_with(with)?;
4652 self.write_space();
4653 }
4654
4655 for comment in &insert.leading_comments {
4657 self.write(comment);
4658 self.write(" ");
4659 }
4660
4661 if let Some(dir) = &insert.directory {
4663 self.write_keyword("INSERT OVERWRITE");
4664 if dir.local {
4665 self.write_space();
4666 self.write_keyword("LOCAL");
4667 }
4668 self.write_space();
4669 self.write_keyword("DIRECTORY");
4670 self.write_space();
4671 self.write("'");
4672 self.write(&dir.path);
4673 self.write("'");
4674
4675 if let Some(row_format) = &dir.row_format {
4677 self.write_space();
4678 self.write_keyword("ROW FORMAT");
4679 if row_format.delimited {
4680 self.write_space();
4681 self.write_keyword("DELIMITED");
4682 }
4683 if let Some(val) = &row_format.fields_terminated_by {
4684 self.write_space();
4685 self.write_keyword("FIELDS TERMINATED BY");
4686 self.write_space();
4687 self.write("'");
4688 self.write(val);
4689 self.write("'");
4690 }
4691 if let Some(val) = &row_format.collection_items_terminated_by {
4692 self.write_space();
4693 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
4694 self.write_space();
4695 self.write("'");
4696 self.write(val);
4697 self.write("'");
4698 }
4699 if let Some(val) = &row_format.map_keys_terminated_by {
4700 self.write_space();
4701 self.write_keyword("MAP KEYS TERMINATED BY");
4702 self.write_space();
4703 self.write("'");
4704 self.write(val);
4705 self.write("'");
4706 }
4707 if let Some(val) = &row_format.lines_terminated_by {
4708 self.write_space();
4709 self.write_keyword("LINES TERMINATED BY");
4710 self.write_space();
4711 self.write("'");
4712 self.write(val);
4713 self.write("'");
4714 }
4715 if let Some(val) = &row_format.null_defined_as {
4716 self.write_space();
4717 self.write_keyword("NULL DEFINED AS");
4718 self.write_space();
4719 self.write("'");
4720 self.write(val);
4721 self.write("'");
4722 }
4723 }
4724
4725 if let Some(format) = &dir.stored_as {
4727 self.write_space();
4728 self.write_keyword("STORED AS");
4729 self.write_space();
4730 self.write_keyword(format);
4731 }
4732
4733 if let Some(query) = &insert.query {
4735 self.write_space();
4736 self.generate_expression(query)?;
4737 }
4738
4739 return Ok(());
4740 }
4741
4742 if insert.is_replace {
4743 self.write_keyword("REPLACE INTO");
4745 } else if insert.overwrite {
4746 self.write_keyword("INSERT");
4748 if let Some(ref hint) = insert.hint {
4750 self.generate_hint(hint)?;
4751 }
4752 self.write(&self.config.insert_overwrite.to_uppercase());
4753 } else if let Some(ref action) = insert.conflict_action {
4754 self.write_keyword("INSERT OR");
4756 self.write_space();
4757 self.write_keyword(action);
4758 self.write_space();
4759 self.write_keyword("INTO");
4760 } else if insert.ignore {
4761 self.write_keyword("INSERT IGNORE INTO");
4763 } else {
4764 self.write_keyword("INSERT");
4765 if let Some(ref hint) = insert.hint {
4767 self.generate_hint(hint)?;
4768 }
4769 self.write_space();
4770 self.write_keyword("INTO");
4771 }
4772 if let Some(ref func) = insert.function_target {
4774 self.write_space();
4775 self.write_keyword("FUNCTION");
4776 self.write_space();
4777 self.generate_expression(func)?;
4778 } else {
4779 self.write_space();
4780 self.generate_table(&insert.table)?;
4781 }
4782
4783 if let Some(ref alias) = insert.alias {
4785 self.write_space();
4786 if insert.alias_explicit_as {
4787 self.write_keyword("AS");
4788 self.write_space();
4789 }
4790 self.generate_identifier(alias)?;
4791 }
4792
4793 if insert.if_exists {
4795 self.write_space();
4796 self.write_keyword("IF EXISTS");
4797 }
4798
4799 if let Some(ref replace_where) = insert.replace_where {
4801 self.write_space();
4802 self.write_keyword("REPLACE WHERE");
4803 self.write_space();
4804 self.generate_expression(replace_where)?;
4805 }
4806
4807 if !insert.partition.is_empty() {
4809 self.write_space();
4810 self.write_keyword("PARTITION");
4811 self.write("(");
4812 for (i, (col, val)) in insert.partition.iter().enumerate() {
4813 if i > 0 {
4814 self.write(", ");
4815 }
4816 self.generate_identifier(col)?;
4817 if let Some(v) = val {
4818 self.write(" = ");
4819 self.generate_expression(v)?;
4820 }
4821 }
4822 self.write(")");
4823 }
4824
4825 if let Some(ref partition_by) = insert.partition_by {
4827 self.write_space();
4828 self.write_keyword("PARTITION BY");
4829 self.write_space();
4830 self.generate_expression(partition_by)?;
4831 }
4832
4833 if !insert.settings.is_empty() {
4835 self.write_space();
4836 self.write_keyword("SETTINGS");
4837 self.write_space();
4838 for (i, setting) in insert.settings.iter().enumerate() {
4839 if i > 0 {
4840 self.write(", ");
4841 }
4842 self.generate_expression(setting)?;
4843 }
4844 }
4845
4846 if !insert.columns.is_empty() {
4847 if insert.alias.is_some() && insert.alias_explicit_as {
4848 self.write("(");
4850 } else {
4851 self.write(" (");
4853 }
4854 for (i, col) in insert.columns.iter().enumerate() {
4855 if i > 0 {
4856 self.write(", ");
4857 }
4858 self.generate_identifier(col)?;
4859 }
4860 self.write(")");
4861 }
4862
4863 if let Some(ref output) = insert.output {
4865 self.generate_output_clause(output)?;
4866 }
4867
4868 if insert.by_name {
4870 self.write_space();
4871 self.write_keyword("BY NAME");
4872 }
4873
4874 if insert.default_values {
4875 self.write_space();
4876 self.write_keyword("DEFAULT VALUES");
4877 } else if let Some(query) = &insert.query {
4878 if self.config.pretty {
4879 self.write_newline();
4880 } else {
4881 self.write_space();
4882 }
4883 if prepend_query_cte.is_some() {
4885 if let Expression::Select(select) = query {
4886 let mut select_no_with = select.clone();
4887 select_no_with.with = None;
4888 self.generate_select(&select_no_with)?;
4889 } else {
4890 self.generate_expression(query)?;
4891 }
4892 } else {
4893 self.generate_expression(query)?;
4894 }
4895 } else if !insert.values.is_empty() {
4896 if self.config.pretty {
4897 self.write_newline();
4899 self.write_keyword("VALUES");
4900 self.write_newline();
4901 self.indent_level += 1;
4902 for (i, row) in insert.values.iter().enumerate() {
4903 if i > 0 {
4904 self.write(",");
4905 self.write_newline();
4906 }
4907 self.write_indent();
4908 self.write("(");
4909 for (j, val) in row.iter().enumerate() {
4910 if j > 0 {
4911 self.write(", ");
4912 }
4913 self.generate_expression(val)?;
4914 }
4915 self.write(")");
4916 }
4917 self.indent_level -= 1;
4918 } else {
4919 self.write_space();
4921 self.write_keyword("VALUES");
4922 for (i, row) in insert.values.iter().enumerate() {
4923 if i > 0 {
4924 self.write(",");
4925 }
4926 self.write(" (");
4927 for (j, val) in row.iter().enumerate() {
4928 if j > 0 {
4929 self.write(", ");
4930 }
4931 self.generate_expression(val)?;
4932 }
4933 self.write(")");
4934 }
4935 }
4936 }
4937
4938 if let Some(ref source) = insert.source {
4940 self.write_space();
4941 self.write_keyword("TABLE");
4942 self.write_space();
4943 self.generate_expression(source)?;
4944 }
4945
4946 if let Some(alias) = &insert.source_alias {
4948 self.write_space();
4949 self.write_keyword("AS");
4950 self.write_space();
4951 self.generate_identifier(alias)?;
4952 }
4953
4954 if let Some(on_conflict) = &insert.on_conflict {
4956 if !matches!(self.config.dialect, Some(DialectType::Materialize)) {
4957 self.write_space();
4958 self.generate_expression(on_conflict)?;
4959 }
4960 }
4961
4962 if !insert.returning.is_empty() {
4964 self.write_space();
4965 self.write_keyword("RETURNING");
4966 self.write_space();
4967 for (i, expr) in insert.returning.iter().enumerate() {
4968 if i > 0 {
4969 self.write(", ");
4970 }
4971 self.generate_expression(expr)?;
4972 }
4973 }
4974
4975 Ok(())
4976 }
4977
4978 fn generate_update(&mut self, update: &Update) -> Result<()> {
4979 for comment in &update.leading_comments {
4981 self.write(comment);
4982 self.write(" ");
4983 }
4984
4985 if let Some(ref with) = update.with {
4987 self.generate_with(with)?;
4988 self.write_space();
4989 }
4990
4991 self.write_keyword("UPDATE");
4992 self.write_space();
4993 self.generate_table(&update.table)?;
4994
4995 let mysql_like_update_from = matches!(
4996 self.config.dialect,
4997 Some(DialectType::MySQL) | Some(DialectType::SingleStore)
4998 ) && update.from_clause.is_some();
4999
5000 let mut set_pairs = update.set.clone();
5001
5002 let mut pre_set_joins = update.table_joins.clone();
5004 if mysql_like_update_from {
5005 let target_name = update.table.alias
5006 .as_ref()
5007 .map(|a| a.name.clone())
5008 .unwrap_or_else(|| update.table.name.name.clone());
5009
5010 for (col, _) in &mut set_pairs {
5011 if !col.name.contains('.') {
5012 col.name = format!("{}.{}", target_name, col.name);
5013 }
5014 }
5015
5016 if let Some(from_clause) = &update.from_clause {
5017 for table_expr in &from_clause.expressions {
5018 pre_set_joins.push(crate::expressions::Join {
5019 this: table_expr.clone(),
5020 on: Some(Expression::Boolean(crate::expressions::BooleanLiteral { value: true })),
5021 using: Vec::new(),
5022 kind: crate::expressions::JoinKind::Inner,
5023 use_inner_keyword: false,
5024 use_outer_keyword: false,
5025 deferred_condition: false,
5026 join_hint: None,
5027 match_condition: None,
5028 pivots: Vec::new(),
5029 });
5030 }
5031 }
5032 for join in &update.from_joins {
5033 let mut join = join.clone();
5034 if join.on.is_none() && join.using.is_empty() {
5035 join.on = Some(Expression::Boolean(crate::expressions::BooleanLiteral { value: true }));
5036 }
5037 pre_set_joins.push(join);
5038 }
5039 }
5040
5041 for extra_table in &update.extra_tables {
5043 self.write(", ");
5044 self.generate_table(extra_table)?;
5045 }
5046
5047 for join in &pre_set_joins {
5049 self.generate_join(join)?;
5051 }
5052
5053 let teradata_from_before_set = matches!(self.config.dialect, Some(DialectType::Teradata));
5055 if teradata_from_before_set && !mysql_like_update_from {
5056 if let Some(ref from_clause) = update.from_clause {
5057 self.write_space();
5058 self.write_keyword("FROM");
5059 self.write_space();
5060 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
5061 if i > 0 {
5062 self.write(", ");
5063 }
5064 self.generate_expression(table_expr)?;
5065 }
5066 }
5067 for join in &update.from_joins {
5068 self.generate_join(join)?;
5069 }
5070 }
5071
5072 self.write_space();
5073 self.write_keyword("SET");
5074 self.write_space();
5075
5076 for (i, (col, val)) in set_pairs.iter().enumerate() {
5077 if i > 0 {
5078 self.write(", ");
5079 }
5080 self.generate_identifier(col)?;
5081 self.write(" = ");
5082 self.generate_expression(val)?;
5083 }
5084
5085 if let Some(ref output) = update.output {
5087 self.generate_output_clause(output)?;
5088 }
5089
5090 if !mysql_like_update_from && !teradata_from_before_set {
5092 if let Some(ref from_clause) = update.from_clause {
5093 self.write_space();
5094 self.write_keyword("FROM");
5095 self.write_space();
5096 for (i, table_expr) in from_clause.expressions.iter().enumerate() {
5098 if i > 0 {
5099 self.write(", ");
5100 }
5101 self.generate_expression(table_expr)?;
5102 }
5103 }
5104 }
5105
5106 if !mysql_like_update_from && !teradata_from_before_set {
5107 for join in &update.from_joins {
5109 self.generate_join(join)?;
5110 }
5111 }
5112
5113 if let Some(where_clause) = &update.where_clause {
5114 self.write_space();
5115 self.write_keyword("WHERE");
5116 self.write_space();
5117 self.generate_expression(&where_clause.this)?;
5118 }
5119
5120 if !update.returning.is_empty() {
5122 self.write_space();
5123 self.write_keyword("RETURNING");
5124 self.write_space();
5125 for (i, expr) in update.returning.iter().enumerate() {
5126 if i > 0 {
5127 self.write(", ");
5128 }
5129 self.generate_expression(expr)?;
5130 }
5131 }
5132
5133 if let Some(ref order_by) = update.order_by {
5135 self.write_space();
5136 self.generate_order_by(order_by)?;
5137 }
5138
5139 if let Some(ref limit) = update.limit {
5141 self.write_space();
5142 self.write_keyword("LIMIT");
5143 self.write_space();
5144 self.generate_expression(limit)?;
5145 }
5146
5147 Ok(())
5148 }
5149
5150 fn generate_delete(&mut self, delete: &Delete) -> Result<()> {
5151 if let Some(with) = &delete.with {
5153 self.generate_with(with)?;
5154 self.write_space();
5155 }
5156
5157 for comment in &delete.leading_comments {
5159 self.write(comment);
5160 self.write(" ");
5161 }
5162
5163 if !delete.tables.is_empty() && !delete.tables_from_using {
5165 self.write_keyword("DELETE");
5167 self.write_space();
5168 for (i, tbl) in delete.tables.iter().enumerate() {
5169 if i > 0 {
5170 self.write(", ");
5171 }
5172 self.generate_table(tbl)?;
5173 }
5174 if let Some(ref output) = delete.output {
5176 self.generate_output_clause(output)?;
5177 }
5178 self.write_space();
5179 self.write_keyword("FROM");
5180 self.write_space();
5181 self.generate_table(&delete.table)?;
5182 } else if !delete.tables.is_empty() && delete.tables_from_using {
5183 self.write_keyword("DELETE FROM");
5185 self.write_space();
5186 for (i, tbl) in delete.tables.iter().enumerate() {
5187 if i > 0 {
5188 self.write(", ");
5189 }
5190 self.generate_table(tbl)?;
5191 }
5192 } else if delete.no_from && matches!(self.config.dialect, Some(DialectType::BigQuery)) {
5193 self.write_keyword("DELETE");
5195 self.write_space();
5196 self.generate_table(&delete.table)?;
5197 } else {
5198 self.write_keyword("DELETE FROM");
5199 self.write_space();
5200 self.generate_table(&delete.table)?;
5201 }
5202
5203 if let Some(ref on_cluster) = delete.on_cluster {
5205 self.write_space();
5206 self.generate_on_cluster(on_cluster)?;
5207 }
5208
5209 if let Some(ref idx) = delete.force_index {
5211 self.write_space();
5212 self.write_keyword("FORCE INDEX");
5213 self.write(" (");
5214 self.write(idx);
5215 self.write(")");
5216 }
5217
5218 if let Some(ref alias) = delete.alias {
5220 self.write_space();
5221 if delete.alias_explicit_as || matches!(self.config.dialect, Some(DialectType::BigQuery)) {
5222 self.write_keyword("AS");
5223 self.write_space();
5224 }
5225 self.generate_identifier(alias)?;
5226 }
5227
5228 if !delete.tables_from_using {
5230 for join in &delete.joins {
5231 self.generate_join(join)?;
5232 }
5233 }
5234
5235 if !delete.using.is_empty() {
5237 self.write_space();
5238 self.write_keyword("USING");
5239 for (i, table) in delete.using.iter().enumerate() {
5240 if i > 0 {
5241 self.write(",");
5242 }
5243 self.write_space();
5244 if !table.hints.is_empty() && table.name.is_empty() {
5246 self.generate_expression(&table.hints[0])?;
5248 if let Some(ref alias) = table.alias {
5249 self.write_space();
5250 if table.alias_explicit_as {
5251 self.write_keyword("AS");
5252 self.write_space();
5253 }
5254 self.generate_identifier(alias)?;
5255 if !table.column_aliases.is_empty() {
5256 self.write("(");
5257 for (j, col_alias) in table.column_aliases.iter().enumerate() {
5258 if j > 0 {
5259 self.write(", ");
5260 }
5261 self.generate_identifier(col_alias)?;
5262 }
5263 self.write(")");
5264 }
5265 }
5266 } else {
5267 self.generate_table(table)?;
5268 }
5269 }
5270 }
5271
5272 if delete.tables_from_using {
5274 for join in &delete.joins {
5275 self.generate_join(join)?;
5276 }
5277 }
5278
5279 let output_already_emitted = !delete.tables.is_empty() && !delete.tables_from_using && delete.output.is_some();
5281 if !output_already_emitted {
5282 if let Some(ref output) = delete.output {
5283 self.generate_output_clause(output)?;
5284 }
5285 }
5286
5287 if let Some(where_clause) = &delete.where_clause {
5288 self.write_space();
5289 self.write_keyword("WHERE");
5290 self.write_space();
5291 self.generate_expression(&where_clause.this)?;
5292 }
5293
5294 if let Some(ref order_by) = delete.order_by {
5296 self.write_space();
5297 self.generate_order_by(order_by)?;
5298 }
5299
5300 if let Some(ref limit) = delete.limit {
5302 self.write_space();
5303 self.write_keyword("LIMIT");
5304 self.write_space();
5305 self.generate_expression(limit)?;
5306 }
5307
5308 if !delete.returning.is_empty() {
5310 self.write_space();
5311 self.write_keyword("RETURNING");
5312 self.write_space();
5313 for (i, expr) in delete.returning.iter().enumerate() {
5314 if i > 0 {
5315 self.write(", ");
5316 }
5317 self.generate_expression(expr)?;
5318 }
5319 }
5320
5321 Ok(())
5322 }
5323
5324 fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> {
5327 let saved_athena_hive_context = self.athena_hive_context;
5331 let is_clickhouse = matches!(self.config.dialect, Some(DialectType::ClickHouse));
5332 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Athena)) {
5333 let is_external = ct.table_modifier.as_ref().map(|m| m.eq_ignore_ascii_case("EXTERNAL")).unwrap_or(false);
5337 let has_as_select = ct.as_select.is_some();
5338 self.athena_hive_context = is_external || !has_as_select;
5339 }
5340
5341 if matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL)) {
5343 if let Some(ref query) = ct.as_select {
5344 if let Some(with_cte) = &ct.with_cte {
5346 self.generate_with(with_cte)?;
5347 self.write_space();
5348 }
5349
5350 self.write_keyword("SELECT");
5352 self.write(" * ");
5353 self.write_keyword("INTO");
5354 self.write_space();
5355
5356 if ct.temporary {
5358 self.write("#");
5359 }
5360 self.generate_table(&ct.name)?;
5361
5362 self.write_space();
5363 self.write_keyword("FROM");
5364 self.write(" (");
5365 let aliased_query = Self::add_column_aliases_to_query(query.clone());
5367 self.generate_expression(&aliased_query)?;
5368 self.write(") ");
5369 self.write_keyword("AS");
5370 self.write(" temp");
5371 return Ok(());
5372 }
5373 }
5374
5375 if let Some(with_cte) = &ct.with_cte {
5377 self.generate_with(with_cte)?;
5378 self.write_space();
5379 }
5380
5381 for comment in &ct.leading_comments {
5383 self.write(comment);
5384 self.write(" ");
5385 }
5386 self.write_keyword("CREATE");
5387
5388 if ct.or_replace {
5389 self.write_space();
5390 self.write_keyword("OR REPLACE");
5391 }
5392
5393 if ct.temporary {
5394 self.write_space();
5395 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
5397 self.write_keyword("GLOBAL TEMPORARY");
5398 } else {
5399 self.write_keyword("TEMPORARY");
5400 }
5401 }
5402
5403 let is_dictionary = ct
5405 .table_modifier
5406 .as_ref()
5407 .map(|m| m.eq_ignore_ascii_case("DICTIONARY"))
5408 .unwrap_or(false);
5409 if let Some(ref modifier) = ct.table_modifier {
5410 let skip_transient = modifier.eq_ignore_ascii_case("TRANSIENT")
5412 && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None);
5413 let is_teradata_modifier = modifier.eq_ignore_ascii_case("VOLATILE")
5415 || modifier.eq_ignore_ascii_case("SET")
5416 || modifier.eq_ignore_ascii_case("MULTISET")
5417 || modifier.to_uppercase().contains("VOLATILE")
5418 || modifier.to_uppercase().starts_with("SET ")
5419 || modifier.to_uppercase().starts_with("MULTISET ");
5420 let skip_teradata = is_teradata_modifier
5421 && !matches!(self.config.dialect, Some(DialectType::Teradata));
5422 if !skip_transient && !skip_teradata {
5423 self.write_space();
5424 self.write_keyword(modifier);
5425 }
5426 }
5427
5428 if !is_dictionary {
5429 self.write_space();
5430 self.write_keyword("TABLE");
5431 }
5432
5433 if ct.if_not_exists {
5434 self.write_space();
5435 self.write_keyword("IF NOT EXISTS");
5436 }
5437
5438 self.write_space();
5439 self.generate_table(&ct.name)?;
5440
5441 if let Some(ref on_cluster) = ct.on_cluster {
5443 self.write_space();
5444 self.generate_on_cluster(on_cluster)?;
5445 }
5446
5447 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Teradata))
5449 && !ct.teradata_post_name_options.is_empty()
5450 {
5451 for opt in &ct.teradata_post_name_options {
5452 self.write(", ");
5453 self.write(opt);
5454 }
5455 }
5456
5457 if ct.copy_grants {
5459 self.write_space();
5460 self.write_keyword("COPY GRANTS");
5461 }
5462
5463 if let Some(ref using_template) = ct.using_template {
5465 self.write_space();
5466 self.write_keyword("USING TEMPLATE");
5467 self.write_space();
5468 self.generate_expression(using_template)?;
5469 return Ok(());
5470 }
5471
5472 if let Some(ref clone_source) = ct.clone_source {
5474 self.write_space();
5475 if ct.is_copy && self.config.supports_table_copy {
5476 self.write_keyword("COPY");
5478 } else if ct.shallow_clone {
5479 self.write_keyword("SHALLOW CLONE");
5480 } else {
5481 self.write_keyword("CLONE");
5482 }
5483 self.write_space();
5484 self.generate_table(clone_source)?;
5485 if let Some(ref at_clause) = ct.clone_at_clause {
5487 self.write_space();
5488 self.generate_expression(at_clause)?;
5489 }
5490 return Ok(());
5491 }
5492
5493 if let Some(ref partition_of) = ct.partition_of {
5497 self.write_space();
5498
5499 if let Expression::PartitionedOfProperty(ref pop) = partition_of {
5501 self.write_keyword("PARTITION OF");
5503 self.write_space();
5504 self.generate_expression(&pop.this)?;
5505
5506 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
5508 self.write(" (");
5509 let mut first = true;
5510 for col in &ct.columns {
5511 if !first {
5512 self.write(", ");
5513 }
5514 first = false;
5515 self.generate_column_def(col)?;
5516 }
5517 for constraint in &ct.constraints {
5518 if !first {
5519 self.write(", ");
5520 }
5521 first = false;
5522 self.generate_table_constraint(constraint)?;
5523 }
5524 self.write(")");
5525 }
5526
5527 if let Expression::PartitionBoundSpec(_) = pop.expression.as_ref() {
5529 self.write_space();
5530 self.write_keyword("FOR VALUES");
5531 self.write_space();
5532 self.generate_expression(&pop.expression)?;
5533 } else {
5534 self.write_space();
5535 self.write_keyword("DEFAULT");
5536 }
5537 } else {
5538 self.generate_expression(partition_of)?;
5540
5541 if !ct.columns.is_empty() || !ct.constraints.is_empty() {
5543 self.write(" (");
5544 let mut first = true;
5545 for col in &ct.columns {
5546 if !first {
5547 self.write(", ");
5548 }
5549 first = false;
5550 self.generate_column_def(col)?;
5551 }
5552 for constraint in &ct.constraints {
5553 if !first {
5554 self.write(", ");
5555 }
5556 first = false;
5557 self.generate_table_constraint(constraint)?;
5558 }
5559 self.write(")");
5560 }
5561 }
5562
5563 for prop in &ct.properties {
5565 self.write_space();
5566 self.generate_expression(prop)?;
5567 }
5568
5569 return Ok(());
5570 }
5571
5572 self.sqlite_inline_pk_columns.clear();
5575 if matches!(self.config.dialect, Some(crate::dialects::DialectType::SQLite)) {
5576 for constraint in &ct.constraints {
5577 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
5578 if columns.len() == 1 && name.is_none() {
5580 let pk_col_name = columns[0].name.to_lowercase();
5581 if ct.columns.iter().any(|c| c.name.name.to_lowercase() == pk_col_name) {
5583 self.sqlite_inline_pk_columns.insert(pk_col_name);
5584 }
5585 }
5586 }
5587 }
5588 }
5589
5590 if !ct.columns.is_empty() {
5592 if self.config.pretty {
5593 self.write(" (");
5595 self.write_newline();
5596 self.indent_level += 1;
5597 for (i, col) in ct.columns.iter().enumerate() {
5598 if i > 0 {
5599 self.write(",");
5600 self.write_newline();
5601 }
5602 self.write_indent();
5603 self.generate_column_def(col)?;
5604 }
5605 for constraint in &ct.constraints {
5607 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
5609 if columns.len() == 1 && name.is_none() &&
5610 self.sqlite_inline_pk_columns.contains(&columns[0].name.to_lowercase()) {
5611 continue;
5612 }
5613 }
5614 self.write(",");
5615 self.write_newline();
5616 self.write_indent();
5617 self.generate_table_constraint(constraint)?;
5618 }
5619 self.indent_level -= 1;
5620 self.write_newline();
5621 self.write(")");
5622 } else {
5623 self.write(" (");
5624 for (i, col) in ct.columns.iter().enumerate() {
5625 if i > 0 {
5626 self.write(", ");
5627 }
5628 self.generate_column_def(col)?;
5629 }
5630 let mut first_constraint = true;
5632 for constraint in &ct.constraints {
5633 if let TableConstraint::PrimaryKey { columns, name, .. } = constraint {
5635 if columns.len() == 1 && name.is_none() &&
5636 self.sqlite_inline_pk_columns.contains(&columns[0].name.to_lowercase()) {
5637 continue;
5638 }
5639 }
5640 if first_constraint {
5641 self.write(", ");
5642 first_constraint = false;
5643 } else {
5644 self.write(", ");
5645 }
5646 self.generate_table_constraint(constraint)?;
5647 }
5648 self.write(")");
5649 }
5650 } else if !ct.constraints.is_empty() {
5651 let has_like_only = ct.constraints.iter().all(|c| matches!(c, TableConstraint::Like { .. }));
5653 let has_tags_only = ct.constraints.iter().all(|c| matches!(c, TableConstraint::Tags(_)));
5654 let is_mysql = matches!(self.config.dialect, Some(crate::dialects::DialectType::MySQL) | Some(crate::dialects::DialectType::SingleStore) | Some(crate::dialects::DialectType::TiDB));
5658 let use_parens = !(has_like_only && is_mysql) && !has_tags_only;
5659 if self.config.pretty && use_parens {
5660 self.write(" (");
5661 self.write_newline();
5662 self.indent_level += 1;
5663 for (i, constraint) in ct.constraints.iter().enumerate() {
5664 if i > 0 {
5665 self.write(",");
5666 self.write_newline();
5667 }
5668 self.write_indent();
5669 self.generate_table_constraint(constraint)?;
5670 }
5671 self.indent_level -= 1;
5672 self.write_newline();
5673 self.write(")");
5674 } else {
5675 if use_parens {
5676 self.write(" (");
5677 } else {
5678 self.write_space();
5679 }
5680 for (i, constraint) in ct.constraints.iter().enumerate() {
5681 if i > 0 {
5682 self.write(", ");
5683 }
5684 self.generate_table_constraint(constraint)?;
5685 }
5686 if use_parens {
5687 self.write(")");
5688 }
5689 }
5690 }
5691
5692 if let Some(ref on_prop) = ct.on_property {
5694 self.write(" ");
5695 self.write_keyword("ON");
5696 self.write(" ");
5697 self.generate_expression(&on_prop.this)?;
5698 }
5699
5700 if !is_clickhouse {
5703 for prop in &ct.properties {
5704 if let Expression::SchemaCommentProperty(_) = prop {
5705 if self.config.pretty {
5706 self.write_newline();
5707 } else {
5708 self.write_space();
5709 }
5710 self.generate_expression(prop)?;
5711 }
5712 }
5713 }
5714
5715 if !ct.with_properties.is_empty() {
5717 let is_snowflake_special_table = matches!(self.config.dialect, Some(crate::dialects::DialectType::Snowflake))
5719 && (ct.table_modifier.as_deref() == Some("ICEBERG") || ct.table_modifier.as_deref() == Some("DYNAMIC"));
5720 if is_snowflake_special_table {
5721 for (key, value) in &ct.with_properties {
5722 self.write_space();
5723 self.write(key);
5724 self.write("=");
5725 self.write(value);
5726 }
5727 } else if self.config.pretty {
5728 self.write_newline();
5729 self.write_keyword("WITH");
5730 self.write(" (");
5731 self.write_newline();
5732 self.indent_level += 1;
5733 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
5734 if i > 0 {
5735 self.write(",");
5736 self.write_newline();
5737 }
5738 self.write_indent();
5739 self.write(key);
5740 self.write("=");
5741 self.write(value);
5742 }
5743 self.indent_level -= 1;
5744 self.write_newline();
5745 self.write(")");
5746 } else {
5747 self.write_space();
5748 self.write_keyword("WITH");
5749 self.write(" (");
5750 for (i, (key, value)) in ct.with_properties.iter().enumerate() {
5751 if i > 0 {
5752 self.write(", ");
5753 }
5754 self.write(key);
5755 self.write("=");
5756 self.write(value);
5757 }
5758 self.write(")");
5759 }
5760 }
5761
5762 let (pre_as_properties, post_as_properties): (Vec<&Expression>, Vec<&Expression>) = if is_clickhouse && ct.as_select.is_some() {
5763 let mut pre = Vec::new();
5764 let mut post = Vec::new();
5765 for prop in &ct.properties {
5766 if matches!(prop, Expression::SchemaCommentProperty(_)) {
5767 post.push(prop);
5768 } else {
5769 pre.push(prop);
5770 }
5771 }
5772 (pre, post)
5773 } else {
5774 (ct.properties.iter().collect(), Vec::new())
5775 };
5776
5777 for prop in pre_as_properties {
5779 if !is_clickhouse && matches!(prop, Expression::SchemaCommentProperty(_)) {
5781 continue;
5782 }
5783 if self.config.pretty {
5784 self.write_newline();
5785 } else {
5786 self.write_space();
5787 }
5788 if let Expression::Properties(props) = prop {
5792 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));
5793 let is_doris_starrocks = matches!(self.config.dialect, Some(crate::dialects::DialectType::Doris) | Some(crate::dialects::DialectType::StarRocks));
5794 if is_hive_dialect {
5795 self.generate_tblproperties_clause(&props.expressions)?;
5796 } else if is_doris_starrocks {
5797 self.generate_properties_clause(&props.expressions)?;
5798 } else {
5799 self.generate_options_clause(&props.expressions)?;
5800 }
5801 } else {
5802 self.generate_expression(prop)?;
5803 }
5804 }
5805
5806 for prop in &ct.post_table_properties {
5808 if let Expression::WithSystemVersioningProperty(ref svp) = prop {
5809 self.write(" WITH(");
5810 self.generate_system_versioning_content(svp)?;
5811 self.write(")");
5812 } else if let Expression::Properties(props) = prop {
5813 let is_doris_starrocks = matches!(self.config.dialect, Some(crate::dialects::DialectType::Doris) | Some(crate::dialects::DialectType::StarRocks));
5815 self.write_space();
5816 if is_doris_starrocks {
5817 self.generate_properties_clause(&props.expressions)?;
5818 } else {
5819 self.generate_options_clause(&props.expressions)?;
5820 }
5821 } else {
5822 self.write_space();
5823 self.generate_expression(prop)?;
5824 }
5825 }
5826
5827 if let Some(ref rollup) = ct.rollup {
5830 if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
5831 self.write_space();
5832 self.generate_rollup_property(rollup)?;
5833 }
5834 }
5835
5836 let is_mysql_compatible = matches!(self.config.dialect,
5840 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::Doris) | Some(DialectType::StarRocks) | None
5841 );
5842 let is_hive_compatible = matches!(self.config.dialect,
5843 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Athena)
5844 );
5845 let mysql_pretty_options = self.config.pretty && matches!(self.config.dialect, Some(DialectType::MySQL));
5846 for (key, value) in &ct.mysql_table_options {
5847 let should_output = if is_mysql_compatible {
5849 true
5850 } else if is_hive_compatible && key == "COMMENT" {
5851 true } else {
5853 false
5854 };
5855 if should_output {
5856 if mysql_pretty_options {
5857 self.write_newline();
5858 self.write_indent();
5859 } else {
5860 self.write_space();
5861 }
5862 self.write_keyword(key);
5863 if key == "COMMENT" && !self.config.schema_comment_with_eq {
5865 self.write_space();
5866 } else {
5867 self.write("=");
5868 }
5869 self.write(value);
5870 }
5871 }
5872
5873 if ct.temporary
5875 && matches!(self.config.dialect, Some(DialectType::Spark) | Some(DialectType::Databricks))
5876 && ct.as_select.is_none()
5877 {
5878 self.write_space();
5879 self.write_keyword("USING PARQUET");
5880 }
5881
5882 if !ct.inherits.is_empty() {
5884 self.write_space();
5885 self.write_keyword("INHERITS");
5886 self.write(" (");
5887 for (i, parent) in ct.inherits.iter().enumerate() {
5888 if i > 0 {
5889 self.write(", ");
5890 }
5891 self.generate_table(parent)?;
5892 }
5893 self.write(")");
5894 }
5895
5896 if let Some(ref query) = ct.as_select {
5898 self.write_space();
5899 self.write_keyword("AS");
5900 self.write_space();
5901 if ct.as_select_parenthesized {
5902 self.write("(");
5903 }
5904 self.generate_expression(query)?;
5905 if ct.as_select_parenthesized {
5906 self.write(")");
5907 }
5908
5909 if let Some(with_data) = ct.with_data {
5911 self.write_space();
5912 self.write_keyword("WITH");
5913 if !with_data {
5914 self.write_space();
5915 self.write_keyword("NO");
5916 }
5917 self.write_space();
5918 self.write_keyword("DATA");
5919 }
5920
5921 if let Some(with_statistics) = ct.with_statistics {
5923 self.write_space();
5924 self.write_keyword("AND");
5925 if !with_statistics {
5926 self.write_space();
5927 self.write_keyword("NO");
5928 }
5929 self.write_space();
5930 self.write_keyword("STATISTICS");
5931 }
5932
5933 for index in &ct.teradata_indexes {
5935 self.write_space();
5936 match index.kind {
5937 TeradataIndexKind::NoPrimary => {
5938 self.write_keyword("NO PRIMARY INDEX");
5939 }
5940 TeradataIndexKind::Primary => {
5941 self.write_keyword("PRIMARY INDEX");
5942 }
5943 TeradataIndexKind::PrimaryAmp => {
5944 self.write_keyword("PRIMARY AMP INDEX");
5945 }
5946 TeradataIndexKind::Unique => {
5947 self.write_keyword("UNIQUE INDEX");
5948 }
5949 TeradataIndexKind::UniquePrimary => {
5950 self.write_keyword("UNIQUE PRIMARY INDEX");
5951 }
5952 TeradataIndexKind::Secondary => {
5953 self.write_keyword("INDEX");
5954 }
5955 }
5956 if let Some(ref name) = index.name {
5958 self.write_space();
5959 self.write(name);
5960 }
5961 if !index.columns.is_empty() {
5963 self.write(" (");
5964 for (i, col) in index.columns.iter().enumerate() {
5965 if i > 0 {
5966 self.write(", ");
5967 }
5968 self.write(col);
5969 }
5970 self.write(")");
5971 }
5972 }
5973
5974 if let Some(ref on_commit) = ct.on_commit {
5976 self.write_space();
5977 self.write_keyword("ON COMMIT");
5978 self.write_space();
5979 match on_commit {
5980 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
5981 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
5982 }
5983 }
5984
5985 if !post_as_properties.is_empty() {
5986 for prop in post_as_properties {
5987 self.write_space();
5988 self.generate_expression(prop)?;
5989 }
5990 }
5991
5992 self.athena_hive_context = saved_athena_hive_context;
5994 return Ok(());
5995 }
5996
5997 if let Some(ref on_commit) = ct.on_commit {
5999 self.write_space();
6000 self.write_keyword("ON COMMIT");
6001 self.write_space();
6002 match on_commit {
6003 OnCommit::PreserveRows => self.write_keyword("PRESERVE ROWS"),
6004 OnCommit::DeleteRows => self.write_keyword("DELETE ROWS"),
6005 }
6006 }
6007
6008 self.athena_hive_context = saved_athena_hive_context;
6010
6011 Ok(())
6012 }
6013
6014 fn generate_column_def_expr(&mut self, col: &ColumnDef) -> Result<()> {
6017 self.generate_identifier(&col.name)?;
6019 if !matches!(col.data_type, DataType::Unknown) {
6021 self.write_space();
6022 self.generate_data_type(&col.data_type)?;
6023 }
6024 for constraint in &col.constraints {
6026 if let ColumnConstraint::Path(path_expr) = constraint {
6027 self.write_space();
6028 self.write_keyword("PATH");
6029 self.write_space();
6030 self.generate_expression(path_expr)?;
6031 }
6032 }
6033 Ok(())
6034 }
6035
6036 fn generate_column_def(&mut self, col: &ColumnDef) -> Result<()> {
6037 let has_computed_no_type = matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
6039 && col.constraints.iter().any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
6040 let omit_computed_type = !self.config.computed_column_with_type
6042 && col.constraints.iter().any(|c| matches!(c, ColumnConstraint::ComputedColumn(_)));
6043
6044 let is_partition_column_spec = matches!(col.data_type, DataType::Unknown);
6047
6048 let has_no_type = col.no_type || (matches!(&col.data_type, DataType::Custom { name } if name.is_empty())
6051 && col.constraints.is_empty());
6052
6053 self.generate_identifier(&col.name)?;
6054
6055 let serial_expansion = if matches!(self.config.dialect, Some(DialectType::Materialize) | Some(DialectType::PostgreSQL)) {
6057 if let DataType::Custom { ref name } = col.data_type {
6058 match name.to_uppercase().as_str() {
6059 "SERIAL" => Some("INT"),
6060 "BIGSERIAL" => Some("BIGINT"),
6061 "SMALLSERIAL" => Some("SMALLINT"),
6062 _ => None,
6063 }
6064 } else {
6065 None
6066 }
6067 } else {
6068 None
6069 };
6070
6071 if !has_computed_no_type && !omit_computed_type && !is_partition_column_spec && !has_no_type {
6072 self.write_space();
6073 if let Some(int_type) = serial_expansion {
6074 self.write_keyword(int_type);
6076 } else if col.unsigned && matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6077 let unsigned_type = match &col.data_type {
6079 DataType::Int { .. } => Some("UINTEGER"),
6080 DataType::BigInt { .. } => Some("UBIGINT"),
6081 DataType::SmallInt { .. } => Some("USMALLINT"),
6082 DataType::TinyInt { .. } => Some("UTINYINT"),
6083 _ => None,
6084 };
6085 if let Some(utype) = unsigned_type {
6086 self.write_keyword(utype);
6087 } else {
6088 self.generate_data_type(&col.data_type)?;
6089 }
6090 } else {
6091 self.generate_data_type(&col.data_type)?;
6092 }
6093 }
6094
6095 if col.unsigned && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
6098 self.write_space();
6099 self.write_keyword("UNSIGNED");
6100 }
6101 if col.zerofill {
6102 self.write_space();
6103 self.write_keyword("ZEROFILL");
6104 }
6105
6106 if let Some(ref charset) = col.character_set {
6110 self.write_space();
6111 self.write_keyword("CHARACTER SET");
6112 self.write_space();
6113 self.write(charset);
6114 }
6115
6116 if col.uppercase {
6117 self.write_space();
6118 self.write_keyword("UPPERCASE");
6119 }
6120
6121 if let Some(casespecific) = col.casespecific {
6122 self.write_space();
6123 if casespecific {
6124 self.write_keyword("CASESPECIFIC");
6125 } else {
6126 self.write_keyword("NOT CASESPECIFIC");
6127 }
6128 }
6129
6130 if let Some(ref format) = col.format {
6131 self.write_space();
6132 self.write_keyword("FORMAT");
6133 self.write(" '");
6134 self.write(format);
6135 self.write("'");
6136 }
6137
6138 if let Some(ref title) = col.title {
6139 self.write_space();
6140 self.write_keyword("TITLE");
6141 self.write(" '");
6142 self.write(title);
6143 self.write("'");
6144 }
6145
6146 if let Some(length) = col.inline_length {
6147 self.write_space();
6148 self.write_keyword("INLINE LENGTH");
6149 self.write(" ");
6150 self.write(&length.to_string());
6151 }
6152
6153 if let Some(ref compress) = col.compress {
6154 self.write_space();
6155 self.write_keyword("COMPRESS");
6156 if !compress.is_empty() {
6157 if compress.len() == 1 {
6159 if let Expression::Literal(Literal::String(_)) = &compress[0] {
6160 self.write_space();
6161 self.generate_expression(&compress[0])?;
6162 } else {
6163 self.write(" (");
6164 self.generate_expression(&compress[0])?;
6165 self.write(")");
6166 }
6167 } else {
6168 self.write(" (");
6169 for (i, val) in compress.iter().enumerate() {
6170 if i > 0 {
6171 self.write(", ");
6172 }
6173 self.generate_expression(val)?;
6174 }
6175 self.write(")");
6176 }
6177 }
6178 }
6179
6180 if !col.constraint_order.is_empty() {
6183 let mut references_idx = 0;
6186 let mut check_idx = 0;
6187 let mut generated_idx = 0;
6188 let mut collate_idx = 0;
6189 let mut comment_idx = 0;
6190 let defer_not_null_after_identity = false;
6193 let mut pending_not_null_after_identity = false;
6194
6195 for constraint_type in &col.constraint_order {
6196 match constraint_type {
6197 ConstraintType::PrimaryKey => {
6198 if col.primary_key && !matches!(self.config.dialect, Some(DialectType::Materialize)) {
6200 if let Some(ref cname) = col.primary_key_constraint_name {
6201 self.write_space();
6202 self.write_keyword("CONSTRAINT");
6203 self.write_space();
6204 self.write(cname);
6205 }
6206 self.write_space();
6207 self.write_keyword("PRIMARY KEY");
6208 if let Some(ref order) = col.primary_key_order {
6209 self.write_space();
6210 match order {
6211 SortOrder::Asc => self.write_keyword("ASC"),
6212 SortOrder::Desc => self.write_keyword("DESC"),
6213 }
6214 }
6215 }
6216 }
6217 ConstraintType::Unique => {
6218 if col.unique {
6219 if let Some(ref cname) = col.unique_constraint_name {
6220 self.write_space();
6221 self.write_keyword("CONSTRAINT");
6222 self.write_space();
6223 self.write(cname);
6224 }
6225 self.write_space();
6226 self.write_keyword("UNIQUE");
6227 if col.unique_nulls_not_distinct {
6229 self.write(" NULLS NOT DISTINCT");
6230 }
6231 }
6232 }
6233 ConstraintType::NotNull => {
6234 if col.nullable == Some(false) {
6235 if defer_not_null_after_identity {
6236 pending_not_null_after_identity = true;
6237 continue;
6238 }
6239 if let Some(ref cname) = col.not_null_constraint_name {
6240 self.write_space();
6241 self.write_keyword("CONSTRAINT");
6242 self.write_space();
6243 self.write(cname);
6244 }
6245 self.write_space();
6246 self.write_keyword("NOT NULL");
6247 }
6248 }
6249 ConstraintType::Null => {
6250 if col.nullable == Some(true) {
6251 self.write_space();
6252 self.write_keyword("NULL");
6253 }
6254 }
6255 ConstraintType::Default => {
6256 if let Some(ref default) = col.default {
6257 self.write_space();
6258 self.write_keyword("DEFAULT");
6259 self.write_space();
6260 self.generate_expression(default)?;
6261 }
6262 }
6263 ConstraintType::AutoIncrement => {
6264 if col.auto_increment {
6265 if matches!(self.config.dialect, Some(crate::dialects::DialectType::DuckDB)) {
6267 } else if matches!(self.config.dialect, Some(crate::dialects::DialectType::Materialize)) {
6269 if !matches!(col.nullable, Some(false)) {
6271 self.write_space();
6272 self.write_keyword("NOT NULL");
6273 }
6274 } else {
6275 self.write_space();
6276 self.generate_auto_increment_keyword(col)?;
6277 if pending_not_null_after_identity {
6278 self.write_space();
6279 self.write_keyword("NOT NULL");
6280 pending_not_null_after_identity = false;
6281 }
6282 }
6283 } }
6285 ConstraintType::References => {
6286 while references_idx < col.constraints.len() {
6288 if let ColumnConstraint::References(fk_ref) = &col.constraints[references_idx] {
6289 if let Some(ref name) = fk_ref.constraint_name {
6291 self.write_space();
6292 self.write_keyword("CONSTRAINT");
6293 self.write_space();
6294 self.write(name);
6295 }
6296 self.write_space();
6297 if fk_ref.has_foreign_key_keywords {
6298 self.write_keyword("FOREIGN KEY");
6299 self.write_space();
6300 }
6301 self.write_keyword("REFERENCES");
6302 self.write_space();
6303 self.generate_table(&fk_ref.table)?;
6304 if !fk_ref.columns.is_empty() {
6305 self.write(" (");
6306 for (i, c) in fk_ref.columns.iter().enumerate() {
6307 if i > 0 {
6308 self.write(", ");
6309 }
6310 self.generate_identifier(c)?;
6311 }
6312 self.write(")");
6313 }
6314 self.generate_referential_actions(fk_ref)?;
6315 references_idx += 1;
6316 break;
6317 }
6318 references_idx += 1;
6319 }
6320 }
6321 ConstraintType::Check => {
6322 while check_idx < col.constraints.len() {
6324 if let ColumnConstraint::Check(expr) = &col.constraints[check_idx] {
6325 if check_idx == 0 {
6327 if let Some(ref cname) = col.check_constraint_name {
6328 self.write_space();
6329 self.write_keyword("CONSTRAINT");
6330 self.write_space();
6331 self.write(cname);
6332 }
6333 }
6334 self.write_space();
6335 self.write_keyword("CHECK");
6336 self.write(" (");
6337 self.generate_expression(expr)?;
6338 self.write(")");
6339 check_idx += 1;
6340 break;
6341 }
6342 check_idx += 1;
6343 }
6344 }
6345 ConstraintType::GeneratedAsIdentity => {
6346 while generated_idx < col.constraints.len() {
6348 if let ColumnConstraint::GeneratedAsIdentity(gen) = &col.constraints[generated_idx] {
6349 self.write_space();
6350 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Redshift)) {
6352 self.write_keyword("IDENTITY");
6353 self.write("(");
6354 if let Some(ref start) = gen.start {
6355 self.generate_expression(start)?;
6356 } else {
6357 self.write("0");
6358 }
6359 self.write(", ");
6360 if let Some(ref incr) = gen.increment {
6361 self.generate_expression(incr)?;
6362 } else {
6363 self.write("1");
6364 }
6365 self.write(")");
6366 } else {
6367 self.write_keyword("GENERATED");
6368 if gen.always {
6369 self.write_space();
6370 self.write_keyword("ALWAYS");
6371 } else {
6372 self.write_space();
6373 self.write_keyword("BY DEFAULT");
6374 if gen.on_null {
6375 self.write_space();
6376 self.write_keyword("ON NULL");
6377 }
6378 }
6379 self.write_space();
6380 self.write_keyword("AS IDENTITY");
6381
6382 let has_options = gen.start.is_some() || gen.increment.is_some()
6383 || gen.minvalue.is_some() || gen.maxvalue.is_some() || gen.cycle.is_some();
6384 if has_options {
6385 self.write(" (");
6386 let mut first = true;
6387 if let Some(ref start) = gen.start {
6388 if !first { self.write(" "); }
6389 first = false;
6390 self.write_keyword("START WITH");
6391 self.write_space();
6392 self.generate_expression(start)?;
6393 }
6394 if let Some(ref incr) = gen.increment {
6395 if !first { self.write(" "); }
6396 first = false;
6397 self.write_keyword("INCREMENT BY");
6398 self.write_space();
6399 self.generate_expression(incr)?;
6400 }
6401 if let Some(ref minv) = gen.minvalue {
6402 if !first { self.write(" "); }
6403 first = false;
6404 self.write_keyword("MINVALUE");
6405 self.write_space();
6406 self.generate_expression(minv)?;
6407 }
6408 if let Some(ref maxv) = gen.maxvalue {
6409 if !first { self.write(" "); }
6410 first = false;
6411 self.write_keyword("MAXVALUE");
6412 self.write_space();
6413 self.generate_expression(maxv)?;
6414 }
6415 if let Some(cycle) = gen.cycle {
6416 if !first { self.write(" "); }
6417 if cycle {
6418 self.write_keyword("CYCLE");
6419 } else {
6420 self.write_keyword("NO CYCLE");
6421 }
6422 }
6423 self.write(")");
6424 }
6425 }
6426 generated_idx += 1;
6427 break;
6428 }
6429 generated_idx += 1;
6430 }
6431 }
6432 ConstraintType::Collate => {
6433 while collate_idx < col.constraints.len() {
6435 if let ColumnConstraint::Collate(collation) = &col.constraints[collate_idx] {
6436 self.write_space();
6437 self.write_keyword("COLLATE");
6438 self.write_space();
6439 self.generate_identifier(collation)?;
6440 collate_idx += 1;
6441 break;
6442 }
6443 collate_idx += 1;
6444 }
6445 }
6446 ConstraintType::Comment => {
6447 while comment_idx < col.constraints.len() {
6449 if let ColumnConstraint::Comment(comment) = &col.constraints[comment_idx] {
6450 self.write_space();
6451 self.write_keyword("COMMENT");
6452 self.write_space();
6453 self.generate_string_literal(comment)?;
6454 comment_idx += 1;
6455 break;
6456 }
6457 comment_idx += 1;
6458 }
6459 }
6460 ConstraintType::Tags => {
6461 for constraint in &col.constraints {
6463 if let ColumnConstraint::Tags(tags) = constraint {
6464 self.write_space();
6465 self.write_keyword("TAG");
6466 self.write(" (");
6467 for (i, expr) in tags.expressions.iter().enumerate() {
6468 if i > 0 {
6469 self.write(", ");
6470 }
6471 self.generate_expression(expr)?;
6472 }
6473 self.write(")");
6474 break;
6475 }
6476 }
6477 }
6478 ConstraintType::ComputedColumn => {
6479 for constraint in &col.constraints {
6481 if let ColumnConstraint::ComputedColumn(cc) = constraint {
6482 self.write_space();
6483 self.generate_computed_column_inline(cc)?;
6484 break;
6485 }
6486 }
6487 }
6488 ConstraintType::GeneratedAsRow => {
6489 for constraint in &col.constraints {
6491 if let ColumnConstraint::GeneratedAsRow(gar) = constraint {
6492 self.write_space();
6493 self.generate_generated_as_row_inline(gar)?;
6494 break;
6495 }
6496 }
6497 }
6498 ConstraintType::OnUpdate => {
6499 if let Some(ref expr) = col.on_update {
6500 self.write_space();
6501 self.write_keyword("ON UPDATE");
6502 self.write_space();
6503 self.generate_expression(expr)?;
6504 }
6505 }
6506 ConstraintType::Encode => {
6507 if let Some(ref encoding) = col.encoding {
6508 self.write_space();
6509 self.write_keyword("ENCODE");
6510 self.write_space();
6511 self.write(encoding);
6512 }
6513 }
6514 ConstraintType::Path => {
6515 for constraint in &col.constraints {
6517 if let ColumnConstraint::Path(path_expr) = constraint {
6518 self.write_space();
6519 self.write_keyword("PATH");
6520 self.write_space();
6521 self.generate_expression(path_expr)?;
6522 break;
6523 }
6524 }
6525 }
6526 }
6527 }
6528 if pending_not_null_after_identity {
6529 self.write_space();
6530 self.write_keyword("NOT NULL");
6531 }
6532 } else {
6533 if col.primary_key {
6535 self.write_space();
6536 self.write_keyword("PRIMARY KEY");
6537 if let Some(ref order) = col.primary_key_order {
6538 self.write_space();
6539 match order {
6540 SortOrder::Asc => self.write_keyword("ASC"),
6541 SortOrder::Desc => self.write_keyword("DESC"),
6542 }
6543 }
6544 }
6545
6546 if col.unique {
6547 self.write_space();
6548 self.write_keyword("UNIQUE");
6549 if col.unique_nulls_not_distinct {
6551 self.write(" NULLS NOT DISTINCT");
6552 }
6553 }
6554
6555 match col.nullable {
6556 Some(false) => {
6557 self.write_space();
6558 self.write_keyword("NOT NULL");
6559 }
6560 Some(true) => {
6561 self.write_space();
6562 self.write_keyword("NULL");
6563 }
6564 None => {}
6565 }
6566
6567 if let Some(ref default) = col.default {
6568 self.write_space();
6569 self.write_keyword("DEFAULT");
6570 self.write_space();
6571 self.generate_expression(default)?;
6572 }
6573
6574 if col.auto_increment {
6575 self.write_space();
6576 self.generate_auto_increment_keyword(col)?;
6577 }
6578
6579 for constraint in &col.constraints {
6581 match constraint {
6582 ColumnConstraint::References(fk_ref) => {
6583 self.write_space();
6584 if fk_ref.has_foreign_key_keywords {
6585 self.write_keyword("FOREIGN KEY");
6586 self.write_space();
6587 }
6588 self.write_keyword("REFERENCES");
6589 self.write_space();
6590 self.generate_table(&fk_ref.table)?;
6591 if !fk_ref.columns.is_empty() {
6592 self.write(" (");
6593 for (i, c) in fk_ref.columns.iter().enumerate() {
6594 if i > 0 {
6595 self.write(", ");
6596 }
6597 self.generate_identifier(c)?;
6598 }
6599 self.write(")");
6600 }
6601 self.generate_referential_actions(fk_ref)?;
6602 }
6603 ColumnConstraint::Check(expr) => {
6604 self.write_space();
6605 self.write_keyword("CHECK");
6606 self.write(" (");
6607 self.generate_expression(expr)?;
6608 self.write(")");
6609 }
6610 ColumnConstraint::GeneratedAsIdentity(gen) => {
6611 self.write_space();
6612 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Redshift)) {
6614 self.write_keyword("IDENTITY");
6615 self.write("(");
6616 if let Some(ref start) = gen.start {
6617 self.generate_expression(start)?;
6618 } else {
6619 self.write("0");
6620 }
6621 self.write(", ");
6622 if let Some(ref incr) = gen.increment {
6623 self.generate_expression(incr)?;
6624 } else {
6625 self.write("1");
6626 }
6627 self.write(")");
6628 } else {
6629 self.write_keyword("GENERATED");
6630 if gen.always {
6631 self.write_space();
6632 self.write_keyword("ALWAYS");
6633 } else {
6634 self.write_space();
6635 self.write_keyword("BY DEFAULT");
6636 if gen.on_null {
6637 self.write_space();
6638 self.write_keyword("ON NULL");
6639 }
6640 }
6641 self.write_space();
6642 self.write_keyword("AS IDENTITY");
6643
6644 let has_options = gen.start.is_some() || gen.increment.is_some()
6645 || gen.minvalue.is_some() || gen.maxvalue.is_some() || gen.cycle.is_some();
6646 if has_options {
6647 self.write(" (");
6648 let mut first = true;
6649 if let Some(ref start) = gen.start {
6650 if !first { self.write(" "); }
6651 first = false;
6652 self.write_keyword("START WITH");
6653 self.write_space();
6654 self.generate_expression(start)?;
6655 }
6656 if let Some(ref incr) = gen.increment {
6657 if !first { self.write(" "); }
6658 first = false;
6659 self.write_keyword("INCREMENT BY");
6660 self.write_space();
6661 self.generate_expression(incr)?;
6662 }
6663 if let Some(ref minv) = gen.minvalue {
6664 if !first { self.write(" "); }
6665 first = false;
6666 self.write_keyword("MINVALUE");
6667 self.write_space();
6668 self.generate_expression(minv)?;
6669 }
6670 if let Some(ref maxv) = gen.maxvalue {
6671 if !first { self.write(" "); }
6672 first = false;
6673 self.write_keyword("MAXVALUE");
6674 self.write_space();
6675 self.generate_expression(maxv)?;
6676 }
6677 if let Some(cycle) = gen.cycle {
6678 if !first { self.write(" "); }
6679 if cycle {
6680 self.write_keyword("CYCLE");
6681 } else {
6682 self.write_keyword("NO CYCLE");
6683 }
6684 }
6685 self.write(")");
6686 }
6687 }
6688 }
6689 ColumnConstraint::Collate(collation) => {
6690 self.write_space();
6691 self.write_keyword("COLLATE");
6692 self.write_space();
6693 self.generate_identifier(collation)?;
6694 }
6695 ColumnConstraint::Comment(comment) => {
6696 self.write_space();
6697 self.write_keyword("COMMENT");
6698 self.write_space();
6699 self.generate_string_literal(comment)?;
6700 }
6701 ColumnConstraint::Path(path_expr) => {
6702 self.write_space();
6703 self.write_keyword("PATH");
6704 self.write_space();
6705 self.generate_expression(path_expr)?;
6706 }
6707 _ => {} }
6709 }
6710
6711 if let Some(ref encoding) = col.encoding {
6713 self.write_space();
6714 self.write_keyword("ENCODE");
6715 self.write_space();
6716 self.write(encoding);
6717 }
6718 }
6719
6720 if let Some(ref codec) = col.codec {
6722 self.write_space();
6723 self.write_keyword("CODEC");
6724 self.write("(");
6725 self.write(codec);
6726 self.write(")");
6727 }
6728
6729 if let Some(ref ephemeral) = col.ephemeral {
6731 self.write_space();
6732 self.write_keyword("EPHEMERAL");
6733 if let Some(ref expr) = ephemeral {
6734 self.write_space();
6735 self.generate_expression(expr)?;
6736 }
6737 }
6738
6739 if let Some(ref mat_expr) = col.materialized_expr {
6741 self.write_space();
6742 self.write_keyword("MATERIALIZED");
6743 self.write_space();
6744 self.generate_expression(mat_expr)?;
6745 }
6746
6747 if let Some(ref alias_expr) = col.alias_expr {
6749 self.write_space();
6750 self.write_keyword("ALIAS");
6751 self.write_space();
6752 self.generate_expression(alias_expr)?;
6753 }
6754
6755 if let Some(ref ttl_expr) = col.ttl_expr {
6757 self.write_space();
6758 self.write_keyword("TTL");
6759 self.write_space();
6760 self.generate_expression(ttl_expr)?;
6761 }
6762
6763 if col.not_for_replication && matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL) | Some(crate::dialects::DialectType::Fabric)) {
6765 self.write_space();
6766 self.write_keyword("NOT FOR REPLICATION");
6767 }
6768
6769 if !col.options.is_empty() {
6771 self.write_space();
6772 self.generate_options_clause(&col.options)?;
6773 }
6774
6775 if !col.primary_key && self.sqlite_inline_pk_columns.contains(&col.name.name.to_lowercase()) {
6778 self.write_space();
6779 self.write_keyword("PRIMARY KEY");
6780 }
6781
6782 if serial_expansion.is_some() {
6785 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
6786 self.write_space();
6787 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY NOT NULL");
6788 } else if matches!(self.config.dialect, Some(DialectType::Materialize)) {
6789 self.write_space();
6790 self.write_keyword("NOT NULL");
6791 }
6792 }
6793
6794 Ok(())
6795 }
6796
6797 fn generate_table_constraint(&mut self, constraint: &TableConstraint) -> Result<()> {
6798 match constraint {
6799 TableConstraint::PrimaryKey { name, columns, include_columns, modifiers, has_constraint_keyword } => {
6800 if let Some(ref n) = name {
6801 if *has_constraint_keyword {
6802 self.write_keyword("CONSTRAINT");
6803 self.write_space();
6804 self.generate_identifier(n)?;
6805 self.write_space();
6806 }
6807 }
6808 self.write_keyword("PRIMARY KEY");
6809 if let Some(ref clustered) = modifiers.clustered {
6811 self.write_space();
6812 self.write_keyword(clustered);
6813 }
6814 if let Some(ref n) = name {
6816 if !*has_constraint_keyword {
6817 self.write_space();
6818 self.generate_identifier(n)?;
6819 }
6820 }
6821 self.write(" (");
6822 for (i, col) in columns.iter().enumerate() {
6823 if i > 0 {
6824 self.write(", ");
6825 }
6826 self.generate_identifier(col)?;
6827 }
6828 self.write(")");
6829 if !include_columns.is_empty() {
6830 self.write_space();
6831 self.write_keyword("INCLUDE");
6832 self.write(" (");
6833 for (i, col) in include_columns.iter().enumerate() {
6834 if i > 0 {
6835 self.write(", ");
6836 }
6837 self.generate_identifier(col)?;
6838 }
6839 self.write(")");
6840 }
6841 self.generate_constraint_modifiers(modifiers);
6842 }
6843 TableConstraint::Unique { name, columns, columns_parenthesized, modifiers, has_constraint_keyword, nulls_not_distinct } => {
6844 if let Some(ref n) = name {
6845 if *has_constraint_keyword {
6846 self.write_keyword("CONSTRAINT");
6847 self.write_space();
6848 self.generate_identifier(n)?;
6849 self.write_space();
6850 }
6851 }
6852 self.write_keyword("UNIQUE");
6853 if let Some(ref clustered) = modifiers.clustered {
6855 self.write_space();
6856 self.write_keyword(clustered);
6857 }
6858 if *nulls_not_distinct {
6860 self.write(" NULLS NOT DISTINCT");
6861 }
6862 if let Some(ref n) = name {
6864 if !*has_constraint_keyword {
6865 self.write_space();
6866 self.generate_identifier(n)?;
6867 }
6868 }
6869 if *columns_parenthesized {
6870 self.write(" (");
6871 for (i, col) in columns.iter().enumerate() {
6872 if i > 0 {
6873 self.write(", ");
6874 }
6875 self.generate_identifier(col)?;
6876 }
6877 self.write(")");
6878 } else {
6879 for col in columns.iter() {
6881 self.write_space();
6882 self.generate_identifier(col)?;
6883 }
6884 }
6885 self.generate_constraint_modifiers(modifiers);
6886 }
6887 TableConstraint::ForeignKey { name, columns, references, on_delete, on_update, modifiers } => {
6888 if let Some(ref n) = name {
6889 self.write_keyword("CONSTRAINT");
6890 self.write_space();
6891 self.generate_identifier(n)?;
6892 self.write_space();
6893 }
6894 self.write_keyword("FOREIGN KEY");
6895 self.write(" (");
6896 for (i, col) in columns.iter().enumerate() {
6897 if i > 0 {
6898 self.write(", ");
6899 }
6900 self.generate_identifier(col)?;
6901 }
6902 self.write(")");
6903 if let Some(ref refs) = references {
6904 self.write(" ");
6905 self.write_keyword("REFERENCES");
6906 self.write_space();
6907 self.generate_table(&refs.table)?;
6908 if !refs.columns.is_empty() {
6909 if self.config.pretty {
6910 self.write(" (");
6911 self.write_newline();
6912 self.indent_level += 1;
6913 for (i, col) in refs.columns.iter().enumerate() {
6914 if i > 0 {
6915 self.write(",");
6916 self.write_newline();
6917 }
6918 self.write_indent();
6919 self.generate_identifier(col)?;
6920 }
6921 self.indent_level -= 1;
6922 self.write_newline();
6923 self.write_indent();
6924 self.write(")");
6925 } else {
6926 self.write(" (");
6927 for (i, col) in refs.columns.iter().enumerate() {
6928 if i > 0 {
6929 self.write(", ");
6930 }
6931 self.generate_identifier(col)?;
6932 }
6933 self.write(")");
6934 }
6935 }
6936 self.generate_referential_actions(refs)?;
6937 } else {
6938 if let Some(ref action) = on_delete {
6940 self.write_space();
6941 self.write_keyword("ON DELETE");
6942 self.write_space();
6943 self.generate_referential_action(action);
6944 }
6945 if let Some(ref action) = on_update {
6946 self.write_space();
6947 self.write_keyword("ON UPDATE");
6948 self.write_space();
6949 self.generate_referential_action(action);
6950 }
6951 }
6952 self.generate_constraint_modifiers(modifiers);
6953 }
6954 TableConstraint::Check { name, expression, modifiers } => {
6955 if let Some(ref n) = name {
6956 self.write_keyword("CONSTRAINT");
6957 self.write_space();
6958 self.generate_identifier(n)?;
6959 self.write_space();
6960 }
6961 self.write_keyword("CHECK");
6962 self.write(" (");
6963 self.generate_expression(expression)?;
6964 self.write(")");
6965 self.generate_constraint_modifiers(modifiers);
6966 }
6967 TableConstraint::Index { name, columns, kind, modifiers, use_key_keyword, expression, index_type, granularity } => {
6968 if expression.is_some() {
6970 self.write_keyword("INDEX");
6971 if let Some(ref n) = name {
6972 self.write_space();
6973 self.generate_identifier(n)?;
6974 }
6975 if let Some(ref expr) = expression {
6976 self.write_space();
6977 self.generate_expression(expr)?;
6978 }
6979 if let Some(ref idx_type) = index_type {
6980 self.write_space();
6981 self.write_keyword("TYPE");
6982 self.write_space();
6983 self.generate_expression(idx_type)?;
6984 }
6985 if let Some(ref gran) = granularity {
6986 self.write_space();
6987 self.write_keyword("GRANULARITY");
6988 self.write_space();
6989 self.generate_expression(gran)?;
6990 }
6991 } else {
6992 use crate::dialects::DialectType;
6996 let index_keyword = if *use_key_keyword && !matches!(self.config.dialect, Some(DialectType::MySQL)) {
6997 "KEY"
6998 } else {
6999 "INDEX"
7000 };
7001
7002 if let Some(ref k) = kind {
7004 self.write_keyword(k);
7005 if k != "UNIQUE" {
7007 self.write_space();
7008 self.write_keyword(index_keyword);
7009 }
7010 } else {
7011 self.write_keyword(index_keyword);
7012 }
7013
7014 if modifiers.using_before_columns && name.is_none() {
7016 if let Some(ref using) = modifiers.using {
7017 self.write_space();
7018 self.write_keyword("USING");
7019 self.write_space();
7020 self.write_keyword(using);
7021 }
7022 }
7023
7024 if let Some(ref n) = name {
7026 self.write_space();
7027 self.generate_identifier(n)?;
7028 }
7029
7030 if modifiers.using_before_columns && name.is_some() {
7032 if let Some(ref using) = modifiers.using {
7033 self.write_space();
7034 self.write_keyword("USING");
7035 self.write_space();
7036 self.write_keyword(using);
7037 }
7038 }
7039
7040 self.write(" (");
7042 for (i, col) in columns.iter().enumerate() {
7043 if i > 0 {
7044 self.write(", ");
7045 }
7046 self.generate_identifier(col)?;
7047 }
7048 self.write(")");
7049
7050 if !modifiers.using_before_columns {
7052 if let Some(ref using) = modifiers.using {
7053 self.write_space();
7054 self.write_keyword("USING");
7055 self.write_space();
7056 self.write_keyword(using);
7057 }
7058 }
7059
7060 self.generate_constraint_modifiers_without_using(modifiers);
7062 }
7063 }
7064 TableConstraint::Projection { name, expression } => {
7065 self.write_keyword("PROJECTION");
7067 self.write_space();
7068 self.generate_identifier(name)?;
7069 self.write(" (");
7070 self.generate_expression(expression)?;
7071 self.write(")");
7072 }
7073 TableConstraint::Like { source, options } => {
7074 self.write_keyword("LIKE");
7075 self.write_space();
7076 self.generate_table(source)?;
7077 for (action, prop) in options {
7078 self.write_space();
7079 match action {
7080 LikeOptionAction::Including => self.write_keyword("INCLUDING"),
7081 LikeOptionAction::Excluding => self.write_keyword("EXCLUDING"),
7082 }
7083 self.write_space();
7084 self.write_keyword(prop);
7085 }
7086 }
7087 TableConstraint::PeriodForSystemTime { start_col, end_col } => {
7088 self.write_keyword("PERIOD FOR SYSTEM_TIME");
7089 self.write(" (");
7090 self.generate_identifier(start_col)?;
7091 self.write(", ");
7092 self.generate_identifier(end_col)?;
7093 self.write(")");
7094 }
7095 TableConstraint::Exclude { name, using, elements, include_columns, where_clause, with_params, using_index_tablespace, modifiers: _ } => {
7096 if let Some(ref n) = name {
7097 self.write_keyword("CONSTRAINT");
7098 self.write_space();
7099 self.generate_identifier(n)?;
7100 self.write_space();
7101 }
7102 self.write_keyword("EXCLUDE");
7103 if let Some(ref method) = using {
7104 self.write_space();
7105 self.write_keyword("USING");
7106 self.write_space();
7107 self.write(method);
7108 self.write("(");
7109 } else {
7110 self.write(" (");
7111 }
7112 for (i, elem) in elements.iter().enumerate() {
7113 if i > 0 {
7114 self.write(", ");
7115 }
7116 self.write(&elem.expression);
7117 self.write_space();
7118 self.write_keyword("WITH");
7119 self.write_space();
7120 self.write(&elem.operator);
7121 }
7122 self.write(")");
7123 if !include_columns.is_empty() {
7124 self.write_space();
7125 self.write_keyword("INCLUDE");
7126 self.write(" (");
7127 for (i, col) in include_columns.iter().enumerate() {
7128 if i > 0 {
7129 self.write(", ");
7130 }
7131 self.generate_identifier(col)?;
7132 }
7133 self.write(")");
7134 }
7135 if !with_params.is_empty() {
7136 self.write_space();
7137 self.write_keyword("WITH");
7138 self.write(" (");
7139 for (i, (key, val)) in with_params.iter().enumerate() {
7140 if i > 0 {
7141 self.write(", ");
7142 }
7143 self.write(key);
7144 self.write("=");
7145 self.write(val);
7146 }
7147 self.write(")");
7148 }
7149 if let Some(ref tablespace) = using_index_tablespace {
7150 self.write_space();
7151 self.write_keyword("USING INDEX TABLESPACE");
7152 self.write_space();
7153 self.write(tablespace);
7154 }
7155 if let Some(ref where_expr) = where_clause {
7156 self.write_space();
7157 self.write_keyword("WHERE");
7158 self.write(" (");
7159 self.generate_expression(where_expr)?;
7160 self.write(")");
7161 }
7162 }
7163 TableConstraint::Tags(tags) => {
7164 self.write_keyword("TAG");
7165 self.write(" (");
7166 for (i, expr) in tags.expressions.iter().enumerate() {
7167 if i > 0 {
7168 self.write(", ");
7169 }
7170 self.generate_expression(expr)?;
7171 }
7172 self.write(")");
7173 }
7174 TableConstraint::InitiallyDeferred { deferred } => {
7175 self.write_keyword("INITIALLY");
7176 self.write_space();
7177 if *deferred {
7178 self.write_keyword("DEFERRED");
7179 } else {
7180 self.write_keyword("IMMEDIATE");
7181 }
7182 }
7183 }
7184 Ok(())
7185 }
7186
7187 fn generate_constraint_modifiers(&mut self, modifiers: &ConstraintModifiers) {
7188 if let Some(using) = &modifiers.using {
7190 self.write_space();
7191 self.write_keyword("USING");
7192 self.write_space();
7193 self.write_keyword(using);
7194 }
7195 if let Some(enforced) = modifiers.enforced {
7197 self.write_space();
7198 if enforced {
7199 self.write_keyword("ENFORCED");
7200 } else {
7201 self.write_keyword("NOT ENFORCED");
7202 }
7203 }
7204 if let Some(deferrable) = modifiers.deferrable {
7206 self.write_space();
7207 if deferrable {
7208 self.write_keyword("DEFERRABLE");
7209 } else {
7210 self.write_keyword("NOT DEFERRABLE");
7211 }
7212 }
7213 if let Some(initially_deferred) = modifiers.initially_deferred {
7215 self.write_space();
7216 if initially_deferred {
7217 self.write_keyword("INITIALLY DEFERRED");
7218 } else {
7219 self.write_keyword("INITIALLY IMMEDIATE");
7220 }
7221 }
7222 if modifiers.norely {
7224 self.write_space();
7225 self.write_keyword("NORELY");
7226 }
7227 if modifiers.rely {
7229 self.write_space();
7230 self.write_keyword("RELY");
7231 }
7232 if modifiers.not_valid {
7234 self.write_space();
7235 self.write_keyword("NOT VALID");
7236 }
7237 if let Some(on_conflict) = &modifiers.on_conflict {
7239 self.write_space();
7240 self.write_keyword("ON CONFLICT");
7241 self.write_space();
7242 self.write_keyword(on_conflict);
7243 }
7244 if !modifiers.with_options.is_empty() {
7246 self.write_space();
7247 self.write_keyword("WITH");
7248 self.write(" (");
7249 for (i, (key, value)) in modifiers.with_options.iter().enumerate() {
7250 if i > 0 {
7251 self.write(", ");
7252 }
7253 self.write(key);
7254 self.write("=");
7255 self.write(value);
7256 }
7257 self.write(")");
7258 }
7259 if let Some(ref fg) = modifiers.on_filegroup {
7261 self.write_space();
7262 self.write_keyword("ON");
7263 self.write_space();
7264 let _ = self.generate_identifier(fg);
7265 }
7266 }
7267
7268 fn generate_constraint_modifiers_without_using(&mut self, modifiers: &ConstraintModifiers) {
7270 if let Some(enforced) = modifiers.enforced {
7272 self.write_space();
7273 if enforced {
7274 self.write_keyword("ENFORCED");
7275 } else {
7276 self.write_keyword("NOT ENFORCED");
7277 }
7278 }
7279 if let Some(deferrable) = modifiers.deferrable {
7281 self.write_space();
7282 if deferrable {
7283 self.write_keyword("DEFERRABLE");
7284 } else {
7285 self.write_keyword("NOT DEFERRABLE");
7286 }
7287 }
7288 if let Some(initially_deferred) = modifiers.initially_deferred {
7290 self.write_space();
7291 if initially_deferred {
7292 self.write_keyword("INITIALLY DEFERRED");
7293 } else {
7294 self.write_keyword("INITIALLY IMMEDIATE");
7295 }
7296 }
7297 if modifiers.norely {
7299 self.write_space();
7300 self.write_keyword("NORELY");
7301 }
7302 if modifiers.rely {
7304 self.write_space();
7305 self.write_keyword("RELY");
7306 }
7307 if modifiers.not_valid {
7309 self.write_space();
7310 self.write_keyword("NOT VALID");
7311 }
7312 if let Some(on_conflict) = &modifiers.on_conflict {
7314 self.write_space();
7315 self.write_keyword("ON CONFLICT");
7316 self.write_space();
7317 self.write_keyword(on_conflict);
7318 }
7319 self.generate_index_specific_modifiers(modifiers);
7321 }
7322
7323 fn generate_index_specific_modifiers(&mut self, modifiers: &ConstraintModifiers) {
7325 if let Some(ref comment) = modifiers.comment {
7326 self.write_space();
7327 self.write_keyword("COMMENT");
7328 self.write(" '");
7329 self.write(comment);
7330 self.write("'");
7331 }
7332 if let Some(visible) = modifiers.visible {
7333 self.write_space();
7334 if visible {
7335 self.write_keyword("VISIBLE");
7336 } else {
7337 self.write_keyword("INVISIBLE");
7338 }
7339 }
7340 if let Some(ref attr) = modifiers.engine_attribute {
7341 self.write_space();
7342 self.write_keyword("ENGINE_ATTRIBUTE");
7343 self.write(" = '");
7344 self.write(attr);
7345 self.write("'");
7346 }
7347 if let Some(ref parser) = modifiers.with_parser {
7348 self.write_space();
7349 self.write_keyword("WITH PARSER");
7350 self.write_space();
7351 self.write(parser);
7352 }
7353 }
7354
7355 fn generate_referential_actions(&mut self, fk_ref: &ForeignKeyRef) -> Result<()> {
7356 if !fk_ref.match_after_actions {
7358 if let Some(ref match_type) = fk_ref.match_type {
7359 self.write_space();
7360 self.write_keyword("MATCH");
7361 self.write_space();
7362 match match_type {
7363 MatchType::Full => self.write_keyword("FULL"),
7364 MatchType::Partial => self.write_keyword("PARTIAL"),
7365 MatchType::Simple => self.write_keyword("SIMPLE"),
7366 }
7367 }
7368 }
7369
7370 if fk_ref.on_update_first {
7372 if let Some(ref action) = fk_ref.on_update {
7373 self.write_space();
7374 self.write_keyword("ON UPDATE");
7375 self.write_space();
7376 self.generate_referential_action(action);
7377 }
7378 if let Some(ref action) = fk_ref.on_delete {
7379 self.write_space();
7380 self.write_keyword("ON DELETE");
7381 self.write_space();
7382 self.generate_referential_action(action);
7383 }
7384 } else {
7385 if let Some(ref action) = fk_ref.on_delete {
7386 self.write_space();
7387 self.write_keyword("ON DELETE");
7388 self.write_space();
7389 self.generate_referential_action(action);
7390 }
7391 if let Some(ref action) = fk_ref.on_update {
7392 self.write_space();
7393 self.write_keyword("ON UPDATE");
7394 self.write_space();
7395 self.generate_referential_action(action);
7396 }
7397 }
7398
7399 if fk_ref.match_after_actions {
7401 if let Some(ref match_type) = fk_ref.match_type {
7402 self.write_space();
7403 self.write_keyword("MATCH");
7404 self.write_space();
7405 match match_type {
7406 MatchType::Full => self.write_keyword("FULL"),
7407 MatchType::Partial => self.write_keyword("PARTIAL"),
7408 MatchType::Simple => self.write_keyword("SIMPLE"),
7409 }
7410 }
7411 }
7412
7413 if let Some(deferrable) = fk_ref.deferrable {
7415 self.write_space();
7416 if deferrable {
7417 self.write_keyword("DEFERRABLE");
7418 } else {
7419 self.write_keyword("NOT DEFERRABLE");
7420 }
7421 }
7422
7423 Ok(())
7424 }
7425
7426 fn generate_referential_action(&mut self, action: &ReferentialAction) {
7427 match action {
7428 ReferentialAction::Cascade => self.write_keyword("CASCADE"),
7429 ReferentialAction::SetNull => self.write_keyword("SET NULL"),
7430 ReferentialAction::SetDefault => self.write_keyword("SET DEFAULT"),
7431 ReferentialAction::Restrict => self.write_keyword("RESTRICT"),
7432 ReferentialAction::NoAction => self.write_keyword("NO ACTION"),
7433 }
7434 }
7435
7436 fn generate_drop_table(&mut self, dt: &DropTable) -> Result<()> {
7437 let saved_athena_hive_context = self.athena_hive_context;
7439 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Athena)) {
7440 self.athena_hive_context = true;
7441 }
7442
7443 self.write_keyword("DROP TABLE");
7444
7445 if dt.if_exists {
7446 self.write_space();
7447 self.write_keyword("IF EXISTS");
7448 }
7449
7450 self.write_space();
7451 for (i, table) in dt.names.iter().enumerate() {
7452 if i > 0 {
7453 self.write(", ");
7454 }
7455 self.generate_table(table)?;
7456 }
7457
7458 if dt.cascade_constraints {
7459 self.write_space();
7460 self.write_keyword("CASCADE CONSTRAINTS");
7461 } else if dt.cascade {
7462 self.write_space();
7463 self.write_keyword("CASCADE");
7464 }
7465
7466 if dt.purge {
7467 self.write_space();
7468 self.write_keyword("PURGE");
7469 }
7470
7471 self.athena_hive_context = saved_athena_hive_context;
7473
7474 Ok(())
7475 }
7476
7477 fn generate_alter_table(&mut self, at: &AlterTable) -> Result<()> {
7478 let saved_athena_hive_context = self.athena_hive_context;
7480 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Athena)) {
7481 self.athena_hive_context = true;
7482 }
7483
7484 self.write_keyword("ALTER TABLE");
7485 if at.if_exists {
7486 self.write_space();
7487 self.write_keyword("IF EXISTS");
7488 }
7489 self.write_space();
7490 self.generate_table(&at.name)?;
7491
7492 if let Some(ref on_cluster) = at.on_cluster {
7494 self.write_space();
7495 self.generate_on_cluster(on_cluster)?;
7496 }
7497
7498 if let Some(ref partition) = at.partition {
7500 self.write_space();
7501 self.write_keyword("PARTITION");
7502 self.write("(");
7503 for (i, (key, value)) in partition.iter().enumerate() {
7504 if i > 0 {
7505 self.write(", ");
7506 }
7507 self.generate_identifier(key)?;
7508 self.write(" = ");
7509 self.generate_expression(value)?;
7510 }
7511 self.write(")");
7512 }
7513
7514 if let Some(ref with_check) = at.with_check {
7516 self.write_space();
7517 self.write_keyword(with_check);
7518 }
7519
7520 if self.config.pretty {
7521 self.write_newline();
7523 self.indent_level += 1;
7524 for (i, action) in at.actions.iter().enumerate() {
7525 let is_continuation = i > 0 && matches!(
7527 (&at.actions[i - 1], action),
7528 (AlterTableAction::AddColumn { .. }, AlterTableAction::AddColumn { .. })
7529 | (AlterTableAction::AddConstraint(_), AlterTableAction::AddConstraint(_))
7530 );
7531 if i > 0 {
7532 self.write(",");
7533 self.write_newline();
7534 }
7535 self.write_indent();
7536 self.generate_alter_action_with_continuation(action, is_continuation)?;
7537 }
7538 self.indent_level -= 1;
7539 } else {
7540 for (i, action) in at.actions.iter().enumerate() {
7541 let is_continuation = i > 0 && matches!(
7543 (&at.actions[i - 1], action),
7544 (AlterTableAction::AddColumn { .. }, AlterTableAction::AddColumn { .. })
7545 | (AlterTableAction::AddConstraint(_), AlterTableAction::AddConstraint(_))
7546 );
7547 if i > 0 {
7548 self.write(",");
7549 }
7550 self.write_space();
7551 self.generate_alter_action_with_continuation(action, is_continuation)?;
7552 }
7553 }
7554
7555 if let Some(ref algorithm) = at.algorithm {
7557 self.write(", ");
7558 self.write_keyword("ALGORITHM");
7559 self.write("=");
7560 self.write_keyword(algorithm);
7561 }
7562 if let Some(ref lock) = at.lock {
7563 self.write(", ");
7564 self.write_keyword("LOCK");
7565 self.write("=");
7566 self.write_keyword(lock);
7567 }
7568
7569 self.athena_hive_context = saved_athena_hive_context;
7571
7572 Ok(())
7573 }
7574
7575 fn generate_alter_action_with_continuation(&mut self, action: &AlterTableAction, is_continuation: bool) -> Result<()> {
7576 match action {
7577 AlterTableAction::AddColumn { column, if_not_exists, position } => {
7578 use crate::dialects::DialectType;
7579 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
7583 let is_tsql_like = matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric));
7584 let is_athena = matches!(self.config.dialect, Some(DialectType::Athena));
7586
7587 if is_continuation && (is_snowflake || is_tsql_like) {
7588 } else if is_snowflake {
7590 self.write_keyword("ADD");
7591 self.write_space();
7592 } else if is_athena {
7593 self.write_keyword("ADD COLUMNS");
7595 self.write(" (");
7596 } else if self.config.alter_table_include_column_keyword {
7597 self.write_keyword("ADD COLUMN");
7598 self.write_space();
7599 } else {
7600 self.write_keyword("ADD");
7602 self.write_space();
7603 }
7604
7605 if *if_not_exists {
7606 self.write_keyword("IF NOT EXISTS");
7607 self.write_space();
7608 }
7609 self.generate_column_def(column)?;
7610
7611 if is_athena {
7613 self.write(")");
7614 }
7615
7616 if let Some(pos) = position {
7618 self.write_space();
7619 match pos {
7620 ColumnPosition::First => self.write_keyword("FIRST"),
7621 ColumnPosition::After(col_name) => {
7622 self.write_keyword("AFTER");
7623 self.write_space();
7624 self.generate_identifier(col_name)?;
7625 }
7626 }
7627 }
7628 }
7629 AlterTableAction::DropColumn { name, if_exists, cascade } => {
7630 self.write_keyword("DROP COLUMN");
7631 if *if_exists {
7632 self.write_space();
7633 self.write_keyword("IF EXISTS");
7634 }
7635 self.write_space();
7636 self.generate_identifier(name)?;
7637 if *cascade {
7638 self.write_space();
7639 self.write_keyword("CASCADE");
7640 }
7641 }
7642 AlterTableAction::DropColumns { names } => {
7643 self.write_keyword("DROP COLUMNS");
7644 self.write(" (");
7645 for (i, name) in names.iter().enumerate() {
7646 if i > 0 {
7647 self.write(", ");
7648 }
7649 self.generate_identifier(name)?;
7650 }
7651 self.write(")");
7652 }
7653 AlterTableAction::RenameColumn { old_name, new_name, if_exists } => {
7654 self.write_keyword("RENAME COLUMN");
7655 if *if_exists {
7656 self.write_space();
7657 self.write_keyword("IF EXISTS");
7658 }
7659 self.write_space();
7660 self.generate_identifier(old_name)?;
7661 self.write_space();
7662 self.write_keyword("TO");
7663 self.write_space();
7664 self.generate_identifier(new_name)?;
7665 }
7666 AlterTableAction::AlterColumn { name, action, use_modify_keyword } => {
7667 use crate::dialects::DialectType;
7668 let use_modify = *use_modify_keyword || (
7671 matches!(self.config.dialect, Some(DialectType::MySQL)) &&
7672 matches!(action, AlterColumnAction::SetDataType { .. })
7673 );
7674 if use_modify {
7675 self.write_keyword("MODIFY COLUMN");
7676 self.write_space();
7677 self.generate_identifier(name)?;
7678 if let AlterColumnAction::SetDataType { data_type, using: _, collate } = action {
7680 self.write_space();
7681 self.generate_data_type(data_type)?;
7682 if let Some(collate_name) = collate {
7684 self.write_space();
7685 self.write_keyword("COLLATE");
7686 self.write_space();
7687 self.write(&format!("'{}'", collate_name));
7689 }
7690 } else {
7691 self.write_space();
7692 self.generate_alter_column_action(action)?;
7693 }
7694 } else if matches!(self.config.dialect, Some(DialectType::Hive))
7695 && matches!(action, AlterColumnAction::SetDataType { .. })
7696 {
7697 self.write_keyword("CHANGE COLUMN");
7699 self.write_space();
7700 self.generate_identifier(name)?;
7701 self.write_space();
7702 self.generate_identifier(name)?;
7703 if let AlterColumnAction::SetDataType { data_type, .. } = action {
7704 self.write_space();
7705 self.generate_data_type(data_type)?;
7706 }
7707 } else {
7708 self.write_keyword("ALTER COLUMN");
7709 self.write_space();
7710 self.generate_identifier(name)?;
7711 self.write_space();
7712 self.generate_alter_column_action(action)?;
7713 }
7714 }
7715 AlterTableAction::RenameTable(new_name) => {
7716 let mysql_like = matches!(self.config.dialect, Some(DialectType::MySQL) | Some(DialectType::Doris) | Some(DialectType::StarRocks) | Some(DialectType::SingleStore));
7718 if mysql_like {
7719 self.write_keyword("RENAME");
7720 } else {
7721 self.write_keyword("RENAME TO");
7722 }
7723 self.write_space();
7724 let rename_table_with_db = !matches!(self.config.dialect, Some(DialectType::Doris) | Some(DialectType::DuckDB) | Some(DialectType::BigQuery) | Some(DialectType::PostgreSQL));
7726 if !rename_table_with_db {
7727 let mut stripped = new_name.clone();
7728 stripped.schema = None;
7729 stripped.catalog = None;
7730 self.generate_table(&stripped)?;
7731 } else {
7732 self.generate_table(new_name)?;
7733 }
7734 }
7735 AlterTableAction::AddConstraint(constraint) => {
7736 if !is_continuation {
7739 self.write_keyword("ADD");
7740 self.write_space();
7741 }
7742 self.generate_table_constraint(constraint)?;
7743 }
7744 AlterTableAction::DropConstraint { name, if_exists } => {
7745 self.write_keyword("DROP CONSTRAINT");
7746 if *if_exists {
7747 self.write_space();
7748 self.write_keyword("IF EXISTS");
7749 }
7750 self.write_space();
7751 self.generate_identifier(name)?;
7752 }
7753 AlterTableAction::DropForeignKey { name } => {
7754 self.write_keyword("DROP FOREIGN KEY");
7755 self.write_space();
7756 self.generate_identifier(name)?;
7757 }
7758 AlterTableAction::DropPartition { partitions, if_exists } => {
7759 self.write_keyword("DROP");
7760 if *if_exists {
7761 self.write_space();
7762 self.write_keyword("IF EXISTS");
7763 }
7764 for (i, partition) in partitions.iter().enumerate() {
7765 if i > 0 {
7766 self.write(",");
7767 }
7768 self.write_space();
7769 self.write_keyword("PARTITION");
7770 if partition.len() == 1 && partition[0].0.name == "__expr__" {
7772 self.write_space();
7774 self.generate_expression(&partition[0].1)?;
7775 } else if partition.len() == 1 && partition[0].0.name == "ALL" {
7776 self.write_space();
7778 self.write_keyword("ALL");
7779 } else if partition.len() == 1 && partition[0].0.name == "ID" {
7780 self.write_space();
7782 self.write_keyword("ID");
7783 self.write_space();
7784 self.generate_expression(&partition[0].1)?;
7785 } else {
7786 self.write("(");
7788 for (j, (key, value)) in partition.iter().enumerate() {
7789 if j > 0 {
7790 self.write(", ");
7791 }
7792 self.generate_identifier(key)?;
7793 self.write(" = ");
7794 self.generate_expression(value)?;
7795 }
7796 self.write(")");
7797 }
7798 }
7799 }
7800 AlterTableAction::Delete { where_clause } => {
7801 self.write_keyword("DELETE");
7802 self.write_space();
7803 self.write_keyword("WHERE");
7804 self.write_space();
7805 self.generate_expression(where_clause)?;
7806 }
7807 AlterTableAction::SwapWith(target) => {
7808 self.write_keyword("SWAP WITH");
7809 self.write_space();
7810 self.generate_table(target)?;
7811 }
7812 AlterTableAction::SetProperty { properties } => {
7813 use crate::dialects::DialectType;
7814 self.write_keyword("SET");
7815 let is_trino_presto = matches!(self.config.dialect, Some(DialectType::Trino) | Some(DialectType::Presto));
7817 if is_trino_presto {
7818 self.write_space();
7819 self.write_keyword("PROPERTIES");
7820 }
7821 let eq = if is_trino_presto { " = " } else { "=" };
7822 for (i, (key, value)) in properties.iter().enumerate() {
7823 if i > 0 {
7824 self.write(",");
7825 }
7826 self.write_space();
7827 if key.contains(' ') {
7829 self.generate_string_literal(key)?;
7830 } else {
7831 self.write(key);
7832 }
7833 self.write(eq);
7834 self.generate_expression(value)?;
7835 }
7836 }
7837 AlterTableAction::UnsetProperty { properties } => {
7838 self.write_keyword("UNSET");
7839 for (i, name) in properties.iter().enumerate() {
7840 if i > 0 {
7841 self.write(",");
7842 }
7843 self.write_space();
7844 self.write(name);
7845 }
7846 }
7847 AlterTableAction::ClusterBy { expressions } => {
7848 self.write_keyword("CLUSTER BY");
7849 self.write(" (");
7850 for (i, expr) in expressions.iter().enumerate() {
7851 if i > 0 {
7852 self.write(", ");
7853 }
7854 self.generate_expression(expr)?;
7855 }
7856 self.write(")");
7857 }
7858 AlterTableAction::SetTag { expressions } => {
7859 self.write_keyword("SET TAG");
7860 for (i, (key, value)) in expressions.iter().enumerate() {
7861 if i > 0 {
7862 self.write(",");
7863 }
7864 self.write_space();
7865 self.write(key);
7866 self.write(" = ");
7867 self.generate_expression(value)?;
7868 }
7869 }
7870 AlterTableAction::UnsetTag { names } => {
7871 self.write_keyword("UNSET TAG");
7872 for (i, name) in names.iter().enumerate() {
7873 if i > 0 {
7874 self.write(",");
7875 }
7876 self.write_space();
7877 self.write(name);
7878 }
7879 }
7880 AlterTableAction::SetOptions { expressions } => {
7881 self.write_keyword("SET");
7882 self.write(" (");
7883 for (i, expr) in expressions.iter().enumerate() {
7884 if i > 0 {
7885 self.write(", ");
7886 }
7887 self.generate_expression(expr)?;
7888 }
7889 self.write(")");
7890 }
7891 AlterTableAction::AlterIndex { name, visible } => {
7892 self.write_keyword("ALTER INDEX");
7893 self.write_space();
7894 self.generate_identifier(name)?;
7895 self.write_space();
7896 if *visible {
7897 self.write_keyword("VISIBLE");
7898 } else {
7899 self.write_keyword("INVISIBLE");
7900 }
7901 }
7902 AlterTableAction::SetAttribute { attribute } => {
7903 self.write_keyword("SET");
7904 self.write_space();
7905 self.write_keyword(attribute);
7906 }
7907 AlterTableAction::SetStageFileFormat { options } => {
7908 self.write_keyword("SET");
7909 self.write_space();
7910 self.write_keyword("STAGE_FILE_FORMAT");
7911 self.write(" = (");
7912 if let Some(opts) = options {
7913 self.generate_space_separated_properties(opts)?;
7914 }
7915 self.write(")");
7916 }
7917 AlterTableAction::SetStageCopyOptions { options } => {
7918 self.write_keyword("SET");
7919 self.write_space();
7920 self.write_keyword("STAGE_COPY_OPTIONS");
7921 self.write(" = (");
7922 if let Some(opts) = options {
7923 self.generate_space_separated_properties(opts)?;
7924 }
7925 self.write(")");
7926 }
7927 AlterTableAction::AddColumns { columns, cascade } => {
7928 let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle));
7931 if is_oracle {
7932 self.write_keyword("ADD");
7933 } else {
7934 self.write_keyword("ADD COLUMNS");
7935 }
7936 self.write(" (");
7937 for (i, col) in columns.iter().enumerate() {
7938 if i > 0 {
7939 self.write(", ");
7940 }
7941 self.generate_column_def(col)?;
7942 }
7943 self.write(")");
7944 if *cascade {
7945 self.write_space();
7946 self.write_keyword("CASCADE");
7947 }
7948 }
7949 AlterTableAction::ChangeColumn { old_name, new_name, data_type, comment, cascade } => {
7950 use crate::dialects::DialectType;
7951 let is_spark = matches!(self.config.dialect,
7952 Some(DialectType::Spark) | Some(DialectType::Databricks));
7953 let is_rename = old_name.name != new_name.name;
7954
7955 if is_spark {
7956 if is_rename {
7957 self.write_keyword("RENAME COLUMN");
7959 self.write_space();
7960 self.generate_identifier(old_name)?;
7961 self.write_space();
7962 self.write_keyword("TO");
7963 self.write_space();
7964 self.generate_identifier(new_name)?;
7965 } else if comment.is_some() {
7966 self.write_keyword("ALTER COLUMN");
7968 self.write_space();
7969 self.generate_identifier(old_name)?;
7970 self.write_space();
7971 self.write_keyword("COMMENT");
7972 self.write_space();
7973 self.write("'");
7974 self.write(comment.as_ref().unwrap());
7975 self.write("'");
7976 } else if data_type.is_some() {
7977 self.write_keyword("ALTER COLUMN");
7979 self.write_space();
7980 self.generate_identifier(old_name)?;
7981 self.write_space();
7982 self.write_keyword("TYPE");
7983 self.write_space();
7984 self.generate_data_type(data_type.as_ref().unwrap())?;
7985 } else {
7986 self.write_keyword("CHANGE COLUMN");
7988 self.write_space();
7989 self.generate_identifier(old_name)?;
7990 self.write_space();
7991 self.generate_identifier(new_name)?;
7992 }
7993 } else {
7994 if data_type.is_some() {
7996 self.write_keyword("CHANGE COLUMN");
7997 } else {
7998 self.write_keyword("CHANGE");
7999 }
8000 self.write_space();
8001 self.generate_identifier(old_name)?;
8002 self.write_space();
8003 self.generate_identifier(new_name)?;
8004 if let Some(ref dt) = data_type {
8005 self.write_space();
8006 self.generate_data_type(dt)?;
8007 }
8008 if let Some(ref c) = comment {
8009 self.write_space();
8010 self.write_keyword("COMMENT");
8011 self.write_space();
8012 self.write("'");
8013 self.write(c);
8014 self.write("'");
8015 }
8016 if *cascade {
8017 self.write_space();
8018 self.write_keyword("CASCADE");
8019 }
8020 }
8021 }
8022 AlterTableAction::AddPartition { partition, if_not_exists, location } => {
8023 self.write_keyword("ADD");
8024 self.write_space();
8025 if *if_not_exists {
8026 self.write_keyword("IF NOT EXISTS");
8027 self.write_space();
8028 }
8029 self.generate_expression(partition)?;
8030 if let Some(ref loc) = location {
8031 self.write_space();
8032 self.write_keyword("LOCATION");
8033 self.write_space();
8034 self.generate_expression(loc)?;
8035 }
8036 }
8037 AlterTableAction::AlterSortKey { this, expressions, compound } => {
8038 self.write_keyword("ALTER");
8040 if *compound {
8041 self.write_space();
8042 self.write_keyword("COMPOUND");
8043 }
8044 self.write_space();
8045 self.write_keyword("SORTKEY");
8046 self.write_space();
8047 if let Some(style) = this {
8048 self.write_keyword(style);
8049 } else if !expressions.is_empty() {
8050 self.write("(");
8051 for (i, expr) in expressions.iter().enumerate() {
8052 if i > 0 {
8053 self.write(", ");
8054 }
8055 self.generate_expression(expr)?;
8056 }
8057 self.write(")");
8058 }
8059 }
8060 AlterTableAction::AlterDistStyle { style, distkey } => {
8061 self.write_keyword("ALTER");
8063 self.write_space();
8064 self.write_keyword("DISTSTYLE");
8065 self.write_space();
8066 self.write_keyword(style);
8067 if let Some(col) = distkey {
8068 self.write_space();
8069 self.write_keyword("DISTKEY");
8070 self.write_space();
8071 self.generate_identifier(col)?;
8072 }
8073 }
8074 AlterTableAction::SetTableProperties { properties } => {
8075 self.write_keyword("SET TABLE PROPERTIES");
8077 self.write(" (");
8078 for (i, (key, value)) in properties.iter().enumerate() {
8079 if i > 0 {
8080 self.write(", ");
8081 }
8082 self.generate_expression(key)?;
8083 self.write(" = ");
8084 self.generate_expression(value)?;
8085 }
8086 self.write(")");
8087 }
8088 AlterTableAction::SetLocation { location } => {
8089 self.write_keyword("SET LOCATION");
8091 self.write_space();
8092 self.write("'");
8093 self.write(location);
8094 self.write("'");
8095 }
8096 AlterTableAction::SetFileFormat { format } => {
8097 self.write_keyword("SET FILE FORMAT");
8099 self.write_space();
8100 self.write_keyword(format);
8101 }
8102 AlterTableAction::ReplacePartition { partition, source } => {
8103 self.write_keyword("REPLACE PARTITION");
8105 self.write_space();
8106 self.generate_expression(partition)?;
8107 if let Some(src) = source {
8108 self.write_space();
8109 self.write_keyword("FROM");
8110 self.write_space();
8111 self.generate_expression(src)?;
8112 }
8113 }
8114 }
8115 Ok(())
8116 }
8117
8118 fn generate_alter_column_action(&mut self, action: &AlterColumnAction) -> Result<()> {
8119 match action {
8120 AlterColumnAction::SetDataType { data_type, using, collate } => {
8121 use crate::dialects::DialectType;
8122 let is_no_prefix = matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric) | Some(DialectType::Hive));
8127 let is_type_only = matches!(self.config.dialect, Some(DialectType::Redshift) | Some(DialectType::Spark) | Some(DialectType::Databricks));
8128 if is_type_only {
8129 self.write_keyword("TYPE");
8130 self.write_space();
8131 } else if !is_no_prefix {
8132 self.write_keyword("SET DATA TYPE");
8133 self.write_space();
8134 }
8135 self.generate_data_type(data_type)?;
8136 if let Some(ref collation) = collate {
8137 self.write_space();
8138 self.write_keyword("COLLATE");
8139 self.write_space();
8140 self.write(collation);
8141 }
8142 if let Some(ref using_expr) = using {
8143 self.write_space();
8144 self.write_keyword("USING");
8145 self.write_space();
8146 self.generate_expression(using_expr)?;
8147 }
8148 }
8149 AlterColumnAction::SetDefault(expr) => {
8150 self.write_keyword("SET DEFAULT");
8151 self.write_space();
8152 self.generate_expression(expr)?;
8153 }
8154 AlterColumnAction::DropDefault => {
8155 self.write_keyword("DROP DEFAULT");
8156 }
8157 AlterColumnAction::SetNotNull => {
8158 self.write_keyword("SET NOT NULL");
8159 }
8160 AlterColumnAction::DropNotNull => {
8161 self.write_keyword("DROP NOT NULL");
8162 }
8163 AlterColumnAction::Comment(comment) => {
8164 self.write_keyword("COMMENT");
8165 self.write_space();
8166 self.generate_string_literal(comment)?;
8167 }
8168 AlterColumnAction::SetVisible => {
8169 self.write_keyword("SET VISIBLE");
8170 }
8171 AlterColumnAction::SetInvisible => {
8172 self.write_keyword("SET INVISIBLE");
8173 }
8174 }
8175 Ok(())
8176 }
8177
8178 fn generate_create_index(&mut self, ci: &CreateIndex) -> Result<()> {
8179 self.write_keyword("CREATE");
8180
8181 if ci.unique {
8182 self.write_space();
8183 self.write_keyword("UNIQUE");
8184 }
8185
8186 if let Some(ref clustered) = ci.clustered {
8188 self.write_space();
8189 self.write_keyword(clustered);
8190 }
8191
8192 self.write_space();
8193 self.write_keyword("INDEX");
8194
8195 if ci.concurrently {
8197 self.write_space();
8198 self.write_keyword("CONCURRENTLY");
8199 }
8200
8201 if ci.if_not_exists {
8202 self.write_space();
8203 self.write_keyword("IF NOT EXISTS");
8204 }
8205
8206 if !ci.name.name.is_empty() {
8208 self.write_space();
8209 self.generate_identifier(&ci.name)?;
8210 }
8211 self.write_space();
8212 self.write_keyword("ON");
8213 self.write_space();
8214 self.generate_table(&ci.table)?;
8215
8216 if !ci.columns.is_empty() || ci.using.is_some() {
8219 let space_before_paren = false;
8220
8221 if let Some(ref using) = ci.using {
8222 self.write_space();
8223 self.write_keyword("USING");
8224 self.write_space();
8225 self.write(using);
8226 if space_before_paren {
8227 self.write(" (");
8228 } else {
8229 self.write("(");
8230 }
8231 } else {
8232 if space_before_paren {
8233 self.write(" (");
8234 } else {
8235 self.write("(");
8236 }
8237 }
8238 for (i, col) in ci.columns.iter().enumerate() {
8239 if i > 0 {
8240 self.write(", ");
8241 }
8242 self.generate_identifier(&col.column)?;
8243 if let Some(ref opclass) = col.opclass {
8244 self.write_space();
8245 self.write(opclass);
8246 }
8247 if col.desc {
8248 self.write_space();
8249 self.write_keyword("DESC");
8250 } else if col.asc {
8251 self.write_space();
8252 self.write_keyword("ASC");
8253 }
8254 if let Some(nulls_first) = col.nulls_first {
8255 self.write_space();
8256 self.write_keyword("NULLS");
8257 self.write_space();
8258 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
8259 }
8260 }
8261 self.write(")");
8262 }
8263
8264 if !ci.include_columns.is_empty() {
8266 self.write_space();
8267 self.write_keyword("INCLUDE");
8268 self.write(" (");
8269 for (i, col) in ci.include_columns.iter().enumerate() {
8270 if i > 0 {
8271 self.write(", ");
8272 }
8273 self.generate_identifier(col)?;
8274 }
8275 self.write(")");
8276 }
8277
8278 if !ci.with_options.is_empty() {
8280 self.write_space();
8281 self.write_keyword("WITH");
8282 self.write(" (");
8283 for (i, (key, value)) in ci.with_options.iter().enumerate() {
8284 if i > 0 {
8285 self.write(", ");
8286 }
8287 self.write(key);
8288 self.write("=");
8289 self.write(value);
8290 }
8291 self.write(")");
8292 }
8293
8294 if let Some(ref where_clause) = ci.where_clause {
8296 self.write_space();
8297 self.write_keyword("WHERE");
8298 self.write_space();
8299 self.generate_expression(where_clause)?;
8300 }
8301
8302 if let Some(ref on_fg) = ci.on_filegroup {
8304 self.write_space();
8305 self.write_keyword("ON");
8306 self.write_space();
8307 self.write(on_fg);
8308 }
8309
8310 Ok(())
8311 }
8312
8313 fn generate_drop_index(&mut self, di: &DropIndex) -> Result<()> {
8314 self.write_keyword("DROP INDEX");
8315
8316 if di.concurrently {
8317 self.write_space();
8318 self.write_keyword("CONCURRENTLY");
8319 }
8320
8321 if di.if_exists {
8322 self.write_space();
8323 self.write_keyword("IF EXISTS");
8324 }
8325
8326 self.write_space();
8327 self.generate_identifier(&di.name)?;
8328
8329 if let Some(ref table) = di.table {
8330 self.write_space();
8331 self.write_keyword("ON");
8332 self.write_space();
8333 self.generate_table(table)?;
8334 }
8335
8336 Ok(())
8337 }
8338
8339 fn generate_create_view(&mut self, cv: &CreateView) -> Result<()> {
8340 self.write_keyword("CREATE");
8341
8342 if let Some(ref algorithm) = cv.algorithm {
8344 self.write_space();
8345 self.write_keyword("ALGORITHM");
8346 self.write("=");
8347 self.write_keyword(algorithm);
8348 }
8349
8350 if let Some(ref definer) = cv.definer {
8352 self.write_space();
8353 self.write_keyword("DEFINER");
8354 self.write("=");
8355 self.write(definer);
8356 }
8357
8358 if cv.security_sql_style {
8360 if let Some(ref security) = cv.security {
8361 self.write_space();
8362 self.write_keyword("SQL SECURITY");
8363 self.write_space();
8364 match security {
8365 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
8366 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
8367 FunctionSecurity::None => self.write_keyword("NONE"),
8368 }
8369 }
8370 }
8371
8372 if cv.or_replace {
8373 self.write_space();
8374 self.write_keyword("OR REPLACE");
8375 }
8376
8377 if cv.temporary {
8378 self.write_space();
8379 self.write_keyword("TEMPORARY");
8380 }
8381
8382 if cv.materialized {
8383 self.write_space();
8384 self.write_keyword("MATERIALIZED");
8385 }
8386
8387 if cv.secure {
8389 self.write_space();
8390 self.write_keyword("SECURE");
8391 }
8392
8393 self.write_space();
8394 self.write_keyword("VIEW");
8395
8396 if cv.if_not_exists {
8397 self.write_space();
8398 self.write_keyword("IF NOT EXISTS");
8399 }
8400
8401 self.write_space();
8402 self.generate_table(&cv.name)?;
8403
8404 if let Some(ref on_cluster) = cv.on_cluster {
8406 self.write_space();
8407 self.generate_on_cluster(on_cluster)?;
8408 }
8409
8410 if let Some(ref to_table) = cv.to_table {
8412 self.write_space();
8413 self.write_keyword("TO");
8414 self.write_space();
8415 self.generate_table(to_table)?;
8416 }
8417
8418 if !cv.materialized {
8421 if !cv.columns.is_empty() {
8423 self.write(" (");
8424 for (i, col) in cv.columns.iter().enumerate() {
8425 if i > 0 {
8426 self.write(", ");
8427 }
8428 self.generate_identifier(&col.name)?;
8429 if !col.options.is_empty() {
8431 self.write_space();
8432 self.generate_options_clause(&col.options)?;
8433 }
8434 if let Some(ref comment) = col.comment {
8435 self.write_space();
8436 self.write_keyword("COMMENT");
8437 self.write_space();
8438 self.generate_string_literal(comment)?;
8439 }
8440 }
8441 self.write(")");
8442 }
8443
8444 if !cv.security_sql_style {
8446 if let Some(ref security) = cv.security {
8447 self.write_space();
8448 self.write_keyword("SECURITY");
8449 self.write_space();
8450 match security {
8451 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
8452 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
8453 FunctionSecurity::None => self.write_keyword("NONE"),
8454 }
8455 }
8456 }
8457
8458 if cv.copy_grants {
8460 self.write_space();
8461 self.write_keyword("COPY GRANTS");
8462 }
8463 } else {
8464 if cv.copy_grants {
8466 self.write_space();
8467 self.write_keyword("COPY GRANTS");
8468 }
8469
8470 if let Some(ref schema) = cv.schema {
8472 self.write(" (");
8473 for (i, expr) in schema.expressions.iter().enumerate() {
8474 if i > 0 {
8475 self.write(", ");
8476 }
8477 self.generate_expression(expr)?;
8478 }
8479 self.write(")");
8480 } else if !cv.columns.is_empty() {
8481 self.write(" (");
8483 for (i, col) in cv.columns.iter().enumerate() {
8484 if i > 0 {
8485 self.write(", ");
8486 }
8487 self.generate_identifier(&col.name)?;
8488 if !col.options.is_empty() {
8490 self.write_space();
8491 self.generate_options_clause(&col.options)?;
8492 }
8493 if let Some(ref comment) = col.comment {
8494 self.write_space();
8495 self.write_keyword("COMMENT");
8496 self.write_space();
8497 self.generate_string_literal(comment)?;
8498 }
8499 }
8500 self.write(")");
8501 }
8502
8503 if let Some(ref unique_key) = cv.unique_key {
8505 self.write_space();
8506 self.write_keyword("KEY");
8507 self.write(" (");
8508 for (i, expr) in unique_key.expressions.iter().enumerate() {
8509 if i > 0 {
8510 self.write(", ");
8511 }
8512 self.generate_expression(expr)?;
8513 }
8514 self.write(")");
8515 }
8516 }
8517
8518 if let Some(ref comment) = cv.comment {
8520 self.write_space();
8521 self.write_keyword("COMMENT");
8522 self.write("=");
8523 self.generate_string_literal(comment)?;
8524 }
8525
8526 if !cv.tags.is_empty() {
8528 self.write_space();
8529 self.write_keyword("TAG");
8530 self.write(" (");
8531 for (i, (name, value)) in cv.tags.iter().enumerate() {
8532 if i > 0 {
8533 self.write(", ");
8534 }
8535 self.write(name);
8536 self.write("='");
8537 self.write(value);
8538 self.write("'");
8539 }
8540 self.write(")");
8541 }
8542
8543 if !cv.options.is_empty() {
8545 self.write_space();
8546 self.generate_options_clause(&cv.options)?;
8547 }
8548
8549 if let Some(ref build) = cv.build {
8551 self.write_space();
8552 self.write_keyword("BUILD");
8553 self.write_space();
8554 self.write_keyword(build);
8555 }
8556
8557 if let Some(ref refresh) = cv.refresh {
8559 self.write_space();
8560 self.generate_refresh_trigger_property(refresh)?;
8561 }
8562
8563 if let Some(auto_refresh) = cv.auto_refresh {
8565 self.write_space();
8566 self.write_keyword("AUTO REFRESH");
8567 self.write_space();
8568 if auto_refresh {
8569 self.write_keyword("YES");
8570 } else {
8571 self.write_keyword("NO");
8572 }
8573 }
8574
8575 for prop in &cv.table_properties {
8577 self.write_space();
8578 self.generate_expression(prop)?;
8579 }
8580
8581 if !matches!(&cv.query, Expression::Null(_)) {
8583 self.write_space();
8584 self.write_keyword("AS");
8585 self.write_space();
8586
8587 if let Some(ref mode) = cv.locking_mode {
8589 self.write_keyword("LOCKING");
8590 self.write_space();
8591 self.write_keyword(mode);
8592 if let Some(ref access) = cv.locking_access {
8593 self.write_space();
8594 self.write_keyword("FOR");
8595 self.write_space();
8596 self.write_keyword(access);
8597 }
8598 self.write_space();
8599 }
8600
8601 if cv.query_parenthesized {
8602 self.write("(");
8603 }
8604 self.generate_expression(&cv.query)?;
8605 if cv.query_parenthesized {
8606 self.write(")");
8607 }
8608 }
8609
8610 if cv.no_schema_binding {
8612 self.write_space();
8613 self.write_keyword("WITH NO SCHEMA BINDING");
8614 }
8615
8616 Ok(())
8617 }
8618
8619 fn generate_drop_view(&mut self, dv: &DropView) -> Result<()> {
8620 self.write_keyword("DROP");
8621
8622 if dv.materialized {
8623 self.write_space();
8624 self.write_keyword("MATERIALIZED");
8625 }
8626
8627 self.write_space();
8628 self.write_keyword("VIEW");
8629
8630 if dv.if_exists {
8631 self.write_space();
8632 self.write_keyword("IF EXISTS");
8633 }
8634
8635 self.write_space();
8636 self.generate_table(&dv.name)?;
8637
8638 Ok(())
8639 }
8640
8641 fn generate_truncate(&mut self, tr: &Truncate) -> Result<()> {
8642 match tr.target {
8643 TruncateTarget::Database => self.write_keyword("TRUNCATE DATABASE"),
8644 TruncateTarget::Table => self.write_keyword("TRUNCATE TABLE"),
8645 }
8646 self.write_space();
8647 self.generate_table(&tr.table)?;
8648
8649 if let Some(ref on_cluster) = tr.on_cluster {
8651 self.write_space();
8652 self.generate_on_cluster(on_cluster)?;
8653 }
8654
8655 if !tr.extra_tables.is_empty() {
8657 let skip_first = if let Some(first) = tr.extra_tables.first() {
8659 first.table.name == tr.table.name && first.star
8660 } else {
8661 false
8662 };
8663
8664 let strip_star = matches!(self.config.dialect, Some(crate::dialects::DialectType::PostgreSQL) | Some(crate::dialects::DialectType::Redshift));
8666 if skip_first && !strip_star {
8667 self.write("*");
8668 }
8669
8670 for (i, entry) in tr.extra_tables.iter().enumerate() {
8672 if i == 0 && skip_first {
8673 continue; }
8675 self.write(", ");
8676 self.generate_table(&entry.table)?;
8677 if entry.star && !strip_star {
8678 self.write("*");
8679 }
8680 }
8681 }
8682
8683 if let Some(identity) = &tr.identity {
8685 self.write_space();
8686 match identity {
8687 TruncateIdentity::Restart => self.write_keyword("RESTART IDENTITY"),
8688 TruncateIdentity::Continue => self.write_keyword("CONTINUE IDENTITY"),
8689 }
8690 }
8691
8692 if tr.cascade {
8693 self.write_space();
8694 self.write_keyword("CASCADE");
8695 }
8696
8697 if tr.restrict {
8698 self.write_space();
8699 self.write_keyword("RESTRICT");
8700 }
8701
8702 if let Some(ref partition) = tr.partition {
8704 self.write_space();
8705 self.generate_expression(partition)?;
8706 }
8707
8708 Ok(())
8709 }
8710
8711 fn generate_use(&mut self, u: &Use) -> Result<()> {
8712 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
8714 self.write_keyword("DATABASE");
8715 self.write_space();
8716 self.generate_identifier(&u.this)?;
8717 return Ok(());
8718 }
8719
8720 self.write_keyword("USE");
8721
8722 if let Some(kind) = &u.kind {
8723 self.write_space();
8724 match kind {
8725 UseKind::Database => self.write_keyword("DATABASE"),
8726 UseKind::Schema => self.write_keyword("SCHEMA"),
8727 UseKind::Role => self.write_keyword("ROLE"),
8728 UseKind::Warehouse => self.write_keyword("WAREHOUSE"),
8729 UseKind::Catalog => self.write_keyword("CATALOG"),
8730 UseKind::SecondaryRoles => self.write_keyword("SECONDARY ROLES"),
8731 }
8732 }
8733
8734 self.write_space();
8735 if matches!(&u.kind, Some(UseKind::SecondaryRoles)) {
8738 self.write(&u.this.name);
8739 } else {
8740 self.generate_identifier(&u.this)?;
8741 }
8742 Ok(())
8743 }
8744
8745 fn generate_cache(&mut self, c: &Cache) -> Result<()> {
8746 self.write_keyword("CACHE");
8747 if c.lazy {
8748 self.write_space();
8749 self.write_keyword("LAZY");
8750 }
8751 self.write_space();
8752 self.write_keyword("TABLE");
8753 self.write_space();
8754 self.generate_identifier(&c.table)?;
8755
8756 if !c.options.is_empty() {
8758 self.write_space();
8759 self.write_keyword("OPTIONS");
8760 self.write("(");
8761 for (i, (key, value)) in c.options.iter().enumerate() {
8762 if i > 0 {
8763 self.write(", ");
8764 }
8765 self.generate_expression(key)?;
8766 self.write(" = ");
8767 self.generate_expression(value)?;
8768 }
8769 self.write(")");
8770 }
8771
8772 if let Some(query) = &c.query {
8774 self.write_space();
8775 self.write_keyword("AS");
8776 self.write_space();
8777 self.generate_expression(query)?;
8778 }
8779
8780 Ok(())
8781 }
8782
8783 fn generate_uncache(&mut self, u: &Uncache) -> Result<()> {
8784 self.write_keyword("UNCACHE TABLE");
8785 if u.if_exists {
8786 self.write_space();
8787 self.write_keyword("IF EXISTS");
8788 }
8789 self.write_space();
8790 self.generate_identifier(&u.table)?;
8791 Ok(())
8792 }
8793
8794 fn generate_load_data(&mut self, l: &LoadData) -> Result<()> {
8795 self.write_keyword("LOAD DATA");
8796 if l.local {
8797 self.write_space();
8798 self.write_keyword("LOCAL");
8799 }
8800 self.write_space();
8801 self.write_keyword("INPATH");
8802 self.write_space();
8803 self.write("'");
8804 self.write(&l.inpath);
8805 self.write("'");
8806
8807 if l.overwrite {
8808 self.write_space();
8809 self.write_keyword("OVERWRITE");
8810 }
8811
8812 self.write_space();
8813 self.write_keyword("INTO TABLE");
8814 self.write_space();
8815 self.generate_expression(&l.table)?;
8816
8817 if !l.partition.is_empty() {
8819 self.write_space();
8820 self.write_keyword("PARTITION");
8821 self.write("(");
8822 for (i, (col, val)) in l.partition.iter().enumerate() {
8823 if i > 0 {
8824 self.write(", ");
8825 }
8826 self.generate_identifier(col)?;
8827 self.write(" = ");
8828 self.generate_expression(val)?;
8829 }
8830 self.write(")");
8831 }
8832
8833 if let Some(fmt) = &l.input_format {
8835 self.write_space();
8836 self.write_keyword("INPUTFORMAT");
8837 self.write_space();
8838 self.write("'");
8839 self.write(fmt);
8840 self.write("'");
8841 }
8842
8843 if let Some(serde) = &l.serde {
8845 self.write_space();
8846 self.write_keyword("SERDE");
8847 self.write_space();
8848 self.write("'");
8849 self.write(serde);
8850 self.write("'");
8851 }
8852
8853 Ok(())
8854 }
8855
8856 fn generate_pragma(&mut self, p: &Pragma) -> Result<()> {
8857 self.write_keyword("PRAGMA");
8858 self.write_space();
8859
8860 if let Some(schema) = &p.schema {
8862 self.generate_identifier(schema)?;
8863 self.write(".");
8864 }
8865
8866 self.generate_identifier(&p.name)?;
8868
8869 if let Some(value) = &p.value {
8871 self.write(" = ");
8872 self.generate_expression(value)?;
8873 } else if !p.args.is_empty() {
8874 self.write("(");
8875 for (i, arg) in p.args.iter().enumerate() {
8876 if i > 0 {
8877 self.write(", ");
8878 }
8879 self.generate_expression(arg)?;
8880 }
8881 self.write(")");
8882 }
8883
8884 Ok(())
8885 }
8886
8887 fn generate_grant(&mut self, g: &Grant) -> Result<()> {
8888 self.write_keyword("GRANT");
8889 self.write_space();
8890
8891 for (i, privilege) in g.privileges.iter().enumerate() {
8893 if i > 0 {
8894 self.write(", ");
8895 }
8896 self.write_keyword(&privilege.name);
8897 if !privilege.columns.is_empty() {
8899 self.write("(");
8900 for (j, col) in privilege.columns.iter().enumerate() {
8901 if j > 0 {
8902 self.write(", ");
8903 }
8904 self.write(col);
8905 }
8906 self.write(")");
8907 }
8908 }
8909
8910 self.write_space();
8911 self.write_keyword("ON");
8912 self.write_space();
8913
8914 if let Some(kind) = &g.kind {
8916 self.write_keyword(kind);
8917 self.write_space();
8918 }
8919
8920 {
8922 use crate::dialects::DialectType;
8923 let should_upper = matches!(
8924 self.config.dialect,
8925 Some(DialectType::PostgreSQL)
8926 | Some(DialectType::CockroachDB)
8927 | Some(DialectType::Materialize)
8928 | Some(DialectType::RisingWave)
8929 ) && (g.kind.as_deref() == Some("FUNCTION") || g.kind.as_deref() == Some("PROCEDURE"));
8930 if should_upper {
8931 use crate::expressions::Identifier;
8932 let upper_id = Identifier {
8933 name: g.securable.name.to_uppercase(),
8934 quoted: g.securable.quoted,
8935 ..g.securable.clone()
8936 };
8937 self.generate_identifier(&upper_id)?;
8938 } else {
8939 self.generate_identifier(&g.securable)?;
8940 }
8941 }
8942
8943 if !g.function_params.is_empty() {
8945 self.write("(");
8946 for (i, param) in g.function_params.iter().enumerate() {
8947 if i > 0 {
8948 self.write(", ");
8949 }
8950 self.write(param);
8951 }
8952 self.write(")");
8953 }
8954
8955 self.write_space();
8956 self.write_keyword("TO");
8957 self.write_space();
8958
8959 for (i, principal) in g.principals.iter().enumerate() {
8961 if i > 0 {
8962 self.write(", ");
8963 }
8964 if principal.is_role {
8965 self.write_keyword("ROLE");
8966 self.write_space();
8967 } else if principal.is_group {
8968 self.write_keyword("GROUP");
8969 self.write_space();
8970 }
8971 self.generate_identifier(&principal.name)?;
8972 }
8973
8974 if g.grant_option {
8976 self.write_space();
8977 self.write_keyword("WITH GRANT OPTION");
8978 }
8979
8980 if let Some(ref principal) = g.as_principal {
8982 self.write_space();
8983 self.write_keyword("AS");
8984 self.write_space();
8985 self.generate_identifier(principal)?;
8986 }
8987
8988 Ok(())
8989 }
8990
8991 fn generate_revoke(&mut self, r: &Revoke) -> Result<()> {
8992 self.write_keyword("REVOKE");
8993 self.write_space();
8994
8995 if r.grant_option {
8997 self.write_keyword("GRANT OPTION FOR");
8998 self.write_space();
8999 }
9000
9001 for (i, privilege) in r.privileges.iter().enumerate() {
9003 if i > 0 {
9004 self.write(", ");
9005 }
9006 self.write_keyword(&privilege.name);
9007 if !privilege.columns.is_empty() {
9009 self.write("(");
9010 for (j, col) in privilege.columns.iter().enumerate() {
9011 if j > 0 {
9012 self.write(", ");
9013 }
9014 self.write(col);
9015 }
9016 self.write(")");
9017 }
9018 }
9019
9020 self.write_space();
9021 self.write_keyword("ON");
9022 self.write_space();
9023
9024 if let Some(kind) = &r.kind {
9026 self.write_keyword(kind);
9027 self.write_space();
9028 }
9029
9030 {
9032 use crate::dialects::DialectType;
9033 let should_upper = matches!(
9034 self.config.dialect,
9035 Some(DialectType::PostgreSQL)
9036 | Some(DialectType::CockroachDB)
9037 | Some(DialectType::Materialize)
9038 | Some(DialectType::RisingWave)
9039 ) && (r.kind.as_deref() == Some("FUNCTION") || r.kind.as_deref() == Some("PROCEDURE"));
9040 if should_upper {
9041 use crate::expressions::Identifier;
9042 let upper_id = Identifier {
9043 name: r.securable.name.to_uppercase(),
9044 quoted: r.securable.quoted,
9045 ..r.securable.clone()
9046 };
9047 self.generate_identifier(&upper_id)?;
9048 } else {
9049 self.generate_identifier(&r.securable)?;
9050 }
9051 }
9052
9053 if !r.function_params.is_empty() {
9055 self.write("(");
9056 for (i, param) in r.function_params.iter().enumerate() {
9057 if i > 0 {
9058 self.write(", ");
9059 }
9060 self.write(param);
9061 }
9062 self.write(")");
9063 }
9064
9065 self.write_space();
9066 self.write_keyword("FROM");
9067 self.write_space();
9068
9069 for (i, principal) in r.principals.iter().enumerate() {
9071 if i > 0 {
9072 self.write(", ");
9073 }
9074 if principal.is_role {
9075 self.write_keyword("ROLE");
9076 self.write_space();
9077 } else if principal.is_group {
9078 self.write_keyword("GROUP");
9079 self.write_space();
9080 }
9081 self.generate_identifier(&principal.name)?;
9082 }
9083
9084 if r.cascade {
9086 self.write_space();
9087 self.write_keyword("CASCADE");
9088 } else if r.restrict {
9089 self.write_space();
9090 self.write_keyword("RESTRICT");
9091 }
9092
9093 Ok(())
9094 }
9095
9096 fn generate_comment(&mut self, c: &Comment) -> Result<()> {
9097 self.write_keyword("COMMENT");
9098
9099 if c.exists {
9101 self.write_space();
9102 self.write_keyword("IF EXISTS");
9103 }
9104
9105 self.write_space();
9106 self.write_keyword("ON");
9107
9108 if c.materialized {
9110 self.write_space();
9111 self.write_keyword("MATERIALIZED");
9112 }
9113
9114 self.write_space();
9115 self.write_keyword(&c.kind);
9116 self.write_space();
9117
9118 self.generate_expression(&c.this)?;
9120
9121 self.write_space();
9122 self.write_keyword("IS");
9123 self.write_space();
9124
9125 self.generate_expression(&c.expression)?;
9127
9128 Ok(())
9129 }
9130
9131 fn generate_set_statement(&mut self, s: &SetStatement) -> Result<()> {
9132 self.write_keyword("SET");
9133
9134 for (i, item) in s.items.iter().enumerate() {
9135 if i > 0 {
9136 self.write(",");
9137 }
9138 self.write_space();
9139
9140 if let Some(ref kind) = item.kind {
9142 self.write_keyword(kind);
9143 self.write_space();
9144 }
9145
9146 let name_str = match &item.name {
9148 Expression::Identifier(id) => Some(id.name.as_str()),
9149 _ => None,
9150 };
9151
9152 let is_transaction = name_str == Some("TRANSACTION");
9153 let is_character_set = name_str == Some("CHARACTER SET");
9154 let is_names = name_str == Some("NAMES");
9155 let is_collate = name_str == Some("COLLATE");
9156 let has_variable_kind = item.kind.as_deref() == Some("VARIABLE");
9157 let name_has_variable_prefix = name_str.map_or(false, |n| n.starts_with("VARIABLE "));
9158 let is_variable = has_variable_kind || name_has_variable_prefix;
9159 let is_value_only = matches!(&item.value, Expression::Identifier(id) if id.name.is_empty());
9160
9161 if is_transaction {
9162 self.write_keyword("TRANSACTION");
9164 if let Expression::Identifier(id) = &item.value {
9165 if !id.name.is_empty() {
9166 self.write_space();
9167 self.write(&id.name);
9168 }
9169 }
9170 } else if is_character_set {
9171 self.write_keyword("CHARACTER SET");
9173 self.write_space();
9174 self.generate_set_value(&item.value)?;
9175 } else if is_names {
9176 self.write_keyword("NAMES");
9178 self.write_space();
9179 self.generate_set_value(&item.value)?;
9180 } else if is_collate {
9181 self.write_keyword("COLLATE");
9183 self.write_space();
9184 self.generate_set_value(&item.value)?;
9185 } else if is_variable {
9186 if name_has_variable_prefix && !has_variable_kind {
9190 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
9191 self.write_keyword("VARIABLE");
9192 self.write_space();
9193 }
9194 }
9195 if let Some(ns) = name_str {
9197 let var_name = if name_has_variable_prefix {
9198 &ns["VARIABLE ".len()..]
9199 } else {
9200 ns
9201 };
9202 self.write(var_name);
9203 } else {
9204 self.generate_expression(&item.name)?;
9205 }
9206 self.write(" = ");
9207 self.generate_set_value(&item.value)?;
9208 } else if is_value_only {
9209 self.generate_expression(&item.name)?;
9211 } else if item.no_equals && matches!(self.config.dialect, Some(DialectType::TSQL)) {
9212 self.generate_expression(&item.name)?;
9214 self.write_space();
9215 self.generate_set_value(&item.value)?;
9216 } else {
9217 match &item.name {
9220 Expression::Identifier(id) => {
9221 self.write(&id.name);
9222 }
9223 _ => {
9224 self.generate_expression(&item.name)?;
9225 }
9226 }
9227 self.write(" = ");
9228 self.generate_set_value(&item.value)?;
9229 }
9230 }
9231
9232 Ok(())
9233 }
9234
9235 fn generate_set_value(&mut self, value: &Expression) -> Result<()> {
9238 if let Expression::Identifier(id) = value {
9239 match id.name.as_str() {
9240 "DEFAULT" | "ON" | "OFF" => {
9241 self.write_keyword(&id.name);
9242 return Ok(());
9243 }
9244 _ => {}
9245 }
9246 }
9247 self.generate_expression(value)
9248 }
9249
9250 fn generate_alter_view(&mut self, av: &AlterView) -> Result<()> {
9253 self.write_keyword("ALTER");
9254 if let Some(ref algorithm) = av.algorithm {
9256 self.write_space();
9257 self.write_keyword("ALGORITHM");
9258 self.write(" = ");
9259 self.write_keyword(algorithm);
9260 }
9261 if let Some(ref definer) = av.definer {
9262 self.write_space();
9263 self.write_keyword("DEFINER");
9264 self.write(" = ");
9265 self.write(definer);
9266 }
9267 if let Some(ref sql_security) = av.sql_security {
9268 self.write_space();
9269 self.write_keyword("SQL SECURITY");
9270 self.write(" = ");
9271 self.write_keyword(sql_security);
9272 }
9273 self.write_space();
9274 self.write_keyword("VIEW");
9275 self.write_space();
9276 self.generate_table(&av.name)?;
9277
9278 if !av.columns.is_empty() {
9280 self.write(" (");
9281 for (i, col) in av.columns.iter().enumerate() {
9282 if i > 0 {
9283 self.write(", ");
9284 }
9285 self.generate_identifier(&col.name)?;
9286 if let Some(ref comment) = col.comment {
9287 self.write_space();
9288 self.write_keyword("COMMENT");
9289 self.write(" ");
9290 self.generate_string_literal(comment)?;
9291 }
9292 }
9293 self.write(")");
9294 }
9295
9296 if let Some(ref opt) = av.with_option {
9298 self.write_space();
9299 self.write_keyword("WITH");
9300 self.write_space();
9301 self.write_keyword(opt);
9302 }
9303
9304 for action in &av.actions {
9305 self.write_space();
9306 match action {
9307 AlterViewAction::Rename(new_name) => {
9308 self.write_keyword("RENAME TO");
9309 self.write_space();
9310 self.generate_table(new_name)?;
9311 }
9312 AlterViewAction::OwnerTo(owner) => {
9313 self.write_keyword("OWNER TO");
9314 self.write_space();
9315 self.generate_identifier(owner)?;
9316 }
9317 AlterViewAction::SetSchema(schema) => {
9318 self.write_keyword("SET SCHEMA");
9319 self.write_space();
9320 self.generate_identifier(schema)?;
9321 }
9322 AlterViewAction::SetAuthorization(auth) => {
9323 self.write_keyword("SET AUTHORIZATION");
9324 self.write_space();
9325 self.write(auth);
9326 }
9327 AlterViewAction::AlterColumn { name, action } => {
9328 self.write_keyword("ALTER COLUMN");
9329 self.write_space();
9330 self.generate_identifier(name)?;
9331 self.write_space();
9332 self.generate_alter_column_action(action)?;
9333 }
9334 AlterViewAction::AsSelect(query) => {
9335 self.write_keyword("AS");
9336 self.write_space();
9337 self.generate_expression(query)?;
9338 }
9339 AlterViewAction::SetTblproperties(props) => {
9340 self.write_keyword("SET TBLPROPERTIES");
9341 self.write(" (");
9342 for (i, (key, value)) in props.iter().enumerate() {
9343 if i > 0 {
9344 self.write(", ");
9345 }
9346 self.generate_string_literal(key)?;
9347 self.write("=");
9348 self.generate_string_literal(value)?;
9349 }
9350 self.write(")");
9351 }
9352 AlterViewAction::UnsetTblproperties(keys) => {
9353 self.write_keyword("UNSET TBLPROPERTIES");
9354 self.write(" (");
9355 for (i, key) in keys.iter().enumerate() {
9356 if i > 0 {
9357 self.write(", ");
9358 }
9359 self.generate_string_literal(key)?;
9360 }
9361 self.write(")");
9362 }
9363 }
9364 }
9365
9366 Ok(())
9367 }
9368
9369 fn generate_alter_index(&mut self, ai: &AlterIndex) -> Result<()> {
9370 self.write_keyword("ALTER INDEX");
9371 self.write_space();
9372 self.generate_identifier(&ai.name)?;
9373
9374 if let Some(table) = &ai.table {
9375 self.write_space();
9376 self.write_keyword("ON");
9377 self.write_space();
9378 self.generate_table(table)?;
9379 }
9380
9381 for action in &ai.actions {
9382 self.write_space();
9383 match action {
9384 AlterIndexAction::Rename(new_name) => {
9385 self.write_keyword("RENAME TO");
9386 self.write_space();
9387 self.generate_identifier(new_name)?;
9388 }
9389 AlterIndexAction::SetTablespace(tablespace) => {
9390 self.write_keyword("SET TABLESPACE");
9391 self.write_space();
9392 self.generate_identifier(tablespace)?;
9393 }
9394 AlterIndexAction::Visible(visible) => {
9395 if *visible {
9396 self.write_keyword("VISIBLE");
9397 } else {
9398 self.write_keyword("INVISIBLE");
9399 }
9400 }
9401 }
9402 }
9403
9404 Ok(())
9405 }
9406
9407 fn generate_create_schema(&mut self, cs: &CreateSchema) -> Result<()> {
9408 for comment in &cs.leading_comments {
9410 self.write(comment);
9411 self.write_space();
9412 }
9413
9414 let saved_athena_hive_context = self.athena_hive_context;
9416 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Athena)) {
9417 self.athena_hive_context = true;
9418 }
9419
9420 self.write_keyword("CREATE SCHEMA");
9421
9422 if cs.if_not_exists {
9423 self.write_space();
9424 self.write_keyword("IF NOT EXISTS");
9425 }
9426
9427 self.write_space();
9428 self.generate_identifier(&cs.name)?;
9429
9430 if let Some(ref clone_src) = cs.clone_from {
9431 self.write_keyword(" CLONE ");
9432 self.generate_identifier(clone_src)?;
9433 }
9434
9435 if let Some(ref at_clause) = cs.at_clause {
9436 self.write_space();
9437 self.generate_expression(at_clause)?;
9438 }
9439
9440 if let Some(auth) = &cs.authorization {
9441 self.write_space();
9442 self.write_keyword("AUTHORIZATION");
9443 self.write_space();
9444 self.generate_identifier(auth)?;
9445 }
9446
9447 let with_properties: Vec<_> = cs.properties.iter()
9450 .filter(|p| matches!(p, Expression::Property(_)))
9451 .collect();
9452 let other_properties: Vec<_> = cs.properties.iter()
9453 .filter(|p| !matches!(p, Expression::Property(_)))
9454 .collect();
9455
9456 if !with_properties.is_empty() {
9458 self.write_space();
9459 self.write_keyword("WITH");
9460 self.write(" (");
9461 for (i, prop) in with_properties.iter().enumerate() {
9462 if i > 0 {
9463 self.write(", ");
9464 }
9465 self.generate_expression(prop)?;
9466 }
9467 self.write(")");
9468 }
9469
9470 for prop in other_properties {
9472 self.write_space();
9473 self.generate_expression(prop)?;
9474 }
9475
9476 self.athena_hive_context = saved_athena_hive_context;
9478
9479 Ok(())
9480 }
9481
9482 fn generate_drop_schema(&mut self, ds: &DropSchema) -> Result<()> {
9483 self.write_keyword("DROP SCHEMA");
9484
9485 if ds.if_exists {
9486 self.write_space();
9487 self.write_keyword("IF EXISTS");
9488 }
9489
9490 self.write_space();
9491 self.generate_identifier(&ds.name)?;
9492
9493 if ds.cascade {
9494 self.write_space();
9495 self.write_keyword("CASCADE");
9496 }
9497
9498 Ok(())
9499 }
9500
9501 fn generate_drop_namespace(&mut self, dn: &DropNamespace) -> Result<()> {
9502 self.write_keyword("DROP NAMESPACE");
9503
9504 if dn.if_exists {
9505 self.write_space();
9506 self.write_keyword("IF EXISTS");
9507 }
9508
9509 self.write_space();
9510 self.generate_identifier(&dn.name)?;
9511
9512 if dn.cascade {
9513 self.write_space();
9514 self.write_keyword("CASCADE");
9515 }
9516
9517 Ok(())
9518 }
9519
9520 fn generate_create_database(&mut self, cd: &CreateDatabase) -> Result<()> {
9521 self.write_keyword("CREATE DATABASE");
9522
9523 if cd.if_not_exists {
9524 self.write_space();
9525 self.write_keyword("IF NOT EXISTS");
9526 }
9527
9528 self.write_space();
9529 self.generate_identifier(&cd.name)?;
9530
9531 if let Some(ref clone_src) = cd.clone_from {
9532 self.write_keyword(" CLONE ");
9533 self.generate_identifier(clone_src)?;
9534 }
9535
9536 if let Some(ref at_clause) = cd.at_clause {
9538 self.write_space();
9539 self.generate_expression(at_clause)?;
9540 }
9541
9542 for option in &cd.options {
9543 self.write_space();
9544 match option {
9545 DatabaseOption::CharacterSet(charset) => {
9546 self.write_keyword("CHARACTER SET");
9547 self.write(" = ");
9548 self.write(&format!("'{}'", charset));
9549 }
9550 DatabaseOption::Collate(collate) => {
9551 self.write_keyword("COLLATE");
9552 self.write(" = ");
9553 self.write(&format!("'{}'", collate));
9554 }
9555 DatabaseOption::Owner(owner) => {
9556 self.write_keyword("OWNER");
9557 self.write(" = ");
9558 self.generate_identifier(owner)?;
9559 }
9560 DatabaseOption::Template(template) => {
9561 self.write_keyword("TEMPLATE");
9562 self.write(" = ");
9563 self.generate_identifier(template)?;
9564 }
9565 DatabaseOption::Encoding(encoding) => {
9566 self.write_keyword("ENCODING");
9567 self.write(" = ");
9568 self.write(&format!("'{}'", encoding));
9569 }
9570 DatabaseOption::Location(location) => {
9571 self.write_keyword("LOCATION");
9572 self.write(" = ");
9573 self.write(&format!("'{}'", location));
9574 }
9575 }
9576 }
9577
9578 Ok(())
9579 }
9580
9581 fn generate_drop_database(&mut self, dd: &DropDatabase) -> Result<()> {
9582 self.write_keyword("DROP DATABASE");
9583
9584 if dd.if_exists {
9585 self.write_space();
9586 self.write_keyword("IF EXISTS");
9587 }
9588
9589 self.write_space();
9590 self.generate_identifier(&dd.name)?;
9591
9592 Ok(())
9593 }
9594
9595 fn generate_create_function(&mut self, cf: &CreateFunction) -> Result<()> {
9596 self.write_keyword("CREATE");
9597
9598 if cf.or_replace {
9599 self.write_space();
9600 self.write_keyword("OR REPLACE");
9601 }
9602
9603 if cf.temporary {
9604 self.write_space();
9605 self.write_keyword("TEMPORARY");
9606 }
9607
9608 self.write_space();
9609 if cf.is_table_function {
9610 self.write_keyword("TABLE FUNCTION");
9611 } else {
9612 self.write_keyword("FUNCTION");
9613 }
9614
9615 if cf.if_not_exists {
9616 self.write_space();
9617 self.write_keyword("IF NOT EXISTS");
9618 }
9619
9620 self.write_space();
9621 self.generate_table(&cf.name)?;
9622 if cf.has_parens {
9623 let func_multiline = self.config.pretty && matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL) | Some(crate::dialects::DialectType::Fabric)) && !cf.parameters.is_empty();
9624 if func_multiline {
9625 self.write("(\n");
9626 self.indent_level += 2;
9627 self.write_indent();
9628 self.generate_function_parameters(&cf.parameters)?;
9629 self.write("\n");
9630 self.indent_level -= 2;
9631 self.write(")");
9632 } else {
9633 self.write("(");
9634 self.generate_function_parameters(&cf.parameters)?;
9635 self.write(")");
9636 }
9637 }
9638
9639 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));
9642
9643 if cf.language_first {
9644 if let Some(lang) = &cf.language {
9646 if use_multiline {
9647 self.write_newline();
9648 } else {
9649 self.write_space();
9650 }
9651 self.write_keyword("LANGUAGE");
9652 self.write_space();
9653 self.write(lang);
9654 }
9655
9656 if let Some(sql_data) = &cf.sql_data_access {
9658 self.write_space();
9659 match sql_data {
9660 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
9661 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
9662 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
9663 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
9664 }
9665 }
9666
9667 if let Some(ref rtb) = cf.returns_table_body {
9668 if use_multiline {
9669 self.write_newline();
9670 } else {
9671 self.write_space();
9672 }
9673 self.write_keyword("RETURNS");
9674 self.write_space();
9675 self.write(rtb);
9676 } else if let Some(return_type) = &cf.return_type {
9677 if use_multiline {
9678 self.write_newline();
9679 } else {
9680 self.write_space();
9681 }
9682 self.write_keyword("RETURNS");
9683 self.write_space();
9684 self.generate_data_type(return_type)?;
9685 }
9686 } else {
9687 let is_duckdb = matches!(self.config.dialect, Some(crate::dialects::DialectType::DuckDB));
9690 if let Some(ref rtb) = cf.returns_table_body {
9691 if !(is_duckdb && rtb.is_empty()) {
9692 if use_multiline {
9693 self.write_newline();
9694 } else {
9695 self.write_space();
9696 }
9697 self.write_keyword("RETURNS");
9698 self.write_space();
9699 self.write(rtb);
9700 }
9701 } else if let Some(return_type) = &cf.return_type {
9702 if use_multiline {
9703 self.write_newline();
9704 } else {
9705 self.write_space();
9706 }
9707 self.write_keyword("RETURNS");
9708 self.write_space();
9709 self.generate_data_type(return_type)?;
9710 }
9711 }
9712
9713 if !cf.property_order.is_empty() {
9715 let is_bigquery = matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery));
9717 let property_order = if is_bigquery {
9718 let mut reordered = Vec::new();
9720 let mut has_as = false;
9721 let mut has_options = false;
9722 for prop in &cf.property_order {
9723 match prop {
9724 FunctionPropertyKind::As => has_as = true,
9725 FunctionPropertyKind::Options => has_options = true,
9726 _ => {}
9727 }
9728 }
9729 if has_as && has_options {
9730 for prop in &cf.property_order {
9732 if *prop != FunctionPropertyKind::As && *prop != FunctionPropertyKind::Options {
9733 reordered.push(*prop);
9734 }
9735 }
9736 reordered.push(FunctionPropertyKind::Options);
9737 reordered.push(FunctionPropertyKind::As);
9738 reordered
9739 } else {
9740 cf.property_order.clone()
9741 }
9742 } else {
9743 cf.property_order.clone()
9744 };
9745
9746 for prop in &property_order {
9747 match prop {
9748 FunctionPropertyKind::Set => {
9749 self.generate_function_set_options(cf)?;
9750 }
9751 FunctionPropertyKind::As => {
9752 self.generate_function_body(cf)?;
9753 }
9754 FunctionPropertyKind::Language => {
9755 if !cf.language_first {
9756 if let Some(lang) = &cf.language {
9758 let use_multiline = self.config.pretty && matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery));
9760 if use_multiline {
9761 self.write_newline();
9762 } else {
9763 self.write_space();
9764 }
9765 self.write_keyword("LANGUAGE");
9766 self.write_space();
9767 self.write(lang);
9768 }
9769 }
9770 }
9771 FunctionPropertyKind::Determinism => {
9772 self.generate_function_determinism(cf)?;
9773 }
9774 FunctionPropertyKind::NullInput => {
9775 self.generate_function_null_input(cf)?;
9776 }
9777 FunctionPropertyKind::Security => {
9778 self.generate_function_security(cf)?;
9779 }
9780 FunctionPropertyKind::SqlDataAccess => {
9781 if !cf.language_first {
9782 self.generate_function_sql_data_access(cf)?;
9784 }
9785 }
9786 FunctionPropertyKind::Options => {
9787 if !cf.options.is_empty() {
9788 self.write_space();
9789 self.generate_options_clause(&cf.options)?;
9790 }
9791 }
9792 FunctionPropertyKind::Environment => {
9793 if !cf.environment.is_empty() {
9794 self.write_space();
9795 self.generate_environment_clause(&cf.environment)?;
9796 }
9797 }
9798 }
9799 }
9800
9801 if !cf.options.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Options) {
9803 self.write_space();
9804 self.generate_options_clause(&cf.options)?;
9805 }
9806
9807 if !cf.environment.is_empty() && !cf.property_order.contains(&FunctionPropertyKind::Environment) {
9809 self.write_space();
9810 self.generate_environment_clause(&cf.environment)?;
9811 }
9812 } else {
9813 if matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery)) {
9816 self.generate_function_determinism(cf)?;
9817 }
9818
9819 let use_multiline = self.config.pretty && matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery));
9821
9822 if !cf.language_first {
9823 if let Some(lang) = &cf.language {
9824 if use_multiline {
9825 self.write_newline();
9826 } else {
9827 self.write_space();
9828 }
9829 self.write_keyword("LANGUAGE");
9830 self.write_space();
9831 self.write(lang);
9832 }
9833
9834 self.generate_function_sql_data_access(cf)?;
9836 }
9837
9838 if !matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery)) {
9840 self.generate_function_determinism(cf)?;
9841 }
9842
9843 self.generate_function_null_input(cf)?;
9844 self.generate_function_security(cf)?;
9845 self.generate_function_set_options(cf)?;
9846
9847 if !cf.options.is_empty() {
9849 self.write_space();
9850 self.generate_options_clause(&cf.options)?;
9851 }
9852
9853 if !cf.environment.is_empty() {
9855 self.write_space();
9856 self.generate_environment_clause(&cf.environment)?;
9857 }
9858
9859 self.generate_function_body(cf)?;
9860 }
9861
9862 Ok(())
9863 }
9864
9865 fn generate_function_set_options(&mut self, cf: &CreateFunction) -> Result<()> {
9867 for opt in &cf.set_options {
9868 self.write_space();
9869 self.write_keyword("SET");
9870 self.write_space();
9871 self.write(&opt.name);
9872 match &opt.value {
9873 FunctionSetValue::Value { value, use_to } => {
9874 if *use_to && !matches!(self.config.dialect, Some(crate::dialects::DialectType::PostgreSQL)) {
9876 self.write(" TO ");
9877 } else {
9878 self.write(" = ");
9879 }
9880 self.write(value);
9881 }
9882 FunctionSetValue::FromCurrent => {
9883 self.write_space();
9884 self.write_keyword("FROM CURRENT");
9885 }
9886 }
9887 }
9888 Ok(())
9889 }
9890
9891 fn generate_function_body(&mut self, cf: &CreateFunction) -> Result<()> {
9893 if let Some(body) = &cf.body {
9894 self.write_space();
9896 let use_multiline = self.config.pretty && matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery));
9898 match body {
9899 FunctionBody::Block(block) => {
9900 self.write_keyword("AS");
9901 if matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL)) {
9902 self.write(" BEGIN ");
9903 self.write(block);
9904 self.write(" END");
9905 } else if matches!(self.config.dialect, Some(crate::dialects::DialectType::PostgreSQL)) {
9906 self.write(" $$");
9907 self.write(block);
9908 self.write("$$");
9909 } else {
9910 let escaped = self.escape_block_for_single_quote(block);
9912 if use_multiline {
9914 self.write_newline();
9915 } else {
9916 self.write(" ");
9917 }
9918 self.write("'");
9919 self.write(&escaped);
9920 self.write("'");
9921 }
9922 }
9923 FunctionBody::StringLiteral(s) => {
9924 self.write_keyword("AS");
9925 if use_multiline {
9927 self.write_newline();
9928 } else {
9929 self.write(" ");
9930 }
9931 self.write("'");
9932 self.write(s);
9933 self.write("'");
9934 }
9935 FunctionBody::Expression(expr) => {
9936 self.write_keyword("AS");
9937 self.write_space();
9938 self.generate_expression(expr)?;
9939 }
9940 FunctionBody::External(name) => {
9941 self.write_keyword("EXTERNAL NAME");
9942 self.write(" '");
9943 self.write(name);
9944 self.write("'");
9945 }
9946 FunctionBody::Return(expr) => {
9947 if matches!(self.config.dialect, Some(crate::dialects::DialectType::DuckDB)) {
9948 self.write_keyword("AS");
9950 self.write_space();
9951 if cf.returns_table_body.is_some() {
9953 self.write_keyword("TABLE");
9954 self.write_space();
9955 }
9956 self.generate_expression(expr)?;
9957 } else {
9958 if self.config.create_function_return_as {
9959 self.write_keyword("AS");
9960 if self.config.pretty && matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL) | Some(crate::dialects::DialectType::Fabric)) {
9962 self.write_newline();
9963 } else {
9964 self.write_space();
9965 }
9966 }
9967 self.write_keyword("RETURN");
9968 self.write_space();
9969 self.generate_expression(expr)?;
9970 }
9971 }
9972 FunctionBody::Statements(stmts) => {
9973 self.write_keyword("AS");
9974 self.write(" BEGIN ");
9975 for (i, stmt) in stmts.iter().enumerate() {
9976 if i > 0 {
9977 self.write(" ");
9978 }
9979 self.generate_expression(stmt)?;
9980 }
9981 self.write(" END");
9982 }
9983 FunctionBody::DollarQuoted { content, tag } => {
9984 self.write_keyword("AS");
9985 self.write(" ");
9986 let supports_dollar_quoting = matches!(
9988 self.config.dialect,
9989 Some(crate::dialects::DialectType::PostgreSQL)
9990 | Some(crate::dialects::DialectType::Databricks)
9991 | Some(crate::dialects::DialectType::Redshift)
9992 | Some(crate::dialects::DialectType::DuckDB)
9993 );
9994 if supports_dollar_quoting {
9995 self.write("$");
9997 if let Some(t) = tag {
9998 self.write(t);
9999 }
10000 self.write("$");
10001 self.write(content);
10002 self.write("$");
10003 if let Some(t) = tag {
10004 self.write(t);
10005 }
10006 self.write("$");
10007 } else {
10008 let escaped = self.escape_block_for_single_quote(content);
10010 self.write("'");
10011 self.write(&escaped);
10012 self.write("'");
10013 }
10014 }
10015 }
10016 }
10017 Ok(())
10018 }
10019
10020 fn generate_function_determinism(&mut self, cf: &CreateFunction) -> Result<()> {
10022 if let Some(det) = cf.deterministic {
10023 self.write_space();
10024 if matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery)) {
10025 if det {
10027 self.write_keyword("DETERMINISTIC");
10028 } else {
10029 self.write_keyword("NOT DETERMINISTIC");
10030 }
10031 } else {
10032 if det {
10034 self.write_keyword("IMMUTABLE");
10035 } else {
10036 self.write_keyword("VOLATILE");
10037 }
10038 }
10039 }
10040 Ok(())
10041 }
10042
10043 fn generate_function_null_input(&mut self, cf: &CreateFunction) -> Result<()> {
10045 if let Some(returns_null) = cf.returns_null_on_null_input {
10046 self.write_space();
10047 if returns_null {
10048 if cf.strict {
10049 self.write_keyword("STRICT");
10050 } else {
10051 self.write_keyword("RETURNS NULL ON NULL INPUT");
10052 }
10053 } else {
10054 self.write_keyword("CALLED ON NULL INPUT");
10055 }
10056 }
10057 Ok(())
10058 }
10059
10060 fn generate_function_security(&mut self, cf: &CreateFunction) -> Result<()> {
10062 if let Some(security) = &cf.security {
10063 self.write_space();
10064 self.write_keyword("SECURITY");
10065 self.write_space();
10066 match security {
10067 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10068 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10069 FunctionSecurity::None => self.write_keyword("NONE"),
10070 }
10071 }
10072 Ok(())
10073 }
10074
10075 fn generate_function_sql_data_access(&mut self, cf: &CreateFunction) -> Result<()> {
10077 if let Some(sql_data) = &cf.sql_data_access {
10078 self.write_space();
10079 match sql_data {
10080 SqlDataAccess::NoSql => self.write_keyword("NO SQL"),
10081 SqlDataAccess::ContainsSql => self.write_keyword("CONTAINS SQL"),
10082 SqlDataAccess::ReadsSqlData => self.write_keyword("READS SQL DATA"),
10083 SqlDataAccess::ModifiesSqlData => self.write_keyword("MODIFIES SQL DATA"),
10084 }
10085 }
10086 Ok(())
10087 }
10088
10089 fn generate_function_parameters(&mut self, params: &[FunctionParameter]) -> Result<()> {
10090 for (i, param) in params.iter().enumerate() {
10091 if i > 0 {
10092 self.write(", ");
10093 }
10094
10095 if let Some(mode) = ¶m.mode {
10096 match mode {
10097 ParameterMode::In => self.write_keyword("IN"),
10098 ParameterMode::Out => self.write_keyword("OUT"),
10099 ParameterMode::InOut => self.write_keyword("INOUT"),
10100 }
10101 self.write_space();
10102 }
10103
10104 if let Some(name) = ¶m.name {
10105 self.generate_identifier(name)?;
10106 let skip_type = matches!(¶m.data_type, DataType::Custom { name } if name.is_empty());
10108 if !skip_type {
10109 self.write_space();
10110 self.generate_data_type(¶m.data_type)?;
10111 }
10112 } else {
10113 self.generate_data_type(¶m.data_type)?;
10114 }
10115
10116 if let Some(default) = ¶m.default {
10117 if self.config.parameter_default_equals {
10118 self.write(" = ");
10119 } else {
10120 self.write(" DEFAULT ");
10121 }
10122 self.generate_expression(default)?;
10123 }
10124 }
10125
10126 Ok(())
10127 }
10128
10129 fn generate_drop_function(&mut self, df: &DropFunction) -> Result<()> {
10130 self.write_keyword("DROP FUNCTION");
10131
10132 if df.if_exists {
10133 self.write_space();
10134 self.write_keyword("IF EXISTS");
10135 }
10136
10137 self.write_space();
10138 self.generate_table(&df.name)?;
10139
10140 if let Some(params) = &df.parameters {
10141 self.write(" (");
10142 for (i, dt) in params.iter().enumerate() {
10143 if i > 0 {
10144 self.write(", ");
10145 }
10146 self.generate_data_type(dt)?;
10147 }
10148 self.write(")");
10149 }
10150
10151 if df.cascade {
10152 self.write_space();
10153 self.write_keyword("CASCADE");
10154 }
10155
10156 Ok(())
10157 }
10158
10159 fn generate_create_procedure(&mut self, cp: &CreateProcedure) -> Result<()> {
10160 self.write_keyword("CREATE");
10161
10162 if cp.or_replace {
10163 self.write_space();
10164 self.write_keyword("OR REPLACE");
10165 }
10166
10167 self.write_space();
10168 if cp.use_proc_keyword {
10169 self.write_keyword("PROC");
10170 } else {
10171 self.write_keyword("PROCEDURE");
10172 }
10173
10174 if cp.if_not_exists {
10175 self.write_space();
10176 self.write_keyword("IF NOT EXISTS");
10177 }
10178
10179 self.write_space();
10180 self.generate_table(&cp.name)?;
10181 if cp.has_parens {
10182 self.write("(");
10183 self.generate_function_parameters(&cp.parameters)?;
10184 self.write(")");
10185 } else if !cp.parameters.is_empty() {
10186 self.write_space();
10188 self.generate_function_parameters(&cp.parameters)?;
10189 }
10190
10191 if let Some(return_type) = &cp.return_type {
10193 self.write_space();
10194 self.write_keyword("RETURNS");
10195 self.write_space();
10196 self.generate_data_type(return_type)?;
10197 }
10198
10199 if let Some(execute_as) = &cp.execute_as {
10201 self.write_space();
10202 self.write_keyword("EXECUTE AS");
10203 self.write_space();
10204 self.write_keyword(execute_as);
10205 }
10206
10207 if let Some(lang) = &cp.language {
10208 self.write_space();
10209 self.write_keyword("LANGUAGE");
10210 self.write_space();
10211 self.write(lang);
10212 }
10213
10214 if let Some(security) = &cp.security {
10215 self.write_space();
10216 self.write_keyword("SECURITY");
10217 self.write_space();
10218 match security {
10219 FunctionSecurity::Definer => self.write_keyword("DEFINER"),
10220 FunctionSecurity::Invoker => self.write_keyword("INVOKER"),
10221 FunctionSecurity::None => self.write_keyword("NONE"),
10222 }
10223 }
10224
10225 if !cp.with_options.is_empty() {
10227 self.write_space();
10228 self.write_keyword("WITH");
10229 self.write_space();
10230 for (i, opt) in cp.with_options.iter().enumerate() {
10231 if i > 0 {
10232 self.write(", ");
10233 }
10234 self.write(opt);
10235 }
10236 }
10237
10238 if let Some(body) = &cp.body {
10239 self.write_space();
10240 match body {
10241 FunctionBody::Block(block) => {
10242 self.write_keyword("AS");
10243 if matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL)) {
10244 self.write(" BEGIN ");
10245 self.write(block);
10246 self.write(" END");
10247 } else if matches!(self.config.dialect, Some(crate::dialects::DialectType::PostgreSQL)) {
10248 self.write(" $$");
10249 self.write(block);
10250 self.write("$$");
10251 } else {
10252 let escaped = self.escape_block_for_single_quote(block);
10254 self.write(" '");
10255 self.write(&escaped);
10256 self.write("'");
10257 }
10258 }
10259 FunctionBody::StringLiteral(s) => {
10260 self.write_keyword("AS");
10261 self.write(" '");
10262 self.write(s);
10263 self.write("'");
10264 }
10265 FunctionBody::Expression(expr) => {
10266 self.write_keyword("AS");
10267 self.write_space();
10268 self.generate_expression(expr)?;
10269 }
10270 FunctionBody::External(name) => {
10271 self.write_keyword("EXTERNAL NAME");
10272 self.write(" '");
10273 self.write(name);
10274 self.write("'");
10275 }
10276 FunctionBody::Return(expr) => {
10277 self.write_keyword("RETURN");
10278 self.write_space();
10279 self.generate_expression(expr)?;
10280 }
10281 FunctionBody::Statements(stmts) => {
10282 self.write_keyword("AS");
10283 self.write(" BEGIN ");
10284 for (i, stmt) in stmts.iter().enumerate() {
10285 if i > 0 {
10286 self.write(" ");
10287 }
10288 self.generate_expression(stmt)?;
10289 }
10290 self.write(" END");
10291 }
10292 FunctionBody::DollarQuoted { content, tag } => {
10293 self.write_keyword("AS");
10294 self.write(" ");
10295 let supports_dollar_quoting = matches!(
10297 self.config.dialect,
10298 Some(crate::dialects::DialectType::PostgreSQL)
10299 | Some(crate::dialects::DialectType::Databricks)
10300 | Some(crate::dialects::DialectType::Redshift)
10301 | Some(crate::dialects::DialectType::DuckDB)
10302 );
10303 if supports_dollar_quoting {
10304 self.write("$");
10306 if let Some(t) = tag {
10307 self.write(t);
10308 }
10309 self.write("$");
10310 self.write(content);
10311 self.write("$");
10312 if let Some(t) = tag {
10313 self.write(t);
10314 }
10315 self.write("$");
10316 } else {
10317 let escaped = self.escape_block_for_single_quote(content);
10319 self.write("'");
10320 self.write(&escaped);
10321 self.write("'");
10322 }
10323 }
10324 }
10325 }
10326
10327 Ok(())
10328 }
10329
10330 fn generate_drop_procedure(&mut self, dp: &DropProcedure) -> Result<()> {
10331 self.write_keyword("DROP PROCEDURE");
10332
10333 if dp.if_exists {
10334 self.write_space();
10335 self.write_keyword("IF EXISTS");
10336 }
10337
10338 self.write_space();
10339 self.generate_table(&dp.name)?;
10340
10341 if let Some(params) = &dp.parameters {
10342 self.write(" (");
10343 for (i, dt) in params.iter().enumerate() {
10344 if i > 0 {
10345 self.write(", ");
10346 }
10347 self.generate_data_type(dt)?;
10348 }
10349 self.write(")");
10350 }
10351
10352 if dp.cascade {
10353 self.write_space();
10354 self.write_keyword("CASCADE");
10355 }
10356
10357 Ok(())
10358 }
10359
10360 fn generate_create_sequence(&mut self, cs: &CreateSequence) -> Result<()> {
10361 self.write_keyword("CREATE");
10362
10363 if cs.temporary {
10364 self.write_space();
10365 self.write_keyword("TEMPORARY");
10366 }
10367
10368 self.write_space();
10369 self.write_keyword("SEQUENCE");
10370
10371 if cs.if_not_exists {
10372 self.write_space();
10373 self.write_keyword("IF NOT EXISTS");
10374 }
10375
10376 self.write_space();
10377 self.generate_table(&cs.name)?;
10378
10379 if let Some(comment) = &cs.comment {
10381 self.write_space();
10382 self.write_keyword("COMMENT");
10383 self.write("=");
10384 self.generate_string_literal(comment)?;
10385 }
10386
10387 if !cs.property_order.is_empty() {
10389 for prop in &cs.property_order {
10390 match prop {
10391 SeqPropKind::Start => {
10392 if let Some(start) = cs.start {
10393 self.write_space();
10394 self.write_keyword("START WITH");
10395 self.write(&format!(" {}", start));
10396 }
10397 }
10398 SeqPropKind::Increment => {
10399 if let Some(inc) = cs.increment {
10400 self.write_space();
10401 self.write_keyword("INCREMENT BY");
10402 self.write(&format!(" {}", inc));
10403 }
10404 }
10405 SeqPropKind::Minvalue => {
10406 if let Some(min) = &cs.minvalue {
10407 self.write_space();
10408 match min {
10409 SequenceBound::Value(v) => {
10410 self.write_keyword("MINVALUE");
10411 self.write(&format!(" {}", v));
10412 }
10413 SequenceBound::None => {
10414 self.write_keyword("NO MINVALUE");
10415 }
10416 }
10417 }
10418 }
10419 SeqPropKind::Maxvalue => {
10420 if let Some(max) = &cs.maxvalue {
10421 self.write_space();
10422 match max {
10423 SequenceBound::Value(v) => {
10424 self.write_keyword("MAXVALUE");
10425 self.write(&format!(" {}", v));
10426 }
10427 SequenceBound::None => {
10428 self.write_keyword("NO MAXVALUE");
10429 }
10430 }
10431 }
10432 }
10433 SeqPropKind::Cache => {
10434 if let Some(cache) = cs.cache {
10435 self.write_space();
10436 self.write_keyword("CACHE");
10437 self.write(&format!(" {}", cache));
10438 }
10439 }
10440 SeqPropKind::Cycle => {
10441 self.write_space();
10442 self.write_keyword("CYCLE");
10443 }
10444 SeqPropKind::NoCycle => {
10445 self.write_space();
10446 self.write_keyword("NO CYCLE");
10447 }
10448 SeqPropKind::OwnedBy => {
10449 if let Some(owned) = &cs.owned_by {
10450 self.write_space();
10451 self.write_keyword("OWNED BY");
10452 self.write_space();
10453 self.generate_table(owned)?;
10454 }
10455 }
10456 SeqPropKind::Order => {
10457 self.write_space();
10458 self.write_keyword("ORDER");
10459 }
10460 SeqPropKind::NoOrder => {
10461 self.write_space();
10462 self.write_keyword("NOORDER");
10463 }
10464 SeqPropKind::Comment => {
10465 }
10467 }
10468 }
10469 } else {
10470 if let Some(inc) = cs.increment {
10472 self.write_space();
10473 self.write_keyword("INCREMENT BY");
10474 self.write(&format!(" {}", inc));
10475 }
10476
10477 if let Some(min) = &cs.minvalue {
10478 self.write_space();
10479 match min {
10480 SequenceBound::Value(v) => {
10481 self.write_keyword("MINVALUE");
10482 self.write(&format!(" {}", v));
10483 }
10484 SequenceBound::None => {
10485 self.write_keyword("NO MINVALUE");
10486 }
10487 }
10488 }
10489
10490 if let Some(max) = &cs.maxvalue {
10491 self.write_space();
10492 match max {
10493 SequenceBound::Value(v) => {
10494 self.write_keyword("MAXVALUE");
10495 self.write(&format!(" {}", v));
10496 }
10497 SequenceBound::None => {
10498 self.write_keyword("NO MAXVALUE");
10499 }
10500 }
10501 }
10502
10503 if let Some(start) = cs.start {
10504 self.write_space();
10505 self.write_keyword("START WITH");
10506 self.write(&format!(" {}", start));
10507 }
10508
10509 if let Some(cache) = cs.cache {
10510 self.write_space();
10511 self.write_keyword("CACHE");
10512 self.write(&format!(" {}", cache));
10513 }
10514
10515 if cs.cycle {
10516 self.write_space();
10517 self.write_keyword("CYCLE");
10518 }
10519
10520 if let Some(owned) = &cs.owned_by {
10521 self.write_space();
10522 self.write_keyword("OWNED BY");
10523 self.write_space();
10524 self.generate_table(owned)?;
10525 }
10526 }
10527
10528 Ok(())
10529 }
10530
10531 fn generate_drop_sequence(&mut self, ds: &DropSequence) -> Result<()> {
10532 self.write_keyword("DROP SEQUENCE");
10533
10534 if ds.if_exists {
10535 self.write_space();
10536 self.write_keyword("IF EXISTS");
10537 }
10538
10539 self.write_space();
10540 self.generate_table(&ds.name)?;
10541
10542 if ds.cascade {
10543 self.write_space();
10544 self.write_keyword("CASCADE");
10545 }
10546
10547 Ok(())
10548 }
10549
10550 fn generate_alter_sequence(&mut self, als: &AlterSequence) -> Result<()> {
10551 self.write_keyword("ALTER SEQUENCE");
10552
10553 if als.if_exists {
10554 self.write_space();
10555 self.write_keyword("IF EXISTS");
10556 }
10557
10558 self.write_space();
10559 self.generate_table(&als.name)?;
10560
10561 if let Some(inc) = als.increment {
10562 self.write_space();
10563 self.write_keyword("INCREMENT BY");
10564 self.write(&format!(" {}", inc));
10565 }
10566
10567 if let Some(min) = &als.minvalue {
10568 self.write_space();
10569 match min {
10570 SequenceBound::Value(v) => {
10571 self.write_keyword("MINVALUE");
10572 self.write(&format!(" {}", v));
10573 }
10574 SequenceBound::None => {
10575 self.write_keyword("NO MINVALUE");
10576 }
10577 }
10578 }
10579
10580 if let Some(max) = &als.maxvalue {
10581 self.write_space();
10582 match max {
10583 SequenceBound::Value(v) => {
10584 self.write_keyword("MAXVALUE");
10585 self.write(&format!(" {}", v));
10586 }
10587 SequenceBound::None => {
10588 self.write_keyword("NO MAXVALUE");
10589 }
10590 }
10591 }
10592
10593 if let Some(start) = als.start {
10594 self.write_space();
10595 self.write_keyword("START WITH");
10596 self.write(&format!(" {}", start));
10597 }
10598
10599 if let Some(restart) = &als.restart {
10600 self.write_space();
10601 self.write_keyword("RESTART");
10602 if let Some(val) = restart {
10603 self.write_keyword(" WITH");
10604 self.write(&format!(" {}", val));
10605 }
10606 }
10607
10608 if let Some(cache) = als.cache {
10609 self.write_space();
10610 self.write_keyword("CACHE");
10611 self.write(&format!(" {}", cache));
10612 }
10613
10614 if let Some(cycle) = als.cycle {
10615 self.write_space();
10616 if cycle {
10617 self.write_keyword("CYCLE");
10618 } else {
10619 self.write_keyword("NO CYCLE");
10620 }
10621 }
10622
10623 if let Some(owned) = &als.owned_by {
10624 self.write_space();
10625 self.write_keyword("OWNED BY");
10626 self.write_space();
10627 if let Some(table) = owned {
10628 self.generate_table(table)?;
10629 } else {
10630 self.write_keyword("NONE");
10631 }
10632 }
10633
10634 Ok(())
10635 }
10636
10637 fn generate_create_trigger(&mut self, ct: &CreateTrigger) -> Result<()> {
10638 self.write_keyword("CREATE");
10639
10640 if ct.or_replace {
10641 self.write_space();
10642 self.write_keyword("OR REPLACE");
10643 }
10644
10645 if ct.constraint {
10646 self.write_space();
10647 self.write_keyword("CONSTRAINT");
10648 }
10649
10650 self.write_space();
10651 self.write_keyword("TRIGGER");
10652 self.write_space();
10653 self.generate_identifier(&ct.name)?;
10654
10655 self.write_space();
10656 match ct.timing {
10657 TriggerTiming::Before => self.write_keyword("BEFORE"),
10658 TriggerTiming::After => self.write_keyword("AFTER"),
10659 TriggerTiming::InsteadOf => self.write_keyword("INSTEAD OF"),
10660 }
10661
10662 for (i, event) in ct.events.iter().enumerate() {
10664 if i > 0 {
10665 self.write_keyword(" OR");
10666 }
10667 self.write_space();
10668 match event {
10669 TriggerEvent::Insert => self.write_keyword("INSERT"),
10670 TriggerEvent::Update(cols) => {
10671 self.write_keyword("UPDATE");
10672 if let Some(cols) = cols {
10673 self.write_space();
10674 self.write_keyword("OF");
10675 for (j, col) in cols.iter().enumerate() {
10676 if j > 0 {
10677 self.write(",");
10678 }
10679 self.write_space();
10680 self.generate_identifier(col)?;
10681 }
10682 }
10683 }
10684 TriggerEvent::Delete => self.write_keyword("DELETE"),
10685 TriggerEvent::Truncate => self.write_keyword("TRUNCATE"),
10686 }
10687 }
10688
10689 self.write_space();
10690 self.write_keyword("ON");
10691 self.write_space();
10692 self.generate_table(&ct.table)?;
10693
10694 if let Some(ref_clause) = &ct.referencing {
10696 self.write_space();
10697 self.write_keyword("REFERENCING");
10698 if let Some(old_table) = &ref_clause.old_table {
10699 self.write_space();
10700 self.write_keyword("OLD TABLE AS");
10701 self.write_space();
10702 self.generate_identifier(old_table)?;
10703 }
10704 if let Some(new_table) = &ref_clause.new_table {
10705 self.write_space();
10706 self.write_keyword("NEW TABLE AS");
10707 self.write_space();
10708 self.generate_identifier(new_table)?;
10709 }
10710 if let Some(old_row) = &ref_clause.old_row {
10711 self.write_space();
10712 self.write_keyword("OLD ROW AS");
10713 self.write_space();
10714 self.generate_identifier(old_row)?;
10715 }
10716 if let Some(new_row) = &ref_clause.new_row {
10717 self.write_space();
10718 self.write_keyword("NEW ROW AS");
10719 self.write_space();
10720 self.generate_identifier(new_row)?;
10721 }
10722 }
10723
10724 if let Some(deferrable) = ct.deferrable {
10726 self.write_space();
10727 if deferrable {
10728 self.write_keyword("DEFERRABLE");
10729 } else {
10730 self.write_keyword("NOT DEFERRABLE");
10731 }
10732 }
10733
10734 if let Some(initially) = ct.initially_deferred {
10735 self.write_space();
10736 self.write_keyword("INITIALLY");
10737 self.write_space();
10738 if initially {
10739 self.write_keyword("DEFERRED");
10740 } else {
10741 self.write_keyword("IMMEDIATE");
10742 }
10743 }
10744
10745 self.write_space();
10746 self.write_keyword("FOR EACH");
10747 self.write_space();
10748 match ct.for_each {
10749 TriggerForEach::Row => self.write_keyword("ROW"),
10750 TriggerForEach::Statement => self.write_keyword("STATEMENT"),
10751 }
10752
10753 if let Some(when) = &ct.when {
10755 self.write_space();
10756 self.write_keyword("WHEN");
10757 self.write(" (");
10758 self.generate_expression(when)?;
10759 self.write(")");
10760 }
10761
10762 self.write_space();
10764 match &ct.body {
10765 TriggerBody::Execute { function, args } => {
10766 self.write_keyword("EXECUTE FUNCTION");
10767 self.write_space();
10768 self.generate_table(function)?;
10769 self.write("(");
10770 for (i, arg) in args.iter().enumerate() {
10771 if i > 0 {
10772 self.write(", ");
10773 }
10774 self.generate_expression(arg)?;
10775 }
10776 self.write(")");
10777 }
10778 TriggerBody::Block(block) => {
10779 self.write_keyword("BEGIN");
10780 self.write_space();
10781 self.write(block);
10782 self.write_space();
10783 self.write_keyword("END");
10784 }
10785 }
10786
10787 Ok(())
10788 }
10789
10790 fn generate_drop_trigger(&mut self, dt: &DropTrigger) -> Result<()> {
10791 self.write_keyword("DROP TRIGGER");
10792
10793 if dt.if_exists {
10794 self.write_space();
10795 self.write_keyword("IF EXISTS");
10796 }
10797
10798 self.write_space();
10799 self.generate_identifier(&dt.name)?;
10800
10801 if let Some(table) = &dt.table {
10802 self.write_space();
10803 self.write_keyword("ON");
10804 self.write_space();
10805 self.generate_table(table)?;
10806 }
10807
10808 if dt.cascade {
10809 self.write_space();
10810 self.write_keyword("CASCADE");
10811 }
10812
10813 Ok(())
10814 }
10815
10816 fn generate_create_type(&mut self, ct: &CreateType) -> Result<()> {
10817 self.write_keyword("CREATE TYPE");
10818
10819 if ct.if_not_exists {
10820 self.write_space();
10821 self.write_keyword("IF NOT EXISTS");
10822 }
10823
10824 self.write_space();
10825 self.generate_table(&ct.name)?;
10826
10827 self.write_space();
10828 self.write_keyword("AS");
10829 self.write_space();
10830
10831 match &ct.definition {
10832 TypeDefinition::Enum(values) => {
10833 self.write_keyword("ENUM");
10834 self.write(" (");
10835 for (i, val) in values.iter().enumerate() {
10836 if i > 0 {
10837 self.write(", ");
10838 }
10839 self.write(&format!("'{}'", val));
10840 }
10841 self.write(")");
10842 }
10843 TypeDefinition::Composite(attrs) => {
10844 self.write("(");
10845 for (i, attr) in attrs.iter().enumerate() {
10846 if i > 0 {
10847 self.write(", ");
10848 }
10849 self.generate_identifier(&attr.name)?;
10850 self.write_space();
10851 self.generate_data_type(&attr.data_type)?;
10852 if let Some(collate) = &attr.collate {
10853 self.write_space();
10854 self.write_keyword("COLLATE");
10855 self.write_space();
10856 self.generate_identifier(collate)?;
10857 }
10858 }
10859 self.write(")");
10860 }
10861 TypeDefinition::Range { subtype, subtype_diff, canonical } => {
10862 self.write_keyword("RANGE");
10863 self.write(" (");
10864 self.write_keyword("SUBTYPE");
10865 self.write(" = ");
10866 self.generate_data_type(subtype)?;
10867 if let Some(diff) = subtype_diff {
10868 self.write(", ");
10869 self.write_keyword("SUBTYPE_DIFF");
10870 self.write(" = ");
10871 self.write(diff);
10872 }
10873 if let Some(canon) = canonical {
10874 self.write(", ");
10875 self.write_keyword("CANONICAL");
10876 self.write(" = ");
10877 self.write(canon);
10878 }
10879 self.write(")");
10880 }
10881 TypeDefinition::Base { input, output, internallength } => {
10882 self.write("(");
10883 self.write_keyword("INPUT");
10884 self.write(" = ");
10885 self.write(input);
10886 self.write(", ");
10887 self.write_keyword("OUTPUT");
10888 self.write(" = ");
10889 self.write(output);
10890 if let Some(len) = internallength {
10891 self.write(", ");
10892 self.write_keyword("INTERNALLENGTH");
10893 self.write(" = ");
10894 self.write(&len.to_string());
10895 }
10896 self.write(")");
10897 }
10898 TypeDefinition::Domain { base_type, default, constraints } => {
10899 self.generate_data_type(base_type)?;
10900 if let Some(def) = default {
10901 self.write_space();
10902 self.write_keyword("DEFAULT");
10903 self.write_space();
10904 self.generate_expression(def)?;
10905 }
10906 for constr in constraints {
10907 self.write_space();
10908 if let Some(name) = &constr.name {
10909 self.write_keyword("CONSTRAINT");
10910 self.write_space();
10911 self.generate_identifier(name)?;
10912 self.write_space();
10913 }
10914 self.write_keyword("CHECK");
10915 self.write(" (");
10916 self.generate_expression(&constr.check)?;
10917 self.write(")");
10918 }
10919 }
10920 }
10921
10922 Ok(())
10923 }
10924
10925 fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
10926 self.write_keyword("DROP TYPE");
10927
10928 if dt.if_exists {
10929 self.write_space();
10930 self.write_keyword("IF EXISTS");
10931 }
10932
10933 self.write_space();
10934 self.generate_table(&dt.name)?;
10935
10936 if dt.cascade {
10937 self.write_space();
10938 self.write_keyword("CASCADE");
10939 }
10940
10941 Ok(())
10942 }
10943
10944 fn generate_describe(&mut self, d: &Describe) -> Result<()> {
10945 let saved_athena_hive_context = self.athena_hive_context;
10947 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Athena)) {
10948 self.athena_hive_context = true;
10949 }
10950
10951 for comment in &d.leading_comments {
10953 self.write_formatted_comment(comment);
10954 self.write(" ");
10955 }
10956
10957 self.write_keyword("DESCRIBE");
10958
10959 if d.extended {
10960 self.write_space();
10961 self.write_keyword("EXTENDED");
10962 } else if d.formatted {
10963 self.write_space();
10964 self.write_keyword("FORMATTED");
10965 }
10966
10967 if let Some(ref style) = d.style {
10969 self.write_space();
10970 self.write_keyword(style);
10971 }
10972
10973 let should_output_kind = match self.config.dialect {
10975 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => false,
10977 Some(DialectType::Snowflake) => true,
10979 _ => d.kind.is_some(),
10980 };
10981 if should_output_kind {
10982 if let Some(ref kind) = d.kind {
10983 self.write_space();
10984 self.write_keyword(kind);
10985 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
10986 self.write_space();
10987 self.write_keyword("TABLE");
10988 }
10989 }
10990
10991 self.write_space();
10992 self.generate_expression(&d.target)?;
10993
10994 if let Some(ref partition) = d.partition {
10996 self.write_space();
10997 self.generate_expression(partition)?;
10998 }
10999
11000 for (name, value) in &d.properties {
11002 self.write_space();
11003 self.write(name);
11004 self.write("=");
11005 self.write(value);
11006 }
11007
11008 self.athena_hive_context = saved_athena_hive_context;
11010
11011 Ok(())
11012 }
11013
11014 fn generate_show(&mut self, s: &Show) -> Result<()> {
11017 self.write_keyword("SHOW");
11018 self.write_space();
11019
11020 let show_terse = s.terse && !matches!(
11023 s.this.as_str(),
11024 "PRIMARY KEYS" | "UNIQUE KEYS" | "IMPORTED KEYS"
11025 );
11026 if show_terse {
11027 self.write_keyword("TERSE");
11028 self.write_space();
11029 }
11030
11031 self.write_keyword(&s.this);
11033
11034 if let Some(ref target_expr) = s.target {
11036 self.write_space();
11037 self.generate_expression(target_expr)?;
11038 }
11039
11040 if s.history {
11042 self.write_space();
11043 self.write_keyword("HISTORY");
11044 }
11045
11046 if let Some(ref for_target) = s.for_target {
11048 self.write_space();
11049 self.write_keyword("FOR");
11050 self.write_space();
11051 self.generate_expression(for_target)?;
11052 }
11053
11054 use crate::dialects::DialectType;
11058 let is_snowflake = matches!(self.config.dialect, Some(DialectType::Snowflake));
11059
11060 if !is_snowflake && s.from.is_some() {
11061 if let Some(ref scope_kind) = s.scope_kind {
11065 self.write_space();
11066 self.write_keyword("IN");
11067 self.write_space();
11068 self.write_keyword(scope_kind);
11069 if let Some(ref scope) = s.scope {
11070 self.write_space();
11071 self.generate_expression(scope)?;
11072 }
11073 } else if let Some(ref scope) = s.scope {
11074 self.write_space();
11075 self.write_keyword("IN");
11076 self.write_space();
11077 self.generate_expression(scope)?;
11078 }
11079
11080 if let Some(ref from) = s.from {
11082 self.write_space();
11083 self.write_keyword("FROM");
11084 self.write_space();
11085 self.generate_expression(from)?;
11086 }
11087
11088 if let Some(ref db) = s.db {
11090 self.write_space();
11091 self.write_keyword("FROM");
11092 self.write_space();
11093 self.generate_expression(db)?;
11094 }
11095
11096 if let Some(ref like) = s.like {
11098 self.write_space();
11099 self.write_keyword("LIKE");
11100 self.write_space();
11101 self.generate_expression(like)?;
11102 }
11103 } else {
11104 if let Some(ref like) = s.like {
11108 self.write_space();
11109 self.write_keyword("LIKE");
11110 self.write_space();
11111 self.generate_expression(like)?;
11112 }
11113
11114 if let Some(ref scope_kind) = s.scope_kind {
11116 self.write_space();
11117 self.write_keyword("IN");
11118 self.write_space();
11119 self.write_keyword(scope_kind);
11120 if let Some(ref scope) = s.scope {
11121 self.write_space();
11122 self.generate_expression(scope)?;
11123 }
11124 } else if let Some(ref scope) = s.scope {
11125 self.write_space();
11126 self.write_keyword("IN");
11127 self.write_space();
11128 self.generate_expression(scope)?;
11129 }
11130 }
11131
11132 if let Some(ref starts_with) = s.starts_with {
11134 self.write_space();
11135 self.write_keyword("STARTS WITH");
11136 self.write_space();
11137 self.generate_expression(starts_with)?;
11138 }
11139
11140 if let Some(ref limit) = s.limit {
11142 self.write_space();
11143 self.generate_limit(limit)?;
11144 }
11145
11146 if is_snowflake {
11148 if let Some(ref from) = s.from {
11149 self.write_space();
11150 self.write_keyword("FROM");
11151 self.write_space();
11152 self.generate_expression(from)?;
11153 }
11154 }
11155
11156 if let Some(ref where_clause) = s.where_clause {
11158 self.write_space();
11159 self.write_keyword("WHERE");
11160 self.write_space();
11161 self.generate_expression(where_clause)?;
11162 }
11163
11164 if let Some(is_mutex) = s.mutex {
11166 self.write_space();
11167 if is_mutex {
11168 self.write_keyword("MUTEX");
11169 } else {
11170 self.write_keyword("STATUS");
11171 }
11172 }
11173
11174 if !s.privileges.is_empty() {
11176 self.write_space();
11177 self.write_keyword("WITH PRIVILEGES");
11178 self.write_space();
11179 for (i, priv_name) in s.privileges.iter().enumerate() {
11180 if i > 0 {
11181 self.write(", ");
11182 }
11183 self.write_keyword(priv_name);
11184 }
11185 }
11186
11187 Ok(())
11188 }
11189
11190 fn generate_literal(&mut self, lit: &Literal) -> Result<()> {
11193 use crate::dialects::DialectType;
11194 match lit {
11195 Literal::String(s) => {
11196 self.generate_string_literal(s)?;
11197 }
11198 Literal::Number(n) => {
11199 if matches!(self.config.dialect, Some(DialectType::MySQL))
11200 && n.len() > 2
11201 && (n.starts_with("0x") || n.starts_with("0X"))
11202 && !n[2..].chars().all(|c| c.is_ascii_hexdigit())
11203 {
11204 return self.generate_identifier(&Identifier {
11205 name: n.clone(),
11206 quoted: true,
11207 trailing_comments: Vec::new(),
11208 });
11209 }
11210 if n.starts_with('.') {
11213 self.write("0");
11214 self.write(n);
11215 } else if n.starts_with("-.") {
11216 self.write("-0");
11218 self.write(&n[1..]);
11219 } else {
11220 self.write(n);
11221 }
11222 }
11223 Literal::HexString(h) => {
11224 match self.config.dialect {
11226 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Teradata) => self.write("X'"),
11227 _ => self.write("x'"),
11228 }
11229 self.write(h);
11230 self.write("'");
11231 }
11232 Literal::HexNumber(h) => {
11233 match self.config.dialect {
11237 Some(DialectType::BigQuery) => {
11238 self.write("0x");
11239 self.write(h);
11240 }
11241 _ => {
11242 if let Ok(val) = u64::from_str_radix(h, 16) {
11244 self.write(&val.to_string());
11245 } else {
11246 self.write("0x");
11248 self.write(h);
11249 }
11250 }
11251 }
11252 }
11253 Literal::BitString(b) => {
11254 self.write("B'");
11256 self.write(b);
11257 self.write("'");
11258 }
11259 Literal::ByteString(b) => {
11260 self.write("b'");
11262 self.write_escaped_byte_string(b);
11264 self.write("'");
11265 }
11266 Literal::NationalString(s) => {
11267 let keep_n_prefix = matches!(self.config.dialect,
11270 Some(DialectType::TSQL) | Some(DialectType::Oracle) | Some(DialectType::MySQL) | None
11271 );
11272 if keep_n_prefix {
11273 self.write("N'");
11274 } else {
11275 self.write("'");
11276 }
11277 self.write(s);
11278 self.write("'");
11279 }
11280 Literal::Date(d) => {
11281 self.generate_date_literal(d)?;
11282 }
11283 Literal::Time(t) => {
11284 self.generate_time_literal(t)?;
11285 }
11286 Literal::Timestamp(ts) => {
11287 self.generate_timestamp_literal(ts)?;
11288 }
11289 Literal::Datetime(dt) => {
11290 self.generate_datetime_literal(dt)?;
11291 }
11292 Literal::TripleQuotedString(s, _quote_char) => {
11293 if matches!(self.config.dialect, Some(crate::dialects::DialectType::BigQuery)
11295 | Some(crate::dialects::DialectType::DuckDB)
11296 | Some(crate::dialects::DialectType::Snowflake)
11297 | Some(crate::dialects::DialectType::Spark)
11298 | Some(crate::dialects::DialectType::Hive)
11299 | Some(crate::dialects::DialectType::Presto)
11300 | Some(crate::dialects::DialectType::Trino)
11301 | Some(crate::dialects::DialectType::PostgreSQL)
11302 | Some(crate::dialects::DialectType::MySQL)
11303 | Some(crate::dialects::DialectType::Redshift)
11304 | Some(crate::dialects::DialectType::TSQL)
11305 | Some(crate::dialects::DialectType::Oracle)
11306 | Some(crate::dialects::DialectType::ClickHouse)
11307 | Some(crate::dialects::DialectType::Databricks)
11308 | Some(crate::dialects::DialectType::SQLite)
11309 ) {
11310 self.generate_string_literal(s)?;
11311 } else {
11312 let quotes = format!("{0}{0}{0}", _quote_char);
11314 self.write("es);
11315 self.write(s);
11316 self.write("es);
11317 }
11318 }
11319 Literal::EscapeString(s) => {
11320 use crate::dialects::DialectType;
11324 let content = if let Some(c) = s.strip_prefix("e:") {
11325 c
11326 } else if let Some(c) = s.strip_prefix("E:") {
11327 c
11328 } else {
11329 s.as_str()
11330 };
11331
11332 if matches!(self.config.dialect, Some(DialectType::MySQL) | Some(DialectType::TiDB)) {
11334 self.write(content);
11335 } else {
11336 let prefix = if matches!(
11338 self.config.dialect,
11339 Some(DialectType::SingleStore)
11340 | Some(DialectType::DuckDB)
11341 | Some(DialectType::PostgreSQL)
11342 | Some(DialectType::CockroachDB)
11343 | Some(DialectType::Materialize)
11344 | Some(DialectType::RisingWave)
11345 ) {
11346 "e'"
11347 } else {
11348 "E'"
11349 };
11350
11351 let normalized = content.replace("\\'", "''");
11353 self.write(prefix);
11354 self.write(&normalized);
11355 self.write("'");
11356 }
11357 }
11358 Literal::DollarString(s) => {
11359 use crate::dialects::DialectType;
11362 let (_tag, content) = crate::tokens::parse_dollar_string_token(s);
11364 let escape_backslash = matches!(
11366 self.config.dialect,
11367 Some(DialectType::Snowflake)
11368 );
11369 let use_backslash_quote = matches!(
11373 self.config.dialect,
11374 Some(DialectType::Snowflake)
11375 );
11376
11377 let mut escaped = String::with_capacity(content.len() + 4);
11378 for ch in content.chars() {
11379 if escape_backslash && ch == '\\' {
11380 escaped.push('\\');
11382 escaped.push('\\');
11383 } else if ch == '\'' {
11384 if use_backslash_quote {
11385 escaped.push('\\');
11386 escaped.push('\'');
11387 } else {
11388 escaped.push('\'');
11389 escaped.push('\'');
11390 }
11391 } else {
11392 escaped.push(ch);
11393 }
11394 }
11395 self.write("'");
11396 self.write(&escaped);
11397 self.write("'");
11398 }
11399 Literal::RawString(s) => {
11400 use crate::dialects::DialectType;
11406
11407 let escape_backslash = matches!(
11409 self.config.dialect,
11410 Some(DialectType::BigQuery)
11411 | Some(DialectType::MySQL)
11412 | Some(DialectType::SingleStore)
11413 | Some(DialectType::TiDB)
11414 | Some(DialectType::Hive)
11415 | Some(DialectType::Spark)
11416
11417 | Some(DialectType::Databricks)
11418 | Some(DialectType::Drill)
11419 | Some(DialectType::Snowflake)
11420 | Some(DialectType::Redshift)
11421 | Some(DialectType::ClickHouse)
11422 );
11423
11424 let backslash_escapes_quote = matches!(
11427 self.config.dialect,
11428 Some(DialectType::BigQuery)
11429 | Some(DialectType::Hive)
11430 | Some(DialectType::Spark)
11431
11432 | Some(DialectType::Databricks)
11433 | Some(DialectType::Drill)
11434 | Some(DialectType::Snowflake)
11435 | Some(DialectType::Redshift)
11436 );
11437
11438 let supports_escape_sequences = escape_backslash;
11441
11442 let mut escaped = String::with_capacity(s.len() + 4);
11443 for ch in s.chars() {
11444 if escape_backslash && ch == '\\' {
11445 escaped.push('\\');
11447 escaped.push('\\');
11448 } else if ch == '\'' {
11449 if backslash_escapes_quote {
11450 escaped.push('\\');
11452 escaped.push('\'');
11453 } else {
11454 escaped.push('\'');
11456 escaped.push('\'');
11457 }
11458 } else if supports_escape_sequences {
11459 match ch {
11462 '\n' => { escaped.push('\\'); escaped.push('n'); }
11463 '\r' => { escaped.push('\\'); escaped.push('r'); }
11464 '\t' => { escaped.push('\\'); escaped.push('t'); }
11465 '\x07' => { escaped.push('\\'); escaped.push('a'); }
11466 '\x08' => { escaped.push('\\'); escaped.push('b'); }
11467 '\x0C' => { escaped.push('\\'); escaped.push('f'); }
11468 '\x0B' => { escaped.push('\\'); escaped.push('v'); }
11469 _ => escaped.push(ch),
11470 }
11471 } else {
11472 escaped.push(ch);
11473 }
11474 }
11475 self.write("'");
11476 self.write(&escaped);
11477 self.write("'");
11478 }
11479 }
11480 Ok(())
11481 }
11482
11483 fn generate_date_literal(&mut self, d: &str) -> Result<()> {
11485 use crate::dialects::DialectType;
11486
11487 match self.config.dialect {
11488 Some(DialectType::TSQL) => {
11490 self.write("CAST('");
11491 self.write(d);
11492 self.write("' AS DATE)");
11493 }
11494 Some(DialectType::BigQuery) => {
11497 self.write("CAST('");
11498 self.write(d);
11499 self.write("' AS DATE)");
11500 }
11501 Some(DialectType::Exasol) => {
11504 self.write("CAST('");
11505 self.write(d);
11506 self.write("' AS DATE)");
11507 }
11508 Some(DialectType::Snowflake) => {
11511 self.write("CAST('");
11512 self.write(d);
11513 self.write("' AS DATE)");
11514 }
11515 Some(DialectType::PostgreSQL) | Some(DialectType::MySQL)
11517 | Some(DialectType::SingleStore) | Some(DialectType::TiDB)
11518 | Some(DialectType::Redshift) => {
11519 self.write("CAST('");
11520 self.write(d);
11521 self.write("' AS DATE)");
11522 }
11523 Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)
11525 | Some(DialectType::Athena) | Some(DialectType::Spark)
11526 | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
11527 self.write("CAST('");
11528 self.write(d);
11529 self.write("' AS DATE)");
11530 }
11531 Some(DialectType::Oracle) => {
11533 self.write("TO_DATE('");
11534 self.write(d);
11535 self.write("', 'YYYY-MM-DD')");
11536 }
11537 _ => {
11539 self.write_keyword("DATE");
11540 self.write(" '");
11541 self.write(d);
11542 self.write("'");
11543 }
11544 }
11545 Ok(())
11546 }
11547
11548 fn generate_time_literal(&mut self, t: &str) -> Result<()> {
11550 use crate::dialects::DialectType;
11551
11552 match self.config.dialect {
11553 Some(DialectType::TSQL) => {
11555 self.write("CAST('");
11556 self.write(t);
11557 self.write("' AS TIME)");
11558 }
11559 _ => {
11561 self.write_keyword("TIME");
11562 self.write(" '");
11563 self.write(t);
11564 self.write("'");
11565 }
11566 }
11567 Ok(())
11568 }
11569
11570 fn generate_dremio_date_expression(&mut self, expr: &Expression) -> Result<()> {
11572 use crate::expressions::Literal;
11573
11574 match expr {
11575 Expression::Literal(Literal::Date(d)) => {
11576 self.write("CAST('");
11578 self.write(d);
11579 self.write("' AS DATE)");
11580 }
11581 _ => {
11582 self.generate_expression(expr)?;
11584 }
11585 }
11586 Ok(())
11587 }
11588
11589 fn generate_timestamp_literal(&mut self, ts: &str) -> Result<()> {
11591 use crate::dialects::DialectType;
11592
11593 match self.config.dialect {
11594 Some(DialectType::TSQL) => {
11596 self.write("CAST('");
11597 self.write(ts);
11598 self.write("' AS DATETIME2)");
11599 }
11600 Some(DialectType::BigQuery) => {
11603 self.write("CAST('");
11604 self.write(ts);
11605 self.write("' AS TIMESTAMP)");
11606 }
11607 Some(DialectType::Snowflake) => {
11610 self.write("CAST('");
11611 self.write(ts);
11612 self.write("' AS TIMESTAMP)");
11613 }
11614 Some(DialectType::Dremio) => {
11617 self.write("CAST('");
11618 self.write(ts);
11619 self.write("' AS TIMESTAMP)");
11620 }
11621 Some(DialectType::Exasol) => {
11624 self.write("CAST('");
11625 self.write(ts);
11626 self.write("' AS TIMESTAMP)");
11627 }
11628 Some(DialectType::Oracle) => {
11631 self.write("TO_TIMESTAMP('");
11632 self.write(ts);
11633 self.write("', 'YYYY-MM-DD HH24:MI:SS.FF6')");
11634 }
11635 Some(DialectType::Presto) | Some(DialectType::Trino) => {
11637 if Self::timestamp_has_timezone(ts) {
11638 self.write("CAST('");
11639 self.write(ts);
11640 self.write("' AS TIMESTAMP WITH TIME ZONE)");
11641 } else {
11642 self.write("CAST('");
11643 self.write(ts);
11644 self.write("' AS TIMESTAMP)");
11645 }
11646 }
11647 Some(DialectType::ClickHouse) => {
11649 self.write("CAST('");
11650 self.write(ts);
11651 self.write("' AS Nullable(DateTime))");
11652 }
11653 Some(DialectType::Spark) => {
11655 self.write("CAST('");
11656 self.write(ts);
11657 self.write("' AS TIMESTAMP)");
11658 }
11659 Some(DialectType::Redshift) => {
11662 if ts == "epoch" {
11663 self.write_keyword("TIMESTAMP");
11664 self.write(" '");
11665 self.write(ts);
11666 self.write("'");
11667 } else {
11668 self.write("CAST('");
11669 self.write(ts);
11670 self.write("' AS TIMESTAMP)");
11671 }
11672 }
11673 Some(DialectType::PostgreSQL) | Some(DialectType::Hive) |
11675 Some(DialectType::SQLite) | Some(DialectType::DuckDB) |
11676 Some(DialectType::Athena) | Some(DialectType::Drill) |
11677 Some(DialectType::Teradata) => {
11678 self.write("CAST('");
11679 self.write(ts);
11680 self.write("' AS TIMESTAMP)");
11681 }
11682 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
11684 self.write("CAST('");
11685 self.write(ts);
11686 self.write("' AS DATETIME)");
11687 }
11688 Some(DialectType::Databricks) => {
11690 self.write("CAST('");
11691 self.write(ts);
11692 self.write("' AS TIMESTAMP_NTZ)");
11693 }
11694 _ => {
11696 self.write_keyword("TIMESTAMP");
11697 self.write(" '");
11698 self.write(ts);
11699 self.write("'");
11700 }
11701 }
11702 Ok(())
11703 }
11704
11705 fn timestamp_has_timezone(ts: &str) -> bool {
11708 let ts_lower = ts.to_lowercase();
11712
11713 let continent_prefixes = [
11715 "africa/", "america/", "antarctica/", "arctic/", "asia/",
11716 "atlantic/", "australia/", "europe/", "indian/", "pacific/",
11717 "etc/", "brazil/", "canada/", "chile/", "mexico/", "us/",
11718 ];
11719
11720 for prefix in &continent_prefixes {
11721 if ts_lower.contains(prefix) {
11722 return true;
11723 }
11724 }
11725
11726 let tz_abbrevs = [
11729 " utc", " gmt", " cet", " cest", " eet", " eest", " wet", " west",
11730 " est", " edt", " cst", " cdt", " mst", " mdt", " pst", " pdt",
11731 " ist", " bst", " jst", " kst", " hkt", " sgt", " aest", " aedt",
11732 " acst", " acdt", " awst",
11733 ];
11734
11735 for abbrev in &tz_abbrevs {
11736 if ts_lower.ends_with(abbrev) {
11737 return true;
11738 }
11739 }
11740
11741 let trimmed = ts.trim();
11745 if let Some(last_space) = trimmed.rfind(' ') {
11746 let suffix = &trimmed[last_space + 1..];
11747 if (suffix.starts_with('+') || suffix.starts_with('-')) && suffix.len() > 1 {
11748 let rest = &suffix[1..];
11750 if rest.chars().all(|c| c.is_ascii_digit() || c == ':') {
11751 return true;
11752 }
11753 }
11754 }
11755
11756 false
11757 }
11758
11759 fn generate_datetime_literal(&mut self, dt: &str) -> Result<()> {
11761 use crate::dialects::DialectType;
11762
11763 match self.config.dialect {
11764 Some(DialectType::BigQuery) => {
11767 self.write("CAST('");
11768 self.write(dt);
11769 self.write("' AS DATETIME)");
11770 }
11771 Some(DialectType::DuckDB) => {
11773 self.write("CAST('");
11774 self.write(dt);
11775 self.write("' AS TIMESTAMP)");
11776 }
11777 _ => {
11780 self.write_keyword("DATETIME");
11781 self.write(" '");
11782 self.write(dt);
11783 self.write("'");
11784 }
11785 }
11786 Ok(())
11787 }
11788
11789 fn generate_string_literal(&mut self, s: &str) -> Result<()> {
11791 use crate::dialects::DialectType;
11792
11793 match self.config.dialect {
11794 Some(DialectType::Hive)
11798 | Some(DialectType::Spark)
11799
11800 | Some(DialectType::Databricks)
11801 | Some(DialectType::Drill) => {
11802 self.write("'");
11804 for c in s.chars() {
11805 match c {
11806 '\'' => self.write("\\'"),
11807 '\\' => self.write("\\\\"),
11808 '\n' => self.write("\\n"),
11809 '\r' => self.write("\\r"),
11810 '\t' => self.write("\\t"),
11811 '\0' => self.write("\\0"),
11812 _ => self.output.push(c),
11813 }
11814 }
11815 self.write("'");
11816 }
11817 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => {
11818 self.write("'");
11819 for c in s.chars() {
11820 match c {
11821 '\'' => self.write("''"),
11823 '\\' => self.write("\\\\"),
11824 '\n' => self.write("\\n"),
11825 '\r' => self.write("\\r"),
11826 '\t' => self.write("\\t"),
11827 '\0' => self.output.push('\0'),
11829 _ => self.output.push(c),
11830 }
11831 }
11832 self.write("'");
11833 }
11834 Some(DialectType::BigQuery) => {
11836 self.write("'");
11837 for c in s.chars() {
11838 match c {
11839 '\'' => self.write("\\'"),
11840 '\\' => self.write("\\\\"),
11841 '\n' => self.write("\\n"),
11842 '\r' => self.write("\\r"),
11843 '\t' => self.write("\\t"),
11844 '\0' => self.write("\\0"),
11845 '\x07' => self.write("\\a"),
11846 '\x08' => self.write("\\b"),
11847 '\x0C' => self.write("\\f"),
11848 '\x0B' => self.write("\\v"),
11849 _ => self.output.push(c),
11850 }
11851 }
11852 self.write("'");
11853 }
11854 Some(DialectType::Athena) => {
11858 if self.athena_hive_context {
11859 self.write("'");
11861 for c in s.chars() {
11862 match c {
11863 '\'' => self.write("\\'"),
11864 '\\' => self.write("\\\\"),
11865 '\n' => self.write("\\n"),
11866 '\r' => self.write("\\r"),
11867 '\t' => self.write("\\t"),
11868 '\0' => self.write("\\0"),
11869 _ => self.output.push(c),
11870 }
11871 }
11872 self.write("'");
11873 } else {
11874 self.write("'");
11876 for c in s.chars() {
11877 match c {
11878 '\'' => self.write("''"),
11879 _ => self.output.push(c),
11881 }
11882 }
11883 self.write("'");
11884 }
11885 }
11886 Some(DialectType::Snowflake) => {
11891 self.write("'");
11892 for c in s.chars() {
11893 match c {
11894 '\'' => self.write("\\'"),
11895 '\n' => self.write("\\n"),
11898 '\r' => self.write("\\r"),
11899 '\t' => self.write("\\t"),
11900 _ => self.output.push(c),
11901 }
11902 }
11903 self.write("'");
11904 }
11905 Some(DialectType::PostgreSQL) => {
11907 self.write("'");
11908 for c in s.chars() {
11909 match c {
11910 '\'' => self.write("''"),
11911 _ => self.output.push(c),
11912 }
11913 }
11914 self.write("'");
11915 }
11916 Some(DialectType::Redshift) => {
11918 self.write("'");
11919 for c in s.chars() {
11920 match c {
11921 '\'' => self.write("\\'"),
11922 _ => self.output.push(c),
11923 }
11924 }
11925 self.write("'");
11926 }
11927 Some(DialectType::Oracle) => {
11929 self.write("'");
11930 self.write(&s.replace('\'', "''"));
11931 self.write("'");
11932 }
11933 Some(DialectType::ClickHouse) => {
11936 self.write("'");
11937 for c in s.chars() {
11938 match c {
11939 '\'' => self.write("''"),
11940 '\\' => self.write("\\\\"),
11941 '\n' => self.write("\\n"),
11942 '\r' => self.write("\\r"),
11943 '\t' => self.write("\\t"),
11944 '\0' => self.write("\\0"),
11945 _ => self.output.push(c),
11946 }
11947 }
11948 self.write("'");
11949 }
11950 _ => {
11953 self.write("'");
11954 self.write(&s.replace('\'', "''"));
11955 self.write("'");
11956 }
11957 }
11958 Ok(())
11959 }
11960
11961 fn write_escaped_byte_string(&mut self, s: &str) {
11964 for c in s.chars() {
11965 match c {
11966 '\'' => self.write("\\'"),
11968 '\\' => self.write("\\\\"),
11970 _ if !c.is_control() => self.output.push(c),
11972 _ => {
11974 let byte = c as u32;
11975 if byte < 256 {
11976 self.write(&format!("\\x{:02x}", byte));
11977 } else {
11978 for b in c.to_string().as_bytes() {
11980 self.write(&format!("\\x{:02x}", b));
11981 }
11982 }
11983 }
11984 }
11985 }
11986 }
11987
11988 fn generate_boolean(&mut self, b: &BooleanLiteral) -> Result<()> {
11989 use crate::dialects::DialectType;
11990
11991 match self.config.dialect {
11993 Some(DialectType::TSQL) => {
11996 self.write(if b.value { "1" } else { "0" });
11997 }
11998 Some(DialectType::Oracle) => {
12000 self.write(if b.value { "1" } else { "0" });
12001 }
12002 Some(DialectType::MySQL) => {
12004 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
12005 }
12006 _ => {
12008 self.write_keyword(if b.value { "TRUE" } else { "FALSE" });
12009 }
12010 }
12011 Ok(())
12012 }
12013
12014 fn generate_alias_identifier(&mut self, id: &Identifier) -> Result<()> {
12017 let name = &id.name;
12018 let quote_style = &self.config.identifier_quote_style;
12019
12020 let needs_quoting = id.quoted || self.is_reserved_keyword(name);
12024
12025 let output_name = if self.config.normalize_identifiers && !id.quoted {
12027 name.to_lowercase()
12028 } else {
12029 name.to_string()
12030 };
12031
12032 if needs_quoting {
12033 let escaped_name = if quote_style.start == quote_style.end {
12035 output_name.replace(
12036 quote_style.end,
12037 &format!("{}{}", quote_style.end, quote_style.end)
12038 )
12039 } else {
12040 output_name.replace(
12041 quote_style.end,
12042 &format!("{}{}", quote_style.end, quote_style.end)
12043 )
12044 };
12045 self.write(&format!("{}{}{}", quote_style.start, escaped_name, quote_style.end));
12046 } else {
12047 self.write(&output_name);
12048 }
12049
12050 for comment in &id.trailing_comments {
12052 self.write(" ");
12053 self.write(comment);
12054 }
12055 Ok(())
12056 }
12057
12058 fn generate_identifier(&mut self, id: &Identifier) -> Result<()> {
12059 use crate::dialects::DialectType;
12060
12061 let name = &id.name;
12062
12063 let quote_style = if matches!(self.config.dialect, Some(DialectType::Athena)) && self.athena_hive_context {
12065 &IdentifierQuoteStyle::BACKTICK
12066 } else {
12067 &self.config.identifier_quote_style
12068 };
12069
12070 let starts_with_digit = name.chars().next().map_or(false, |c| c.is_ascii_digit());
12077 let needs_digit_quoting = starts_with_digit && !self.config.identifiers_can_start_with_digit && self.config.dialect.is_some();
12078 let mysql_invalid_hex_identifier = matches!(self.config.dialect, Some(DialectType::MySQL))
12079 && name.len() > 2
12080 && (name.starts_with("0x") || name.starts_with("0X"))
12081 && !name[2..].chars().all(|c| c.is_ascii_hexdigit());
12082 let needs_quoting = id.quoted
12083 || self.is_reserved_keyword(name)
12084 || self.config.always_quote_identifiers
12085 || needs_digit_quoting
12086 || mysql_invalid_hex_identifier;
12087
12088 let (base_name, suffix) = if needs_quoting {
12091 if let Some(paren_pos) = name.find('(') {
12093 let base = &name[..paren_pos];
12094 let rest = &name[paren_pos..];
12095 if rest.starts_with('(') && (rest.ends_with(')') || rest.ends_with(") ASC") || rest.ends_with(") DESC")) {
12097 let close_paren = rest.find(')').unwrap_or(rest.len());
12099 let inside = &rest[1..close_paren];
12100 if inside.chars().all(|c| c.is_ascii_digit()) {
12101 (base.to_string(), rest.to_string())
12102 } else {
12103 (name.to_string(), String::new())
12104 }
12105 } else {
12106 (name.to_string(), String::new())
12107 }
12108 } else if name.ends_with(" ASC") {
12109 let base = &name[..name.len() - 4];
12110 (base.to_string(), " ASC".to_string())
12111 } else if name.ends_with(" DESC") {
12112 let base = &name[..name.len() - 5];
12113 (base.to_string(), " DESC".to_string())
12114 } else {
12115 (name.to_string(), String::new())
12116 }
12117 } else {
12118 (name.to_string(), String::new())
12119 };
12120
12121 let output_name = if self.config.normalize_identifiers && !id.quoted {
12125 base_name.to_lowercase()
12126 } else if matches!(self.config.dialect, Some(DialectType::Exasol)) && !id.quoted && self.is_reserved_keyword(name) {
12127 base_name.to_uppercase()
12130 } else {
12131 base_name
12132 };
12133
12134 if needs_quoting {
12135 let escaped_name = if quote_style.start == quote_style.end {
12137 output_name.replace(
12139 quote_style.end,
12140 &format!("{}{}", quote_style.end, quote_style.end)
12141 )
12142 } else {
12143 output_name.replace(
12145 quote_style.end,
12146 &format!("{}{}", quote_style.end, quote_style.end)
12147 )
12148 };
12149 self.write(&format!("{}{}{}{}", quote_style.start, escaped_name, quote_style.end, suffix));
12150 } else {
12151 self.write(&output_name);
12152 }
12153
12154 for comment in &id.trailing_comments {
12156 self.write(" ");
12157 self.write(comment);
12158 }
12159 Ok(())
12160 }
12161
12162 fn generate_column(&mut self, col: &Column) -> Result<()> {
12163 use crate::dialects::DialectType;
12164
12165 if let Some(table) = &col.table {
12166 let is_exasol_local_prefix = matches!(self.config.dialect, Some(DialectType::Exasol))
12170 && !table.quoted
12171 && table.name.eq_ignore_ascii_case("LOCAL");
12172
12173 if is_exasol_local_prefix {
12174 self.write("LOCAL");
12176 } else {
12177 self.generate_identifier(table)?;
12178 }
12179 self.write(".");
12180 }
12181 self.generate_identifier(&col.name)?;
12182 if col.join_mark && self.config.supports_column_join_marks {
12185 self.write(" (+)");
12186 }
12187 for comment in &col.trailing_comments {
12189 self.write_space();
12190 self.write(comment);
12191 }
12192 Ok(())
12193 }
12194
12195 fn generate_pseudocolumn(&mut self, pc: &Pseudocolumn) -> Result<()> {
12198 use crate::dialects::DialectType;
12199 use crate::expressions::PseudocolumnType;
12200
12201 if pc.kind == PseudocolumnType::Sysdate
12203 && !matches!(self.config.dialect, Some(DialectType::Oracle) | Some(DialectType::Redshift) | None)
12204 {
12205 self.write_keyword("CURRENT_TIMESTAMP");
12206 if matches!(self.config.dialect, Some(DialectType::MySQL) | Some(DialectType::ClickHouse)
12208 | Some(DialectType::Spark) | Some(DialectType::Databricks)
12209 | Some(DialectType::Hive)) {
12210 self.write("()");
12211 }
12212 } else {
12213 self.write(pc.kind.as_str());
12214 }
12215 Ok(())
12216 }
12217
12218 fn generate_connect(&mut self, connect: &Connect) -> Result<()> {
12220 use crate::dialects::DialectType;
12221
12222 let supports_connect_by = matches!(self.config.dialect, Some(DialectType::Oracle) | Some(DialectType::Snowflake));
12225
12226 if !supports_connect_by && self.config.dialect.is_some() {
12227 if self.config.pretty {
12229 self.write_newline();
12230 } else {
12231 self.write_space();
12232 }
12233 self.write("/* CONNECT BY requires manual conversion to recursive CTE */");
12234 }
12235
12236 if let Some(start) = &connect.start {
12238 if self.config.pretty {
12239 self.write_newline();
12240 } else {
12241 self.write_space();
12242 }
12243 self.write_keyword("START WITH");
12244 self.write_space();
12245 self.generate_expression(start)?;
12246 }
12247
12248 if self.config.pretty {
12250 self.write_newline();
12251 } else {
12252 self.write_space();
12253 }
12254 self.write_keyword("CONNECT BY");
12255 if connect.nocycle {
12256 self.write_space();
12257 self.write_keyword("NOCYCLE");
12258 }
12259 self.write_space();
12260 self.generate_expression(&connect.connect)?;
12261
12262 Ok(())
12263 }
12264
12265 fn generate_connect_expr(&mut self, connect: &Connect) -> Result<()> {
12267 self.generate_connect(connect)
12268 }
12269
12270 fn generate_prior(&mut self, prior: &Prior) -> Result<()> {
12272 self.write_keyword("PRIOR");
12273 self.write_space();
12274 self.generate_expression(&prior.this)?;
12275 Ok(())
12276 }
12277
12278 fn generate_connect_by_root(&mut self, cbr: &ConnectByRoot) -> Result<()> {
12281 self.write_keyword("CONNECT_BY_ROOT");
12282 self.write_space();
12283 self.generate_expression(&cbr.this)?;
12284 Ok(())
12285 }
12286
12287 fn generate_match_recognize(&mut self, mr: &MatchRecognize) -> Result<()> {
12289 use crate::dialects::DialectType;
12290
12291 let supports_match_recognize = matches!(
12293 self.config.dialect,
12294 Some(DialectType::Oracle) | Some(DialectType::Snowflake) | Some(DialectType::Presto) | Some(DialectType::Trino)
12295 );
12296
12297 if let Some(source) = &mr.this {
12299 self.generate_expression(source)?;
12300 }
12301
12302 if !supports_match_recognize {
12303 self.write("/* MATCH_RECOGNIZE not supported in this dialect */");
12304 return Ok(());
12305 }
12306
12307 if self.config.pretty {
12309 self.write_newline();
12310 } else {
12311 self.write_space();
12312 }
12313
12314 self.write_keyword("MATCH_RECOGNIZE");
12315 self.write(" (");
12316
12317 if self.config.pretty {
12318 self.indent_level += 1;
12319 }
12320
12321 let mut needs_separator = false;
12322
12323 if let Some(partition_by) = &mr.partition_by {
12325 if !partition_by.is_empty() {
12326 if self.config.pretty {
12327 self.write_newline();
12328 self.write_indent();
12329 }
12330 self.write_keyword("PARTITION BY");
12331 self.write_space();
12332 for (i, expr) in partition_by.iter().enumerate() {
12333 if i > 0 {
12334 self.write(", ");
12335 }
12336 self.generate_expression(expr)?;
12337 }
12338 needs_separator = true;
12339 }
12340 }
12341
12342 if let Some(order_by) = &mr.order_by {
12344 if !order_by.is_empty() {
12345 if needs_separator {
12346 if self.config.pretty {
12347 self.write_newline();
12348 self.write_indent();
12349 } else {
12350 self.write_space();
12351 }
12352 } else if self.config.pretty {
12353 self.write_newline();
12354 self.write_indent();
12355 }
12356 self.write_keyword("ORDER BY");
12357 if self.config.pretty {
12359 self.indent_level += 1;
12360 for (i, ordered) in order_by.iter().enumerate() {
12361 if i > 0 {
12362 self.write(",");
12363 }
12364 self.write_newline();
12365 self.write_indent();
12366 self.generate_ordered(ordered)?;
12367 }
12368 self.indent_level -= 1;
12369 } else {
12370 self.write_space();
12371 for (i, ordered) in order_by.iter().enumerate() {
12372 if i > 0 {
12373 self.write(", ");
12374 }
12375 self.generate_ordered(ordered)?;
12376 }
12377 }
12378 needs_separator = true;
12379 }
12380 }
12381
12382 if let Some(measures) = &mr.measures {
12384 if !measures.is_empty() {
12385 if needs_separator {
12386 if self.config.pretty {
12387 self.write_newline();
12388 self.write_indent();
12389 } else {
12390 self.write_space();
12391 }
12392 } else if self.config.pretty {
12393 self.write_newline();
12394 self.write_indent();
12395 }
12396 self.write_keyword("MEASURES");
12397 if self.config.pretty {
12399 self.indent_level += 1;
12400 for (i, measure) in measures.iter().enumerate() {
12401 if i > 0 {
12402 self.write(",");
12403 }
12404 self.write_newline();
12405 self.write_indent();
12406 if let Some(semantics) = &measure.window_frame {
12408 match semantics {
12409 MatchRecognizeSemantics::Running => {
12410 self.write_keyword("RUNNING");
12411 self.write_space();
12412 }
12413 MatchRecognizeSemantics::Final => {
12414 self.write_keyword("FINAL");
12415 self.write_space();
12416 }
12417 }
12418 }
12419 self.generate_expression(&measure.this)?;
12420 }
12421 self.indent_level -= 1;
12422 } else {
12423 self.write_space();
12424 for (i, measure) in measures.iter().enumerate() {
12425 if i > 0 {
12426 self.write(", ");
12427 }
12428 if let Some(semantics) = &measure.window_frame {
12430 match semantics {
12431 MatchRecognizeSemantics::Running => {
12432 self.write_keyword("RUNNING");
12433 self.write_space();
12434 }
12435 MatchRecognizeSemantics::Final => {
12436 self.write_keyword("FINAL");
12437 self.write_space();
12438 }
12439 }
12440 }
12441 self.generate_expression(&measure.this)?;
12442 }
12443 }
12444 needs_separator = true;
12445 }
12446 }
12447
12448 if let Some(rows) = &mr.rows {
12450 if needs_separator {
12451 if self.config.pretty {
12452 self.write_newline();
12453 self.write_indent();
12454 } else {
12455 self.write_space();
12456 }
12457 } else if self.config.pretty {
12458 self.write_newline();
12459 self.write_indent();
12460 }
12461 match rows {
12462 MatchRecognizeRows::OneRowPerMatch => {
12463 self.write_keyword("ONE ROW PER MATCH");
12464 }
12465 MatchRecognizeRows::AllRowsPerMatch => {
12466 self.write_keyword("ALL ROWS PER MATCH");
12467 }
12468 MatchRecognizeRows::AllRowsPerMatchShowEmptyMatches => {
12469 self.write_keyword("ALL ROWS PER MATCH SHOW EMPTY MATCHES");
12470 }
12471 MatchRecognizeRows::AllRowsPerMatchOmitEmptyMatches => {
12472 self.write_keyword("ALL ROWS PER MATCH OMIT EMPTY MATCHES");
12473 }
12474 MatchRecognizeRows::AllRowsPerMatchWithUnmatchedRows => {
12475 self.write_keyword("ALL ROWS PER MATCH WITH UNMATCHED ROWS");
12476 }
12477 }
12478 needs_separator = true;
12479 }
12480
12481 if let Some(after) = &mr.after {
12483 if needs_separator {
12484 if self.config.pretty {
12485 self.write_newline();
12486 self.write_indent();
12487 } else {
12488 self.write_space();
12489 }
12490 } else if self.config.pretty {
12491 self.write_newline();
12492 self.write_indent();
12493 }
12494 match after {
12495 MatchRecognizeAfter::PastLastRow => {
12496 self.write_keyword("AFTER MATCH SKIP PAST LAST ROW");
12497 }
12498 MatchRecognizeAfter::ToNextRow => {
12499 self.write_keyword("AFTER MATCH SKIP TO NEXT ROW");
12500 }
12501 MatchRecognizeAfter::ToFirst(ident) => {
12502 self.write_keyword("AFTER MATCH SKIP TO FIRST");
12503 self.write_space();
12504 self.generate_identifier(ident)?;
12505 }
12506 MatchRecognizeAfter::ToLast(ident) => {
12507 self.write_keyword("AFTER MATCH SKIP TO LAST");
12508 self.write_space();
12509 self.generate_identifier(ident)?;
12510 }
12511 }
12512 needs_separator = true;
12513 }
12514
12515 if let Some(pattern) = &mr.pattern {
12517 if needs_separator {
12518 if self.config.pretty {
12519 self.write_newline();
12520 self.write_indent();
12521 } else {
12522 self.write_space();
12523 }
12524 } else if self.config.pretty {
12525 self.write_newline();
12526 self.write_indent();
12527 }
12528 self.write_keyword("PATTERN");
12529 self.write_space();
12530 self.write("(");
12531 self.write(pattern);
12532 self.write(")");
12533 needs_separator = true;
12534 }
12535
12536 if let Some(define) = &mr.define {
12538 if !define.is_empty() {
12539 if needs_separator {
12540 if self.config.pretty {
12541 self.write_newline();
12542 self.write_indent();
12543 } else {
12544 self.write_space();
12545 }
12546 } else if self.config.pretty {
12547 self.write_newline();
12548 self.write_indent();
12549 }
12550 self.write_keyword("DEFINE");
12551 if self.config.pretty {
12553 self.indent_level += 1;
12554 for (i, (name, expr)) in define.iter().enumerate() {
12555 if i > 0 {
12556 self.write(",");
12557 }
12558 self.write_newline();
12559 self.write_indent();
12560 self.generate_identifier(name)?;
12561 self.write(" AS ");
12562 self.generate_expression(expr)?;
12563 }
12564 self.indent_level -= 1;
12565 } else {
12566 self.write_space();
12567 for (i, (name, expr)) in define.iter().enumerate() {
12568 if i > 0 {
12569 self.write(", ");
12570 }
12571 self.generate_identifier(name)?;
12572 self.write(" AS ");
12573 self.generate_expression(expr)?;
12574 }
12575 }
12576 }
12577 }
12578
12579 if self.config.pretty {
12580 self.indent_level -= 1;
12581 self.write_newline();
12582 }
12583 self.write(")");
12584
12585 if let Some(alias) = &mr.alias {
12587 self.write(" ");
12588 if mr.alias_explicit_as {
12589 self.write_keyword("AS");
12590 self.write(" ");
12591 }
12592 self.generate_identifier(alias)?;
12593 }
12594
12595 Ok(())
12596 }
12597
12598 fn generate_hint(&mut self, hint: &Hint) -> Result<()> {
12600 use crate::dialects::DialectType;
12601
12602 let supports_hints = matches!(
12604 self.config.dialect,
12605 None | Some(DialectType::Oracle) | Some(DialectType::MySQL) |
12607 Some(DialectType::Spark) | Some(DialectType::Hive) |
12608 Some(DialectType::Databricks) | Some(DialectType::PostgreSQL)
12609 );
12610
12611 if !supports_hints || hint.expressions.is_empty() {
12612 return Ok(());
12613 }
12614
12615 let mut hint_strings: Vec<String> = Vec::new();
12618 for expr in &hint.expressions {
12619 match expr {
12620 HintExpression::Raw(text) => {
12621 let parsed = self.parse_raw_hint_text(text);
12623 hint_strings.extend(parsed);
12624 }
12625 _ => {
12626 hint_strings.push(self.hint_expression_to_string(expr)?);
12627 }
12628 }
12629 }
12630
12631 let use_multiline = self.config.pretty && hint_strings.len() > 1;
12635
12636 if use_multiline {
12637 self.write(" /*+ ");
12639 for (i, hint_str) in hint_strings.iter().enumerate() {
12640 if i > 0 {
12641 self.write_newline();
12642 self.write(" "); }
12644 self.write(hint_str);
12645 }
12646 self.write(" */");
12647 } else {
12648 self.write(" /*+ ");
12650 let sep = match self.config.dialect {
12651 Some(DialectType::Spark) | Some(DialectType::Databricks) => ", ",
12652 _ => " ",
12653 };
12654 for (i, hint_str) in hint_strings.iter().enumerate() {
12655 if i > 0 {
12656 self.write(sep);
12657 }
12658 self.write(hint_str);
12659 }
12660 self.write(" */");
12661 }
12662
12663 Ok(())
12664 }
12665
12666 fn parse_raw_hint_text(&self, text: &str) -> Vec<String> {
12670 let mut results = Vec::new();
12671 let mut chars = text.chars().peekable();
12672 let mut current = String::new();
12673 let mut paren_depth = 0;
12674 let mut has_unparseable_content = false;
12675 let mut position_after_last_function = 0;
12676 let mut char_position = 0;
12677
12678 while let Some(c) = chars.next() {
12679 char_position += c.len_utf8();
12680 match c {
12681 '(' => {
12682 paren_depth += 1;
12683 current.push(c);
12684 }
12685 ')' => {
12686 paren_depth -= 1;
12687 current.push(c);
12688 if paren_depth == 0 {
12690 let trimmed = current.trim().to_string();
12691 if !trimmed.is_empty() {
12692 let formatted = self.format_hint_function(&trimmed);
12694 results.push(formatted);
12695 }
12696 current.clear();
12697 position_after_last_function = char_position;
12698 }
12699 }
12700 ' ' | '\t' | '\n' | ',' if paren_depth == 0 => {
12701 }
12703 _ if paren_depth == 0 => {
12704 current.push(c);
12706 }
12707 _ => {
12708 current.push(c);
12709 }
12710 }
12711 }
12712
12713 let remaining_text = text[position_after_last_function..].trim();
12715 if !remaining_text.is_empty() {
12716 let words: Vec<&str> = remaining_text.split_whitespace().collect();
12720 let looks_like_hint_functions = words.iter().all(|word| {
12721 word.contains('(') || (word.chars().all(|c| c.is_ascii_uppercase() || c == '_'))
12723 });
12724
12725 if !looks_like_hint_functions && words.len() > 1 {
12726 has_unparseable_content = true;
12727 }
12728 }
12729
12730 if has_unparseable_content {
12732 return vec![text.trim().to_string()];
12733 }
12734
12735 if results.is_empty() {
12737 results.push(text.trim().to_string());
12738 }
12739
12740 results
12741 }
12742
12743 fn format_hint_function(&self, hint: &str) -> String {
12746 if !self.config.pretty {
12747 return hint.to_string();
12748 }
12749
12750 if let Some(paren_pos) = hint.find('(') {
12752 if hint.ends_with(')') {
12753 let name = &hint[..paren_pos];
12754 let args_str = &hint[paren_pos + 1..hint.len() - 1];
12755
12756 let args: Vec<&str> = args_str.split_whitespace().collect();
12758
12759 let total_args_width: usize = args.iter().map(|s| s.len()).sum::<usize>()
12761 + args.len().saturating_sub(1); if total_args_width > self.config.max_text_width && !args.is_empty() {
12765 let mut result = format!("{}(\n", name);
12766 for arg in &args {
12767 result.push_str(" "); result.push_str(arg);
12769 result.push('\n');
12770 }
12771 result.push_str(" )"); return result;
12773 }
12774 }
12775 }
12776
12777 hint.to_string()
12778 }
12779
12780 fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result<String> {
12782 match expr {
12783 HintExpression::Function { name, args } => {
12784 let arg_strings: Vec<String> = args.iter()
12786 .map(|arg| {
12787 let mut gen = Generator::with_config(self.config.clone());
12788 gen.generate_expression(arg)?;
12789 Ok(gen.output)
12790 })
12791 .collect::<Result<Vec<_>>>()?;
12792
12793 let total_args_width: usize = arg_strings.iter().map(|s| s.len()).sum::<usize>()
12795 + arg_strings.len().saturating_sub(1); let args_multiline = self.config.pretty
12800 && total_args_width > self.config.max_text_width;
12801
12802 if args_multiline && !arg_strings.is_empty() {
12803 let mut result = format!("{}(\n", name);
12805 for arg_str in &arg_strings {
12806 result.push_str(" "); result.push_str(arg_str);
12808 result.push('\n');
12809 }
12810 result.push_str(" )"); Ok(result)
12812 } else {
12813 let args_str = arg_strings.join(" ");
12815 Ok(format!("{}({})", name, args_str))
12816 }
12817 }
12818 HintExpression::Identifier(name) => Ok(name.clone()),
12819 HintExpression::Raw(text) => {
12820 if self.config.pretty {
12822 Ok(self.format_hint_function(text))
12823 } else {
12824 Ok(text.clone())
12825 }
12826 }
12827 }
12828 }
12829
12830 fn generate_table(&mut self, table: &TableRef) -> Result<()> {
12831 if table.only {
12833 self.write_keyword("ONLY");
12834 self.write_space();
12835 }
12836
12837 if let Some(ref identifier_func) = table.identifier_func {
12839 self.generate_expression(identifier_func)?;
12840 } else {
12841 if let Some(catalog) = &table.catalog {
12842 self.generate_identifier(catalog)?;
12843 self.write(".");
12844 }
12845 if let Some(schema) = &table.schema {
12846 self.generate_identifier(schema)?;
12847 self.write(".");
12848 }
12849 self.generate_identifier(&table.name)?;
12850 }
12851
12852 if let Some(changes) = &table.changes {
12854 self.write(" ");
12855 self.generate_changes(changes)?;
12856 }
12857
12858 if !table.partitions.is_empty() {
12860 self.write_space();
12861 self.write_keyword("PARTITION");
12862 self.write("(");
12863 for (i, partition) in table.partitions.iter().enumerate() {
12864 if i > 0 {
12865 self.write(", ");
12866 }
12867 self.generate_identifier(partition)?;
12868 }
12869 self.write(")");
12870 }
12871
12872 if table.changes.is_none() {
12875 if let Some(when) = &table.when {
12876 self.write_space();
12877 self.generate_historical_data(when)?;
12878 }
12879 }
12880
12881 if let Some(ref system_time) = table.system_time {
12883 self.write_space();
12884 self.write(system_time);
12885 }
12886
12887 if let Some(ref version) = table.version {
12889 self.write_space();
12890 self.generate_version(version)?;
12891 }
12892
12893 let alias_post_tablesample = self.config.alias_post_tablesample;
12897
12898 if alias_post_tablesample {
12899 self.generate_table_sample_clause(table)?;
12901 }
12902
12903 let is_sqlite_hint = matches!(self.config.dialect, Some(DialectType::SQLite))
12906 && table.hints.iter().any(|h| {
12907 if let Expression::Identifier(id) = h {
12908 id.name.starts_with("INDEXED BY") || id.name == "NOT INDEXED"
12909 } else {
12910 false
12911 }
12912 });
12913 if !table.hints.is_empty() && !is_sqlite_hint {
12914 for hint in &table.hints {
12915 self.write_space();
12916 self.generate_expression(hint)?;
12917 }
12918 }
12919
12920 if let Some(alias) = &table.alias {
12921 self.write_space();
12922 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));
12925 let is_stage_ref = table.name.name.starts_with('@');
12926 if table.alias_explicit_as || always_use_as || is_stage_ref {
12927 self.write_keyword("AS");
12928 self.write_space();
12929 }
12930 self.generate_identifier(alias)?;
12931
12932 if !table.column_aliases.is_empty() && self.config.supports_table_alias_columns {
12935 self.write("(");
12936 for (i, col_alias) in table.column_aliases.iter().enumerate() {
12937 if i > 0 {
12938 self.write(", ");
12939 }
12940 self.generate_identifier(col_alias)?;
12941 }
12942 self.write(")");
12943 }
12944 }
12945
12946 if !alias_post_tablesample {
12948 self.generate_table_sample_clause(table)?;
12949 }
12950
12951 if is_sqlite_hint {
12953 for hint in &table.hints {
12954 self.write_space();
12955 self.generate_expression(hint)?;
12956 }
12957 }
12958
12959 if table.final_ && matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
12961 self.write_space();
12962 self.write_keyword("FINAL");
12963 }
12964
12965 for comment in &table.trailing_comments {
12967 self.write_space();
12968 self.write_formatted_comment(comment);
12969 }
12970
12971 Ok(())
12972 }
12973
12974 fn generate_table_sample_clause(&mut self, table: &TableRef) -> Result<()> {
12976 if let Some(ref ts) = table.table_sample {
12977 self.write_space();
12978 if ts.is_using_sample {
12979 self.write_keyword("USING SAMPLE");
12980 } else {
12981 self.write_keyword(self.config.tablesample_keywords);
12983 }
12984 self.generate_sample_body(ts)?;
12985 if let Some(ref seed) = ts.seed {
12987 self.write_space();
12988 self.write_keyword(self.config.tablesample_seed_keyword);
12989 self.write(" (");
12990 self.generate_expression(seed)?;
12991 self.write(")");
12992 }
12993 }
12994 Ok(())
12995 }
12996
12997 fn generate_stage_reference(&mut self, sr: &StageReference) -> Result<()> {
12998 if sr.quoted {
13002 self.write("'");
13003 }
13004
13005 self.write(&sr.name);
13006 if let Some(path) = &sr.path {
13007 self.write(path);
13008 }
13009
13010 if sr.quoted {
13011 self.write("'");
13012 }
13013
13014 let has_options = sr.file_format.is_some() || sr.pattern.is_some();
13016 if has_options {
13017 self.write(" (");
13018 let mut first = true;
13019
13020 if let Some(file_format) = &sr.file_format {
13021 if !first {
13022 self.write(", ");
13023 }
13024 self.write_keyword("FILE_FORMAT");
13025 self.write(" => ");
13026 self.generate_expression(file_format)?;
13027 first = false;
13028 }
13029
13030 if let Some(pattern) = &sr.pattern {
13031 if !first {
13032 self.write(", ");
13033 }
13034 self.write_keyword("PATTERN");
13035 self.write(" => '");
13036 self.write(pattern);
13037 self.write("'");
13038 }
13039
13040 self.write(")");
13041 }
13042 Ok(())
13043 }
13044
13045
13046 fn generate_star(&mut self, star: &Star) -> Result<()> {
13047 use crate::dialects::DialectType;
13048
13049 if let Some(table) = &star.table {
13050 self.generate_identifier(table)?;
13051 self.write(".");
13052 }
13053 self.write("*");
13054
13055 if let Some(except) = &star.except {
13057 if !except.is_empty() {
13058 self.write_space();
13059 match self.config.dialect {
13061 Some(DialectType::BigQuery) => self.write_keyword("EXCEPT"),
13062 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => {
13063 self.write_keyword("EXCLUDE")
13064 }
13065 _ => self.write_keyword("EXCEPT"), }
13067 self.write(" (");
13068 for (i, col) in except.iter().enumerate() {
13069 if i > 0 {
13070 self.write(", ");
13071 }
13072 self.generate_identifier(col)?;
13073 }
13074 self.write(")");
13075 }
13076 }
13077
13078 if let Some(replace) = &star.replace {
13080 if !replace.is_empty() {
13081 self.write_space();
13082 self.write_keyword("REPLACE");
13083 self.write(" (");
13084 for (i, alias) in replace.iter().enumerate() {
13085 if i > 0 {
13086 self.write(", ");
13087 }
13088 self.generate_expression(&alias.this)?;
13089 self.write_space();
13090 self.write_keyword("AS");
13091 self.write_space();
13092 self.generate_identifier(&alias.alias)?;
13093 }
13094 self.write(")");
13095 }
13096 }
13097
13098 if let Some(rename) = &star.rename {
13100 if !rename.is_empty() {
13101 self.write_space();
13102 self.write_keyword("RENAME");
13103 self.write(" (");
13104 for (i, (old_name, new_name)) in rename.iter().enumerate() {
13105 if i > 0 {
13106 self.write(", ");
13107 }
13108 self.generate_identifier(old_name)?;
13109 self.write_space();
13110 self.write_keyword("AS");
13111 self.write_space();
13112 self.generate_identifier(new_name)?;
13113 }
13114 self.write(")");
13115 }
13116 }
13117
13118 for comment in &star.trailing_comments {
13120 self.write_space();
13121 self.write(comment);
13122 }
13123
13124 Ok(())
13125 }
13126
13127 fn generate_braced_wildcard(&mut self, expr: &Expression) -> Result<()> {
13129 self.write("{");
13130 match expr {
13131 Expression::Star(star) => {
13132 self.generate_star(star)?;
13134 }
13135 Expression::ILike(ilike) => {
13136 self.generate_expression(&ilike.left)?;
13138 self.write_space();
13139 self.write_keyword("ILIKE");
13140 self.write_space();
13141 self.generate_expression(&ilike.right)?;
13142 }
13143 _ => {
13144 self.generate_expression(expr)?;
13145 }
13146 }
13147 self.write("}");
13148 Ok(())
13149 }
13150
13151 fn generate_alias(&mut self, alias: &Alias) -> Result<()> {
13152 match &alias.this {
13156 Expression::Column(col) => {
13157 if let Some(table) = &col.table {
13159 self.generate_identifier(table)?;
13160 self.write(".");
13161 }
13162 self.generate_identifier(&col.name)?;
13163 }
13164 _ => {
13165 self.generate_expression(&alias.this)?;
13166 }
13167 }
13168
13169 for comment in &alias.pre_alias_comments {
13171 self.write_space();
13172 self.write(comment);
13173 }
13174
13175 use crate::dialects::DialectType;
13176
13177 let is_table_source = matches!(
13183 &alias.this,
13184 Expression::JSONTable(_)
13185 | Expression::XMLTable(_)
13186 | Expression::TableFromRows(_)
13187 | Expression::Unnest(_)
13188 | Expression::MatchRecognize(_)
13189 | Expression::Select(_)
13190 | Expression::Subquery(_)
13191 | Expression::Paren(_)
13192 );
13193 let dialect_skips_table_alias_as = matches!(
13194 self.config.dialect,
13195 Some(DialectType::Oracle)
13196 );
13197 let skip_as = is_table_source && dialect_skips_table_alias_as;
13198
13199 self.write_space();
13200 if !skip_as {
13201 self.write_keyword("AS");
13202 self.write_space();
13203 }
13204
13205 let skip_column_aliases = matches!(self.config.dialect, Some(DialectType::BigQuery));
13207
13208 if alias.alias.is_empty() && !alias.column_aliases.is_empty() && !skip_column_aliases {
13210 self.write("(");
13212 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
13213 if i > 0 {
13214 self.write(", ");
13215 }
13216 self.generate_alias_identifier(col_alias)?;
13217 }
13218 self.write(")");
13219 } else if !alias.column_aliases.is_empty() && !skip_column_aliases {
13220 self.generate_alias_identifier(&alias.alias)?;
13222 self.write("(");
13223 for (i, col_alias) in alias.column_aliases.iter().enumerate() {
13224 if i > 0 {
13225 self.write(", ");
13226 }
13227 self.generate_alias_identifier(col_alias)?;
13228 }
13229 self.write(")");
13230 } else {
13231 self.generate_alias_identifier(&alias.alias)?;
13233 }
13234
13235 for comment in &alias.trailing_comments {
13237 self.write_space();
13238 self.write(comment);
13239 }
13240
13241 Ok(())
13242 }
13243
13244 fn generate_cast(&mut self, cast: &Cast) -> Result<()> {
13245 use crate::dialects::DialectType;
13246
13247 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
13249 self.generate_expression(&cast.this)?;
13250 self.write(" :> ");
13251 self.generate_data_type(&cast.to)?;
13252 return Ok(());
13253 }
13254
13255 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
13257 let is_unknown_type = matches!(cast.to, DataType::Unknown)
13258 || matches!(cast.to, DataType::Custom { ref name } if name.is_empty());
13259 if is_unknown_type {
13260 if let Some(format) = &cast.format {
13261 self.write_keyword("CAST");
13262 self.write("(");
13263 self.generate_expression(&cast.this)?;
13264 self.write_space();
13265 self.write_keyword("AS");
13266 self.write_space();
13267 self.write_keyword("FORMAT");
13268 self.write_space();
13269 self.generate_expression(format)?;
13270 self.write(")");
13271 return Ok(());
13272 }
13273 }
13274 }
13275
13276 if matches!(self.config.dialect, Some(DialectType::Oracle)) {
13279 if let Some(format) = &cast.format {
13280 let is_date = matches!(cast.to, DataType::Date);
13282 let is_timestamp = matches!(cast.to, DataType::Timestamp { .. });
13283
13284 if is_date || is_timestamp {
13285 let func_name = if is_date { "TO_DATE" } else { "TO_TIMESTAMP" };
13286 self.write_keyword(func_name);
13287 self.write("(");
13288 self.generate_expression(&cast.this)?;
13289 self.write(", ");
13290
13291 if let Expression::Literal(Literal::String(fmt_str)) = format.as_ref() {
13294 let normalized = self.normalize_oracle_format(fmt_str);
13295 self.write("'");
13296 self.write(&normalized);
13297 self.write("'");
13298 } else {
13299 self.generate_expression(format)?;
13300 }
13301
13302 self.write(")");
13303 return Ok(());
13304 }
13305 }
13306 }
13307
13308 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
13311 if let Expression::Array(arr) = &cast.this {
13312 self.generate_data_type(&cast.to)?;
13313 self.write("[");
13315 for (i, expr) in arr.expressions.iter().enumerate() {
13316 if i > 0 {
13317 self.write(", ");
13318 }
13319 self.generate_expression(expr)?;
13320 }
13321 self.write("]");
13322 return Ok(());
13323 }
13324 if matches!(&cast.this, Expression::ArrayFunc(_)) {
13325 self.generate_data_type(&cast.to)?;
13326 self.generate_expression(&cast.this)?;
13327 return Ok(());
13328 }
13329 }
13330
13331 if matches!(self.config.dialect, Some(DialectType::DuckDB) | Some(DialectType::Presto) | Some(DialectType::Trino)) {
13334 if let Expression::Struct(ref s) = cast.this {
13335 let all_unnamed = s.fields.iter().all(|(name, _)| name.is_none());
13336 if all_unnamed && matches!(cast.to, DataType::Struct { .. }) {
13337 self.write_keyword("CAST");
13338 self.write("(");
13339 self.generate_struct_as_row(s)?;
13340 self.write_space();
13341 self.write_keyword("AS");
13342 self.write_space();
13343 self.generate_data_type(&cast.to)?;
13344 self.write(")");
13345 return Ok(());
13346 }
13347 }
13348 }
13349
13350 let use_double_colon = cast.double_colon_syntax && self.dialect_prefers_double_colon();
13353
13354 if use_double_colon {
13355 self.generate_expression(&cast.this)?;
13357 self.write("::");
13358 self.generate_data_type(&cast.to)?;
13359 } else {
13360 self.write_keyword("CAST");
13362 self.write("(");
13363 self.generate_expression(&cast.this)?;
13364 self.write_space();
13365 self.write_keyword("AS");
13366 self.write_space();
13367 if matches!(self.config.dialect, Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB)) {
13370 if let DataType::Custom { ref name } = cast.to {
13371 let upper = name.to_uppercase();
13372 match upper.as_str() {
13373 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" | "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => {
13374 self.write_keyword("CHAR");
13375 }
13376 _ => {
13377 self.generate_data_type(&cast.to)?;
13378 }
13379 }
13380 } else {
13381 self.generate_data_type(&cast.to)?;
13382 }
13383 } else {
13384 self.generate_data_type(&cast.to)?;
13385 }
13386
13387 if let Some(default) = &cast.default {
13389 self.write_space();
13390 self.write_keyword("DEFAULT");
13391 self.write_space();
13392 self.generate_expression(default)?;
13393 self.write_space();
13394 self.write_keyword("ON");
13395 self.write_space();
13396 self.write_keyword("CONVERSION");
13397 self.write_space();
13398 self.write_keyword("ERROR");
13399 }
13400
13401 if let Some(format) = &cast.format {
13404 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Oracle)) {
13406 self.write(", ");
13407 } else {
13408 self.write_space();
13409 self.write_keyword("FORMAT");
13410 self.write_space();
13411 }
13412 self.generate_expression(format)?;
13413 }
13414
13415 self.write(")");
13416 for comment in &cast.trailing_comments {
13418 self.write_space();
13419 self.write(comment);
13420 }
13421 }
13422 Ok(())
13423 }
13424
13425 fn generate_struct_as_row(&mut self, s: &crate::expressions::Struct) -> Result<()> {
13428 self.write_keyword("ROW");
13429 self.write("(");
13430 for (i, (_, expr)) in s.fields.iter().enumerate() {
13431 if i > 0 { self.write(", "); }
13432 if let Expression::Struct(ref inner_s) = expr {
13434 self.generate_struct_as_row(inner_s)?;
13435 } else {
13436 self.generate_expression(expr)?;
13437 }
13438 }
13439 self.write(")");
13440 Ok(())
13441 }
13442
13443 fn normalize_oracle_format(&self, format: &str) -> String {
13446 let mut result = String::new();
13449 let chars: Vec<char> = format.chars().collect();
13450 let mut i = 0;
13451
13452 while i < chars.len() {
13453 if i + 1 < chars.len() && chars[i] == 'H' && chars[i + 1] == 'H' {
13454 if i + 2 < chars.len() {
13456 let next = chars[i + 2];
13457 if next == '1' || next == '2' {
13458 result.push('H');
13460 result.push('H');
13461 i += 2;
13462 continue;
13463 }
13464 }
13465 result.push_str("HH12");
13467 i += 2;
13468 } else {
13469 result.push(chars[i]);
13470 i += 1;
13471 }
13472 }
13473
13474 result
13475 }
13476
13477 fn dialect_prefers_double_colon(&self) -> bool {
13481 false
13484 }
13485
13486 fn generate_mod_func(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
13488 use crate::dialects::DialectType;
13489
13490 let use_percent_operator = matches!(
13492 self.config.dialect,
13493 Some(DialectType::Snowflake) | Some(DialectType::MySQL) | Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::PostgreSQL) | Some(DialectType::DuckDB)
13494 );
13495
13496 if use_percent_operator {
13497 self.generate_expression(&f.this)?;
13498 self.write(" % ");
13499 self.generate_expression(&f.expression)?;
13500 Ok(())
13501 } else {
13502 self.generate_binary_func("MOD", &f.this, &f.expression)
13503 }
13504 }
13505
13506 fn generate_ifnull(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
13508 use crate::dialects::DialectType;
13509
13510 let func_name = match self.config.dialect {
13512 Some(DialectType::Snowflake) => "COALESCE",
13513 _ => "IFNULL",
13514 };
13515
13516 self.generate_binary_func(func_name, &f.this, &f.expression)
13517 }
13518
13519 fn generate_nvl(&mut self, f: &crate::expressions::BinaryFunc) -> Result<()> {
13521 if let Some(ref original_name) = f.original_name {
13523 return self.generate_binary_func(original_name, &f.this, &f.expression);
13524 }
13525
13526 use crate::dialects::DialectType;
13528 let func_name = match self.config.dialect {
13529 Some(DialectType::Snowflake) |
13530 Some(DialectType::ClickHouse) |
13531 Some(DialectType::PostgreSQL) |
13532 Some(DialectType::Presto) |
13533 Some(DialectType::Trino) |
13534 Some(DialectType::Athena) |
13535 Some(DialectType::DuckDB) |
13536 Some(DialectType::BigQuery) |
13537 Some(DialectType::Spark) |
13538 Some(DialectType::Databricks) |
13539 Some(DialectType::Hive) => "COALESCE",
13540 Some(DialectType::MySQL) |
13541 Some(DialectType::Doris) |
13542 Some(DialectType::StarRocks) |
13543 Some(DialectType::SingleStore) |
13544 Some(DialectType::TiDB) => "IFNULL",
13545 _ => "NVL",
13546 };
13547
13548 self.generate_binary_func(func_name, &f.this, &f.expression)
13549 }
13550
13551 fn generate_stddev_samp(&mut self, f: &crate::expressions::AggFunc) -> Result<()> {
13553 use crate::dialects::DialectType;
13554
13555 let func_name = match self.config.dialect {
13557 Some(DialectType::Snowflake) => "STDDEV",
13558 _ => "STDDEV_SAMP",
13559 };
13560
13561 self.generate_agg_func(func_name, f)
13562 }
13563
13564 fn generate_collation(&mut self, coll: &CollationExpr) -> Result<()> {
13565 self.generate_expression(&coll.this)?;
13566 self.write_space();
13567 self.write_keyword("COLLATE");
13568 self.write_space();
13569 if coll.quoted {
13570 self.write("'");
13572 self.write(&coll.collation);
13573 self.write("'");
13574 } else if coll.double_quoted {
13575 self.write("\"");
13577 self.write(&coll.collation);
13578 self.write("\"");
13579 } else {
13580 self.write(&coll.collation);
13582 }
13583 Ok(())
13584 }
13585
13586 fn generate_case(&mut self, case: &Case) -> Result<()> {
13587 let multiline_case = self.config.pretty
13588 && matches!(self.config.dialect, Some(DialectType::Snowflake));
13589
13590 self.write_keyword("CASE");
13591 if let Some(operand) = &case.operand {
13592 self.write_space();
13593 self.generate_expression(operand)?;
13594 }
13595 if multiline_case {
13596 self.indent_level += 1;
13597 }
13598 for (condition, result) in &case.whens {
13599 if multiline_case {
13600 self.write_newline();
13601 self.write_indent();
13602 } else {
13603 self.write_space();
13604 }
13605 self.write_keyword("WHEN");
13606 self.write_space();
13607 self.generate_expression(condition)?;
13608 if multiline_case {
13609 self.write_newline();
13610 self.write_indent();
13611 } else {
13612 self.write_space();
13613 }
13614 self.write_keyword("THEN");
13615 self.write_space();
13616 self.generate_expression(result)?;
13617 }
13618 if let Some(else_) = &case.else_ {
13619 if multiline_case {
13620 self.write_newline();
13621 self.write_indent();
13622 } else {
13623 self.write_space();
13624 }
13625 self.write_keyword("ELSE");
13626 self.write_space();
13627 self.generate_expression(else_)?;
13628 }
13629 if multiline_case {
13630 self.indent_level -= 1;
13631 self.write_newline();
13632 self.write_indent();
13633 } else {
13634 self.write_space();
13635 }
13636 self.write_keyword("END");
13637 Ok(())
13638 }
13639
13640 fn generate_function(&mut self, func: &Function) -> Result<()> {
13641 let normalized_name = self.normalize_func_name(&func.name);
13643 let upper_name = func.name.to_uppercase();
13644
13645 if upper_name == "STRUCT" && !matches!(self.config.dialect, Some(DialectType::BigQuery) | Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) | None) {
13647 return self.generate_struct_function_cross_dialect(func);
13648 }
13649
13650 if upper_name == "__SS_JSON_PATH_QMARK__" && func.args.len() == 2 {
13653 self.generate_expression(&func.args[0])?;
13654 self.write("::?");
13655 if let Expression::Literal(crate::expressions::Literal::String(key)) = &func.args[1] {
13657 self.write(key);
13658 } else {
13659 self.generate_expression(&func.args[1])?;
13660 }
13661 return Ok(());
13662 }
13663
13664 if upper_name == "__PG_BITWISE_XOR__" && func.args.len() == 2 {
13666 self.generate_expression(&func.args[0])?;
13667 self.write(" # ");
13668 self.generate_expression(&func.args[1])?;
13669 return Ok(());
13670 }
13671
13672 if matches!(
13674 self.config.dialect,
13675 Some(DialectType::Spark | DialectType::Databricks | DialectType::Hive)
13676 ) && upper_name == "TRY"
13677 && func.args.len() == 1
13678 {
13679 self.generate_expression(&func.args[0])?;
13680 return Ok(());
13681 }
13682
13683 if self.config.dialect == Some(DialectType::ClickHouse)
13685 && upper_name == "TOSTARTOFDAY"
13686 && func.args.len() == 1
13687 {
13688 self.write("dateTrunc('DAY', ");
13689 self.generate_expression(&func.args[0])?;
13690 self.write(")");
13691 return Ok(());
13692 }
13693
13694 if self.config.dialect == Some(DialectType::Redshift) && upper_name == "CONCAT" && func.args.len() >= 2 {
13696 for (i, arg) in func.args.iter().enumerate() {
13697 if i > 0 {
13698 self.write(" || ");
13699 }
13700 self.generate_expression(arg)?;
13701 }
13702 return Ok(());
13703 }
13704
13705 if self.config.dialect == Some(DialectType::Redshift) && upper_name == "CONCAT_WS" && func.args.len() >= 2 {
13707 let sep = &func.args[0];
13708 for (i, arg) in func.args.iter().skip(1).enumerate() {
13709 if i > 0 {
13710 self.write(" || ");
13711 self.generate_expression(sep)?;
13712 self.write(" || ");
13713 }
13714 self.generate_expression(arg)?;
13715 }
13716 return Ok(());
13717 }
13718
13719 if self.config.dialect == Some(DialectType::Redshift)
13722 && (upper_name == "DATEDIFF" || upper_name == "DATE_DIFF")
13723 && func.args.len() == 3
13724 {
13725 self.write_keyword("DATEDIFF");
13726 self.write("(");
13727 self.write_redshift_date_part(&func.args[0]);
13729 self.write(", ");
13730 self.generate_expression(&func.args[1])?;
13731 self.write(", ");
13732 self.generate_expression(&func.args[2])?;
13733 self.write(")");
13734 return Ok(());
13735 }
13736
13737 if self.config.dialect == Some(DialectType::Redshift)
13740 && (upper_name == "DATEADD" || upper_name == "DATE_ADD")
13741 && func.args.len() == 3
13742 {
13743 self.write_keyword("DATEADD");
13744 self.write("(");
13745 self.write_redshift_date_part(&func.args[0]);
13747 self.write(", ");
13748 self.generate_expression(&func.args[1])?;
13749 self.write(", ");
13750 self.generate_expression(&func.args[2])?;
13751 self.write(")");
13752 return Ok(());
13753 }
13754
13755 if upper_name == "UUID_STRING" && !matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
13757 let func_name = match self.config.dialect {
13758 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
13759 Some(DialectType::BigQuery) => "GENERATE_UUID",
13760 _ => "UUID",
13761 };
13762 self.write_keyword(func_name);
13763 self.write("()");
13764 return Ok(());
13765 }
13766
13767 if self.config.dialect == Some(DialectType::Redshift)
13770 && upper_name == "DATE_TRUNC"
13771 && func.args.len() == 2
13772 {
13773 self.write_keyword("DATE_TRUNC");
13774 self.write("(");
13775 self.write_redshift_date_part_quoted(&func.args[0]);
13777 self.write(", ");
13778 self.generate_expression(&func.args[1])?;
13779 self.write(")");
13780 return Ok(());
13781 }
13782
13783 if matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric))
13785 && (upper_name == "DATE_PART" || upper_name == "DATEPART")
13786 && func.args.len() == 2
13787 {
13788 self.write_keyword("DATEPART");
13789 self.write("(");
13790 self.generate_expression(&func.args[0])?;
13791 self.write(", ");
13792 self.generate_expression(&func.args[1])?;
13793 self.write(")");
13794 return Ok(());
13795 }
13796
13797 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift))
13799 && (upper_name == "DATE_PART" || upper_name == "DATEPART")
13800 && func.args.len() == 2
13801 {
13802 self.write_keyword("EXTRACT");
13803 self.write("(");
13804 match &func.args[0] {
13806 Expression::Literal(crate::expressions::Literal::String(s)) => {
13807 self.write(&s.to_lowercase());
13808 }
13809 _ => self.generate_expression(&func.args[0])?,
13810 }
13811 self.write_space();
13812 self.write_keyword("FROM");
13813 self.write_space();
13814 self.generate_expression(&func.args[1])?;
13815 self.write(")");
13816 return Ok(());
13817 }
13818
13819 if self.config.dialect == Some(DialectType::Dremio)
13822 && (upper_name == "DATE_PART" || upper_name == "DATEPART")
13823 && func.args.len() == 2
13824 {
13825 self.write_keyword("EXTRACT");
13826 self.write("(");
13827 self.generate_expression(&func.args[0])?;
13828 self.write_space();
13829 self.write_keyword("FROM");
13830 self.write_space();
13831 self.generate_dremio_date_expression(&func.args[1])?;
13833 self.write(")");
13834 return Ok(());
13835 }
13836
13837 if self.config.dialect == Some(DialectType::Dremio)
13839 && upper_name == "CURRENT_DATE_UTC"
13840 && func.args.is_empty()
13841 {
13842 self.write_keyword("CURRENT_DATE_UTC");
13843 return Ok(());
13844 }
13845
13846 if self.config.dialect == Some(DialectType::Dremio)
13850 && upper_name == "DATETYPE"
13851 && func.args.len() == 3
13852 {
13853 fn get_int_literal(expr: &Expression) -> Option<i64> {
13855 if let Expression::Literal(crate::expressions::Literal::Number(s)) = expr {
13856 s.parse::<i64>().ok()
13857 } else {
13858 None
13859 }
13860 }
13861
13862 if let (Some(year), Some(month), Some(day)) = (
13864 get_int_literal(&func.args[0]),
13865 get_int_literal(&func.args[1]),
13866 get_int_literal(&func.args[2]),
13867 ) {
13868 self.write_keyword("DATE");
13870 self.write(&format!("('{:04}-{:02}-{:02}')", year, month, day));
13871 return Ok(());
13872 }
13873
13874 self.write_keyword("CAST");
13876 self.write("(");
13877 self.write_keyword("CONCAT");
13878 self.write("(");
13879 self.generate_expression(&func.args[0])?;
13880 self.write(", '-', ");
13881 self.generate_expression(&func.args[1])?;
13882 self.write(", '-', ");
13883 self.generate_expression(&func.args[2])?;
13884 self.write(")");
13885 self.write_space();
13886 self.write_keyword("AS");
13887 self.write_space();
13888 self.write_keyword("DATE");
13889 self.write(")");
13890 return Ok(());
13891 }
13892
13893 let is_presto_like = matches!(
13896 self.config.dialect,
13897 Some(DialectType::Presto) | Some(DialectType::Trino)
13898 );
13899 if is_presto_like
13900 && upper_name == "DATE_ADD"
13901 && func.args.len() == 3
13902 {
13903 self.write_keyword("DATE_ADD");
13904 self.write("(");
13905 self.generate_expression(&func.args[0])?;
13907 self.write(", ");
13908 let interval = &func.args[1];
13910 let needs_cast = !self.returns_integer_type(interval);
13911 if needs_cast {
13912 self.write_keyword("CAST");
13913 self.write("(");
13914 }
13915 self.generate_expression(interval)?;
13916 if needs_cast {
13917 self.write_space();
13918 self.write_keyword("AS");
13919 self.write_space();
13920 self.write_keyword("BIGINT");
13921 self.write(")");
13922 }
13923 self.write(", ");
13924 self.generate_expression(&func.args[2])?;
13926 self.write(")");
13927 return Ok(());
13928 }
13929
13930 let use_brackets = func.use_bracket_syntax;
13932
13933 let has_ordinality = upper_name.ends_with(" WITH ORDINALITY");
13938 let output_name = if has_ordinality {
13939 let base_name = &func.name[..func.name.len() - " WITH ORDINALITY".len()];
13940 self.normalize_func_name(base_name)
13941 } else {
13942 normalized_name.clone()
13943 };
13944
13945 if func.name.contains('.') && !has_ordinality {
13948 if func.quoted {
13951 self.write("`");
13952 self.write(&func.name);
13953 self.write("`");
13954 } else {
13955 self.write(&func.name);
13956 }
13957 } else {
13958 self.write(&output_name);
13959 }
13960
13961 let force_parens = func.no_parens && func.args.is_empty() && !func.distinct && {
13964 let needs_parens = match upper_name.as_str() {
13965 "CURRENT_USER" | "SESSION_USER" | "SYSTEM_USER" => matches!(
13966 self.config.dialect,
13967 Some(DialectType::Snowflake) | Some(DialectType::Spark)
13968 | Some(DialectType::Databricks) | Some(DialectType::Hive)
13969 ),
13970 _ => false,
13971 };
13972 !needs_parens
13973 };
13974 if force_parens {
13975 for comment in &func.trailing_comments {
13977 self.write_space();
13978 self.write(comment);
13979 }
13980 return Ok(());
13981 }
13982
13983 if upper_name == "CUBE" || upper_name == "ROLLUP" || upper_name == "GROUPING SETS" {
13985 self.write(" (");
13986 } else if use_brackets {
13987 self.write("[");
13988 } else {
13989 self.write("(");
13990 }
13991 if func.distinct {
13992 self.write_keyword("DISTINCT");
13993 self.write_space();
13994 }
13995
13996 let compact_pretty_func = matches!(self.config.dialect, Some(DialectType::Snowflake))
13998 && (upper_name == "TABLE" || upper_name == "FLATTEN");
13999 let should_split = if self.config.pretty && !func.args.is_empty() && !compact_pretty_func {
14000 let mut expr_strings: Vec<String> = Vec::with_capacity(func.args.len());
14002 for arg in &func.args {
14003 let mut temp_gen = Generator::with_config(self.config.clone());
14004 temp_gen.config.pretty = false; temp_gen.generate_expression(arg)?;
14006 expr_strings.push(temp_gen.output);
14007 }
14008 self.too_wide(&expr_strings)
14009 } else {
14010 false
14011 };
14012
14013 if should_split {
14014 self.write_newline();
14016 self.indent_level += 1;
14017 for (i, arg) in func.args.iter().enumerate() {
14018 self.write_indent();
14019 self.generate_expression(arg)?;
14020 if i + 1 < func.args.len() {
14021 self.write(",");
14022 }
14023 self.write_newline();
14024 }
14025 self.indent_level -= 1;
14026 self.write_indent();
14027 } else {
14028 for (i, arg) in func.args.iter().enumerate() {
14030 if i > 0 {
14031 self.write(", ");
14032 }
14033 self.generate_expression(arg)?;
14034 }
14035 }
14036
14037 if use_brackets {
14038 self.write("]");
14039 } else {
14040 self.write(")");
14041 }
14042 if has_ordinality {
14044 self.write_space();
14045 self.write_keyword("WITH ORDINALITY");
14046 }
14047 for comment in &func.trailing_comments {
14049 self.write_space();
14050 self.write(comment);
14051 }
14052 Ok(())
14053 }
14054
14055 fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> {
14056 let mut normalized_name = self.normalize_func_name(&func.name);
14058
14059 let upper = normalized_name.to_uppercase();
14061 if upper == "MAX_BY" || upper == "MIN_BY" {
14062 let is_max = upper == "MAX_BY";
14063 match self.config.dialect {
14064 Some(DialectType::ClickHouse) => {
14065 normalized_name = if is_max { "argMax".to_string() } else { "argMin".to_string() };
14066 }
14067 Some(DialectType::DuckDB) => {
14068 normalized_name = if is_max { "ARG_MAX".to_string() } else { "ARG_MIN".to_string() };
14069 }
14070 _ => {}
14071 }
14072 }
14073 self.write(&normalized_name);
14074 self.write("(");
14075 if func.distinct {
14076 self.write_keyword("DISTINCT");
14077 self.write_space();
14078 }
14079
14080 let is_count = normalized_name.eq_ignore_ascii_case("COUNT");
14084 let needs_multi_arg_transform = func.distinct
14085 && is_count
14086 && func.args.len() > 1
14087 && !self.config.multi_arg_distinct;
14088
14089 if needs_multi_arg_transform {
14090 self.write_keyword("CASE");
14092 for arg in &func.args {
14093 self.write_space();
14094 self.write_keyword("WHEN");
14095 self.write_space();
14096 self.generate_expression(arg)?;
14097 self.write_space();
14098 self.write_keyword("IS NULL THEN NULL");
14099 }
14100 self.write_space();
14101 self.write_keyword("ELSE");
14102 self.write(" (");
14103 for (i, arg) in func.args.iter().enumerate() {
14104 if i > 0 {
14105 self.write(", ");
14106 }
14107 self.generate_expression(arg)?;
14108 }
14109 self.write(")");
14110 self.write_space();
14111 self.write_keyword("END");
14112 } else {
14113 for (i, arg) in func.args.iter().enumerate() {
14114 if i > 0 {
14115 self.write(", ");
14116 }
14117 self.generate_expression(arg)?;
14118 }
14119 }
14120
14121 if self.config.ignore_nulls_in_func && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
14123 if let Some(ignore) = func.ignore_nulls {
14124 self.write_space();
14125 if ignore {
14126 self.write_keyword("IGNORE NULLS");
14127 } else {
14128 self.write_keyword("RESPECT NULLS");
14129 }
14130 }
14131 }
14132
14133 if !func.order_by.is_empty() {
14135 self.write_space();
14136 self.write_keyword("ORDER BY");
14137 self.write_space();
14138 for (i, ord) in func.order_by.iter().enumerate() {
14139 if i > 0 {
14140 self.write(", ");
14141 }
14142 self.generate_ordered(ord)?;
14143 }
14144 }
14145
14146 if let Some(limit) = &func.limit {
14148 self.write_space();
14149 self.write_keyword("LIMIT");
14150 self.write_space();
14151 if let Expression::Tuple(t) = limit.as_ref() {
14153 if t.expressions.len() == 2 {
14154 self.generate_expression(&t.expressions[0])?;
14155 self.write(", ");
14156 self.generate_expression(&t.expressions[1])?;
14157 } else {
14158 self.generate_expression(limit)?;
14159 }
14160 } else {
14161 self.generate_expression(limit)?;
14162 }
14163 }
14164
14165 self.write(")");
14166
14167 if !self.config.ignore_nulls_in_func && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
14169 if let Some(ignore) = func.ignore_nulls {
14170 self.write_space();
14171 if ignore {
14172 self.write_keyword("IGNORE NULLS");
14173 } else {
14174 self.write_keyword("RESPECT NULLS");
14175 }
14176 }
14177 }
14178
14179 if let Some(filter) = &func.filter {
14180 self.write_space();
14181 self.write_keyword("FILTER");
14182 self.write("(");
14183 self.write_keyword("WHERE");
14184 self.write_space();
14185 self.generate_expression(filter)?;
14186 self.write(")");
14187 }
14188
14189 Ok(())
14190 }
14191
14192 fn generate_window_function(&mut self, wf: &WindowFunction) -> Result<()> {
14193 self.generate_expression(&wf.this)?;
14194
14195 if let Some(keep) = &wf.keep {
14197 self.write_space();
14198 self.write_keyword("KEEP");
14199 self.write(" (");
14200 self.write_keyword("DENSE_RANK");
14201 self.write_space();
14202 if keep.first {
14203 self.write_keyword("FIRST");
14204 } else {
14205 self.write_keyword("LAST");
14206 }
14207 self.write_space();
14208 self.write_keyword("ORDER BY");
14209 self.write_space();
14210 for (i, ord) in keep.order_by.iter().enumerate() {
14211 if i > 0 {
14212 self.write(", ");
14213 }
14214 self.generate_ordered(ord)?;
14215 }
14216 self.write(")");
14217 }
14218
14219 let has_over = !wf.over.partition_by.is_empty()
14221 || !wf.over.order_by.is_empty()
14222 || wf.over.frame.is_some()
14223 || wf.over.window_name.is_some();
14224
14225 if has_over {
14227 self.write_space();
14228 self.write_keyword("OVER");
14229
14230 let has_specs = !wf.over.partition_by.is_empty()
14232 || !wf.over.order_by.is_empty()
14233 || wf.over.frame.is_some();
14234
14235 if wf.over.window_name.is_some() && !has_specs {
14236 self.write_space();
14238 self.write(&wf.over.window_name.as_ref().unwrap().name);
14239 } else {
14240 self.write(" (");
14242 self.generate_over(&wf.over)?;
14243 self.write(")");
14244 }
14245 } else if wf.keep.is_none() {
14246 self.write_space();
14248 self.write_keyword("OVER");
14249 self.write(" ()");
14250 }
14251
14252 Ok(())
14253 }
14254
14255 fn generate_within_group(&mut self, wg: &WithinGroup) -> Result<()> {
14257 self.generate_expression(&wg.this)?;
14258 self.write_space();
14259 self.write_keyword("WITHIN GROUP");
14260 self.write(" (");
14261 self.write_keyword("ORDER BY");
14262 self.write_space();
14263 for (i, ord) in wg.order_by.iter().enumerate() {
14264 if i > 0 {
14265 self.write(", ");
14266 }
14267 self.generate_ordered(ord)?;
14268 }
14269 self.write(")");
14270 Ok(())
14271 }
14272
14273 fn generate_over(&mut self, over: &Over) -> Result<()> {
14275 let mut has_content = false;
14276
14277 if let Some(name) = &over.window_name {
14279 self.write(&name.name);
14280 has_content = true;
14281 }
14282
14283 if !over.partition_by.is_empty() {
14285 if has_content {
14286 self.write_space();
14287 }
14288 self.write_keyword("PARTITION BY");
14289 self.write_space();
14290 for (i, expr) in over.partition_by.iter().enumerate() {
14291 if i > 0 {
14292 self.write(", ");
14293 }
14294 self.generate_expression(expr)?;
14295 }
14296 has_content = true;
14297 }
14298
14299 if !over.order_by.is_empty() {
14301 if has_content {
14302 self.write_space();
14303 }
14304 self.write_keyword("ORDER BY");
14305 self.write_space();
14306 for (i, ordered) in over.order_by.iter().enumerate() {
14307 if i > 0 {
14308 self.write(", ");
14309 }
14310 self.generate_ordered(ordered)?;
14311 }
14312 has_content = true;
14313 }
14314
14315 if let Some(frame) = &over.frame {
14317 if has_content {
14318 self.write_space();
14319 }
14320 self.generate_window_frame(frame)?;
14321 }
14322
14323 Ok(())
14324 }
14325
14326 fn generate_window_frame(&mut self, frame: &WindowFrame) -> Result<()> {
14327 let lowercase_frame = self.config.lowercase_window_frame_keywords;
14329
14330 if !lowercase_frame {
14332 if let Some(kind_text) = &frame.kind_text {
14333 self.write(kind_text);
14334 } else {
14335 match frame.kind {
14336 WindowFrameKind::Rows => self.write_keyword("ROWS"),
14337 WindowFrameKind::Range => self.write_keyword("RANGE"),
14338 WindowFrameKind::Groups => self.write_keyword("GROUPS"),
14339 }
14340 }
14341 } else {
14342 match frame.kind {
14343 WindowFrameKind::Rows => self.write("rows"),
14344 WindowFrameKind::Range => self.write("range"),
14345 WindowFrameKind::Groups => self.write("groups"),
14346 }
14347 }
14348
14349 self.write_space();
14352 let should_normalize = self.config.normalize_window_frame_between
14353 && frame.end.is_none()
14354 && matches!(
14355 frame.start,
14356 WindowFrameBound::Preceding(_)
14357 | WindowFrameBound::Following(_)
14358 | WindowFrameBound::UnboundedPreceding
14359 | WindowFrameBound::UnboundedFollowing
14360 );
14361
14362 if let Some(end) = &frame.end {
14363 self.write_keyword("BETWEEN");
14365 self.write_space();
14366 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
14367 self.write_space();
14368 self.write_keyword("AND");
14369 self.write_space();
14370 self.generate_window_frame_bound(end, frame.end_side_text.as_deref())?;
14371 } else if should_normalize {
14372 self.write_keyword("BETWEEN");
14374 self.write_space();
14375 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
14376 self.write_space();
14377 self.write_keyword("AND");
14378 self.write_space();
14379 self.write_keyword("CURRENT ROW");
14380 } else {
14381 self.generate_window_frame_bound(&frame.start, frame.start_side_text.as_deref())?;
14383 }
14384
14385 if let Some(exclude) = &frame.exclude {
14387 self.write_space();
14388 self.write_keyword("EXCLUDE");
14389 self.write_space();
14390 match exclude {
14391 WindowFrameExclude::CurrentRow => self.write_keyword("CURRENT ROW"),
14392 WindowFrameExclude::Group => self.write_keyword("GROUP"),
14393 WindowFrameExclude::Ties => self.write_keyword("TIES"),
14394 WindowFrameExclude::NoOthers => self.write_keyword("NO OTHERS"),
14395 }
14396 }
14397
14398 Ok(())
14399 }
14400
14401 fn generate_window_frame_bound(&mut self, bound: &WindowFrameBound, side_text: Option<&str>) -> Result<()> {
14402 let lowercase_frame = self.config.lowercase_window_frame_keywords;
14404
14405 match bound {
14406 WindowFrameBound::CurrentRow => {
14407 self.write_keyword("CURRENT ROW");
14408 }
14409 WindowFrameBound::UnboundedPreceding => {
14410 self.write_keyword("UNBOUNDED");
14411 self.write_space();
14412 if lowercase_frame {
14413 self.write("preceding");
14414 } else if let Some(text) = side_text {
14415 self.write(text);
14416 } else {
14417 self.write_keyword("PRECEDING");
14418 }
14419 }
14420 WindowFrameBound::UnboundedFollowing => {
14421 self.write_keyword("UNBOUNDED");
14422 self.write_space();
14423 if lowercase_frame {
14424 self.write("following");
14425 } else if let Some(text) = side_text {
14426 self.write(text);
14427 } else {
14428 self.write_keyword("FOLLOWING");
14429 }
14430 }
14431 WindowFrameBound::Preceding(expr) => {
14432 self.generate_expression(expr)?;
14433 self.write_space();
14434 if lowercase_frame {
14435 self.write("preceding");
14436 } else if let Some(text) = side_text {
14437 self.write(text);
14438 } else {
14439 self.write_keyword("PRECEDING");
14440 }
14441 }
14442 WindowFrameBound::Following(expr) => {
14443 self.generate_expression(expr)?;
14444 self.write_space();
14445 if lowercase_frame {
14446 self.write("following");
14447 } else if let Some(text) = side_text {
14448 self.write(text);
14449 } else {
14450 self.write_keyword("FOLLOWING");
14451 }
14452 }
14453 WindowFrameBound::BarePreceding => {
14454 if lowercase_frame {
14455 self.write("preceding");
14456 } else if let Some(text) = side_text {
14457 self.write(text);
14458 } else {
14459 self.write_keyword("PRECEDING");
14460 }
14461 }
14462 WindowFrameBound::BareFollowing => {
14463 if lowercase_frame {
14464 self.write("following");
14465 } else if let Some(text) = side_text {
14466 self.write(text);
14467 } else {
14468 self.write_keyword("FOLLOWING");
14469 }
14470 }
14471 WindowFrameBound::Value(expr) => {
14472 self.generate_expression(expr)?;
14474 }
14475 }
14476 Ok(())
14477 }
14478
14479 fn generate_interval(&mut self, interval: &Interval) -> Result<()> {
14480 let skip_interval_keyword = matches!(self.config.dialect, Some(DialectType::Oracle))
14483 && matches!(&interval.unit, Some(IntervalUnitSpec::ExprSpan(_)))
14484 && !matches!(&interval.this, Some(Expression::Literal(_)));
14485
14486 if !skip_interval_keyword {
14487 self.write_keyword("INTERVAL");
14488 }
14489
14490 if let Some(ref value) = interval.this {
14492 if !skip_interval_keyword {
14493 self.write_space();
14494 }
14495 let needs_parens = interval.unit.is_some() && matches!(value,
14499 Expression::Add(_) | Expression::Sub(_) | Expression::Mul(_) |
14500 Expression::Div(_) | Expression::Mod(_) | Expression::BitwiseAnd(_) |
14501 Expression::BitwiseOr(_) | Expression::BitwiseXor(_)
14502 );
14503 if needs_parens {
14504 self.write("(");
14505 }
14506 self.generate_expression(value)?;
14507 if needs_parens {
14508 self.write(")");
14509 }
14510 }
14511
14512 if let Some(ref unit_spec) = interval.unit {
14514 self.write_space();
14515 self.write_interval_unit_spec(unit_spec)?;
14516 }
14517
14518 Ok(())
14519 }
14520
14521 fn write_interval_unit_spec(&mut self, unit_spec: &IntervalUnitSpec) -> Result<()> {
14522 match unit_spec {
14523 IntervalUnitSpec::Simple { unit, use_plural } => {
14524 let effective_plural = *use_plural && self.config.interval_allows_plural_form;
14526 self.write_simple_interval_unit(unit, effective_plural);
14527 }
14528 IntervalUnitSpec::Span(span) => {
14529 self.write_simple_interval_unit(&span.this, false);
14530 self.write_space();
14531 self.write_keyword("TO");
14532 self.write_space();
14533 self.write_simple_interval_unit(&span.expression, false);
14534 }
14535 IntervalUnitSpec::ExprSpan(span) => {
14536 self.generate_expression(&span.this)?;
14538 self.write_space();
14539 self.write_keyword("TO");
14540 self.write_space();
14541 self.generate_expression(&span.expression)?;
14542 }
14543 IntervalUnitSpec::Expr(expr) => {
14544 self.generate_expression(expr)?;
14545 }
14546 }
14547 Ok(())
14548 }
14549
14550 fn write_simple_interval_unit(&mut self, unit: &IntervalUnit, use_plural: bool) {
14551 match (unit, use_plural) {
14553 (IntervalUnit::Year, false) => self.write_keyword("YEAR"),
14554 (IntervalUnit::Year, true) => self.write_keyword("YEARS"),
14555 (IntervalUnit::Quarter, false) => self.write_keyword("QUARTER"),
14556 (IntervalUnit::Quarter, true) => self.write_keyword("QUARTERS"),
14557 (IntervalUnit::Month, false) => self.write_keyword("MONTH"),
14558 (IntervalUnit::Month, true) => self.write_keyword("MONTHS"),
14559 (IntervalUnit::Week, false) => self.write_keyword("WEEK"),
14560 (IntervalUnit::Week, true) => self.write_keyword("WEEKS"),
14561 (IntervalUnit::Day, false) => self.write_keyword("DAY"),
14562 (IntervalUnit::Day, true) => self.write_keyword("DAYS"),
14563 (IntervalUnit::Hour, false) => self.write_keyword("HOUR"),
14564 (IntervalUnit::Hour, true) => self.write_keyword("HOURS"),
14565 (IntervalUnit::Minute, false) => self.write_keyword("MINUTE"),
14566 (IntervalUnit::Minute, true) => self.write_keyword("MINUTES"),
14567 (IntervalUnit::Second, false) => self.write_keyword("SECOND"),
14568 (IntervalUnit::Second, true) => self.write_keyword("SECONDS"),
14569 (IntervalUnit::Millisecond, false) => self.write_keyword("MILLISECOND"),
14570 (IntervalUnit::Millisecond, true) => self.write_keyword("MILLISECONDS"),
14571 (IntervalUnit::Microsecond, false) => self.write_keyword("MICROSECOND"),
14572 (IntervalUnit::Microsecond, true) => self.write_keyword("MICROSECONDS"),
14573 }
14574 }
14575
14576 fn write_redshift_date_part(&mut self, expr: &Expression) {
14579 let part_str = self.extract_date_part_string(expr);
14580 if let Some(part) = part_str {
14581 let normalized = self.normalize_date_part(&part);
14582 self.write_keyword(&normalized);
14583 } else {
14584 let _ = self.generate_expression(expr);
14586 }
14587 }
14588
14589 fn write_redshift_date_part_quoted(&mut self, expr: &Expression) {
14592 let part_str = self.extract_date_part_string(expr);
14593 if let Some(part) = part_str {
14594 let normalized = self.normalize_date_part(&part);
14595 self.write("'");
14596 self.write(&normalized);
14597 self.write("'");
14598 } else {
14599 let _ = self.generate_expression(expr);
14601 }
14602 }
14603
14604 fn extract_date_part_string(&self, expr: &Expression) -> Option<String> {
14606 match expr {
14607 Expression::Literal(crate::expressions::Literal::String(s)) => Some(s.clone()),
14608 Expression::Identifier(id) => Some(id.name.clone()),
14609 Expression::Column(col) if col.table.is_none() => {
14610 Some(col.name.name.clone())
14612 }
14613 _ => None,
14614 }
14615 }
14616
14617 fn normalize_date_part(&self, part: &str) -> String {
14620 let lower = part.to_lowercase();
14621 match lower.as_str() {
14622 "day" | "days" | "d" => "DAY".to_string(),
14623 "month" | "months" | "mon" | "mm" => "MONTH".to_string(),
14624 "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
14625 "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
14626 "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
14627 "minute" | "minutes" | "m" | "mi" | "n" => "MINUTE".to_string(),
14628 "second" | "seconds" | "s" | "ss" => "SECOND".to_string(),
14629 "millisecond" | "milliseconds" | "ms" => "MILLISECOND".to_string(),
14630 "microsecond" | "microseconds" | "us" => "MICROSECOND".to_string(),
14631 "quarter" | "quarters" | "q" | "qq" => "QUARTER".to_string(),
14632 _ => part.to_uppercase(),
14633 }
14634 }
14635
14636 fn write_datetime_field(&mut self, field: &DateTimeField) {
14637 match field {
14638 DateTimeField::Year => self.write_keyword("YEAR"),
14639 DateTimeField::Month => self.write_keyword("MONTH"),
14640 DateTimeField::Day => self.write_keyword("DAY"),
14641 DateTimeField::Hour => self.write_keyword("HOUR"),
14642 DateTimeField::Minute => self.write_keyword("MINUTE"),
14643 DateTimeField::Second => self.write_keyword("SECOND"),
14644 DateTimeField::Millisecond => self.write_keyword("MILLISECOND"),
14645 DateTimeField::Microsecond => self.write_keyword("MICROSECOND"),
14646 DateTimeField::DayOfWeek => {
14647 let name = match self.config.dialect {
14648 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFWEEK",
14649 _ => "DOW",
14650 };
14651 self.write_keyword(name);
14652 }
14653 DateTimeField::DayOfYear => {
14654 let name = match self.config.dialect {
14655 Some(DialectType::DuckDB) | Some(DialectType::Snowflake) => "DAYOFYEAR",
14656 _ => "DOY",
14657 };
14658 self.write_keyword(name);
14659 }
14660 DateTimeField::Week => self.write_keyword("WEEK"),
14661 DateTimeField::WeekWithModifier(modifier) => {
14662 self.write_keyword("WEEK");
14663 self.write("(");
14664 self.write(modifier);
14665 self.write(")");
14666 }
14667 DateTimeField::Quarter => self.write_keyword("QUARTER"),
14668 DateTimeField::Epoch => self.write_keyword("EPOCH"),
14669 DateTimeField::Timezone => self.write_keyword("TIMEZONE"),
14670 DateTimeField::TimezoneHour => self.write_keyword("TIMEZONE_HOUR"),
14671 DateTimeField::TimezoneMinute => self.write_keyword("TIMEZONE_MINUTE"),
14672 DateTimeField::Date => self.write_keyword("DATE"),
14673 DateTimeField::Time => self.write_keyword("TIME"),
14674 DateTimeField::Custom(name) => self.write(name),
14675 }
14676 }
14677
14678 fn write_datetime_field_lower(&mut self, field: &DateTimeField) {
14680 match field {
14681 DateTimeField::Year => self.write("year"),
14682 DateTimeField::Month => self.write("month"),
14683 DateTimeField::Day => self.write("day"),
14684 DateTimeField::Hour => self.write("hour"),
14685 DateTimeField::Minute => self.write("minute"),
14686 DateTimeField::Second => self.write("second"),
14687 DateTimeField::Millisecond => self.write("millisecond"),
14688 DateTimeField::Microsecond => self.write("microsecond"),
14689 DateTimeField::DayOfWeek => self.write("dow"),
14690 DateTimeField::DayOfYear => self.write("doy"),
14691 DateTimeField::Week => self.write("week"),
14692 DateTimeField::WeekWithModifier(modifier) => {
14693 self.write("week(");
14694 self.write(modifier);
14695 self.write(")");
14696 }
14697 DateTimeField::Quarter => self.write("quarter"),
14698 DateTimeField::Epoch => self.write("epoch"),
14699 DateTimeField::Timezone => self.write("timezone"),
14700 DateTimeField::TimezoneHour => self.write("timezone_hour"),
14701 DateTimeField::TimezoneMinute => self.write("timezone_minute"),
14702 DateTimeField::Date => self.write("date"),
14703 DateTimeField::Time => self.write("time"),
14704 DateTimeField::Custom(name) => self.write(name),
14705 }
14706 }
14707
14708 fn generate_simple_func(&mut self, name: &str, arg: &Expression) -> Result<()> {
14711 self.write_keyword(name);
14712 self.write("(");
14713 self.generate_expression(arg)?;
14714 self.write(")");
14715 Ok(())
14716 }
14717
14718 fn generate_unary_func(&mut self, default_name: &str, f: &crate::expressions::UnaryFunc) -> Result<()> {
14720 let name = f.original_name.as_deref().unwrap_or(default_name);
14721 self.write_keyword(name);
14722 self.write("(");
14723 self.generate_expression(&f.this)?;
14724 self.write(")");
14725 Ok(())
14726 }
14727
14728 fn generate_sqrt_cbrt(&mut self, f: &crate::expressions::UnaryFunc, func_name: &str, _op: &str) -> Result<()> {
14730 self.write_keyword(func_name);
14733 self.write("(");
14734 self.generate_expression(&f.this)?;
14735 self.write(")");
14736 Ok(())
14737 }
14738
14739 fn generate_binary_func(&mut self, name: &str, arg1: &Expression, arg2: &Expression) -> Result<()> {
14740 self.write_keyword(name);
14741 self.write("(");
14742 self.generate_expression(arg1)?;
14743 self.write(", ");
14744 self.generate_expression(arg2)?;
14745 self.write(")");
14746 Ok(())
14747 }
14748
14749 fn generate_char_func(&mut self, f: &crate::expressions::CharFunc) -> Result<()> {
14753 let func_name = f.name.as_deref().unwrap_or("CHAR");
14755 self.write_keyword(func_name);
14756 self.write("(");
14757 for (i, arg) in f.args.iter().enumerate() {
14758 if i > 0 {
14759 self.write(", ");
14760 }
14761 self.generate_expression(arg)?;
14762 }
14763 if let Some(ref charset) = f.charset {
14764 self.write(" ");
14765 self.write_keyword("USING");
14766 self.write(" ");
14767 self.write(charset);
14768 }
14769 self.write(")");
14770 Ok(())
14771 }
14772
14773 fn generate_power(&mut self, f: &BinaryFunc) -> Result<()> {
14774 use crate::dialects::DialectType;
14775
14776 match self.config.dialect {
14777 Some(DialectType::Teradata) => {
14778 self.generate_expression(&f.this)?;
14780 self.write(" ** ");
14781 self.generate_expression(&f.expression)?;
14782 Ok(())
14783 }
14784 _ => {
14785 self.generate_binary_func("POWER", &f.this, &f.expression)
14787 }
14788 }
14789 }
14790
14791 fn generate_vararg_func(&mut self, name: &str, args: &[Expression]) -> Result<()> {
14792 self.write_keyword(name);
14793 self.write("(");
14794 for (i, arg) in args.iter().enumerate() {
14795 if i > 0 {
14796 self.write(", ");
14797 }
14798 self.generate_expression(arg)?;
14799 }
14800 self.write(")");
14801 Ok(())
14802 }
14803
14804 fn generate_concat_ws(&mut self, f: &ConcatWs) -> Result<()> {
14807 self.write_keyword("CONCAT_WS");
14808 self.write("(");
14809 self.generate_expression(&f.separator)?;
14810 for expr in &f.expressions {
14811 self.write(", ");
14812 self.generate_expression(expr)?;
14813 }
14814 self.write(")");
14815 Ok(())
14816 }
14817
14818 fn generate_substring(&mut self, f: &SubstringFunc) -> Result<()> {
14819 self.write_keyword("SUBSTRING");
14820 self.write("(");
14821 self.generate_expression(&f.this)?;
14822 let use_comma_syntax = matches!(
14824 self.config.dialect,
14825 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
14826 );
14827 if f.from_for_syntax && !use_comma_syntax {
14828 self.write_space();
14830 self.write_keyword("FROM");
14831 self.write_space();
14832 self.generate_expression(&f.start)?;
14833 if let Some(length) = &f.length {
14834 self.write_space();
14835 self.write_keyword("FOR");
14836 self.write_space();
14837 self.generate_expression(length)?;
14838 }
14839 } else {
14840 self.write(", ");
14842 self.generate_expression(&f.start)?;
14843 if let Some(length) = &f.length {
14844 self.write(", ");
14845 self.generate_expression(length)?;
14846 }
14847 }
14848 self.write(")");
14849 Ok(())
14850 }
14851
14852 fn generate_overlay(&mut self, f: &OverlayFunc) -> Result<()> {
14853 self.write_keyword("OVERLAY");
14854 self.write("(");
14855 self.generate_expression(&f.this)?;
14856 self.write_space();
14857 self.write_keyword("PLACING");
14858 self.write_space();
14859 self.generate_expression(&f.replacement)?;
14860 self.write_space();
14861 self.write_keyword("FROM");
14862 self.write_space();
14863 self.generate_expression(&f.from)?;
14864 if let Some(length) = &f.length {
14865 self.write_space();
14866 self.write_keyword("FOR");
14867 self.write_space();
14868 self.generate_expression(length)?;
14869 }
14870 self.write(")");
14871 Ok(())
14872 }
14873
14874 fn generate_trim(&mut self, f: &TrimFunc) -> Result<()> {
14875 if f.position_explicit && f.characters.is_none() {
14878 match f.position {
14879 TrimPosition::Leading => {
14880 self.write_keyword("LTRIM");
14881 self.write("(");
14882 self.generate_expression(&f.this)?;
14883 self.write(")");
14884 return Ok(());
14885 }
14886 TrimPosition::Trailing => {
14887 self.write_keyword("RTRIM");
14888 self.write("(");
14889 self.generate_expression(&f.this)?;
14890 self.write(")");
14891 return Ok(());
14892 }
14893 TrimPosition::Both => {
14894 }
14897 }
14898 }
14899
14900 self.write_keyword("TRIM");
14901 self.write("(");
14902 let use_standard = f.sql_standard_syntax
14904 && !(f.position_explicit && f.characters.is_none() && matches!(f.position, TrimPosition::Both));
14905 if use_standard {
14906 if f.position_explicit {
14909 match f.position {
14910 TrimPosition::Both => self.write_keyword("BOTH"),
14911 TrimPosition::Leading => self.write_keyword("LEADING"),
14912 TrimPosition::Trailing => self.write_keyword("TRAILING"),
14913 }
14914 self.write_space();
14915 }
14916 if let Some(chars) = &f.characters {
14917 self.generate_expression(chars)?;
14918 self.write_space();
14919 }
14920 self.write_keyword("FROM");
14921 self.write_space();
14922 self.generate_expression(&f.this)?;
14923 } else {
14924 self.generate_expression(&f.this)?;
14926 if let Some(chars) = &f.characters {
14927 self.write(", ");
14928 self.generate_expression(chars)?;
14929 }
14930 }
14931 self.write(")");
14932 Ok(())
14933 }
14934
14935 fn generate_replace(&mut self, f: &ReplaceFunc) -> Result<()> {
14936 self.write_keyword("REPLACE");
14937 self.write("(");
14938 self.generate_expression(&f.this)?;
14939 self.write(", ");
14940 self.generate_expression(&f.old)?;
14941 self.write(", ");
14942 self.generate_expression(&f.new)?;
14943 self.write(")");
14944 Ok(())
14945 }
14946
14947 fn generate_left_right(&mut self, name: &str, f: &LeftRightFunc) -> Result<()> {
14948 self.write_keyword(name);
14949 self.write("(");
14950 self.generate_expression(&f.this)?;
14951 self.write(", ");
14952 self.generate_expression(&f.length)?;
14953 self.write(")");
14954 Ok(())
14955 }
14956
14957 fn generate_repeat(&mut self, f: &RepeatFunc) -> Result<()> {
14958 self.write_keyword("REPEAT");
14959 self.write("(");
14960 self.generate_expression(&f.this)?;
14961 self.write(", ");
14962 self.generate_expression(&f.times)?;
14963 self.write(")");
14964 Ok(())
14965 }
14966
14967 fn generate_pad(&mut self, name: &str, f: &PadFunc) -> Result<()> {
14968 self.write_keyword(name);
14969 self.write("(");
14970 self.generate_expression(&f.this)?;
14971 self.write(", ");
14972 self.generate_expression(&f.length)?;
14973 if let Some(fill) = &f.fill {
14974 self.write(", ");
14975 self.generate_expression(fill)?;
14976 }
14977 self.write(")");
14978 Ok(())
14979 }
14980
14981 fn generate_split(&mut self, f: &SplitFunc) -> Result<()> {
14982 self.write_keyword("SPLIT");
14983 self.write("(");
14984 self.generate_expression(&f.this)?;
14985 self.write(", ");
14986 self.generate_expression(&f.delimiter)?;
14987 self.write(")");
14988 Ok(())
14989 }
14990
14991 fn generate_regexp_like(&mut self, f: &RegexpFunc) -> Result<()> {
14992 use crate::dialects::DialectType;
14993 if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) && f.flags.is_none() {
14995 self.generate_expression(&f.this)?;
14996 self.write(" ~ ");
14997 self.generate_expression(&f.pattern)?;
14998 } else if matches!(self.config.dialect, Some(DialectType::SingleStore) | Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)) && f.flags.is_none() {
14999 self.generate_expression(&f.this)?;
15001 self.write_keyword(" RLIKE ");
15002 self.generate_expression(&f.pattern)?;
15003 } else if matches!(self.config.dialect, Some(DialectType::StarRocks)) {
15004 self.write_keyword("REGEXP");
15006 self.write("(");
15007 self.generate_expression(&f.this)?;
15008 self.write(", ");
15009 self.generate_expression(&f.pattern)?;
15010 if let Some(flags) = &f.flags {
15011 self.write(", ");
15012 self.generate_expression(flags)?;
15013 }
15014 self.write(")");
15015 } else {
15016 self.write_keyword("REGEXP_LIKE");
15017 self.write("(");
15018 self.generate_expression(&f.this)?;
15019 self.write(", ");
15020 self.generate_expression(&f.pattern)?;
15021 if let Some(flags) = &f.flags {
15022 self.write(", ");
15023 self.generate_expression(flags)?;
15024 }
15025 self.write(")");
15026 }
15027 Ok(())
15028 }
15029
15030 fn generate_regexp_replace(&mut self, f: &RegexpReplaceFunc) -> Result<()> {
15031 self.write_keyword("REGEXP_REPLACE");
15032 self.write("(");
15033 self.generate_expression(&f.this)?;
15034 self.write(", ");
15035 self.generate_expression(&f.pattern)?;
15036 self.write(", ");
15037 self.generate_expression(&f.replacement)?;
15038 if let Some(flags) = &f.flags {
15039 self.write(", ");
15040 self.generate_expression(flags)?;
15041 }
15042 self.write(")");
15043 Ok(())
15044 }
15045
15046 fn generate_regexp_extract(&mut self, f: &RegexpExtractFunc) -> Result<()> {
15047 self.write_keyword("REGEXP_EXTRACT");
15048 self.write("(");
15049 self.generate_expression(&f.this)?;
15050 self.write(", ");
15051 self.generate_expression(&f.pattern)?;
15052 if let Some(group) = &f.group {
15053 self.write(", ");
15054 self.generate_expression(group)?;
15055 }
15056 self.write(")");
15057 Ok(())
15058 }
15059
15060 fn generate_round(&mut self, f: &RoundFunc) -> Result<()> {
15063 self.write_keyword("ROUND");
15064 self.write("(");
15065 self.generate_expression(&f.this)?;
15066 if let Some(decimals) = &f.decimals {
15067 self.write(", ");
15068 self.generate_expression(decimals)?;
15069 }
15070 self.write(")");
15071 Ok(())
15072 }
15073
15074 fn generate_floor(&mut self, f: &FloorFunc) -> Result<()> {
15075 self.write_keyword("FLOOR");
15076 self.write("(");
15077 self.generate_expression(&f.this)?;
15078 if let Some(to) = &f.to {
15080 self.write(" ");
15081 self.write_keyword("TO");
15082 self.write(" ");
15083 self.generate_expression(to)?;
15084 } else if let Some(scale) = &f.scale {
15085 self.write(", ");
15086 self.generate_expression(scale)?;
15087 }
15088 self.write(")");
15089 Ok(())
15090 }
15091
15092 fn generate_ceil(&mut self, f: &CeilFunc) -> Result<()> {
15093 self.write_keyword("CEIL");
15094 self.write("(");
15095 self.generate_expression(&f.this)?;
15096 if let Some(to) = &f.to {
15098 self.write(" ");
15099 self.write_keyword("TO");
15100 self.write(" ");
15101 self.generate_expression(to)?;
15102 } else if let Some(decimals) = &f.decimals {
15103 self.write(", ");
15104 self.generate_expression(decimals)?;
15105 }
15106 self.write(")");
15107 Ok(())
15108 }
15109
15110 fn generate_log(&mut self, f: &LogFunc) -> Result<()> {
15111 self.write_keyword("LOG");
15112 self.write("(");
15113 if let Some(base) = &f.base {
15114 self.generate_expression(base)?;
15115 self.write(", ");
15116 }
15117 self.generate_expression(&f.this)?;
15118 self.write(")");
15119 Ok(())
15120 }
15121
15122 fn generate_current_time(&mut self, f: &CurrentTime) -> Result<()> {
15125 self.write_keyword("CURRENT_TIME");
15126 if let Some(precision) = f.precision {
15127 self.write(&format!("({})", precision));
15128 }
15129 Ok(())
15130 }
15131
15132 fn generate_current_timestamp(&mut self, f: &CurrentTimestamp) -> Result<()> {
15133 use crate::dialects::DialectType;
15134
15135 if f.sysdate {
15137 match self.config.dialect {
15138 Some(DialectType::Oracle) | Some(DialectType::Redshift) => {
15139 self.write_keyword("SYSDATE");
15140 return Ok(());
15141 }
15142 Some(DialectType::Snowflake) => {
15143 self.write_keyword("SYSDATE");
15145 self.write("()");
15146 return Ok(());
15147 }
15148 _ => {
15149 }
15151 }
15152 }
15153
15154 self.write_keyword("CURRENT_TIMESTAMP");
15155 if let Some(precision) = f.precision {
15157 self.write(&format!("({})", precision));
15158 } else if matches!(
15159 self.config.dialect,
15160 Some(crate::dialects::DialectType::MySQL) | Some(crate::dialects::DialectType::SingleStore) |
15161 Some(crate::dialects::DialectType::TiDB) | Some(crate::dialects::DialectType::Spark) |
15162 Some(crate::dialects::DialectType::Hive) |
15163 Some(crate::dialects::DialectType::Databricks) | Some(crate::dialects::DialectType::ClickHouse) |
15164 Some(crate::dialects::DialectType::BigQuery) | Some(crate::dialects::DialectType::Snowflake)
15165 ) {
15166 self.write("()");
15167 }
15168 Ok(())
15169 }
15170
15171 fn generate_at_time_zone(&mut self, f: &AtTimeZone) -> Result<()> {
15172 if self.config.dialect == Some(DialectType::Exasol) {
15174 self.write_keyword("CONVERT_TZ");
15175 self.write("(");
15176 self.generate_expression(&f.this)?;
15177 self.write(", 'UTC', ");
15178 self.generate_expression(&f.zone)?;
15179 self.write(")");
15180 return Ok(());
15181 }
15182
15183 self.generate_expression(&f.this)?;
15184 self.write_space();
15185 self.write_keyword("AT TIME ZONE");
15186 self.write_space();
15187 self.generate_expression(&f.zone)?;
15188 Ok(())
15189 }
15190
15191 fn generate_date_add(&mut self, f: &DateAddFunc, name: &str) -> Result<()> {
15192 use crate::dialects::DialectType;
15193
15194 let is_presto_like = matches!(
15197 self.config.dialect,
15198 Some(DialectType::Presto) | Some(DialectType::Trino)
15199 );
15200
15201 if is_presto_like {
15202 self.write_keyword(name);
15203 self.write("(");
15204 self.write("'");
15206 self.write_simple_interval_unit(&f.unit, false);
15207 self.write("'");
15208 self.write(", ");
15209 let needs_cast = !self.returns_integer_type(&f.interval);
15211 if needs_cast {
15212 self.write_keyword("CAST");
15213 self.write("(");
15214 }
15215 self.generate_expression(&f.interval)?;
15216 if needs_cast {
15217 self.write_space();
15218 self.write_keyword("AS");
15219 self.write_space();
15220 self.write_keyword("BIGINT");
15221 self.write(")");
15222 }
15223 self.write(", ");
15224 self.generate_expression(&f.this)?;
15225 self.write(")");
15226 } else {
15227 self.write_keyword(name);
15228 self.write("(");
15229 self.generate_expression(&f.this)?;
15230 self.write(", ");
15231 self.write_keyword("INTERVAL");
15232 self.write_space();
15233 self.generate_expression(&f.interval)?;
15234 self.write_space();
15235 self.write_simple_interval_unit(&f.unit, false); self.write(")");
15237 }
15238 Ok(())
15239 }
15240
15241 fn returns_integer_type(&self, expr: &Expression) -> bool {
15244 use crate::expressions::{DataType, Literal};
15245 match expr {
15246 Expression::Literal(Literal::Number(n)) => !n.contains('.'),
15248
15249 Expression::Floor(f) => self.returns_integer_type(&f.this),
15251
15252 Expression::Round(f) => {
15254 f.decimals.is_none() && self.returns_integer_type(&f.this)
15256 }
15257
15258 Expression::Sign(f) => self.returns_integer_type(&f.this),
15260
15261 Expression::Abs(f) => self.returns_integer_type(&f.this),
15263
15264 Expression::Mul(op) => self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right),
15266 Expression::Add(op) => self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right),
15267 Expression::Sub(op) => self.returns_integer_type(&op.left) && self.returns_integer_type(&op.right),
15268 Expression::Mod(op) => self.returns_integer_type(&op.left),
15269
15270 Expression::Cast(c) => matches!(&c.to,
15272 DataType::BigInt { .. } | DataType::Int { .. } |
15273 DataType::SmallInt { .. } | DataType::TinyInt { .. }
15274 ),
15275
15276 Expression::Neg(op) => self.returns_integer_type(&op.this),
15278
15279 Expression::Paren(p) => self.returns_integer_type(&p.this),
15281
15282 _ => false,
15285 }
15286 }
15287
15288 fn generate_datediff(&mut self, f: &DateDiffFunc) -> Result<()> {
15289 self.write_keyword("DATEDIFF");
15290 self.write("(");
15291 if let Some(unit) = &f.unit {
15292 self.write_simple_interval_unit(unit, false); self.write(", ");
15294 }
15295 self.generate_expression(&f.this)?;
15296 self.write(", ");
15297 self.generate_expression(&f.expression)?;
15298 self.write(")");
15299 Ok(())
15300 }
15301
15302 fn generate_date_trunc(&mut self, f: &DateTruncFunc) -> Result<()> {
15303 self.write_keyword("DATE_TRUNC");
15304 self.write("('");
15305 self.write_datetime_field(&f.unit);
15306 self.write("', ");
15307 self.generate_expression(&f.this)?;
15308 self.write(")");
15309 Ok(())
15310 }
15311
15312 fn generate_last_day(&mut self, f: &LastDayFunc) -> Result<()> {
15313 use crate::dialects::DialectType;
15314 use crate::expressions::DateTimeField;
15315
15316 self.write_keyword("LAST_DAY");
15317 self.write("(");
15318 self.generate_expression(&f.this)?;
15319 if let Some(unit) = &f.unit {
15320 self.write(", ");
15321 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
15324 if let DateTimeField::WeekWithModifier(_) = unit {
15325 self.write_keyword("WEEK");
15326 } else {
15327 self.write_datetime_field(unit);
15328 }
15329 } else {
15330 self.write_datetime_field(unit);
15331 }
15332 }
15333 self.write(")");
15334 Ok(())
15335 }
15336
15337 fn generate_extract(&mut self, f: &ExtractFunc) -> Result<()> {
15338 if matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) {
15340 self.write_keyword("DATEPART");
15341 self.write("(");
15342 self.write_datetime_field(&f.field);
15343 self.write(", ");
15344 self.generate_expression(&f.this)?;
15345 self.write(")");
15346 return Ok(());
15347 }
15348 self.write_keyword("EXTRACT");
15349 self.write("(");
15350 if matches!(self.config.dialect, Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)) {
15352 self.write_datetime_field_lower(&f.field);
15353 } else {
15354 self.write_datetime_field(&f.field);
15355 }
15356 self.write_space();
15357 self.write_keyword("FROM");
15358 self.write_space();
15359 self.generate_expression(&f.this)?;
15360 self.write(")");
15361 Ok(())
15362 }
15363
15364 fn generate_to_date(&mut self, f: &ToDateFunc) -> Result<()> {
15365 self.write_keyword("TO_DATE");
15366 self.write("(");
15367 self.generate_expression(&f.this)?;
15368 if let Some(format) = &f.format {
15369 self.write(", ");
15370 self.generate_expression(format)?;
15371 }
15372 self.write(")");
15373 Ok(())
15374 }
15375
15376 fn generate_to_timestamp(&mut self, f: &ToTimestampFunc) -> Result<()> {
15377 self.write_keyword("TO_TIMESTAMP");
15378 self.write("(");
15379 self.generate_expression(&f.this)?;
15380 if let Some(format) = &f.format {
15381 self.write(", ");
15382 self.generate_expression(format)?;
15383 }
15384 self.write(")");
15385 Ok(())
15386 }
15387
15388 fn generate_if_func(&mut self, f: &IfFunc) -> Result<()> {
15391 use crate::dialects::DialectType;
15392
15393 if self.config.dialect == Some(DialectType::Exasol) {
15395 self.write_keyword("IF");
15396 self.write_space();
15397 self.generate_expression(&f.condition)?;
15398 self.write_space();
15399 self.write_keyword("THEN");
15400 self.write_space();
15401 self.generate_expression(&f.true_value)?;
15402 if let Some(false_val) = &f.false_value {
15403 self.write_space();
15404 self.write_keyword("ELSE");
15405 self.write_space();
15406 self.generate_expression(false_val)?;
15407 }
15408 self.write_space();
15409 self.write_keyword("ENDIF");
15410 return Ok(());
15411 }
15412
15413 let func_name = match self.config.dialect {
15415 Some(DialectType::Snowflake) => "IFF",
15416 Some(DialectType::SQLite) | Some(DialectType::TSQL) => "IIF",
15417 _ => "IF",
15418 };
15419 self.write_keyword(func_name);
15420 self.write("(");
15421 self.generate_expression(&f.condition)?;
15422 self.write(", ");
15423 self.generate_expression(&f.true_value)?;
15424 if let Some(false_val) = &f.false_value {
15425 self.write(", ");
15426 self.generate_expression(false_val)?;
15427 }
15428 self.write(")");
15429 Ok(())
15430 }
15431
15432 fn generate_nvl2(&mut self, f: &Nvl2Func) -> Result<()> {
15433 self.write_keyword("NVL2");
15434 self.write("(");
15435 self.generate_expression(&f.this)?;
15436 self.write(", ");
15437 self.generate_expression(&f.true_value)?;
15438 self.write(", ");
15439 self.generate_expression(&f.false_value)?;
15440 self.write(")");
15441 Ok(())
15442 }
15443
15444 fn generate_count(&mut self, f: &CountFunc) -> Result<()> {
15447 let count_name = match self.config.normalize_functions {
15449 NormalizeFunctions::Upper => "COUNT".to_string(),
15450 NormalizeFunctions::Lower => "count".to_string(),
15451 NormalizeFunctions::None => f.original_name.clone().unwrap_or_else(|| "COUNT".to_string()),
15452 };
15453 self.write(&count_name);
15454 self.write("(");
15455 if f.distinct {
15456 self.write_keyword("DISTINCT");
15457 self.write_space();
15458 }
15459 if f.star {
15460 self.write("*");
15461 } else if let Some(ref expr) = f.this {
15462 if let Expression::Tuple(tuple) = expr {
15464 let needs_transform = f.distinct
15468 && tuple.expressions.len() > 1
15469 && !self.config.multi_arg_distinct;
15470
15471 if needs_transform {
15472 self.write_keyword("CASE");
15474 for e in &tuple.expressions {
15475 self.write_space();
15476 self.write_keyword("WHEN");
15477 self.write_space();
15478 self.generate_expression(e)?;
15479 self.write_space();
15480 self.write_keyword("IS NULL THEN NULL");
15481 }
15482 self.write_space();
15483 self.write_keyword("ELSE");
15484 self.write(" (");
15485 for (i, e) in tuple.expressions.iter().enumerate() {
15486 if i > 0 {
15487 self.write(", ");
15488 }
15489 self.generate_expression(e)?;
15490 }
15491 self.write(")");
15492 self.write_space();
15493 self.write_keyword("END");
15494 } else {
15495 for (i, e) in tuple.expressions.iter().enumerate() {
15496 if i > 0 {
15497 self.write(", ");
15498 }
15499 self.generate_expression(e)?;
15500 }
15501 }
15502 } else {
15503 self.generate_expression(expr)?;
15504 }
15505 }
15506 if let Some(ignore) = f.ignore_nulls {
15508 self.write_space();
15509 if ignore {
15510 self.write_keyword("IGNORE NULLS");
15511 } else {
15512 self.write_keyword("RESPECT NULLS");
15513 }
15514 }
15515 self.write(")");
15516 if let Some(ref filter) = f.filter {
15517 self.write_space();
15518 self.write_keyword("FILTER");
15519 self.write("(");
15520 self.write_keyword("WHERE");
15521 self.write_space();
15522 self.generate_expression(filter)?;
15523 self.write(")");
15524 }
15525 Ok(())
15526 }
15527
15528 fn generate_agg_func(&mut self, name: &str, f: &AggFunc) -> Result<()> {
15529 let func_name = match self.config.normalize_functions {
15531 NormalizeFunctions::Upper => name.to_uppercase(),
15532 NormalizeFunctions::Lower => name.to_lowercase(),
15533 NormalizeFunctions::None => {
15534 if let Some(ref original) = f.name {
15537 original.clone()
15538 } else {
15539 name.to_lowercase()
15540 }
15541 }
15542 };
15543 self.write(&func_name);
15544 self.write("(");
15545 if f.distinct {
15546 self.write_keyword("DISTINCT");
15547 self.write_space();
15548 }
15549 if !matches!(f.this, Expression::Null(_)) {
15551 self.generate_expression(&f.this)?;
15552 }
15553 if self.config.ignore_nulls_in_func && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
15556 match f.ignore_nulls {
15557 Some(true) => {
15558 self.write_space();
15559 self.write_keyword("IGNORE NULLS");
15560 }
15561 Some(false) => {
15562 self.write_space();
15563 self.write_keyword("RESPECT NULLS");
15564 }
15565 None => {}
15566 }
15567 }
15568 if let Some((ref expr, is_max)) = f.having_max {
15571 self.write_space();
15572 self.write_keyword("HAVING");
15573 self.write_space();
15574 if is_max {
15575 self.write_keyword("MAX");
15576 } else {
15577 self.write_keyword("MIN");
15578 }
15579 self.write_space();
15580 self.generate_expression(expr)?;
15581 }
15582 if !f.order_by.is_empty() {
15584 self.write_space();
15585 self.write_keyword("ORDER BY");
15586 self.write_space();
15587 for (i, ord) in f.order_by.iter().enumerate() {
15588 if i > 0 { self.write(", "); }
15589 self.generate_ordered(ord)?;
15590 }
15591 }
15592 if let Some(ref limit) = f.limit {
15594 self.write_space();
15595 self.write_keyword("LIMIT");
15596 self.write_space();
15597 if let Expression::Tuple(t) = limit.as_ref() {
15599 if t.expressions.len() == 2 {
15600 self.generate_expression(&t.expressions[0])?;
15601 self.write(", ");
15602 self.generate_expression(&t.expressions[1])?;
15603 } else {
15604 self.generate_expression(limit)?;
15605 }
15606 } else {
15607 self.generate_expression(limit)?;
15608 }
15609 }
15610 self.write(")");
15611 if !self.config.ignore_nulls_in_func && !matches!(self.config.dialect, Some(DialectType::DuckDB)) {
15614 match f.ignore_nulls {
15615 Some(true) => {
15616 self.write_space();
15617 self.write_keyword("IGNORE NULLS");
15618 }
15619 Some(false) => {
15620 self.write_space();
15621 self.write_keyword("RESPECT NULLS");
15622 }
15623 None => {}
15624 }
15625 }
15626 if let Some(ref filter) = f.filter {
15627 self.write_space();
15628 self.write_keyword("FILTER");
15629 self.write("(");
15630 self.write_keyword("WHERE");
15631 self.write_space();
15632 self.generate_expression(filter)?;
15633 self.write(")");
15634 }
15635 Ok(())
15636 }
15637
15638 fn generate_group_concat(&mut self, f: &GroupConcatFunc) -> Result<()> {
15639 self.write_keyword("GROUP_CONCAT");
15640 self.write("(");
15641 if f.distinct {
15642 self.write_keyword("DISTINCT");
15643 self.write_space();
15644 }
15645 self.generate_expression(&f.this)?;
15646 if let Some(ref order_by) = f.order_by {
15647 self.write_space();
15648 self.write_keyword("ORDER BY");
15649 self.write_space();
15650 for (i, ord) in order_by.iter().enumerate() {
15651 if i > 0 { self.write(", "); }
15652 self.generate_ordered(ord)?;
15653 }
15654 }
15655 if let Some(ref sep) = f.separator {
15656 if matches!(self.config.dialect, Some(crate::dialects::DialectType::SQLite)) {
15659 self.write(", ");
15660 self.generate_expression(sep)?;
15661 } else {
15662 self.write_space();
15663 self.write_keyword("SEPARATOR");
15664 self.write_space();
15665 self.generate_expression(sep)?;
15666 }
15667 }
15668 self.write(")");
15669 if let Some(ref filter) = f.filter {
15670 self.write_space();
15671 self.write_keyword("FILTER");
15672 self.write("(");
15673 self.write_keyword("WHERE");
15674 self.write_space();
15675 self.generate_expression(filter)?;
15676 self.write(")");
15677 }
15678 Ok(())
15679 }
15680
15681 fn generate_string_agg(&mut self, f: &StringAggFunc) -> Result<()> {
15682 let is_tsql = matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL));
15683 self.write_keyword("STRING_AGG");
15684 self.write("(");
15685 if f.distinct {
15686 self.write_keyword("DISTINCT");
15687 self.write_space();
15688 }
15689 self.generate_expression(&f.this)?;
15690 if let Some(ref separator) = f.separator {
15691 self.write(", ");
15692 self.generate_expression(separator)?;
15693 }
15694 if !is_tsql {
15696 if let Some(ref order_by) = f.order_by {
15697 self.write_space();
15698 self.write_keyword("ORDER BY");
15699 self.write_space();
15700 for (i, ord) in order_by.iter().enumerate() {
15701 if i > 0 { self.write(", "); }
15702 self.generate_ordered(ord)?;
15703 }
15704 }
15705 }
15706 if let Some(ref limit) = f.limit {
15707 self.write_space();
15708 self.write_keyword("LIMIT");
15709 self.write_space();
15710 self.generate_expression(limit)?;
15711 }
15712 self.write(")");
15713 if is_tsql {
15715 if let Some(ref order_by) = f.order_by {
15716 self.write_space();
15717 self.write_keyword("WITHIN GROUP");
15718 self.write(" (");
15719 self.write_keyword("ORDER BY");
15720 self.write_space();
15721 for (i, ord) in order_by.iter().enumerate() {
15722 if i > 0 { self.write(", "); }
15723 self.generate_ordered(ord)?;
15724 }
15725 self.write(")");
15726 }
15727 }
15728 if let Some(ref filter) = f.filter {
15729 self.write_space();
15730 self.write_keyword("FILTER");
15731 self.write("(");
15732 self.write_keyword("WHERE");
15733 self.write_space();
15734 self.generate_expression(filter)?;
15735 self.write(")");
15736 }
15737 Ok(())
15738 }
15739
15740 fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
15741 use crate::dialects::DialectType;
15742 self.write_keyword("LISTAGG");
15743 self.write("(");
15744 if f.distinct {
15745 self.write_keyword("DISTINCT");
15746 self.write_space();
15747 }
15748 self.generate_expression(&f.this)?;
15749 if let Some(ref sep) = f.separator {
15750 self.write(", ");
15751 self.generate_expression(sep)?;
15752 } else if matches!(self.config.dialect, Some(DialectType::Trino) | Some(DialectType::Presto)) {
15753 self.write(", ','");
15755 }
15756 if let Some(ref overflow) = f.on_overflow {
15757 self.write_space();
15758 self.write_keyword("ON OVERFLOW");
15759 self.write_space();
15760 match overflow {
15761 ListAggOverflow::Error => self.write_keyword("ERROR"),
15762 ListAggOverflow::Truncate { filler, with_count } => {
15763 self.write_keyword("TRUNCATE");
15764 if let Some(ref fill) = filler {
15765 self.write_space();
15766 self.generate_expression(fill)?;
15767 }
15768 if *with_count {
15769 self.write_space();
15770 self.write_keyword("WITH COUNT");
15771 } else {
15772 self.write_space();
15773 self.write_keyword("WITHOUT COUNT");
15774 }
15775 }
15776 }
15777 }
15778 self.write(")");
15779 if let Some(ref order_by) = f.order_by {
15780 self.write_space();
15781 self.write_keyword("WITHIN GROUP");
15782 self.write(" (");
15783 self.write_keyword("ORDER BY");
15784 self.write_space();
15785 for (i, ord) in order_by.iter().enumerate() {
15786 if i > 0 { self.write(", "); }
15787 self.generate_ordered(ord)?;
15788 }
15789 self.write(")");
15790 }
15791 if let Some(ref filter) = f.filter {
15792 self.write_space();
15793 self.write_keyword("FILTER");
15794 self.write("(");
15795 self.write_keyword("WHERE");
15796 self.write_space();
15797 self.generate_expression(filter)?;
15798 self.write(")");
15799 }
15800 Ok(())
15801 }
15802
15803 fn generate_sum_if(&mut self, f: &SumIfFunc) -> Result<()> {
15804 self.write_keyword("SUM_IF");
15805 self.write("(");
15806 self.generate_expression(&f.this)?;
15807 self.write(", ");
15808 self.generate_expression(&f.condition)?;
15809 self.write(")");
15810 if let Some(ref filter) = f.filter {
15811 self.write_space();
15812 self.write_keyword("FILTER");
15813 self.write("(");
15814 self.write_keyword("WHERE");
15815 self.write_space();
15816 self.generate_expression(filter)?;
15817 self.write(")");
15818 }
15819 Ok(())
15820 }
15821
15822 fn generate_approx_percentile(&mut self, f: &ApproxPercentileFunc) -> Result<()> {
15823 self.write_keyword("APPROX_PERCENTILE");
15824 self.write("(");
15825 self.generate_expression(&f.this)?;
15826 self.write(", ");
15827 self.generate_expression(&f.percentile)?;
15828 if let Some(ref acc) = f.accuracy {
15829 self.write(", ");
15830 self.generate_expression(acc)?;
15831 }
15832 self.write(")");
15833 if let Some(ref filter) = f.filter {
15834 self.write_space();
15835 self.write_keyword("FILTER");
15836 self.write("(");
15837 self.write_keyword("WHERE");
15838 self.write_space();
15839 self.generate_expression(filter)?;
15840 self.write(")");
15841 }
15842 Ok(())
15843 }
15844
15845 fn generate_percentile(&mut self, name: &str, f: &PercentileFunc) -> Result<()> {
15846 self.write_keyword(name);
15847 self.write("(");
15848 self.generate_expression(&f.percentile)?;
15849 self.write(")");
15850 if let Some(ref order_by) = f.order_by {
15851 self.write_space();
15852 self.write_keyword("WITHIN GROUP");
15853 self.write(" (");
15854 self.write_keyword("ORDER BY");
15855 self.write_space();
15856 self.generate_expression(&f.this)?;
15857 for ord in order_by.iter() {
15858 if ord.desc {
15859 self.write_space();
15860 self.write_keyword("DESC");
15861 }
15862 }
15863 self.write(")");
15864 }
15865 if let Some(ref filter) = f.filter {
15866 self.write_space();
15867 self.write_keyword("FILTER");
15868 self.write("(");
15869 self.write_keyword("WHERE");
15870 self.write_space();
15871 self.generate_expression(filter)?;
15872 self.write(")");
15873 }
15874 Ok(())
15875 }
15876
15877 fn generate_ntile(&mut self, f: &NTileFunc) -> Result<()> {
15880 self.write_keyword("NTILE");
15881 self.write("(");
15882 if let Some(num_buckets) = &f.num_buckets {
15883 self.generate_expression(num_buckets)?;
15884 }
15885 if let Some(order_by) = &f.order_by {
15886 self.write_keyword(" ORDER BY ");
15887 for (i, ob) in order_by.iter().enumerate() {
15888 if i > 0 { self.write(", "); }
15889 self.generate_ordered(ob)?;
15890 }
15891 }
15892 self.write(")");
15893 Ok(())
15894 }
15895
15896 fn generate_lead_lag(&mut self, name: &str, f: &LeadLagFunc) -> Result<()> {
15897 self.write_keyword(name);
15898 self.write("(");
15899 self.generate_expression(&f.this)?;
15900 if let Some(ref offset) = f.offset {
15901 self.write(", ");
15902 self.generate_expression(offset)?;
15903 if let Some(ref default) = f.default {
15904 self.write(", ");
15905 self.generate_expression(default)?;
15906 }
15907 }
15908 if f.ignore_nulls && self.config.ignore_nulls_in_func {
15910 self.write_space();
15911 self.write_keyword("IGNORE NULLS");
15912 }
15913 self.write(")");
15914 if f.ignore_nulls && !self.config.ignore_nulls_in_func {
15916 self.write_space();
15917 self.write_keyword("IGNORE NULLS");
15918 }
15919 Ok(())
15920 }
15921
15922 fn generate_value_func(&mut self, name: &str, f: &ValueFunc) -> Result<()> {
15923 self.write_keyword(name);
15924 self.write("(");
15925 self.generate_expression(&f.this)?;
15926 if self.config.ignore_nulls_in_func {
15928 match f.ignore_nulls {
15929 Some(true) => {
15930 self.write_space();
15931 self.write_keyword("IGNORE NULLS");
15932 }
15933 Some(false) => {
15934 self.write_space();
15935 self.write_keyword("RESPECT NULLS");
15936 }
15937 None => {}
15938 }
15939 }
15940 self.write(")");
15941 if !self.config.ignore_nulls_in_func {
15943 match f.ignore_nulls {
15944 Some(true) => {
15945 self.write_space();
15946 self.write_keyword("IGNORE NULLS");
15947 }
15948 Some(false) => {
15949 self.write_space();
15950 self.write_keyword("RESPECT NULLS");
15951 }
15952 None => {}
15953 }
15954 }
15955 Ok(())
15956 }
15957
15958 fn generate_nth_value(&mut self, f: &NthValueFunc) -> Result<()> {
15959 self.write_keyword("NTH_VALUE");
15960 self.write("(");
15961 self.generate_expression(&f.this)?;
15962 self.write(", ");
15963 self.generate_expression(&f.offset)?;
15964 if self.config.ignore_nulls_in_func {
15966 match f.ignore_nulls {
15967 Some(true) => {
15968 self.write_space();
15969 self.write_keyword("IGNORE NULLS");
15970 }
15971 Some(false) => {
15972 self.write_space();
15973 self.write_keyword("RESPECT NULLS");
15974 }
15975 None => {}
15976 }
15977 }
15978 self.write(")");
15979 if !self.config.ignore_nulls_in_func {
15981 match f.ignore_nulls {
15982 Some(true) => {
15983 self.write_space();
15984 self.write_keyword("IGNORE NULLS");
15985 }
15986 Some(false) => {
15987 self.write_space();
15988 self.write_keyword("RESPECT NULLS");
15989 }
15990 None => {}
15991 }
15992 }
15993 Ok(())
15994 }
15995
15996 fn generate_position(&mut self, f: &PositionFunc) -> Result<()> {
15999 if matches!(self.config.dialect, Some(crate::dialects::DialectType::ClickHouse)) {
16002 self.write_keyword("POSITION");
16003 self.write("(");
16004 self.generate_expression(&f.string)?;
16005 self.write(", ");
16006 self.generate_expression(&f.substring)?;
16007 if let Some(ref start) = f.start {
16008 self.write(", ");
16009 self.generate_expression(start)?;
16010 }
16011 self.write(")");
16012 return Ok(());
16013 }
16014
16015 self.write_keyword("POSITION");
16016 self.write("(");
16017 self.generate_expression(&f.substring)?;
16018 self.write_space();
16019 self.write_keyword("IN");
16020 self.write_space();
16021 self.generate_expression(&f.string)?;
16022 if let Some(ref start) = f.start {
16023 self.write(", ");
16024 self.generate_expression(start)?;
16025 }
16026 self.write(")");
16027 Ok(())
16028 }
16029
16030 fn generate_rand(&mut self, f: &Rand) -> Result<()> {
16033 if f.lower.is_some() || f.upper.is_some() {
16035 self.write_keyword("RANDOM");
16036 self.write("(");
16037 if let Some(ref lower) = f.lower {
16038 self.generate_expression(lower)?;
16039 }
16040 if let Some(ref upper) = f.upper {
16041 self.write(", ");
16042 self.generate_expression(upper)?;
16043 }
16044 self.write(")");
16045 return Ok(());
16046 }
16047 let func_name = match self.config.dialect {
16049 Some(crate::dialects::DialectType::Snowflake) | Some(crate::dialects::DialectType::DuckDB) => "RANDOM",
16050 _ => "RAND",
16051 };
16052 self.write_keyword(func_name);
16053 self.write("(");
16054 if !matches!(self.config.dialect, Some(crate::dialects::DialectType::DuckDB)) {
16056 if let Some(ref seed) = f.seed {
16057 self.generate_expression(seed)?;
16058 }
16059 }
16060 self.write(")");
16061 Ok(())
16062 }
16063
16064 fn generate_truncate_func(&mut self, f: &TruncateFunc) -> Result<()> {
16065 self.write_keyword("TRUNCATE");
16066 self.write("(");
16067 self.generate_expression(&f.this)?;
16068 if let Some(ref decimals) = f.decimals {
16069 self.write(", ");
16070 self.generate_expression(decimals)?;
16071 }
16072 self.write(")");
16073 Ok(())
16074 }
16075
16076 fn generate_decode(&mut self, f: &DecodeFunc) -> Result<()> {
16079 self.write_keyword("DECODE");
16080 self.write("(");
16081 self.generate_expression(&f.this)?;
16082 for (search, result) in &f.search_results {
16083 self.write(", ");
16084 self.generate_expression(search)?;
16085 self.write(", ");
16086 self.generate_expression(result)?;
16087 }
16088 if let Some(ref default) = f.default {
16089 self.write(", ");
16090 self.generate_expression(default)?;
16091 }
16092 self.write(")");
16093 Ok(())
16094 }
16095
16096 fn generate_date_format(&mut self, name: &str, f: &DateFormatFunc) -> Result<()> {
16099 self.write_keyword(name);
16100 self.write("(");
16101 self.generate_expression(&f.this)?;
16102 self.write(", ");
16103 self.generate_expression(&f.format)?;
16104 self.write(")");
16105 Ok(())
16106 }
16107
16108 fn generate_from_unixtime(&mut self, f: &FromUnixtimeFunc) -> Result<()> {
16109 self.write_keyword("FROM_UNIXTIME");
16110 self.write("(");
16111 self.generate_expression(&f.this)?;
16112 if let Some(ref format) = f.format {
16113 self.write(", ");
16114 self.generate_expression(format)?;
16115 }
16116 self.write(")");
16117 Ok(())
16118 }
16119
16120 fn generate_unix_timestamp(&mut self, f: &UnixTimestampFunc) -> Result<()> {
16121 self.write_keyword("UNIX_TIMESTAMP");
16122 self.write("(");
16123 if let Some(ref expr) = f.this {
16124 self.generate_expression(expr)?;
16125 if let Some(ref format) = f.format {
16126 self.write(", ");
16127 self.generate_expression(format)?;
16128 }
16129 } else if matches!(
16130 self.config.dialect,
16131 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
16132 ) {
16133 self.write_keyword("CURRENT_TIMESTAMP");
16135 self.write("()");
16136 }
16137 self.write(")");
16138 Ok(())
16139 }
16140
16141 fn generate_make_date(&mut self, f: &MakeDateFunc) -> Result<()> {
16142 self.write_keyword("MAKE_DATE");
16143 self.write("(");
16144 self.generate_expression(&f.year)?;
16145 self.write(", ");
16146 self.generate_expression(&f.month)?;
16147 self.write(", ");
16148 self.generate_expression(&f.day)?;
16149 self.write(")");
16150 Ok(())
16151 }
16152
16153 fn generate_make_timestamp(&mut self, f: &MakeTimestampFunc) -> Result<()> {
16154 self.write_keyword("MAKE_TIMESTAMP");
16155 self.write("(");
16156 self.generate_expression(&f.year)?;
16157 self.write(", ");
16158 self.generate_expression(&f.month)?;
16159 self.write(", ");
16160 self.generate_expression(&f.day)?;
16161 self.write(", ");
16162 self.generate_expression(&f.hour)?;
16163 self.write(", ");
16164 self.generate_expression(&f.minute)?;
16165 self.write(", ");
16166 self.generate_expression(&f.second)?;
16167 if let Some(ref tz) = f.timezone {
16168 self.write(", ");
16169 self.generate_expression(tz)?;
16170 }
16171 self.write(")");
16172 Ok(())
16173 }
16174
16175 fn extract_struct_field_names(expr: &Expression) -> Option<Vec<String>> {
16177 match expr {
16178 Expression::Struct(s) => {
16179 if s.fields.iter().all(|(name, _)| name.is_some()) {
16180 Some(s.fields.iter().map(|(name, _)| name.as_deref().unwrap_or("").to_string()).collect())
16181 } else {
16182 None
16183 }
16184 }
16185 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
16186 if f.args.iter().all(|a| matches!(a, Expression::Alias(_))) {
16188 Some(f.args.iter().filter_map(|a| {
16189 if let Expression::Alias(alias) = a {
16190 Some(alias.alias.name.clone())
16191 } else {
16192 None
16193 }
16194 }).collect())
16195 } else {
16196 None
16197 }
16198 }
16199 _ => None,
16200 }
16201 }
16202
16203 fn struct_has_unnamed_fields(expr: &Expression) -> bool {
16205 match expr {
16206 Expression::Struct(s) => s.fields.iter().any(|(name, _)| name.is_none()),
16207 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
16208 f.args.iter().any(|a| !matches!(a, Expression::Alias(_)))
16209 }
16210 _ => false,
16211 }
16212 }
16213
16214 fn struct_field_count(expr: &Expression) -> usize {
16216 match expr {
16217 Expression::Struct(s) => s.fields.len(),
16218 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => f.args.len(),
16219 _ => 0,
16220 }
16221 }
16222
16223 fn apply_struct_field_names(expr: &Expression, field_names: &[String]) -> Expression {
16225 match expr {
16226 Expression::Struct(s) => {
16227 let mut new_fields = Vec::with_capacity(s.fields.len());
16228 for (i, (name, value)) in s.fields.iter().enumerate() {
16229 if name.is_none() && i < field_names.len() {
16230 new_fields.push((Some(field_names[i].clone()), value.clone()));
16231 } else {
16232 new_fields.push((name.clone(), value.clone()));
16233 }
16234 }
16235 Expression::Struct(Box::new(crate::expressions::Struct { fields: new_fields }))
16236 }
16237 Expression::Function(f) if f.name.to_uppercase() == "STRUCT" => {
16238 let mut new_args = Vec::with_capacity(f.args.len());
16239 for (i, arg) in f.args.iter().enumerate() {
16240 if !matches!(arg, Expression::Alias(_)) && i < field_names.len() {
16241 new_args.push(Expression::Alias(Box::new(crate::expressions::Alias {
16243 this: arg.clone(),
16244 alias: crate::expressions::Identifier::new(field_names[i].clone()),
16245 column_aliases: Vec::new(),
16246 pre_alias_comments: Vec::new(),
16247 trailing_comments: Vec::new(),
16248 })));
16249 } else {
16250 new_args.push(arg.clone());
16251 }
16252 }
16253 Expression::Function(Box::new(crate::expressions::Function {
16254 name: f.name.clone(),
16255 args: new_args,
16256 distinct: f.distinct,
16257 trailing_comments: f.trailing_comments.clone(),
16258 use_bracket_syntax: f.use_bracket_syntax,
16259 no_parens: f.no_parens,
16260 quoted: f.quoted,
16261 }))
16262 }
16263 _ => expr.clone(),
16264 }
16265 }
16266
16267 fn inherit_struct_field_names(expressions: &[Expression]) -> Vec<Expression> {
16271 let first = match expressions.first() {
16272 Some(e) => e,
16273 None => return expressions.to_vec(),
16274 };
16275
16276 let field_names = match Self::extract_struct_field_names(first) {
16277 Some(names) if !names.is_empty() => names,
16278 _ => return expressions.to_vec(),
16279 };
16280
16281 let mut result = Vec::with_capacity(expressions.len());
16282 for (idx, expr) in expressions.iter().enumerate() {
16283 if idx == 0 {
16284 result.push(expr.clone());
16285 continue;
16286 }
16287 if Self::struct_field_count(expr) == field_names.len() && Self::struct_has_unnamed_fields(expr) {
16289 result.push(Self::apply_struct_field_names(expr, &field_names));
16290 } else {
16291 result.push(expr.clone());
16292 }
16293 }
16294 result
16295 }
16296
16297 fn generate_array_constructor(&mut self, f: &ArrayConstructor) -> Result<()> {
16300 let needs_inheritance = matches!(self.config.dialect,
16303 Some(DialectType::DuckDB) | Some(DialectType::Spark)
16304 | Some(DialectType::Databricks) | Some(DialectType::Hive)
16305 | Some(DialectType::Snowflake) | Some(DialectType::Presto) | Some(DialectType::Trino)
16306 );
16307 let propagated: Vec<Expression>;
16308 let expressions = if needs_inheritance && f.expressions.len() > 1 {
16309 propagated = Self::inherit_struct_field_names(&f.expressions);
16310 &propagated
16311 } else {
16312 &f.expressions
16313 };
16314
16315 let should_split = if self.config.pretty && !expressions.is_empty() {
16317 let mut expr_strings: Vec<String> = Vec::with_capacity(expressions.len());
16318 for expr in expressions {
16319 let mut temp_gen = Generator::with_config(self.config.clone());
16320 temp_gen.config.pretty = false;
16321 temp_gen.generate_expression(expr)?;
16322 expr_strings.push(temp_gen.output);
16323 }
16324 self.too_wide(&expr_strings)
16325 } else {
16326 false
16327 };
16328
16329 if f.bracket_notation {
16330 let (open, close) = match self.config.dialect {
16334 Some(DialectType::Spark) | Some(DialectType::Databricks)
16335 | Some(DialectType::Hive) => {
16336 self.write_keyword("ARRAY");
16337 ("(", ")")
16338 }
16339 Some(DialectType::Presto) | Some(DialectType::Trino)
16340 | Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
16341 | Some(DialectType::Materialize) | Some(DialectType::RisingWave)
16342 | Some(DialectType::CockroachDB) => {
16343 self.write_keyword("ARRAY");
16344 ("[", "]")
16345 }
16346 _ => ("[", "]"),
16347 };
16348 self.write(open);
16349 if should_split {
16350 self.write_newline();
16351 self.indent_level += 1;
16352 for (i, expr) in expressions.iter().enumerate() {
16353 self.write_indent();
16354 self.generate_expression(expr)?;
16355 if i + 1 < expressions.len() {
16356 self.write(",");
16357 }
16358 self.write_newline();
16359 }
16360 self.indent_level -= 1;
16361 self.write_indent();
16362 } else {
16363 for (i, expr) in expressions.iter().enumerate() {
16364 if i > 0 { self.write(", "); }
16365 self.generate_expression(expr)?;
16366 }
16367 }
16368 self.write(close);
16369 } else {
16370 if f.use_list_keyword {
16372 self.write_keyword("LIST");
16373 } else {
16374 self.write_keyword("ARRAY");
16375 }
16376 let (open, close) = if matches!(self.config.dialect,
16378 Some(DialectType::Spark)
16379 | Some(DialectType::Databricks) | Some(DialectType::Hive)) {
16380 ("(", ")")
16381 } else {
16382 ("[", "]")
16383 };
16384 self.write(open);
16385 if should_split {
16386 self.write_newline();
16387 self.indent_level += 1;
16388 for (i, expr) in expressions.iter().enumerate() {
16389 self.write_indent();
16390 self.generate_expression(expr)?;
16391 if i + 1 < expressions.len() {
16392 self.write(",");
16393 }
16394 self.write_newline();
16395 }
16396 self.indent_level -= 1;
16397 self.write_indent();
16398 } else {
16399 for (i, expr) in expressions.iter().enumerate() {
16400 if i > 0 { self.write(", "); }
16401 self.generate_expression(expr)?;
16402 }
16403 }
16404 self.write(close);
16405 }
16406 Ok(())
16407 }
16408
16409 fn generate_array_sort(&mut self, f: &ArraySortFunc) -> Result<()> {
16410 self.write_keyword("ARRAY_SORT");
16411 self.write("(");
16412 self.generate_expression(&f.this)?;
16413 if let Some(ref comp) = f.comparator {
16414 self.write(", ");
16415 self.generate_expression(comp)?;
16416 }
16417 self.write(")");
16418 Ok(())
16419 }
16420
16421 fn generate_array_join(&mut self, name: &str, f: &ArrayJoinFunc) -> Result<()> {
16422 self.write_keyword(name);
16423 self.write("(");
16424 self.generate_expression(&f.this)?;
16425 self.write(", ");
16426 self.generate_expression(&f.separator)?;
16427 if let Some(ref null_rep) = f.null_replacement {
16428 self.write(", ");
16429 self.generate_expression(null_rep)?;
16430 }
16431 self.write(")");
16432 Ok(())
16433 }
16434
16435 fn generate_unnest(&mut self, f: &UnnestFunc) -> Result<()> {
16436 self.write_keyword("UNNEST");
16437 self.write("(");
16438 self.generate_expression(&f.this)?;
16439 for extra in &f.expressions {
16440 self.write(", ");
16441 self.generate_expression(extra)?;
16442 }
16443 self.write(")");
16444 if f.with_ordinality {
16445 self.write_space();
16446 if self.config.unnest_with_ordinality {
16447 self.write_keyword("WITH ORDINALITY");
16449 } else if f.offset_alias.is_some() {
16450 if let Some(ref alias) = f.alias {
16453 self.write_keyword("AS");
16454 self.write_space();
16455 self.generate_identifier(alias)?;
16456 self.write_space();
16457 }
16458 self.write_keyword("WITH OFFSET");
16459 if let Some(ref offset_alias) = f.offset_alias {
16460 self.write_space();
16461 self.write_keyword("AS");
16462 self.write_space();
16463 self.generate_identifier(offset_alias)?;
16464 }
16465 } else {
16466 self.write_keyword("WITH OFFSET");
16468 if f.alias.is_none() {
16469 self.write(" AS offset");
16470 }
16471 }
16472 }
16473 if let Some(ref alias) = f.alias {
16474 let should_add_alias = if !f.with_ordinality {
16476 true
16477 } else if self.config.unnest_with_ordinality {
16478 true
16480 } else if f.offset_alias.is_some() {
16481 false
16483 } else {
16484 true
16486 };
16487 if should_add_alias {
16488 self.write_space();
16489 self.write_keyword("AS");
16490 self.write_space();
16491 self.generate_identifier(alias)?;
16492 }
16493 }
16494 Ok(())
16495 }
16496
16497 fn generate_array_filter(&mut self, f: &ArrayFilterFunc) -> Result<()> {
16498 self.write_keyword("FILTER");
16499 self.write("(");
16500 self.generate_expression(&f.this)?;
16501 self.write(", ");
16502 self.generate_expression(&f.filter)?;
16503 self.write(")");
16504 Ok(())
16505 }
16506
16507 fn generate_array_transform(&mut self, f: &ArrayTransformFunc) -> Result<()> {
16508 self.write_keyword("TRANSFORM");
16509 self.write("(");
16510 self.generate_expression(&f.this)?;
16511 self.write(", ");
16512 self.generate_expression(&f.transform)?;
16513 self.write(")");
16514 Ok(())
16515 }
16516
16517 fn generate_sequence(&mut self, name: &str, f: &SequenceFunc) -> Result<()> {
16518 self.write_keyword(name);
16519 self.write("(");
16520 self.generate_expression(&f.start)?;
16521 self.write(", ");
16522 self.generate_expression(&f.stop)?;
16523 if let Some(ref step) = f.step {
16524 self.write(", ");
16525 self.generate_expression(step)?;
16526 }
16527 self.write(")");
16528 Ok(())
16529 }
16530
16531 fn generate_struct_constructor(&mut self, f: &StructConstructor) -> Result<()> {
16534 self.write_keyword("STRUCT");
16535 self.write("(");
16536 for (i, (name, expr)) in f.fields.iter().enumerate() {
16537 if i > 0 { self.write(", "); }
16538 if let Some(ref id) = name {
16539 self.generate_identifier(id)?;
16540 self.write(" ");
16541 self.write_keyword("AS");
16542 self.write(" ");
16543 }
16544 self.generate_expression(expr)?;
16545 }
16546 self.write(")");
16547 Ok(())
16548 }
16549
16550 fn generate_struct_function_cross_dialect(&mut self, func: &Function) -> Result<()> {
16552 let mut names: Vec<Option<String>> = Vec::new();
16555 let mut values: Vec<&Expression> = Vec::new();
16556 let mut all_named = true;
16557
16558 for arg in &func.args {
16559 match arg {
16560 Expression::Alias(a) => {
16561 names.push(Some(a.alias.name.clone()));
16562 values.push(&a.this);
16563 }
16564 _ => {
16565 names.push(None);
16566 values.push(arg);
16567 all_named = false;
16568 }
16569 }
16570 }
16571
16572 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
16573 self.write("{");
16575 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
16576 if i > 0 { self.write(", "); }
16577 if let Some(n) = name {
16578 self.write("'");
16579 self.write(n);
16580 self.write("'");
16581 } else {
16582 self.write("'_");
16583 self.write(&i.to_string());
16584 self.write("'");
16585 }
16586 self.write(": ");
16587 self.generate_expression(value)?;
16588 }
16589 self.write("}");
16590 return Ok(());
16591 }
16592
16593 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
16594 self.write_keyword("OBJECT_CONSTRUCT");
16596 self.write("(");
16597 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
16598 if i > 0 { self.write(", "); }
16599 if let Some(n) = name {
16600 self.write("'");
16601 self.write(n);
16602 self.write("'");
16603 } else {
16604 self.write("'_");
16605 self.write(&i.to_string());
16606 self.write("'");
16607 }
16608 self.write(", ");
16609 self.generate_expression(value)?;
16610 }
16611 self.write(")");
16612 return Ok(());
16613 }
16614
16615 if matches!(self.config.dialect, Some(DialectType::Presto) | Some(DialectType::Trino)) {
16616 if all_named && !names.is_empty() {
16617 self.write_keyword("CAST");
16620 self.write("(");
16621 self.write_keyword("ROW");
16622 self.write("(");
16623 for (i, value) in values.iter().enumerate() {
16624 if i > 0 { self.write(", "); }
16625 self.generate_expression(value)?;
16626 }
16627 self.write(")");
16628 self.write(" ");
16629 self.write_keyword("AS");
16630 self.write(" ");
16631 self.write_keyword("ROW");
16632 self.write("(");
16633 for (i, (name, value)) in names.iter().zip(values.iter()).enumerate() {
16634 if i > 0 { self.write(", "); }
16635 if let Some(n) = name {
16636 self.write(n);
16637 }
16638 self.write(" ");
16639 let type_str = Self::infer_sql_type_for_presto(value);
16640 self.write_keyword(&type_str);
16641 }
16642 self.write(")");
16643 self.write(")");
16644 } else {
16645 self.write_keyword("ROW");
16647 self.write("(");
16648 for (i, value) in values.iter().enumerate() {
16649 if i > 0 { self.write(", "); }
16650 self.generate_expression(value)?;
16651 }
16652 self.write(")");
16653 }
16654 return Ok(());
16655 }
16656
16657 self.write_keyword("ROW");
16659 self.write("(");
16660 for (i, value) in values.iter().enumerate() {
16661 if i > 0 { self.write(", "); }
16662 self.generate_expression(value)?;
16663 }
16664 self.write(")");
16665 Ok(())
16666 }
16667
16668 fn infer_sql_type_for_presto(expr: &Expression) -> String {
16670 match expr {
16671 Expression::Literal(crate::expressions::Literal::String(_)) => "VARCHAR".to_string(),
16672 Expression::Literal(crate::expressions::Literal::Number(n)) => {
16673 if n.contains('.') { "DOUBLE".to_string() } else { "INTEGER".to_string() }
16674 }
16675 Expression::Boolean(_) => "BOOLEAN".to_string(),
16676 Expression::Literal(crate::expressions::Literal::Date(_)) => "DATE".to_string(),
16677 Expression::Literal(crate::expressions::Literal::Timestamp(_)) => "TIMESTAMP".to_string(),
16678 Expression::Literal(crate::expressions::Literal::Datetime(_)) => "TIMESTAMP".to_string(),
16679 Expression::Array(_) | Expression::ArrayFunc(_) => {
16680 "ARRAY(VARCHAR)".to_string()
16682 }
16683 Expression::Struct(_) | Expression::StructFunc(_) => "ROW".to_string(),
16685 Expression::Function(f) => {
16686 let up = f.name.to_uppercase();
16687 if up == "STRUCT" { "ROW".to_string() }
16688 else if up == "CURRENT_DATE" { "DATE".to_string() }
16689 else if up == "CURRENT_TIMESTAMP" || up == "NOW" { "TIMESTAMP".to_string() }
16690 else { "VARCHAR".to_string() }
16691 }
16692 _ => "VARCHAR".to_string(),
16693 }
16694 }
16695
16696 fn generate_struct_extract(&mut self, f: &StructExtractFunc) -> Result<()> {
16697 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
16699 self.write_keyword("STRUCT_EXTRACT");
16700 self.write("(");
16701 self.generate_expression(&f.this)?;
16702 self.write(", ");
16703 self.write("'");
16705 self.write(&f.field.name);
16706 self.write("'");
16707 self.write(")");
16708 return Ok(());
16709 }
16710 self.generate_expression(&f.this)?;
16711 self.write(".");
16712 self.generate_identifier(&f.field)
16713 }
16714
16715 fn generate_named_struct(&mut self, f: &NamedStructFunc) -> Result<()> {
16716 self.write_keyword("NAMED_STRUCT");
16717 self.write("(");
16718 for (i, (name, value)) in f.pairs.iter().enumerate() {
16719 if i > 0 { self.write(", "); }
16720 self.generate_expression(name)?;
16721 self.write(", ");
16722 self.generate_expression(value)?;
16723 }
16724 self.write(")");
16725 Ok(())
16726 }
16727
16728 fn generate_map_constructor(&mut self, f: &MapConstructor) -> Result<()> {
16731 if f.curly_brace_syntax {
16732 if f.with_map_keyword {
16734 self.write_keyword("MAP");
16735 self.write(" ");
16736 }
16737 self.write("{");
16738 for (i, (key, val)) in f.keys.iter().zip(f.values.iter()).enumerate() {
16739 if i > 0 { self.write(", "); }
16740 self.generate_expression(key)?;
16741 self.write(": ");
16742 self.generate_expression(val)?;
16743 }
16744 self.write("}");
16745 } else {
16746 self.write_keyword("MAP");
16748 self.write("(");
16749 self.write_keyword("ARRAY");
16750 self.write("[");
16751 for (i, key) in f.keys.iter().enumerate() {
16752 if i > 0 { self.write(", "); }
16753 self.generate_expression(key)?;
16754 }
16755 self.write("], ");
16756 self.write_keyword("ARRAY");
16757 self.write("[");
16758 for (i, val) in f.values.iter().enumerate() {
16759 if i > 0 { self.write(", "); }
16760 self.generate_expression(val)?;
16761 }
16762 self.write("])");
16763 }
16764 Ok(())
16765 }
16766
16767 fn generate_transform_func(&mut self, name: &str, f: &TransformFunc) -> Result<()> {
16768 self.write_keyword(name);
16769 self.write("(");
16770 self.generate_expression(&f.this)?;
16771 self.write(", ");
16772 self.generate_expression(&f.transform)?;
16773 self.write(")");
16774 Ok(())
16775 }
16776
16777 fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> {
16780 use crate::dialects::DialectType;
16781
16782 let use_arrow = f.arrow_syntax && self.dialect_supports_json_arrow();
16784
16785 if use_arrow {
16786 self.generate_expression(&f.this)?;
16788 if name == "JSON_EXTRACT_SCALAR" || name == "JSON_EXTRACT_PATH_TEXT" {
16789 self.write(" ->> ");
16790 } else {
16791 self.write(" -> ");
16792 }
16793 self.generate_expression(&f.path)?;
16794 return Ok(());
16795 }
16796
16797 if f.hash_arrow_syntax && matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) {
16799 self.generate_expression(&f.this)?;
16800 self.write(" #>> ");
16801 self.generate_expression(&f.path)?;
16802 return Ok(());
16803 }
16804
16805 let func_name = if matches!(self.config.dialect, Some(DialectType::Redshift)) {
16808 match name {
16809 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" | "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH_TEXT",
16810 _ => name,
16811 }
16812 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
16813 match name {
16814 "JSON_EXTRACT_SCALAR" | "JSON_EXTRACT_PATH_TEXT" => "JSON_EXTRACT_PATH_TEXT",
16815 "JSON_EXTRACT" | "JSON_EXTRACT_PATH" => "JSON_EXTRACT_PATH",
16816 _ => name,
16817 }
16818 } else {
16819 name
16820 };
16821
16822 self.write_keyword(func_name);
16823 self.write("(");
16824 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
16826 if let Expression::Cast(ref cast) = f.this {
16827 if matches!(cast.to, crate::expressions::DataType::Json) {
16828 self.generate_expression(&cast.this)?;
16829 } else {
16830 self.generate_expression(&f.this)?;
16831 }
16832 } else {
16833 self.generate_expression(&f.this)?;
16834 }
16835 } else {
16836 self.generate_expression(&f.this)?;
16837 }
16838 self.write(", ");
16839 self.generate_expression(&f.path)?;
16840
16841 if let Some(ref wrapper) = f.wrapper_option {
16844 self.write_space();
16845 self.write_keyword(wrapper);
16846 }
16847 if let Some(ref quotes) = f.quotes_option {
16848 self.write_space();
16849 self.write_keyword(quotes);
16850 if f.on_scalar_string {
16851 self.write_space();
16852 self.write_keyword("ON SCALAR STRING");
16853 }
16854 }
16855 if let Some(ref on_err) = f.on_error {
16856 self.write_space();
16857 self.write_keyword(on_err);
16858 }
16859 if let Some(ref ret_type) = f.returning {
16860 self.write_space();
16861 self.write_keyword("RETURNING");
16862 self.write_space();
16863 self.generate_data_type(ret_type)?;
16864 }
16865
16866 self.write(")");
16867 Ok(())
16868 }
16869
16870 fn dialect_supports_json_arrow(&self) -> bool {
16872 use crate::dialects::DialectType;
16873 match self.config.dialect {
16874 Some(DialectType::PostgreSQL) => true,
16876 Some(DialectType::MySQL) => true,
16877 Some(DialectType::DuckDB) => true,
16878 Some(DialectType::CockroachDB) => true,
16879 Some(DialectType::StarRocks) => true,
16880 Some(DialectType::SQLite) => true,
16881 _ => false,
16883 }
16884 }
16885
16886 fn generate_json_path(&mut self, name: &str, f: &JsonPathFunc) -> Result<()> {
16887 use crate::dialects::DialectType;
16888
16889 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) && name == "JSON_EXTRACT_PATH" {
16891 self.generate_expression(&f.this)?;
16892 self.write(" #> ");
16893 if f.paths.len() == 1 {
16894 self.generate_expression(&f.paths[0])?;
16895 } else {
16896 self.write_keyword("ARRAY");
16898 self.write("[");
16899 for (i, path) in f.paths.iter().enumerate() {
16900 if i > 0 { self.write(", "); }
16901 self.generate_expression(path)?;
16902 }
16903 self.write("]");
16904 }
16905 return Ok(());
16906 }
16907
16908 self.write_keyword(name);
16909 self.write("(");
16910 self.generate_expression(&f.this)?;
16911 for path in &f.paths {
16912 self.write(", ");
16913 self.generate_expression(path)?;
16914 }
16915 self.write(")");
16916 Ok(())
16917 }
16918
16919 fn generate_json_object(&mut self, f: &JsonObjectFunc) -> Result<()> {
16920 use crate::dialects::DialectType;
16921
16922 self.write_keyword("JSON_OBJECT");
16923 self.write("(");
16924 if f.star {
16925 self.write("*");
16926 } else {
16927 let use_comma_syntax = self.config.json_key_value_pair_sep == "," ||
16931 matches!(self.config.dialect, Some(DialectType::BigQuery) | Some(DialectType::MySQL) | Some(DialectType::SQLite));
16932
16933 for (i, (key, value)) in f.pairs.iter().enumerate() {
16934 if i > 0 { self.write(", "); }
16935 self.generate_expression(key)?;
16936 if use_comma_syntax {
16937 self.write(", ");
16938 } else {
16939 self.write(": ");
16940 }
16941 self.generate_expression(value)?;
16942 }
16943 }
16944 if let Some(null_handling) = f.null_handling {
16945 self.write_space();
16946 match null_handling {
16947 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
16948 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
16949 }
16950 }
16951 if f.with_unique_keys {
16952 self.write_space();
16953 self.write_keyword("WITH UNIQUE KEYS");
16954 }
16955 if let Some(ref ret_type) = f.returning_type {
16956 self.write_space();
16957 self.write_keyword("RETURNING");
16958 self.write_space();
16959 self.generate_data_type(ret_type)?;
16960 if f.format_json {
16961 self.write_space();
16962 self.write_keyword("FORMAT JSON");
16963 }
16964 if let Some(ref enc) = f.encoding {
16965 self.write_space();
16966 self.write_keyword("ENCODING");
16967 self.write_space();
16968 self.write(enc);
16969 }
16970 }
16971 self.write(")");
16972 Ok(())
16973 }
16974
16975 fn generate_json_modify(&mut self, name: &str, f: &JsonModifyFunc) -> Result<()> {
16976 self.write_keyword(name);
16977 self.write("(");
16978 self.generate_expression(&f.this)?;
16979 for (path, value) in &f.path_values {
16980 self.write(", ");
16981 self.generate_expression(path)?;
16982 self.write(", ");
16983 self.generate_expression(value)?;
16984 }
16985 self.write(")");
16986 Ok(())
16987 }
16988
16989 fn generate_json_array_agg(&mut self, f: &JsonArrayAggFunc) -> Result<()> {
16990 self.write_keyword("JSON_ARRAYAGG");
16991 self.write("(");
16992 self.generate_expression(&f.this)?;
16993 if let Some(ref order_by) = f.order_by {
16994 self.write_space();
16995 self.write_keyword("ORDER BY");
16996 self.write_space();
16997 for (i, ord) in order_by.iter().enumerate() {
16998 if i > 0 { self.write(", "); }
16999 self.generate_ordered(ord)?;
17000 }
17001 }
17002 if let Some(null_handling) = f.null_handling {
17003 self.write_space();
17004 match null_handling {
17005 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
17006 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
17007 }
17008 }
17009 self.write(")");
17010 if let Some(ref filter) = f.filter {
17011 self.write_space();
17012 self.write_keyword("FILTER");
17013 self.write("(");
17014 self.write_keyword("WHERE");
17015 self.write_space();
17016 self.generate_expression(filter)?;
17017 self.write(")");
17018 }
17019 Ok(())
17020 }
17021
17022 fn generate_json_object_agg(&mut self, f: &JsonObjectAggFunc) -> Result<()> {
17023 self.write_keyword("JSON_OBJECTAGG");
17024 self.write("(");
17025 self.generate_expression(&f.key)?;
17026 self.write(": ");
17027 self.generate_expression(&f.value)?;
17028 if let Some(null_handling) = f.null_handling {
17029 self.write_space();
17030 match null_handling {
17031 JsonNullHandling::NullOnNull => self.write_keyword("NULL ON NULL"),
17032 JsonNullHandling::AbsentOnNull => self.write_keyword("ABSENT ON NULL"),
17033 }
17034 }
17035 self.write(")");
17036 if let Some(ref filter) = f.filter {
17037 self.write_space();
17038 self.write_keyword("FILTER");
17039 self.write("(");
17040 self.write_keyword("WHERE");
17041 self.write_space();
17042 self.generate_expression(filter)?;
17043 self.write(")");
17044 }
17045 Ok(())
17046 }
17047
17048 fn generate_convert(&mut self, f: &ConvertFunc) -> Result<()> {
17051 use crate::dialects::DialectType;
17052
17053 if self.config.dialect == Some(DialectType::Redshift) {
17055 self.write_keyword("CAST");
17056 self.write("(");
17057 self.generate_expression(&f.this)?;
17058 self.write_space();
17059 self.write_keyword("AS");
17060 self.write_space();
17061 self.generate_data_type(&f.to)?;
17062 self.write(")");
17063 return Ok(());
17064 }
17065
17066 self.write_keyword("CONVERT");
17067 self.write("(");
17068 self.generate_data_type(&f.to)?;
17069 self.write(", ");
17070 self.generate_expression(&f.this)?;
17071 if let Some(ref style) = f.style {
17072 self.write(", ");
17073 self.generate_expression(style)?;
17074 }
17075 self.write(")");
17076 Ok(())
17077 }
17078
17079 fn generate_lambda(&mut self, f: &LambdaExpr) -> Result<()> {
17082 if f.colon {
17083 self.write_keyword("LAMBDA");
17085 self.write_space();
17086 for (i, param) in f.parameters.iter().enumerate() {
17087 if i > 0 { self.write(", "); }
17088 self.generate_identifier(param)?;
17089 }
17090 self.write(" : ");
17091 } else {
17092 if f.parameters.len() == 1 {
17094 self.generate_identifier(&f.parameters[0])?;
17095 } else {
17096 self.write("(");
17097 for (i, param) in f.parameters.iter().enumerate() {
17098 if i > 0 { self.write(", "); }
17099 self.generate_identifier(param)?;
17100 }
17101 self.write(")");
17102 }
17103 self.write(" -> ");
17104 }
17105 self.generate_expression(&f.body)
17106 }
17107
17108 fn generate_named_argument(&mut self, f: &NamedArgument) -> Result<()> {
17109 self.generate_identifier(&f.name)?;
17110 match f.separator {
17111 NamedArgSeparator::DArrow => self.write(" => "),
17112 NamedArgSeparator::ColonEq => self.write(" := "),
17113 NamedArgSeparator::Eq => self.write(" = "),
17114 }
17115 self.generate_expression(&f.value)
17116 }
17117
17118 fn generate_table_argument(&mut self, f: &TableArgument) -> Result<()> {
17119 self.write_keyword(&f.prefix);
17120 self.write(" ");
17121 self.generate_expression(&f.this)
17122 }
17123
17124 fn generate_parameter(&mut self, f: &Parameter) -> Result<()> {
17125 match f.style {
17126 ParameterStyle::Question => self.write("?"),
17127 ParameterStyle::Dollar => {
17128 self.write("$");
17129 if let Some(idx) = f.index {
17130 self.write(&idx.to_string());
17131 } else if let Some(ref name) = f.name {
17132 self.write(name);
17134 }
17135 }
17136 ParameterStyle::DollarBrace => {
17137 self.write("${");
17139 if let Some(ref name) = f.name {
17140 self.write(name);
17141 }
17142 if let Some(ref expr) = f.expression {
17143 self.write(":");
17144 self.write(expr);
17145 }
17146 self.write("}");
17147 }
17148 ParameterStyle::Colon => {
17149 self.write(":");
17150 if let Some(idx) = f.index {
17151 self.write(&idx.to_string());
17152 } else if let Some(ref name) = f.name {
17153 self.write(name);
17154 }
17155 }
17156 ParameterStyle::At => {
17157 self.write("@");
17158 if let Some(ref name) = f.name {
17159 if f.quoted {
17160 self.write("\"");
17161 self.write(name);
17162 self.write("\"");
17163 } else {
17164 self.write(name);
17165 }
17166 }
17167 }
17168 ParameterStyle::DoubleAt => {
17169 self.write("@@");
17170 if let Some(ref name) = f.name {
17171 self.write(name);
17172 }
17173 }
17174 ParameterStyle::DoubleDollar => {
17175 self.write("$$");
17176 if let Some(ref name) = f.name {
17177 self.write(name);
17178 }
17179 }
17180 ParameterStyle::Percent => {
17181 if let Some(ref name) = f.name {
17182 self.write("%(");
17184 self.write(name);
17185 self.write(")s");
17186 } else {
17187 self.write("%s");
17189 }
17190 }
17191 ParameterStyle::Brace => {
17192 self.write("{");
17195 if let Some(ref name) = f.name {
17196 self.write(name);
17197 }
17198 if let Some(ref expr) = f.expression {
17199 self.write(": ");
17200 self.write(expr);
17201 }
17202 self.write("}");
17203 }
17204 }
17205 Ok(())
17206 }
17207
17208 fn generate_placeholder(&mut self, f: &Placeholder) -> Result<()> {
17209 self.write("?");
17210 if let Some(idx) = f.index {
17211 self.write(&idx.to_string());
17212 }
17213 Ok(())
17214 }
17215
17216 fn generate_sql_comment(&mut self, f: &SqlComment) -> Result<()> {
17217 if f.is_block {
17218 self.write("/*");
17219 self.write(&f.text);
17220 self.write("*/");
17221 } else {
17222 self.write("--");
17223 self.write(&f.text);
17224 }
17225 Ok(())
17226 }
17227
17228 fn generate_similar_to(&mut self, f: &SimilarToExpr) -> Result<()> {
17231 self.generate_expression(&f.this)?;
17232 if f.not {
17233 self.write_space();
17234 self.write_keyword("NOT");
17235 }
17236 self.write_space();
17237 self.write_keyword("SIMILAR TO");
17238 self.write_space();
17239 self.generate_expression(&f.pattern)?;
17240 if let Some(ref escape) = f.escape {
17241 self.write_space();
17242 self.write_keyword("ESCAPE");
17243 self.write_space();
17244 self.generate_expression(escape)?;
17245 }
17246 Ok(())
17247 }
17248
17249 fn generate_quantified(&mut self, name: &str, f: &QuantifiedExpr) -> Result<()> {
17250 self.generate_expression(&f.this)?;
17251 self.write_space();
17252 if let Some(op) = &f.op {
17254 match op {
17255 QuantifiedOp::Eq => self.write("="),
17256 QuantifiedOp::Neq => self.write("<>"),
17257 QuantifiedOp::Lt => self.write("<"),
17258 QuantifiedOp::Lte => self.write("<="),
17259 QuantifiedOp::Gt => self.write(">"),
17260 QuantifiedOp::Gte => self.write(">="),
17261 }
17262 self.write_space();
17263 }
17264 self.write_keyword(name);
17265 if self.config.quantified_no_paren_space {
17266 self.write("(");
17267 } else {
17268 self.write(" (");
17269 }
17270 self.generate_expression(&f.subquery)?;
17271 self.write(")");
17272 Ok(())
17273 }
17274
17275 fn generate_overlaps(&mut self, f: &OverlapsExpr) -> Result<()> {
17276 if let (Some(this), Some(expr)) = (&f.this, &f.expression) {
17278 self.generate_expression(this)?;
17279 self.write_space();
17280 self.write_keyword("OVERLAPS");
17281 self.write_space();
17282 self.generate_expression(expr)?;
17283 } else if let (Some(ls), Some(le), Some(rs), Some(re)) =
17284 (&f.left_start, &f.left_end, &f.right_start, &f.right_end)
17285 {
17286 self.write("(");
17288 self.generate_expression(ls)?;
17289 self.write(", ");
17290 self.generate_expression(le)?;
17291 self.write(")");
17292 self.write_space();
17293 self.write_keyword("OVERLAPS");
17294 self.write_space();
17295 self.write("(");
17296 self.generate_expression(rs)?;
17297 self.write(", ");
17298 self.generate_expression(re)?;
17299 self.write(")");
17300 }
17301 Ok(())
17302 }
17303
17304 fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> {
17307 use crate::dialects::DialectType;
17308
17309 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
17311 self.generate_expression(&cast.this)?;
17312 self.write(" !:> ");
17313 self.generate_data_type(&cast.to)?;
17314 return Ok(());
17315 }
17316
17317 if matches!(self.config.dialect, Some(DialectType::Teradata)) {
17319 self.write_keyword("TRYCAST");
17320 self.write("(");
17321 self.generate_expression(&cast.this)?;
17322 self.write_space();
17323 self.write_keyword("AS");
17324 self.write_space();
17325 self.generate_data_type(&cast.to)?;
17326 self.write(")");
17327 return Ok(());
17328 }
17329
17330 let keyword = if matches!(self.config.dialect,
17332 Some(DialectType::Hive)
17333 | Some(DialectType::MySQL) | Some(DialectType::SQLite) | Some(DialectType::Oracle)
17334 | Some(DialectType::ClickHouse)
17335 | Some(DialectType::Redshift) | Some(DialectType::PostgreSQL)
17336 | Some(DialectType::StarRocks) | Some(DialectType::Doris)
17337 ) {
17338 "CAST"
17339 } else {
17340 "TRY_CAST"
17341 };
17342
17343 self.write_keyword(keyword);
17344 self.write("(");
17345 self.generate_expression(&cast.this)?;
17346 self.write_space();
17347 self.write_keyword("AS");
17348 self.write_space();
17349 self.generate_data_type(&cast.to)?;
17350
17351 if let Some(format) = &cast.format {
17353 self.write_space();
17354 self.write_keyword("FORMAT");
17355 self.write_space();
17356 self.generate_expression(format)?;
17357 }
17358
17359 self.write(")");
17360 Ok(())
17361 }
17362
17363 fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> {
17364 self.write_keyword("SAFE_CAST");
17365 self.write("(");
17366 self.generate_expression(&cast.this)?;
17367 self.write_space();
17368 self.write_keyword("AS");
17369 self.write_space();
17370 self.generate_data_type(&cast.to)?;
17371
17372 if let Some(format) = &cast.format {
17374 self.write_space();
17375 self.write_keyword("FORMAT");
17376 self.write_space();
17377 self.generate_expression(format)?;
17378 }
17379
17380 self.write(")");
17381 Ok(())
17382 }
17383
17384 fn generate_subscript(&mut self, s: &Subscript) -> Result<()> {
17387 self.generate_expression(&s.this)?;
17388 self.write("[");
17389 self.generate_expression(&s.index)?;
17390 self.write("]");
17391 Ok(())
17392 }
17393
17394 fn generate_dot_access(&mut self, d: &DotAccess) -> Result<()> {
17395 self.generate_expression(&d.this)?;
17396 let use_colon = matches!(self.config.dialect, Some(DialectType::Snowflake))
17399 && matches!(&d.this, Expression::Cast(_) | Expression::SafeCast(_) | Expression::TryCast(_));
17400 if use_colon {
17401 self.write(":");
17402 } else {
17403 self.write(".");
17404 }
17405 self.generate_identifier(&d.field)
17406 }
17407
17408 fn generate_method_call(&mut self, m: &MethodCall) -> Result<()> {
17409 self.generate_expression(&m.this)?;
17410 self.write(".");
17411 if m.method.quoted {
17414 let q = self.config.identifier_quote;
17415 self.write(&format!("{}{}{}", q, m.method.name, q));
17416 } else {
17417 self.write(&m.method.name);
17418 }
17419 self.write("(");
17420 for (i, arg) in m.args.iter().enumerate() {
17421 if i > 0 {
17422 self.write(", ");
17423 }
17424 self.generate_expression(arg)?;
17425 }
17426 self.write(")");
17427 Ok(())
17428 }
17429
17430 fn generate_array_slice(&mut self, s: &ArraySlice) -> Result<()> {
17431 let needs_parens = matches!(
17434 &s.this,
17435 Expression::JsonExtract(f) if f.arrow_syntax
17436 ) || matches!(
17437 &s.this,
17438 Expression::JsonExtractScalar(f) if f.arrow_syntax
17439 );
17440
17441 if needs_parens {
17442 self.write("(");
17443 }
17444 self.generate_expression(&s.this)?;
17445 if needs_parens {
17446 self.write(")");
17447 }
17448 self.write("[");
17449 if let Some(start) = &s.start {
17450 self.generate_expression(start)?;
17451 }
17452 self.write(":");
17453 if let Some(end) = &s.end {
17454 self.generate_expression(end)?;
17455 }
17456 self.write("]");
17457 Ok(())
17458 }
17459
17460
17461 fn generate_binary_op(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
17462 match &op.left {
17466 Expression::Column(col) => {
17467 if let Some(table) = &col.table {
17469 self.generate_identifier(table)?;
17470 self.write(".");
17471 }
17472 self.generate_identifier(&col.name)?;
17473 if col.join_mark && self.config.supports_column_join_marks {
17475 self.write(" (+)");
17476 }
17477 }
17478 Expression::Add(inner_op) | Expression::Sub(inner_op) |
17479 Expression::Mul(inner_op) | Expression::Div(inner_op) |
17480 Expression::Concat(inner_op) => {
17481 self.generate_binary_op_no_trailing(inner_op, match &op.left {
17483 Expression::Add(_) => "+",
17484 Expression::Sub(_) => "-",
17485 Expression::Mul(_) => "*",
17486 Expression::Div(_) => "/",
17487 Expression::Concat(_) => "||",
17488 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
17489 })?;
17490 }
17491 _ => {
17492 self.generate_expression(&op.left)?;
17493 }
17494 }
17495 for comment in &op.left_comments {
17497 self.write_space();
17498 self.write(comment);
17499 }
17500 if self.config.pretty
17501 && matches!(self.config.dialect, Some(DialectType::Snowflake))
17502 && (operator == "AND" || operator == "OR")
17503 {
17504 self.write_newline();
17505 self.write_indent();
17506 self.write_keyword(operator);
17507 } else {
17508 self.write_space();
17509 if operator.chars().all(|c| c.is_alphabetic()) {
17510 self.write_keyword(operator);
17511 } else {
17512 self.write(operator);
17513 }
17514 }
17515 for comment in &op.operator_comments {
17517 self.write_space();
17518 self.write(comment);
17519 }
17520 self.write_space();
17521 self.generate_expression(&op.right)?;
17522 for comment in &op.trailing_comments {
17524 self.write_space();
17525 self.write(comment);
17526 }
17527 Ok(())
17528 }
17529
17530 fn generate_like_op(&mut self, op: &LikeOp, operator: &str) -> Result<()> {
17532 self.generate_expression(&op.left)?;
17533 self.write_space();
17534 self.write_keyword(operator);
17535 if let Some(quantifier) = &op.quantifier {
17536 self.write_space();
17537 self.write_keyword(quantifier);
17538 }
17539 self.write_space();
17540 self.generate_expression(&op.right)?;
17541 if let Some(escape) = &op.escape {
17542 self.write_space();
17543 self.write_keyword("ESCAPE");
17544 self.write_space();
17545 self.generate_expression(escape)?;
17546 }
17547 Ok(())
17548 }
17549
17550 fn generate_null_safe_eq(&mut self, op: &BinaryOp) -> Result<()> {
17553 use crate::dialects::DialectType;
17554 self.generate_expression(&op.left)?;
17555 self.write_space();
17556 if matches!(self.config.dialect, Some(DialectType::MySQL)) {
17557 self.write("<=>");
17558 } else {
17559 self.write_keyword("IS NOT DISTINCT FROM");
17560 }
17561 self.write_space();
17562 self.generate_expression(&op.right)?;
17563 Ok(())
17564 }
17565
17566 fn generate_null_safe_neq(&mut self, op: &BinaryOp) -> Result<()> {
17568 self.generate_expression(&op.left)?;
17569 self.write_space();
17570 self.write_keyword("IS DISTINCT FROM");
17571 self.write_space();
17572 self.generate_expression(&op.right)?;
17573 Ok(())
17574 }
17575
17576 fn generate_binary_op_no_trailing(&mut self, op: &BinaryOp, operator: &str) -> Result<()> {
17578 match &op.left {
17580 Expression::Column(col) => {
17581 if let Some(table) = &col.table {
17582 self.generate_identifier(table)?;
17583 self.write(".");
17584 }
17585 self.generate_identifier(&col.name)?;
17586 if col.join_mark && self.config.supports_column_join_marks {
17588 self.write(" (+)");
17589 }
17590 }
17591 Expression::Add(inner_op) | Expression::Sub(inner_op) |
17592 Expression::Mul(inner_op) | Expression::Div(inner_op) |
17593 Expression::Concat(inner_op) => {
17594 self.generate_binary_op_no_trailing(inner_op, match &op.left {
17595 Expression::Add(_) => "+",
17596 Expression::Sub(_) => "-",
17597 Expression::Mul(_) => "*",
17598 Expression::Div(_) => "/",
17599 Expression::Concat(_) => "||",
17600 _ => unreachable!("op.left variant already matched by outer arm as Add/Sub/Mul/Div/Concat"),
17601 })?;
17602 }
17603 _ => {
17604 self.generate_expression(&op.left)?;
17605 }
17606 }
17607 for comment in &op.left_comments {
17609 self.write_space();
17610 self.write(comment);
17611 }
17612 self.write_space();
17613 if operator.chars().all(|c| c.is_alphabetic()) {
17614 self.write_keyword(operator);
17615 } else {
17616 self.write(operator);
17617 }
17618 for comment in &op.operator_comments {
17620 self.write_space();
17621 self.write(comment);
17622 }
17623 self.write_space();
17624 match &op.right {
17627 Expression::Column(col) => {
17628 if let Some(table) = &col.table {
17629 self.generate_identifier(table)?;
17630 self.write(".");
17631 }
17632 self.generate_identifier(&col.name)?;
17633 if col.join_mark && self.config.supports_column_join_marks {
17635 self.write(" (+)");
17636 }
17637 }
17638 _ => {
17639 self.generate_expression(&op.right)?;
17640 }
17641 }
17642 Ok(())
17644 }
17645
17646 fn generate_unary_op(&mut self, op: &UnaryOp, operator: &str) -> Result<()> {
17647 if operator.chars().all(|c| c.is_alphabetic()) {
17648 self.write_keyword(operator);
17649 self.write_space();
17650 } else {
17651 self.write(operator);
17652 if matches!(&op.this, Expression::Neg(_) | Expression::BitwiseNot(_)) {
17654 self.write_space();
17655 }
17656 }
17657 self.generate_expression(&op.this)
17658 }
17659
17660 fn generate_in(&mut self, in_expr: &In) -> Result<()> {
17661 self.generate_expression(&in_expr.this)?;
17662 if in_expr.global {
17663 self.write_space();
17664 self.write_keyword("GLOBAL");
17665 }
17666 if in_expr.not {
17667 self.write_space();
17668 self.write_keyword("NOT");
17669 }
17670 self.write_space();
17671 self.write_keyword("IN");
17672
17673 if let Some(unnest_expr) = &in_expr.unnest {
17675 self.write_space();
17676 self.write_keyword("UNNEST");
17677 self.write("(");
17678 self.generate_expression(unnest_expr)?;
17679 self.write(")");
17680 return Ok(());
17681 }
17682
17683 if let Some(query) = &in_expr.query {
17684 let is_bare = in_expr.expressions.is_empty() && !matches!(
17687 query,
17688 Expression::Select(_) | Expression::Union(_) |
17689 Expression::Intersect(_) | Expression::Except(_) |
17690 Expression::Subquery(_)
17691 );
17692 if is_bare {
17693 self.write_space();
17695 self.generate_expression(query)?;
17696 } else {
17697 self.write(" (");
17699 let is_statement = matches!(
17700 query,
17701 Expression::Select(_) | Expression::Union(_) |
17702 Expression::Intersect(_) | Expression::Except(_) |
17703 Expression::Subquery(_)
17704 );
17705 if self.config.pretty && is_statement {
17706 self.write_newline();
17707 self.indent_level += 1;
17708 self.write_indent();
17709 }
17710 self.generate_expression(query)?;
17711 if self.config.pretty && is_statement {
17712 self.write_newline();
17713 self.indent_level -= 1;
17714 self.write_indent();
17715 }
17716 self.write(")");
17717 }
17718 } else {
17719 let is_duckdb = matches!(self.config.dialect, Some(crate::dialects::DialectType::DuckDB));
17723 let is_clickhouse = matches!(self.config.dialect, Some(crate::dialects::DialectType::ClickHouse));
17724 let single_expr = in_expr.expressions.len() == 1;
17725 if is_clickhouse && single_expr {
17726 if let Expression::Array(arr) = &in_expr.expressions[0] {
17727 self.write(" (");
17729 for (i, expr) in arr.expressions.iter().enumerate() {
17730 if i > 0 {
17731 self.write(", ");
17732 }
17733 self.generate_expression(expr)?;
17734 }
17735 self.write(")");
17736 } else {
17737 self.write_space();
17738 self.generate_expression(&in_expr.expressions[0])?;
17739 }
17740 } else {
17741 let is_bare_ref = single_expr && matches!(
17742 &in_expr.expressions[0],
17743 Expression::Column(_) | Expression::Identifier(_) | Expression::Dot(_)
17744 );
17745 if is_duckdb && is_bare_ref {
17746 self.write_space();
17747 self.generate_expression(&in_expr.expressions[0])?;
17748 } else {
17749 self.write(" (");
17751 for (i, expr) in in_expr.expressions.iter().enumerate() {
17752 if i > 0 {
17753 self.write(", ");
17754 }
17755 self.generate_expression(expr)?;
17756 }
17757 self.write(")");
17758 }
17759 }
17760 }
17761
17762 Ok(())
17763 }
17764
17765 fn generate_between(&mut self, between: &Between) -> Result<()> {
17766 self.generate_expression(&between.this)?;
17767 if between.not {
17768 self.write_space();
17769 self.write_keyword("NOT");
17770 }
17771 self.write_space();
17772 self.write_keyword("BETWEEN");
17773 self.write_space();
17774 self.generate_expression(&between.low)?;
17775 self.write_space();
17776 self.write_keyword("AND");
17777 self.write_space();
17778 self.generate_expression(&between.high)
17779 }
17780
17781 fn generate_is_null(&mut self, is_null: &IsNull) -> Result<()> {
17782 if is_null.not && is_null.postfix_form {
17784 self.write_keyword("NOT");
17786 self.write_space();
17787 self.generate_expression(&is_null.this)?;
17788 self.write_space();
17789 self.write_keyword("IS");
17790 self.write_space();
17791 self.write_keyword("NULL");
17792 } else {
17793 self.generate_expression(&is_null.this)?;
17794 self.write_space();
17795 self.write_keyword("IS");
17796 if is_null.not {
17797 self.write_space();
17798 self.write_keyword("NOT");
17799 }
17800 self.write_space();
17801 self.write_keyword("NULL");
17802 }
17803 Ok(())
17804 }
17805
17806 fn generate_is_true(&mut self, is_true: &IsTrueFalse) -> Result<()> {
17807 self.generate_expression(&is_true.this)?;
17808 self.write_space();
17809 self.write_keyword("IS");
17810 if is_true.not {
17811 self.write_space();
17812 self.write_keyword("NOT");
17813 }
17814 self.write_space();
17815 self.write_keyword("TRUE");
17816 Ok(())
17817 }
17818
17819 fn generate_is_false(&mut self, is_false: &IsTrueFalse) -> Result<()> {
17820 self.generate_expression(&is_false.this)?;
17821 self.write_space();
17822 self.write_keyword("IS");
17823 if is_false.not {
17824 self.write_space();
17825 self.write_keyword("NOT");
17826 }
17827 self.write_space();
17828 self.write_keyword("FALSE");
17829 Ok(())
17830 }
17831
17832 fn generate_is_json(&mut self, is_json: &IsJson) -> Result<()> {
17833 self.generate_expression(&is_json.this)?;
17834 self.write_space();
17835 self.write_keyword("IS");
17836 if is_json.negated {
17837 self.write_space();
17838 self.write_keyword("NOT");
17839 }
17840 self.write_space();
17841 self.write_keyword("JSON");
17842
17843 if let Some(ref json_type) = is_json.json_type {
17845 self.write_space();
17846 self.write_keyword(json_type);
17847 }
17848
17849 match &is_json.unique_keys {
17851 Some(JsonUniqueKeys::With) => {
17852 self.write_space();
17853 self.write_keyword("WITH UNIQUE KEYS");
17854 }
17855 Some(JsonUniqueKeys::Without) => {
17856 self.write_space();
17857 self.write_keyword("WITHOUT UNIQUE KEYS");
17858 }
17859 Some(JsonUniqueKeys::Shorthand) => {
17860 self.write_space();
17861 self.write_keyword("UNIQUE KEYS");
17862 }
17863 None => {}
17864 }
17865
17866 Ok(())
17867 }
17868
17869 fn generate_is(&mut self, is_expr: &BinaryOp) -> Result<()> {
17870 self.generate_expression(&is_expr.left)?;
17871 self.write_space();
17872 self.write_keyword("IS");
17873 self.write_space();
17874 self.generate_expression(&is_expr.right)
17875 }
17876
17877 fn generate_exists(&mut self, exists: &Exists) -> Result<()> {
17878 if exists.not {
17879 self.write_keyword("NOT");
17880 self.write_space();
17881 }
17882 self.write_keyword("EXISTS");
17883 self.write("(");
17884 self.generate_expression(&exists.this)?;
17885 self.write(")");
17886 Ok(())
17887 }
17888
17889 fn generate_member_of(&mut self, op: &BinaryOp) -> Result<()> {
17890 self.generate_expression(&op.left)?;
17891 self.write_space();
17892 self.write_keyword("MEMBER OF");
17893 self.write("(");
17894 self.generate_expression(&op.right)?;
17895 self.write(")");
17896 Ok(())
17897 }
17898
17899 fn generate_subquery(&mut self, subquery: &Subquery) -> Result<()> {
17900 if subquery.lateral {
17901 self.write_keyword("LATERAL");
17902 self.write_space();
17903 }
17904
17905 let skip_outer_parens = matches!(&subquery.this, Expression::Paren(_));
17909
17910 let is_statement = matches!(
17912 &subquery.this,
17913 Expression::Select(_) | Expression::Union(_) |
17914 Expression::Intersect(_) | Expression::Except(_) |
17915 Expression::Merge(_)
17916 );
17917
17918 if !skip_outer_parens {
17919 self.write("(");
17920 if self.config.pretty && is_statement {
17921 self.write_newline();
17922 self.indent_level += 1;
17923 self.write_indent();
17924 }
17925 }
17926 self.generate_expression(&subquery.this)?;
17927
17928 if subquery.modifiers_inside {
17930 if let Some(order_by) = &subquery.order_by {
17932 self.write_space();
17933 self.write_keyword("ORDER BY");
17934 self.write_space();
17935 for (i, ord) in order_by.expressions.iter().enumerate() {
17936 if i > 0 {
17937 self.write(", ");
17938 }
17939 self.generate_ordered(ord)?;
17940 }
17941 }
17942
17943 if let Some(limit) = &subquery.limit {
17944 self.write_space();
17945 self.write_keyword("LIMIT");
17946 self.write_space();
17947 self.generate_expression(&limit.this)?;
17948 if limit.percent {
17949 self.write_space();
17950 self.write_keyword("PERCENT");
17951 }
17952 }
17953
17954 if let Some(offset) = &subquery.offset {
17955 self.write_space();
17956 self.write_keyword("OFFSET");
17957 self.write_space();
17958 self.generate_expression(&offset.this)?;
17959 }
17960 }
17961
17962 if !skip_outer_parens {
17963 if self.config.pretty && is_statement {
17964 self.write_newline();
17965 self.indent_level -= 1;
17966 self.write_indent();
17967 }
17968 self.write(")");
17969 }
17970
17971 if !subquery.modifiers_inside {
17973 if let Some(order_by) = &subquery.order_by {
17974 self.write_space();
17975 self.write_keyword("ORDER BY");
17976 self.write_space();
17977 for (i, ord) in order_by.expressions.iter().enumerate() {
17978 if i > 0 {
17979 self.write(", ");
17980 }
17981 self.generate_ordered(ord)?;
17982 }
17983 }
17984
17985 if let Some(limit) = &subquery.limit {
17986 self.write_space();
17987 self.write_keyword("LIMIT");
17988 self.write_space();
17989 self.generate_expression(&limit.this)?;
17990 if limit.percent {
17991 self.write_space();
17992 self.write_keyword("PERCENT");
17993 }
17994 }
17995
17996 if let Some(offset) = &subquery.offset {
17997 self.write_space();
17998 self.write_keyword("OFFSET");
17999 self.write_space();
18000 self.generate_expression(&offset.this)?;
18001 }
18002
18003 if let Some(distribute_by) = &subquery.distribute_by {
18005 self.write_space();
18006 self.write_keyword("DISTRIBUTE BY");
18007 self.write_space();
18008 for (i, expr) in distribute_by.expressions.iter().enumerate() {
18009 if i > 0 {
18010 self.write(", ");
18011 }
18012 self.generate_expression(expr)?;
18013 }
18014 }
18015
18016 if let Some(sort_by) = &subquery.sort_by {
18018 self.write_space();
18019 self.write_keyword("SORT BY");
18020 self.write_space();
18021 for (i, ord) in sort_by.expressions.iter().enumerate() {
18022 if i > 0 {
18023 self.write(", ");
18024 }
18025 self.generate_ordered(ord)?;
18026 }
18027 }
18028
18029 if let Some(cluster_by) = &subquery.cluster_by {
18031 self.write_space();
18032 self.write_keyword("CLUSTER BY");
18033 self.write_space();
18034 for (i, ord) in cluster_by.expressions.iter().enumerate() {
18035 if i > 0 {
18036 self.write(", ");
18037 }
18038 self.generate_ordered(ord)?;
18039 }
18040 }
18041 }
18042
18043 if let Some(alias) = &subquery.alias {
18044 self.write_space();
18045 let skip_as = matches!(self.config.dialect, Some(crate::dialects::DialectType::Oracle));
18047 if !skip_as {
18048 self.write_keyword("AS");
18049 self.write_space();
18050 }
18051 self.generate_identifier(alias)?;
18052 if !subquery.column_aliases.is_empty() {
18053 self.write("(");
18054 for (i, col) in subquery.column_aliases.iter().enumerate() {
18055 if i > 0 {
18056 self.write(", ");
18057 }
18058 self.generate_identifier(col)?;
18059 }
18060 self.write(")");
18061 }
18062 }
18063 for comment in &subquery.trailing_comments {
18065 self.write(" ");
18066 self.write(comment);
18067 }
18068 Ok(())
18069 }
18070
18071 fn generate_pivot(&mut self, pivot: &Pivot) -> Result<()> {
18072 if let Some(ref with) = pivot.with {
18074 self.generate_with(with)?;
18075 self.write_space();
18076 }
18077
18078 let direction = if pivot.unpivot { "UNPIVOT" } else { "PIVOT" };
18079
18080 let is_redshift_unpivot = pivot.unpivot
18084 && pivot.expressions.is_empty()
18085 && pivot.fields.is_empty()
18086 && pivot.using.is_empty()
18087 && pivot.into.is_none()
18088 && !matches!(&pivot.this, Expression::Null(_));
18089
18090 if is_redshift_unpivot {
18091 self.write_keyword("UNPIVOT");
18093 self.write_space();
18094 self.generate_expression(&pivot.this)?;
18095 if let Some(alias) = &pivot.alias {
18097 self.write_space();
18098 self.write_keyword("AS");
18099 self.write_space();
18100 self.write(&alias.name);
18102 }
18103 return Ok(());
18104 }
18105
18106 let is_simplified = !pivot.using.is_empty() || pivot.into.is_some()
18108 || (pivot.fields.is_empty() && !pivot.expressions.is_empty()
18109 && !matches!(&pivot.this, Expression::Null(_)));
18110
18111 if is_simplified {
18112 self.write_keyword(direction);
18116 self.write_space();
18117 self.generate_expression(&pivot.this)?;
18118
18119 if !pivot.expressions.is_empty() {
18120 self.write_space();
18121 self.write_keyword("ON");
18122 self.write_space();
18123 for (i, expr) in pivot.expressions.iter().enumerate() {
18124 if i > 0 {
18125 self.write(", ");
18126 }
18127 self.generate_expression(expr)?;
18128 }
18129 }
18130
18131 if let Some(into) = &pivot.into {
18133 self.write_space();
18134 self.write_keyword("INTO");
18135 self.write_space();
18136 self.generate_expression(into)?;
18137 }
18138
18139 if !pivot.using.is_empty() {
18141 self.write_space();
18142 self.write_keyword("USING");
18143 self.write_space();
18144 for (i, expr) in pivot.using.iter().enumerate() {
18145 if i > 0 {
18146 self.write(", ");
18147 }
18148 self.generate_expression(expr)?;
18149 }
18150 }
18151
18152 if let Some(group) = &pivot.group {
18154 self.write_space();
18155 self.generate_expression(group)?;
18156 }
18157 } else {
18158 if !matches!(&pivot.this, Expression::Null(_)) {
18163 self.generate_expression(&pivot.this)?;
18164 self.write_space();
18165 }
18166 self.write_keyword(direction);
18167 self.write("(");
18168
18169 for (i, expr) in pivot.expressions.iter().enumerate() {
18171 if i > 0 {
18172 self.write(", ");
18173 }
18174 self.generate_expression(expr)?;
18175 }
18176
18177 if !pivot.fields.is_empty() {
18179 if !pivot.expressions.is_empty() {
18180 self.write_space();
18181 }
18182 self.write_keyword("FOR");
18183 self.write_space();
18184 for (i, field) in pivot.fields.iter().enumerate() {
18185 if i > 0 {
18186 self.write_space();
18187 }
18188 self.generate_expression(field)?;
18190 }
18191 }
18192
18193 if let Some(default_val) = &pivot.default_on_null {
18195 self.write_space();
18196 self.write_keyword("DEFAULT ON NULL");
18197 self.write(" (");
18198 self.generate_expression(default_val)?;
18199 self.write(")");
18200 }
18201
18202 if let Some(group) = &pivot.group {
18204 self.write_space();
18205 self.generate_expression(group)?;
18206 }
18207
18208 self.write(")");
18209 }
18210
18211 if let Some(alias) = &pivot.alias {
18213 self.write_space();
18214 self.write_keyword("AS");
18215 self.write_space();
18216 self.generate_identifier(alias)?;
18217 }
18218
18219 Ok(())
18220 }
18221
18222 fn generate_unpivot(&mut self, unpivot: &Unpivot) -> Result<()> {
18223 self.generate_expression(&unpivot.this)?;
18224 self.write_space();
18225 self.write_keyword("UNPIVOT");
18226 if let Some(include) = unpivot.include_nulls {
18228 self.write_space();
18229 if include {
18230 self.write_keyword("INCLUDE NULLS");
18231 } else {
18232 self.write_keyword("EXCLUDE NULLS");
18233 }
18234 self.write_space();
18235 }
18236 self.write("(");
18237 if unpivot.value_column_parenthesized {
18238 self.write("(");
18239 }
18240 self.generate_identifier(&unpivot.value_column)?;
18241 for extra_col in &unpivot.extra_value_columns {
18243 self.write(", ");
18244 self.generate_identifier(extra_col)?;
18245 }
18246 if unpivot.value_column_parenthesized {
18247 self.write(")");
18248 }
18249 self.write_space();
18250 self.write_keyword("FOR");
18251 self.write_space();
18252 self.generate_identifier(&unpivot.name_column)?;
18253 self.write_space();
18254 self.write_keyword("IN");
18255 self.write(" (");
18256 for (i, col) in unpivot.columns.iter().enumerate() {
18257 if i > 0 {
18258 self.write(", ");
18259 }
18260 self.generate_expression(col)?;
18261 }
18262 self.write("))");
18263 if let Some(alias) = &unpivot.alias {
18264 self.write_space();
18265 self.write_keyword("AS");
18266 self.write_space();
18267 self.generate_identifier(alias)?;
18268 }
18269 Ok(())
18270 }
18271
18272 fn generate_values(&mut self, values: &Values) -> Result<()> {
18273 self.write_keyword("VALUES");
18274 for (i, row) in values.expressions.iter().enumerate() {
18275 if i > 0 {
18276 self.write(",");
18277 }
18278 self.write(" (");
18279 for (j, expr) in row.expressions.iter().enumerate() {
18280 if j > 0 {
18281 self.write(", ");
18282 }
18283 self.generate_expression(expr)?;
18284 }
18285 self.write(")");
18286 }
18287 if let Some(alias) = &values.alias {
18288 self.write_space();
18289 self.write_keyword("AS");
18290 self.write_space();
18291 self.generate_identifier(alias)?;
18292 if !values.column_aliases.is_empty() {
18293 self.write("(");
18294 for (i, col) in values.column_aliases.iter().enumerate() {
18295 if i > 0 {
18296 self.write(", ");
18297 }
18298 self.generate_identifier(col)?;
18299 }
18300 self.write(")");
18301 }
18302 }
18303 Ok(())
18304 }
18305
18306 fn generate_array(&mut self, arr: &Array) -> Result<()> {
18307 let needs_inheritance = matches!(self.config.dialect,
18309 Some(DialectType::DuckDB) | Some(DialectType::Spark)
18310 | Some(DialectType::Databricks) | Some(DialectType::Hive)
18311 | Some(DialectType::Snowflake) | Some(DialectType::Presto) | Some(DialectType::Trino)
18312 );
18313 let propagated: Vec<Expression>;
18314 let expressions = if needs_inheritance && arr.expressions.len() > 1 {
18315 propagated = Self::inherit_struct_field_names(&arr.expressions);
18316 &propagated
18317 } else {
18318 &arr.expressions
18319 };
18320
18321 if !self.config.array_bracket_only {
18322 self.write_keyword("ARRAY");
18323 }
18324 self.write("[");
18325 for (i, expr) in expressions.iter().enumerate() {
18326 if i > 0 {
18327 self.write(", ");
18328 }
18329 self.generate_expression(expr)?;
18330 }
18331 self.write("]");
18332 Ok(())
18333 }
18334
18335 fn generate_tuple(&mut self, tuple: &Tuple) -> Result<()> {
18336 if tuple.expressions.len() == 2 {
18339 if let Expression::TableAlias(_) = &tuple.expressions[1] {
18340 self.generate_expression(&tuple.expressions[0])?;
18342 self.write_space();
18343 self.write_keyword("AS");
18344 self.write_space();
18345 self.generate_expression(&tuple.expressions[1])?;
18346 return Ok(());
18347 }
18348 }
18349
18350 if self.config.pretty && tuple.expressions.len() > 1 {
18352 self.write("(");
18353 self.write_newline();
18354 self.indent_level += 1;
18355 for (i, expr) in tuple.expressions.iter().enumerate() {
18356 if i > 0 {
18357 self.write(",");
18358 self.write_newline();
18359 }
18360 self.write_indent();
18361 self.generate_expression(expr)?;
18362 }
18363 self.indent_level -= 1;
18364 self.write_newline();
18365 self.write(")");
18366 } else {
18367 self.write("(");
18368 for (i, expr) in tuple.expressions.iter().enumerate() {
18369 if i > 0 {
18370 self.write(", ");
18371 }
18372 self.generate_expression(expr)?;
18373 }
18374 self.write(")");
18375 }
18376 Ok(())
18377 }
18378
18379 fn generate_pipe_operator(&mut self, pipe: &PipeOperator) -> Result<()> {
18380 self.generate_expression(&pipe.this)?;
18381 self.write(" |> ");
18382 self.generate_expression(&pipe.expression)?;
18383 Ok(())
18384 }
18385
18386 fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
18387 self.generate_expression(&ordered.this)?;
18388 if ordered.desc {
18389 self.write_space();
18390 self.write_keyword("DESC");
18391 } else if ordered.explicit_asc {
18392 self.write_space();
18393 self.write_keyword("ASC");
18394 }
18395 if let Some(nulls_first) = ordered.nulls_first {
18396 let is_asc = !ordered.desc;
18410 let is_nulls_are_large = matches!(
18411 self.config.dialect,
18412 Some(DialectType::Oracle) | Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
18413 | Some(DialectType::Snowflake)
18414 );
18415 let is_nulls_are_last = matches!(
18416 self.config.dialect,
18417 Some(DialectType::Dremio) | Some(DialectType::DuckDB) | Some(DialectType::Presto)
18418 | Some(DialectType::Trino) | Some(DialectType::Athena) | Some(DialectType::ClickHouse)
18419 | Some(DialectType::Drill) | Some(DialectType::Exasol)
18420 );
18421
18422 let is_default_nulls = if is_nulls_are_large {
18424 (is_asc && !nulls_first) || (!is_asc && nulls_first)
18426 } else if is_nulls_are_last {
18427 !nulls_first
18429 } else {
18430 false
18431 };
18432
18433 if !is_default_nulls {
18434 self.write_space();
18435 self.write_keyword("NULLS");
18436 self.write_space();
18437 self.write_keyword(if nulls_first { "FIRST" } else { "LAST" });
18438 }
18439 }
18440 if let Some(ref with_fill) = ordered.with_fill {
18442 self.write_space();
18443 self.generate_with_fill(with_fill)?;
18444 }
18445 Ok(())
18446 }
18447
18448 fn generate_data_type(&mut self, dt: &DataType) -> Result<()> {
18449 use crate::dialects::DialectType;
18450
18451 match dt {
18452 DataType::Boolean => {
18453 match self.config.dialect {
18455 Some(DialectType::TSQL) => self.write_keyword("BIT"),
18456 Some(DialectType::MySQL) => self.write_keyword("BOOLEAN"), Some(DialectType::Oracle) => {
18458 self.write_keyword("NUMBER(1)")
18460 }
18461 Some(DialectType::ClickHouse) => self.write("Bool"), _ => self.write_keyword("BOOLEAN"),
18463 }
18464 }
18465 DataType::TinyInt { length } => {
18466 match self.config.dialect {
18469 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) | Some(DialectType::Oracle) | Some(DialectType::Exasol) => {
18470 self.write_keyword("SMALLINT");
18471 }
18472 Some(DialectType::Teradata) => {
18473 self.write_keyword("BYTEINT");
18475 }
18476 Some(DialectType::Dremio) => {
18477 self.write_keyword("INT");
18479 }
18480 _ => {
18481 self.write_keyword("TINYINT");
18482 }
18483 }
18484 if let Some(n) = length {
18485 if !matches!(self.config.dialect, Some(DialectType::Dremio)) {
18486 self.write(&format!("({})", n));
18487 }
18488 }
18489 }
18490 DataType::SmallInt { length } => {
18491 match self.config.dialect {
18493 Some(DialectType::Dremio) => {
18494 self.write_keyword("INT");
18495 }
18496 Some(DialectType::SQLite) => {
18497 self.write_keyword("INTEGER");
18498 }
18499 _ => {
18500 self.write_keyword("SMALLINT");
18501 if let Some(n) = length {
18502 self.write(&format!("({})", n));
18503 }
18504 }
18505 }
18506 }
18507 DataType::Int { length, integer_spelling } => {
18508 if matches!(self.config.dialect, Some(DialectType::BigQuery)) {
18510 self.write_keyword("INT64");
18511 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
18512 self.write("Int32");
18513 } else {
18514 let use_integer = match self.config.dialect {
18516 Some(DialectType::TSQL) | Some(DialectType::Fabric)
18517 | Some(DialectType::Presto) | Some(DialectType::Trino)
18518 | Some(DialectType::SQLite) | Some(DialectType::Redshift) => true,
18519 Some(DialectType::Databricks) => *integer_spelling,
18521 _ => false,
18522 };
18523 if use_integer {
18524 self.write_keyword("INTEGER");
18525 } else {
18526 self.write_keyword("INT");
18527 }
18528 if let Some(n) = length {
18529 self.write(&format!("({})", n));
18530 }
18531 }
18532 }
18533 DataType::BigInt { length } => {
18534 match self.config.dialect {
18536 Some(DialectType::Oracle) => {
18537 self.write_keyword("NUMBER(19)");
18539 }
18540 _ => {
18541 self.write_keyword("BIGINT");
18542 if let Some(n) = length {
18543 self.write(&format!("({})", n));
18544 }
18545 }
18546 }
18547 }
18548 DataType::Float { precision, scale, real_spelling } => {
18549 if *real_spelling && !matches!(self.config.dialect, Some(DialectType::Spark)
18553 | Some(DialectType::Databricks) | Some(DialectType::Hive)
18554 | Some(DialectType::Snowflake) | Some(DialectType::MySQL)
18555 | Some(DialectType::BigQuery)) {
18556 self.write_keyword("REAL")
18557 } else {
18558 match self.config.dialect {
18559 Some(DialectType::PostgreSQL) => {
18560 self.write_keyword("REAL")
18561 }
18562 Some(DialectType::BigQuery) => {
18563 self.write_keyword("FLOAT64")
18564 }
18565 _ => self.write_keyword("FLOAT"),
18566 }
18567 }
18568 if !matches!(self.config.dialect, Some(DialectType::Spark)
18571 | Some(DialectType::Databricks) | Some(DialectType::Hive)
18572 | Some(DialectType::Presto) | Some(DialectType::Trino)) {
18573 if let Some(p) = precision {
18574 self.write(&format!("({}", p));
18575 if let Some(s) = scale {
18576 self.write(&format!(", {})", s));
18577 } else {
18578 self.write(")");
18579 }
18580 }
18581 }
18582 }
18583 DataType::Double { precision, scale } => {
18584 match self.config.dialect {
18586 Some(DialectType::TSQL) | Some(DialectType::Fabric) => self.write_keyword("FLOAT"), Some(DialectType::Oracle) => self.write_keyword("DOUBLE PRECISION"),
18588 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) | Some(DialectType::Teradata) => {
18589 self.write_keyword("DOUBLE PRECISION")
18590 }
18591 _ => self.write_keyword("DOUBLE"),
18592 }
18593 if let Some(p) = precision {
18595 self.write(&format!("({}", p));
18596 if let Some(s) = scale {
18597 self.write(&format!(", {})", s));
18598 } else {
18599 self.write(")");
18600 }
18601 }
18602 }
18603 DataType::Decimal { precision, scale } => {
18604 match self.config.dialect {
18606 Some(DialectType::ClickHouse) => {
18607 self.write("Decimal");
18608 if let Some(p) = precision {
18609 self.write(&format!("({}", p));
18610 if let Some(s) = scale {
18611 self.write(&format!(", {}", s));
18612 }
18613 self.write(")");
18614 }
18615 }
18616 Some(DialectType::Oracle) => {
18617 self.write_keyword("NUMBER");
18619 if let Some(p) = precision {
18620 self.write(&format!("({}", p));
18621 if let Some(s) = scale {
18622 self.write(&format!(", {}", s));
18623 }
18624 self.write(")");
18625 }
18626 }
18627 Some(DialectType::BigQuery) => {
18628 self.write_keyword("NUMERIC");
18630 if let Some(p) = precision {
18631 self.write(&format!("({}", p));
18632 if let Some(s) = scale {
18633 self.write(&format!(", {}", s));
18634 }
18635 self.write(")");
18636 }
18637 }
18638 _ => {
18639 self.write_keyword("DECIMAL");
18640 if let Some(p) = precision {
18641 self.write(&format!("({}", p));
18642 if let Some(s) = scale {
18643 self.write(&format!(", {}", s));
18644 }
18645 self.write(")");
18646 }
18647 }
18648 }
18649 }
18650 DataType::Char { length } => {
18651 match self.config.dialect {
18653 Some(DialectType::DuckDB) => {
18654 self.write_keyword("TEXT");
18656 }
18657 Some(DialectType::Dremio) => {
18658 self.write_keyword("VARCHAR");
18660 if let Some(n) = length {
18661 self.write(&format!("({})", n));
18662 }
18663 }
18664 _ => {
18665 self.write_keyword("CHAR");
18666 if let Some(n) = length {
18667 self.write(&format!("({})", n));
18668 }
18669 }
18670 }
18671 }
18672 DataType::VarChar { length, parenthesized_length } => {
18673 match self.config.dialect {
18675 Some(DialectType::Oracle) => {
18676 self.write_keyword("VARCHAR2");
18677 if let Some(n) = length {
18678 self.write(&format!("({})", n));
18679 }
18680 }
18681 Some(DialectType::DuckDB) => {
18682 self.write_keyword("TEXT");
18684 }
18685 Some(DialectType::SQLite) => {
18686 self.write_keyword("TEXT");
18688 if let Some(n) = length {
18689 self.write(&format!("({})", n));
18690 }
18691 }
18692 Some(DialectType::MySQL) if length.is_none() => {
18693 self.write_keyword("TEXT");
18695 }
18696 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks) if length.is_none() => {
18697 self.write_keyword("STRING");
18699 }
18700 _ => {
18701 self.write_keyword("VARCHAR");
18702 if let Some(n) = length {
18703 if *parenthesized_length {
18705 self.write(&format!("(({}))", n));
18706 } else {
18707 self.write(&format!("({})", n));
18708 }
18709 }
18710 }
18711 }
18712 }
18713 DataType::Text => {
18714 match self.config.dialect {
18716 Some(DialectType::Oracle) => self.write_keyword("CLOB"),
18717 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
18718 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
18719 Some(DialectType::Snowflake) | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
18720 Some(DialectType::Exasol) => self.write_keyword("LONG VARCHAR"),
18721 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
18722 Some(DialectType::Spark) | Some(DialectType::Databricks)
18723 | Some(DialectType::Hive) => self.write_keyword("STRING"),
18724 Some(DialectType::Redshift) => self.write_keyword("VARCHAR"),
18725 Some(DialectType::StarRocks) => self.write_keyword("STRING"),
18726 _ => self.write_keyword("TEXT"),
18727 }
18728 }
18729 DataType::String { length } => {
18730 match self.config.dialect {
18732 Some(DialectType::ClickHouse) => {
18733 self.write("String");
18735 if let Some(n) = length {
18736 self.write(&format!("({})", n));
18737 }
18738 }
18739 Some(DialectType::BigQuery) => {
18740 self.write_keyword("STRING");
18741 if let Some(n) = length {
18742 self.write(&format!("({})", n));
18743 }
18744 }
18745 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
18746 if let Some(n) = length {
18748 self.write_keyword("VARCHAR");
18749 self.write(&format!("({})", n));
18750 } else {
18751 self.write_keyword("TEXT");
18752 }
18753 }
18754 Some(DialectType::MySQL) | Some(DialectType::StarRocks) | Some(DialectType::Doris) => {
18755 if let Some(n) = length {
18757 self.write_keyword("VARCHAR");
18758 self.write(&format!("({})", n));
18759 } else {
18760 self.write_keyword("TEXT");
18761 }
18762 }
18763 Some(DialectType::TSQL) => {
18764 if let Some(n) = length {
18766 self.write_keyword("VARCHAR");
18767 self.write(&format!("({})", n));
18768 } else {
18769 self.write_keyword("NVARCHAR(MAX)");
18770 }
18771 }
18772 Some(DialectType::DuckDB) => {
18773 self.write_keyword("TEXT");
18775 if let Some(n) = length {
18776 self.write(&format!("({})", n));
18777 }
18778 }
18779 Some(DialectType::Presto) | Some(DialectType::Trino) => {
18780 self.write_keyword("VARCHAR");
18782 if let Some(n) = length {
18783 self.write(&format!("({})", n));
18784 }
18785 }
18786 _ => {
18787 self.write_keyword("STRING");
18789 if let Some(n) = length {
18790 self.write(&format!("({})", n));
18791 }
18792 }
18793 }
18794 }
18795 DataType::Binary { length } => {
18796 match self.config.dialect {
18798 Some(DialectType::PostgreSQL) => {
18799 self.write_keyword("BYTEA");
18800 }
18801 Some(DialectType::Redshift) => {
18802 self.write_keyword("VARBYTE");
18803 }
18804 Some(DialectType::DuckDB) => {
18805 self.write_keyword("BLOB");
18807 }
18808 Some(DialectType::Dremio) => {
18809 self.write_keyword("VARBINARY");
18811 if let Some(n) = length {
18812 self.write(&format!("({})", n));
18813 }
18814 }
18815 _ => {
18816 self.write_keyword("BINARY");
18817 if let Some(n) = length {
18818 self.write(&format!("({})", n));
18819 }
18820 }
18821 }
18822 }
18823 DataType::VarBinary { length } => {
18824 match self.config.dialect {
18826 Some(DialectType::PostgreSQL) => {
18827 self.write_keyword("BYTEA");
18828 }
18829 Some(DialectType::Redshift) => {
18830 self.write_keyword("VARBYTE");
18831 if let Some(n) = length {
18832 self.write(&format!("({})", n));
18833 }
18834 }
18835 Some(DialectType::DuckDB) => {
18836 self.write_keyword("BLOB");
18838 }
18839 Some(DialectType::Exasol) => {
18840 self.write_keyword("VARCHAR");
18842 }
18843 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks) => {
18844 self.write_keyword("BINARY");
18846 }
18847 _ => {
18848 self.write_keyword("VARBINARY");
18849 if let Some(n) = length {
18850 self.write(&format!("({})", n));
18851 }
18852 }
18853 }
18854 }
18855 DataType::Blob => {
18856 match self.config.dialect {
18858 Some(DialectType::PostgreSQL) => self.write_keyword("BYTEA"),
18859 Some(DialectType::Redshift) => self.write_keyword("VARBYTE"),
18860 Some(DialectType::TSQL) | Some(DialectType::Fabric) => self.write_keyword("VARBINARY"),
18861 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
18862 Some(DialectType::Exasol) => self.write_keyword("VARCHAR"),
18863 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
18864 Some(DialectType::DuckDB) => {
18865 self.write_keyword("VARBINARY");
18868 }
18869 Some(DialectType::Spark) | Some(DialectType::Databricks)
18870 | Some(DialectType::Hive) => self.write_keyword("BINARY"),
18871 Some(DialectType::ClickHouse) => self.write("Nullable(String)"),
18872 _ => self.write_keyword("BLOB"),
18873 }
18874 }
18875 DataType::Bit { length } => {
18876 match self.config.dialect {
18878 Some(DialectType::Dremio) | Some(DialectType::Spark)
18879 | Some(DialectType::Databricks) | Some(DialectType::Hive)
18880 | Some(DialectType::Snowflake) | Some(DialectType::BigQuery)
18881 | Some(DialectType::Presto) | Some(DialectType::Trino)
18882 | Some(DialectType::ClickHouse) | Some(DialectType::Redshift) => {
18883 self.write_keyword("BOOLEAN");
18885 }
18886 _ => {
18887 self.write_keyword("BIT");
18888 if let Some(n) = length {
18889 self.write(&format!("({})", n));
18890 }
18891 }
18892 }
18893 }
18894 DataType::VarBit { length } => {
18895 self.write_keyword("VARBIT");
18896 if let Some(n) = length {
18897 self.write(&format!("({})", n));
18898 }
18899 }
18900 DataType::Date => self.write_keyword("DATE"),
18901 DataType::Time { precision, timezone } => {
18902 if *timezone {
18903 match self.config.dialect {
18905 Some(DialectType::DuckDB) => {
18906 self.write_keyword("TIMETZ");
18908 }
18909 Some(DialectType::PostgreSQL) => {
18910 self.write_keyword("TIMETZ");
18912 if let Some(p) = precision {
18913 self.write(&format!("({})", p));
18914 }
18915 }
18916 _ => {
18917 self.write_keyword("TIME");
18919 if let Some(p) = precision {
18920 self.write(&format!("({})", p));
18921 }
18922 self.write_keyword(" WITH TIME ZONE");
18923 }
18924 }
18925 } else {
18926 if matches!(self.config.dialect, Some(DialectType::Spark)
18928 | Some(DialectType::Databricks) | Some(DialectType::Hive)) {
18929 self.write_keyword("TIMESTAMP");
18930 } else {
18931 self.write_keyword("TIME");
18932 if let Some(p) = precision {
18933 self.write(&format!("({})", p));
18934 }
18935 }
18936 }
18937 }
18938 DataType::Timestamp { precision, timezone } => {
18939 match self.config.dialect {
18941 Some(DialectType::ClickHouse) => {
18942 self.write("DateTime");
18943 if let Some(p) = precision {
18944 self.write(&format!("({})", p));
18945 }
18946 }
18947 Some(DialectType::TSQL) => {
18948 if *timezone {
18949 self.write_keyword("DATETIMEOFFSET");
18950 } else {
18951 self.write_keyword("DATETIME2");
18952 }
18953 if let Some(p) = precision {
18954 self.write(&format!("({})", p));
18955 }
18956 }
18957 Some(DialectType::MySQL) => {
18958 self.write_keyword("TIMESTAMP");
18961 if let Some(p) = precision {
18962 self.write(&format!("({})", p));
18963 }
18964 }
18965 Some(DialectType::BigQuery) => {
18966 if *timezone {
18968 self.write_keyword("TIMESTAMP");
18969 } else {
18970 self.write_keyword("DATETIME");
18971 }
18972 }
18973 Some(DialectType::DuckDB) => {
18974 if *timezone {
18976 self.write_keyword("TIMESTAMPTZ");
18977 } else {
18978 self.write_keyword("TIMESTAMP");
18979 if let Some(p) = precision {
18980 self.write(&format!("({})", p));
18981 }
18982 }
18983 }
18984 _ => {
18985 if *timezone && !self.config.tz_to_with_time_zone {
18986 self.write_keyword("TIMESTAMPTZ");
18988 if let Some(p) = precision {
18989 self.write(&format!("({})", p));
18990 }
18991 } else {
18992 self.write_keyword("TIMESTAMP");
18993 if let Some(p) = precision {
18994 self.write(&format!("({})", p));
18995 }
18996 if *timezone {
18997 self.write_space();
18998 self.write_keyword("WITH TIME ZONE");
18999 }
19000 }
19001 }
19002 }
19003 }
19004 DataType::Interval { unit, to } => {
19005 self.write_keyword("INTERVAL");
19006 if let Some(u) = unit {
19007 self.write_space();
19008 self.write_keyword(u);
19009 }
19010 if let Some(t) = to {
19012 self.write_space();
19013 self.write_keyword("TO");
19014 self.write_space();
19015 self.write_keyword(t);
19016 }
19017 }
19018 DataType::Json => {
19019 match self.config.dialect {
19021 Some(DialectType::Oracle) => self.write_keyword("JSON"), Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"), Some(DialectType::MySQL) => self.write_keyword("JSON"),
19024 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
19025 _ => self.write_keyword("JSON"),
19026 }
19027 }
19028 DataType::JsonB => {
19029 match self.config.dialect {
19031 Some(DialectType::PostgreSQL) => self.write_keyword("JSONB"),
19032 Some(DialectType::Doris) => self.write_keyword("JSONB"),
19033 Some(DialectType::Snowflake) => self.write_keyword("VARIANT"),
19034 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
19035 Some(DialectType::DuckDB) => self.write_keyword("JSON"), _ => self.write_keyword("JSON"), }
19038 }
19039 DataType::Uuid => {
19040 match self.config.dialect {
19042 Some(DialectType::TSQL) => self.write_keyword("UNIQUEIDENTIFIER"),
19043 Some(DialectType::MySQL) => self.write_keyword("CHAR(36)"),
19044 Some(DialectType::Oracle) => self.write_keyword("RAW(16)"),
19045 Some(DialectType::BigQuery) | Some(DialectType::Spark) | Some(DialectType::Databricks) => self.write_keyword("STRING"),
19046 _ => self.write_keyword("UUID"),
19047 }
19048 }
19049 DataType::Array { element_type, dimension } => {
19050 match self.config.dialect {
19052 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) | Some(DialectType::DuckDB) => {
19053 self.generate_data_type(element_type)?;
19055 if let Some(dim) = dimension {
19056 self.write(&format!("[{}]", dim));
19057 } else {
19058 self.write("[]");
19059 }
19060 }
19061 Some(DialectType::BigQuery) => {
19062 self.write_keyword("ARRAY<");
19063 self.generate_data_type(element_type)?;
19064 self.write(">");
19065 }
19066 Some(DialectType::Snowflake) | Some(DialectType::Presto) | Some(DialectType::Trino)
19067 | Some(DialectType::ClickHouse) => {
19068 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
19070 self.write("Array(");
19071 } else {
19072 self.write_keyword("ARRAY(");
19073 }
19074 self.generate_data_type(element_type)?;
19075 self.write(")");
19076 }
19077 Some(DialectType::TSQL) | Some(DialectType::MySQL) | Some(DialectType::Oracle) => {
19078 match self.config.dialect {
19081 Some(DialectType::MySQL) => self.write_keyword("JSON"),
19082 Some(DialectType::TSQL) => self.write_keyword("NVARCHAR(MAX)"),
19083 _ => self.write_keyword("JSON"),
19084 }
19085 }
19086 _ => {
19087 self.write_keyword("ARRAY<");
19089 self.generate_data_type(element_type)?;
19090 self.write(">");
19091 }
19092 }
19093 }
19094 DataType::List { element_type } => {
19095 self.generate_data_type(element_type)?;
19097 self.write_keyword(" LIST");
19098 }
19099 DataType::Map { key_type, value_type } => {
19100 match self.config.dialect {
19102 Some(DialectType::Materialize) => {
19103 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 Some(DialectType::Snowflake) | Some(DialectType::RisingWave) | Some(DialectType::DuckDB)
19111 | Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => {
19112 self.write_keyword("MAP(");
19113 self.generate_data_type(key_type)?;
19114 self.write(", ");
19115 self.generate_data_type(value_type)?;
19116 self.write(")");
19117 }
19118 _ => {
19119 self.write_keyword("MAP<");
19120 self.generate_data_type(key_type)?;
19121 self.write(", ");
19122 self.generate_data_type(value_type)?;
19123 self.write(">");
19124 }
19125 }
19126 }
19127 DataType::Vector { element_type, dimension } => {
19128 if matches!(self.config.dialect, Some(DialectType::SingleStore)) {
19129 self.write_keyword("VECTOR(");
19131 if let Some(dim) = dimension {
19132 self.write(&dim.to_string());
19133 }
19134 let type_alias = element_type.as_ref().and_then(|et| match et.as_ref() {
19136 DataType::TinyInt { .. } => Some("I8"),
19137 DataType::SmallInt { .. } => Some("I16"),
19138 DataType::Int { .. } => Some("I32"),
19139 DataType::BigInt { .. } => Some("I64"),
19140 DataType::Float { .. } => Some("F32"),
19141 DataType::Double { .. } => Some("F64"),
19142 _ => None,
19143 });
19144 if let Some(alias) = type_alias {
19145 if dimension.is_some() {
19146 self.write(", ");
19147 }
19148 self.write(alias);
19149 }
19150 self.write(")");
19151 } else {
19152 self.write_keyword("VECTOR(");
19154 if let Some(ref et) = element_type {
19155 self.generate_data_type(et)?;
19156 if dimension.is_some() {
19157 self.write(", ");
19158 }
19159 }
19160 if let Some(dim) = dimension {
19161 self.write(&dim.to_string());
19162 }
19163 self.write(")");
19164 }
19165 }
19166 DataType::Object { fields, modifier } => {
19167 self.write_keyword("OBJECT(");
19168 for (i, (name, dt, not_null)) in fields.iter().enumerate() {
19169 if i > 0 {
19170 self.write(", ");
19171 }
19172 self.write(name);
19173 self.write(" ");
19174 self.generate_data_type(dt)?;
19175 if *not_null {
19176 self.write_keyword(" NOT NULL");
19177 }
19178 }
19179 self.write(")");
19180 if let Some(mod_str) = modifier {
19181 self.write(" ");
19182 self.write_keyword(mod_str);
19183 }
19184 }
19185 DataType::Struct { fields, nested } => {
19186 match self.config.dialect {
19188 Some(DialectType::Snowflake) => {
19189 self.write_keyword("OBJECT(");
19191 for (i, field) in fields.iter().enumerate() {
19192 if i > 0 {
19193 self.write(", ");
19194 }
19195 if !field.name.is_empty() {
19196 self.write(&field.name);
19197 self.write(" ");
19198 }
19199 self.generate_data_type(&field.data_type)?;
19200 }
19201 self.write(")");
19202 }
19203 Some(DialectType::Presto) | Some(DialectType::Trino) => {
19204 self.write_keyword("ROW(");
19206 for (i, field) in fields.iter().enumerate() {
19207 if i > 0 {
19208 self.write(", ");
19209 }
19210 if !field.name.is_empty() {
19211 self.write(&field.name);
19212 self.write(" ");
19213 }
19214 self.generate_data_type(&field.data_type)?;
19215 }
19216 self.write(")");
19217 }
19218 Some(DialectType::DuckDB) => {
19219 self.write_keyword("STRUCT(");
19221 for (i, field) in fields.iter().enumerate() {
19222 if i > 0 {
19223 self.write(", ");
19224 }
19225 if !field.name.is_empty() {
19226 self.write(&field.name);
19227 self.write(" ");
19228 }
19229 self.generate_data_type(&field.data_type)?;
19230 }
19231 self.write(")");
19232 }
19233 Some(DialectType::SingleStore) => {
19234 self.write_keyword("RECORD(");
19236 for (i, field) in fields.iter().enumerate() {
19237 if i > 0 {
19238 self.write(", ");
19239 }
19240 if !field.name.is_empty() {
19241 self.write(&field.name);
19242 self.write(" ");
19243 }
19244 self.generate_data_type(&field.data_type)?;
19245 }
19246 self.write(")");
19247 }
19248 _ => {
19249 let force_angle_brackets = matches!(
19251 self.config.dialect,
19252 Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)
19253 );
19254 if *nested && !force_angle_brackets {
19255 self.write_keyword("STRUCT(");
19256 for (i, field) in fields.iter().enumerate() {
19257 if i > 0 {
19258 self.write(", ");
19259 }
19260 if !field.name.is_empty() {
19261 self.write(&field.name);
19262 self.write(" ");
19263 }
19264 self.generate_data_type(&field.data_type)?;
19265 }
19266 self.write(")");
19267 } else {
19268 self.write_keyword("STRUCT<");
19269 for (i, field) in fields.iter().enumerate() {
19270 if i > 0 {
19271 self.write(", ");
19272 }
19273 if !field.name.is_empty() {
19274 self.write(&field.name);
19276 self.write(self.config.struct_field_sep);
19277 }
19278 self.generate_data_type(&field.data_type)?;
19280 if let Some(comment) = &field.comment {
19282 self.write(" COMMENT '");
19283 self.write(comment);
19284 self.write("'");
19285 }
19286 if !field.options.is_empty() {
19288 self.write(" ");
19289 self.generate_options_clause(&field.options)?;
19290 }
19291 }
19292 self.write(">");
19293 }
19294 }
19295 }
19296 }
19297 DataType::Enum { values, assignments } => {
19298 if self.config.dialect == Some(DialectType::ClickHouse) {
19301 self.write("Enum(");
19302 } else {
19303 self.write_keyword("ENUM(");
19304 }
19305 for (i, val) in values.iter().enumerate() {
19306 if i > 0 {
19307 self.write(", ");
19308 }
19309 self.write("'");
19310 self.write(val);
19311 self.write("'");
19312 if let Some(Some(assignment)) = assignments.get(i) {
19313 self.write(" = ");
19314 self.write(assignment);
19315 }
19316 }
19317 self.write(")");
19318 }
19319 DataType::Set { values } => {
19320 self.write_keyword("SET(");
19322 for (i, val) in values.iter().enumerate() {
19323 if i > 0 {
19324 self.write(", ");
19325 }
19326 self.write("'");
19327 self.write(val);
19328 self.write("'");
19329 }
19330 self.write(")");
19331 }
19332 DataType::Union { fields } => {
19333 self.write_keyword("UNION(");
19335 for (i, (name, dt)) in fields.iter().enumerate() {
19336 if i > 0 {
19337 self.write(", ");
19338 }
19339 if !name.is_empty() {
19340 self.write(name);
19341 self.write(" ");
19342 }
19343 self.generate_data_type(dt)?;
19344 }
19345 self.write(")");
19346 }
19347 DataType::Custom { name } => {
19348 let name_upper = name.to_uppercase();
19350 match self.config.dialect {
19351 Some(DialectType::ClickHouse) => {
19352 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
19353 (name_upper[..idx].to_string(), &name[idx..])
19354 } else {
19355 (name_upper.clone(), "")
19356 };
19357 let mapped = match base_upper.as_str() {
19358 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ" | "SMALLDATETIME" | "DATETIME2" => "DateTime",
19359 "DATETIME64" => "DateTime64",
19360 "DATE32" => "Date32",
19361 "INT" => "Int32",
19362 "MEDIUMINT" => "Int32",
19363 "INT8" => "Int8",
19364 "INT16" => "Int16",
19365 "INT32" => "Int32",
19366 "INT64" => "Int64",
19367 "INT128" => "Int128",
19368 "INT256" => "Int256",
19369 "UINT8" => "UInt8",
19370 "UINT16" => "UInt16",
19371 "UINT32" => "UInt32",
19372 "UINT64" => "UInt64",
19373 "UINT128" => "UInt128",
19374 "UINT256" => "UInt256",
19375 "FLOAT32" => "Float32",
19376 "FLOAT64" => "Float64",
19377 "DECIMAL32" => "Decimal32",
19378 "DECIMAL64" => "Decimal64",
19379 "DECIMAL128" => "Decimal128",
19380 "DECIMAL256" => "Decimal256",
19381 "ENUM" => "Enum",
19382 "ENUM8" => "Enum8",
19383 "ENUM16" => "Enum16",
19384 "FIXEDSTRING" => "FixedString",
19385 "NESTED" => "Nested",
19386 "LOWCARDINALITY" => "LowCardinality",
19387 "NULLABLE" => "Nullable",
19388 "IPV4" => "IPv4",
19389 "IPV6" => "IPv6",
19390 "POINT" => "Point",
19391 "RING" => "Ring",
19392 "LINESTRING" => "LineString",
19393 "MULTILINESTRING" => "MultiLineString",
19394 "POLYGON" => "Polygon",
19395 "MULTIPOLYGON" => "MultiPolygon",
19396 "AGGREGATEFUNCTION" => "AggregateFunction",
19397 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
19398 "DYNAMIC" => "Dynamic",
19399 _ => "",
19400 };
19401 if mapped.is_empty() {
19402 self.write(name);
19403 } else {
19404 self.write(mapped);
19405 self.write(suffix);
19406 }
19407 }
19408 Some(DialectType::MySQL) if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" => {
19409 self.write_keyword("TIMESTAMP");
19411 }
19412 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
19413 self.write_keyword("SQL_VARIANT");
19414 }
19415 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
19416 self.write_keyword("DECIMAL(38, 5)");
19417 }
19418 Some(DialectType::Exasol) => {
19419 match name_upper.as_str() {
19421 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
19423 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
19425 "MEDIUMINT" => self.write_keyword("INT"),
19427 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => self.write_keyword("DECIMAL"),
19429 "DATETIME" => self.write_keyword("TIMESTAMP"),
19431 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
19432 _ => self.write(name),
19433 }
19434 }
19435 Some(DialectType::Dremio) => {
19436 match name_upper.as_str() {
19438 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
19439 "ARRAY" => self.write_keyword("LIST"),
19440 "NCHAR" => self.write_keyword("VARCHAR"),
19441 _ => self.write(name),
19442 }
19443 }
19444 _ => {
19446 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
19448 (name_upper[..idx].to_string(), Some(&name[idx..]))
19449 } else {
19450 (name_upper.clone(), None)
19451 };
19452
19453 match base_upper.as_str() {
19454 "INT64" if !matches!(self.config.dialect, Some(DialectType::BigQuery)) => {
19455 self.write_keyword("BIGINT");
19456 }
19457 "FLOAT64" if !matches!(self.config.dialect, Some(DialectType::BigQuery)) => {
19458 self.write_keyword("DOUBLE");
19459 }
19460 "BOOL" if !matches!(self.config.dialect, Some(DialectType::BigQuery)) => {
19461 self.write_keyword("BOOLEAN");
19462 }
19463 "BYTES" if matches!(self.config.dialect, Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)) => {
19464 self.write_keyword("BINARY");
19465 }
19466 "BYTES" if !matches!(self.config.dialect, Some(DialectType::BigQuery)) => {
19467 self.write_keyword("VARBINARY");
19468 }
19469 "DATETIME2" | "SMALLDATETIME" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) => {
19471 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) {
19473 self.write_keyword("TIMESTAMP");
19474 if let Some(args) = _args_str {
19475 self.write(args);
19476 }
19477 } else {
19478 self.write_keyword("TIMESTAMP");
19479 }
19480 }
19481 "DATETIMEOFFSET" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) => {
19483 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) {
19484 self.write_keyword("TIMESTAMPTZ");
19485 if let Some(args) = _args_str {
19486 self.write(args);
19487 }
19488 } else {
19489 self.write_keyword("TIMESTAMPTZ");
19490 }
19491 }
19492 "UNIQUEIDENTIFIER" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) => {
19494 match self.config.dialect {
19495 Some(DialectType::Spark) | Some(DialectType::Databricks)
19496 | Some(DialectType::Hive) => self.write_keyword("STRING"),
19497 _ => self.write_keyword("UUID"),
19498 }
19499 }
19500 "BIT" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)
19502 | Some(DialectType::PostgreSQL) | Some(DialectType::MySQL) | Some(DialectType::DuckDB)) => {
19503 self.write_keyword("BOOLEAN");
19504 }
19505 "NVARCHAR" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) => {
19507 match self.config.dialect {
19508 Some(DialectType::SQLite) => {
19509 self.write_keyword("TEXT");
19510 if let Some(args) = _args_str {
19511 self.write(args);
19512 }
19513 }
19514 Some(DialectType::Spark) | Some(DialectType::Databricks)
19515 | Some(DialectType::Hive) => {
19516 if _args_str.is_some() {
19517 self.write_keyword("VARCHAR");
19518 self.write(_args_str.unwrap());
19519 } else {
19520 self.write_keyword("VARCHAR(30)");
19521 }
19522 }
19523 _ => {
19524 self.write_keyword("VARCHAR");
19525 if let Some(args) = _args_str {
19526 self.write(args);
19527 }
19528 }
19529 }
19530 }
19531 "NCHAR" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) => {
19533 match self.config.dialect {
19534 Some(DialectType::Spark) | Some(DialectType::Databricks)
19535 | Some(DialectType::Hive) => {
19536 if _args_str.is_some() {
19537 self.write_keyword("CHAR");
19538 self.write(_args_str.unwrap());
19539 } else {
19540 self.write_keyword("CHAR(30)");
19541 }
19542 }
19543 _ => {
19544 self.write_keyword("CHAR");
19545 if let Some(args) = _args_str {
19546 self.write(args);
19547 }
19548 }
19549 }
19550 }
19551 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => {
19554 match self.config.dialect {
19555 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
19556 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => self.write_keyword("TEXT"),
19557 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
19558 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
19559 Some(DialectType::Snowflake) | Some(DialectType::Redshift) | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
19560 _ => self.write_keyword("TEXT"),
19561 }
19562 }
19563 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => {
19566 match self.config.dialect {
19567 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
19568 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => self.write_keyword("BLOB"),
19569 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
19570 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
19571 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
19572 Some(DialectType::Snowflake) | Some(DialectType::Redshift) | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
19573 _ => self.write_keyword("BLOB"),
19574 }
19575 }
19576 "LONGVARCHAR" => {
19578 match self.config.dialect {
19579 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
19580 _ => self.write_keyword("VARCHAR"),
19581 }
19582 }
19583 _ => self.write(name),
19584 }
19585 }
19586 }
19587 }
19588 DataType::Geometry { subtype, srid } => {
19589 match self.config.dialect {
19591 Some(DialectType::MySQL) => {
19592 if let Some(sub) = subtype {
19594 self.write_keyword(sub);
19595 if let Some(s) = srid {
19596 self.write(" SRID ");
19597 self.write(&s.to_string());
19598 }
19599 } else {
19600 self.write_keyword("GEOMETRY");
19601 }
19602 }
19603 Some(DialectType::BigQuery) => {
19604 self.write_keyword("GEOGRAPHY");
19606 }
19607 Some(DialectType::Teradata) => {
19608 self.write_keyword("ST_GEOMETRY");
19610 if subtype.is_some() || srid.is_some() {
19611 self.write("(");
19612 if let Some(sub) = subtype {
19613 self.write_keyword(sub);
19614 }
19615 if let Some(s) = srid {
19616 if subtype.is_some() {
19617 self.write(", ");
19618 }
19619 self.write(&s.to_string());
19620 }
19621 self.write(")");
19622 }
19623 }
19624 _ => {
19625 self.write_keyword("GEOMETRY");
19627 if subtype.is_some() || srid.is_some() {
19628 self.write("(");
19629 if let Some(sub) = subtype {
19630 self.write_keyword(sub);
19631 }
19632 if let Some(s) = srid {
19633 if subtype.is_some() {
19634 self.write(", ");
19635 }
19636 self.write(&s.to_string());
19637 }
19638 self.write(")");
19639 }
19640 }
19641 }
19642 }
19643 DataType::Geography { subtype, srid } => {
19644 match self.config.dialect {
19646 Some(DialectType::MySQL) => {
19647 if let Some(sub) = subtype {
19649 self.write_keyword(sub);
19650 } else {
19651 self.write_keyword("GEOMETRY");
19652 }
19653 let effective_srid = srid.unwrap_or(4326);
19655 self.write(" SRID ");
19656 self.write(&effective_srid.to_string());
19657 }
19658 Some(DialectType::BigQuery) => {
19659 self.write_keyword("GEOGRAPHY");
19661 }
19662 Some(DialectType::Snowflake) => {
19663 self.write_keyword("GEOGRAPHY");
19665 }
19666 _ => {
19667 self.write_keyword("GEOGRAPHY");
19669 if subtype.is_some() || srid.is_some() {
19670 self.write("(");
19671 if let Some(sub) = subtype {
19672 self.write_keyword(sub);
19673 }
19674 if let Some(s) = srid {
19675 if subtype.is_some() {
19676 self.write(", ");
19677 }
19678 self.write(&s.to_string());
19679 }
19680 self.write(")");
19681 }
19682 }
19683 }
19684 }
19685 DataType::CharacterSet { name } => {
19686 self.write_keyword("CHAR CHARACTER SET ");
19688 self.write(name);
19689 }
19690 _ => self.write("UNKNOWN"),
19691 }
19692 Ok(())
19693 }
19694
19695 fn write(&mut self, s: &str) {
19698 self.output.push_str(s);
19699 }
19700
19701 fn write_space(&mut self) {
19702 self.output.push(' ');
19703 }
19704
19705 fn write_keyword(&mut self, keyword: &str) {
19706 if self.config.uppercase_keywords {
19707 self.output.push_str(keyword);
19708 } else {
19709 self.output.push_str(&keyword.to_lowercase());
19710 }
19711 }
19712
19713 fn convert_strptime_to_exasol_format(format: &str) -> String {
19717 let mut result = String::new();
19718 let chars: Vec<char> = format.chars().collect();
19719 let mut i = 0;
19720 while i < chars.len() {
19721 if chars[i] == '%' && i + 1 < chars.len() {
19722 let spec = chars[i + 1];
19723 let exasol_spec = match spec {
19724 'Y' => "YYYY",
19725 'y' => "YY",
19726 'm' => "MM",
19727 'd' => "DD",
19728 'H' => "HH",
19729 'M' => "MI",
19730 'S' => "SS",
19731 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
19743 result.push('%');
19745 result.push(spec);
19746 i += 2;
19747 continue;
19748 }
19749 };
19750 result.push_str(exasol_spec);
19751 i += 2;
19752 } else {
19753 result.push(chars[i]);
19754 i += 1;
19755 }
19756 }
19757 result
19758 }
19759
19760 fn convert_strptime_to_postgres_format(format: &str) -> String {
19764 let mut result = String::new();
19765 let chars: Vec<char> = format.chars().collect();
19766 let mut i = 0;
19767 while i < chars.len() {
19768 if chars[i] == '%' && i + 1 < chars.len() {
19769 let spec = chars[i + 1];
19770 let pg_spec = match spec {
19771 'Y' => "YYYY",
19772 'y' => "YY",
19773 'm' => "MM",
19774 'd' => "DD",
19775 'H' => "HH24",
19776 'I' => "HH12",
19777 'M' => "MI",
19778 'S' => "SS",
19779 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
19790 result.push('%');
19792 result.push(spec);
19793 i += 2;
19794 continue;
19795 }
19796 };
19797 result.push_str(pg_spec);
19798 i += 2;
19799 } else {
19800 result.push(chars[i]);
19801 i += 1;
19802 }
19803 }
19804 result
19805 }
19806
19807 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
19809 if self.config.limit_only_literals {
19810 if let Some(value) = Self::try_evaluate_constant(expr) {
19811 self.write(&value.to_string());
19812 return Ok(());
19813 }
19814 }
19815 self.generate_expression(expr)
19816 }
19817
19818 fn write_formatted_comment(&mut self, comment: &str) {
19822 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
19825 comment[2..comment.len() - 2].trim()
19827 } else if comment.starts_with("--") {
19828 comment[2..].trim()
19830 } else {
19831 comment.trim()
19833 };
19834 self.output.push_str("/* ");
19835 self.output.push_str(content);
19836 self.output.push_str(" */");
19837 }
19838
19839 fn escape_block_for_single_quote(&self, block: &str) -> String {
19842 let escape_backslash = matches!(
19843 self.config.dialect,
19844 Some(crate::dialects::DialectType::Snowflake)
19845 );
19846 let mut escaped = String::with_capacity(block.len() + 4);
19847 for ch in block.chars() {
19848 if ch == '\'' {
19849 escaped.push('\\');
19850 escaped.push('\'');
19851 } else if escape_backslash && ch == '\\' {
19852 escaped.push('\\');
19853 escaped.push('\\');
19854 } else {
19855 escaped.push(ch);
19856 }
19857 }
19858 escaped
19859 }
19860
19861 fn write_newline(&mut self) {
19862 self.output.push('\n');
19863 }
19864
19865 fn write_indent(&mut self) {
19866 for _ in 0..self.indent_level {
19867 self.output.push_str(&self.config.indent);
19868 }
19869 }
19870
19871 fn too_wide(&self, args: &[String]) -> bool {
19877 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
19878 }
19879
19880 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
19883 if self.config.pretty {
19884 self.write_newline();
19885 self.write_indent();
19886 self.write_keyword(keyword);
19887 self.write_newline();
19888 self.indent_level += 1;
19889 self.write_indent();
19890 self.generate_expression(condition)?;
19891 self.indent_level -= 1;
19892 } else {
19893 self.write_space();
19894 self.write_keyword(keyword);
19895 self.write_space();
19896 self.generate_expression(condition)?;
19897 }
19898 Ok(())
19899 }
19900
19901 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
19904 if exprs.is_empty() {
19905 return Ok(());
19906 }
19907
19908 if self.config.pretty {
19909 self.write_newline();
19910 self.write_indent();
19911 self.write_keyword(keyword);
19912 self.write_newline();
19913 self.indent_level += 1;
19914 for (i, expr) in exprs.iter().enumerate() {
19915 if i > 0 {
19916 self.write(",");
19917 self.write_newline();
19918 }
19919 self.write_indent();
19920 self.generate_expression(expr)?;
19921 }
19922 self.indent_level -= 1;
19923 } else {
19924 self.write_space();
19925 self.write_keyword(keyword);
19926 self.write_space();
19927 for (i, expr) in exprs.iter().enumerate() {
19928 if i > 0 {
19929 self.write(", ");
19930 }
19931 self.generate_expression(expr)?;
19932 }
19933 }
19934 Ok(())
19935 }
19936
19937 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
19939 if orderings.is_empty() {
19940 return Ok(());
19941 }
19942
19943 if self.config.pretty {
19944 self.write_newline();
19945 self.write_indent();
19946 self.write_keyword(keyword);
19947 self.write_newline();
19948 self.indent_level += 1;
19949 for (i, ordered) in orderings.iter().enumerate() {
19950 if i > 0 {
19951 self.write(",");
19952 self.write_newline();
19953 }
19954 self.write_indent();
19955 self.generate_ordered(ordered)?;
19956 }
19957 self.indent_level -= 1;
19958 } else {
19959 self.write_space();
19960 self.write_keyword(keyword);
19961 self.write_space();
19962 for (i, ordered) in orderings.iter().enumerate() {
19963 if i > 0 {
19964 self.write(", ");
19965 }
19966 self.generate_ordered(ordered)?;
19967 }
19968 }
19969 Ok(())
19970 }
19971
19972 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
19974 if windows.is_empty() {
19975 return Ok(());
19976 }
19977
19978 if self.config.pretty {
19979 self.write_newline();
19980 self.write_indent();
19981 self.write_keyword("WINDOW");
19982 self.write_newline();
19983 self.indent_level += 1;
19984 for (i, named_window) in windows.iter().enumerate() {
19985 if i > 0 {
19986 self.write(",");
19987 self.write_newline();
19988 }
19989 self.write_indent();
19990 self.generate_identifier(&named_window.name)?;
19991 self.write_space();
19992 self.write_keyword("AS");
19993 self.write(" (");
19994 self.generate_over(&named_window.spec)?;
19995 self.write(")");
19996 }
19997 self.indent_level -= 1;
19998 } else {
19999 self.write_space();
20000 self.write_keyword("WINDOW");
20001 self.write_space();
20002 for (i, named_window) in windows.iter().enumerate() {
20003 if i > 0 {
20004 self.write(", ");
20005 }
20006 self.generate_identifier(&named_window.name)?;
20007 self.write_space();
20008 self.write_keyword("AS");
20009 self.write(" (");
20010 self.generate_over(&named_window.spec)?;
20011 self.write(")");
20012 }
20013 }
20014 Ok(())
20015 }
20016
20017 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
20019 self.write_keyword("AI_AGG");
20021 self.write("(");
20022 self.generate_expression(&e.this)?;
20023 self.write(", ");
20024 self.generate_expression(&e.expression)?;
20025 self.write(")");
20026 Ok(())
20027 }
20028
20029 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
20030 self.write_keyword("AI_CLASSIFY");
20032 self.write("(");
20033 self.generate_expression(&e.this)?;
20034 if let Some(categories) = &e.categories {
20035 self.write(", ");
20036 self.generate_expression(categories)?;
20037 }
20038 if let Some(config) = &e.config {
20039 self.write(", ");
20040 self.generate_expression(config)?;
20041 }
20042 self.write(")");
20043 Ok(())
20044 }
20045
20046 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
20047 self.write_keyword("ADD");
20049 self.write_space();
20050 if e.exists {
20051 self.write_keyword("IF NOT EXISTS");
20052 self.write_space();
20053 }
20054 self.generate_expression(&e.this)?;
20055 if let Some(location) = &e.location {
20056 self.write_space();
20057 self.generate_expression(location)?;
20058 }
20059 Ok(())
20060 }
20061
20062 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
20063 self.write_keyword("ALGORITHM");
20065 self.write("=");
20066 self.generate_expression(&e.this)?;
20067 Ok(())
20068 }
20069
20070 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
20071 self.generate_expression(&e.this)?;
20073 self.write_space();
20074 self.write_keyword("AS");
20075 self.write(" (");
20076 for (i, expr) in e.expressions.iter().enumerate() {
20077 if i > 0 {
20078 self.write(", ");
20079 }
20080 self.generate_expression(expr)?;
20081 }
20082 self.write(")");
20083 Ok(())
20084 }
20085
20086 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
20087 self.write_keyword("ALLOWED_VALUES");
20089 self.write_space();
20090 for (i, expr) in e.expressions.iter().enumerate() {
20091 if i > 0 {
20092 self.write(", ");
20093 }
20094 self.generate_expression(expr)?;
20095 }
20096 Ok(())
20097 }
20098
20099 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
20100 self.write_keyword("ALTER COLUMN");
20102 self.write_space();
20103 self.generate_expression(&e.this)?;
20104
20105 if let Some(dtype) = &e.dtype {
20106 self.write_space();
20107 self.write_keyword("SET DATA TYPE");
20108 self.write_space();
20109 self.generate_expression(dtype)?;
20110 if let Some(collate) = &e.collate {
20111 self.write_space();
20112 self.write_keyword("COLLATE");
20113 self.write_space();
20114 self.generate_expression(collate)?;
20115 }
20116 if let Some(using) = &e.using {
20117 self.write_space();
20118 self.write_keyword("USING");
20119 self.write_space();
20120 self.generate_expression(using)?;
20121 }
20122 } else if let Some(default) = &e.default {
20123 self.write_space();
20124 self.write_keyword("SET DEFAULT");
20125 self.write_space();
20126 self.generate_expression(default)?;
20127 } else if let Some(comment) = &e.comment {
20128 self.write_space();
20129 self.write_keyword("COMMENT");
20130 self.write_space();
20131 self.generate_expression(comment)?;
20132 } else if let Some(drop) = &e.drop {
20133 self.write_space();
20134 self.write_keyword("DROP");
20135 self.write_space();
20136 self.generate_expression(drop)?;
20137 } else if let Some(visible) = &e.visible {
20138 self.write_space();
20139 self.generate_expression(visible)?;
20140 } else if let Some(rename_to) = &e.rename_to {
20141 self.write_space();
20142 self.write_keyword("RENAME TO");
20143 self.write_space();
20144 self.generate_expression(rename_to)?;
20145 } else if let Some(allow_null) = &e.allow_null {
20146 self.write_space();
20147 self.generate_expression(allow_null)?;
20148 }
20149 Ok(())
20150 }
20151
20152 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
20153 self.write_keyword("ALTER SESSION");
20155 self.write_space();
20156 if e.unset.is_some() {
20157 self.write_keyword("UNSET");
20158 } else {
20159 self.write_keyword("SET");
20160 }
20161 self.write_space();
20162 for (i, expr) in e.expressions.iter().enumerate() {
20163 if i > 0 {
20164 self.write(", ");
20165 }
20166 self.generate_expression(expr)?;
20167 }
20168 Ok(())
20169 }
20170
20171 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
20172 self.write_keyword("SET");
20174
20175 if let Some(opt) = &e.option {
20177 self.write_space();
20178 self.generate_expression(opt)?;
20179 }
20180
20181 if !e.expressions.is_empty() {
20184 let is_properties = e.expressions.iter().any(|expr| matches!(expr, Expression::Eq(_)));
20186 if is_properties && e.option.is_none() {
20187 self.write_space();
20188 self.write_keyword("PROPERTIES");
20189 }
20190 self.write_space();
20191 for (i, expr) in e.expressions.iter().enumerate() {
20192 if i > 0 {
20193 self.write(", ");
20194 }
20195 self.generate_expression(expr)?;
20196 }
20197 }
20198
20199 if let Some(file_format) = &e.file_format {
20201 self.write(" ");
20202 self.write_keyword("STAGE_FILE_FORMAT");
20203 self.write(" = (");
20204 self.generate_space_separated_properties(file_format)?;
20205 self.write(")");
20206 }
20207
20208 if let Some(copy_options) = &e.copy_options {
20210 self.write(" ");
20211 self.write_keyword("STAGE_COPY_OPTIONS");
20212 self.write(" = (");
20213 self.generate_space_separated_properties(copy_options)?;
20214 self.write(")");
20215 }
20216
20217 if let Some(tag) = &e.tag {
20219 self.write(" ");
20220 self.write_keyword("TAG");
20221 self.write(" ");
20222 self.generate_expression(tag)?;
20223 }
20224
20225 Ok(())
20226 }
20227
20228 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
20230 match expr {
20231 Expression::Tuple(t) => {
20232 for (i, prop) in t.expressions.iter().enumerate() {
20233 if i > 0 {
20234 self.write(" ");
20235 }
20236 self.generate_expression(prop)?;
20237 }
20238 }
20239 _ => {
20240 self.generate_expression(expr)?;
20241 }
20242 }
20243 Ok(())
20244 }
20245
20246 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
20247 self.write_keyword("ALTER");
20249 if e.compound.is_some() {
20250 self.write_space();
20251 self.write_keyword("COMPOUND");
20252 }
20253 self.write_space();
20254 self.write_keyword("SORTKEY");
20255 self.write_space();
20256 if let Some(this) = &e.this {
20257 self.generate_expression(this)?;
20258 } else if !e.expressions.is_empty() {
20259 self.write("(");
20260 for (i, expr) in e.expressions.iter().enumerate() {
20261 if i > 0 {
20262 self.write(", ");
20263 }
20264 self.generate_expression(expr)?;
20265 }
20266 self.write(")");
20267 }
20268 Ok(())
20269 }
20270
20271 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
20272 self.write_keyword("ANALYZE");
20274 if !e.options.is_empty() {
20275 self.write_space();
20276 for (i, opt) in e.options.iter().enumerate() {
20277 if i > 0 {
20278 self.write_space();
20279 }
20280 if let Expression::Identifier(id) = opt {
20282 self.write_keyword(&id.name);
20283 } else {
20284 self.generate_expression(opt)?;
20285 }
20286 }
20287 }
20288 if let Some(kind) = &e.kind {
20289 self.write_space();
20290 self.write_keyword(kind);
20291 }
20292 if let Some(this) = &e.this {
20293 self.write_space();
20294 self.generate_expression(this)?;
20295 }
20296 if !e.columns.is_empty() {
20298 self.write("(");
20299 for (i, col) in e.columns.iter().enumerate() {
20300 if i > 0 {
20301 self.write(", ");
20302 }
20303 self.write(col);
20304 }
20305 self.write(")");
20306 }
20307 if let Some(partition) = &e.partition {
20308 self.write_space();
20309 self.generate_expression(partition)?;
20310 }
20311 if let Some(mode) = &e.mode {
20312 self.write_space();
20313 self.generate_expression(mode)?;
20314 }
20315 if let Some(expression) = &e.expression {
20316 self.write_space();
20317 self.generate_expression(expression)?;
20318 }
20319 if !e.properties.is_empty() {
20320 self.write_space();
20321 self.write_keyword(self.config.with_properties_prefix);
20322 self.write(" (");
20323 for (i, prop) in e.properties.iter().enumerate() {
20324 if i > 0 {
20325 self.write(", ");
20326 }
20327 self.generate_expression(prop)?;
20328 }
20329 self.write(")");
20330 }
20331 Ok(())
20332 }
20333
20334 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
20335 self.write_keyword("DELETE");
20337 if let Some(kind) = &e.kind {
20338 self.write_space();
20339 self.write_keyword(kind);
20340 }
20341 self.write_space();
20342 self.write_keyword("STATISTICS");
20343 Ok(())
20344 }
20345
20346 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
20347 if let Expression::Identifier(id) = e.this.as_ref() {
20350 self.write_keyword(&id.name);
20351 } else {
20352 self.generate_expression(&e.this)?;
20353 }
20354 self.write_space();
20355 self.write_keyword("HISTOGRAM ON");
20356 self.write_space();
20357 for (i, expr) in e.expressions.iter().enumerate() {
20358 if i > 0 {
20359 self.write(", ");
20360 }
20361 self.generate_expression(expr)?;
20362 }
20363 if let Some(expression) = &e.expression {
20364 self.write_space();
20365 self.generate_expression(expression)?;
20366 }
20367 if let Some(update_options) = &e.update_options {
20368 self.write_space();
20369 self.generate_expression(update_options)?;
20370 self.write_space();
20371 self.write_keyword("UPDATE");
20372 }
20373 Ok(())
20374 }
20375
20376 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
20377 self.write_keyword("LIST CHAINED ROWS");
20379 if let Some(expression) = &e.expression {
20380 self.write_space();
20381 self.write_keyword("INTO");
20382 self.write_space();
20383 self.generate_expression(expression)?;
20384 }
20385 Ok(())
20386 }
20387
20388 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
20389 self.write_keyword("SAMPLE");
20391 self.write_space();
20392 if let Some(sample) = &e.sample {
20393 self.generate_expression(sample)?;
20394 self.write_space();
20395 }
20396 self.write_keyword(&e.kind);
20397 Ok(())
20398 }
20399
20400 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
20401 self.write_keyword(&e.kind);
20403 if let Some(option) = &e.option {
20404 self.write_space();
20405 self.generate_expression(option)?;
20406 }
20407 self.write_space();
20408 self.write_keyword("STATISTICS");
20409 if let Some(this) = &e.this {
20410 self.write_space();
20411 self.generate_expression(this)?;
20412 }
20413 if !e.expressions.is_empty() {
20414 self.write_space();
20415 for (i, expr) in e.expressions.iter().enumerate() {
20416 if i > 0 {
20417 self.write(", ");
20418 }
20419 self.generate_expression(expr)?;
20420 }
20421 }
20422 Ok(())
20423 }
20424
20425 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
20426 self.write_keyword("VALIDATE");
20428 self.write_space();
20429 self.write_keyword(&e.kind);
20430 if let Some(this) = &e.this {
20431 self.write_space();
20432 if let Expression::Identifier(id) = this.as_ref() {
20434 self.write_keyword(&id.name);
20435 } else {
20436 self.generate_expression(this)?;
20437 }
20438 }
20439 if let Some(expression) = &e.expression {
20440 self.write_space();
20441 self.write_keyword("INTO");
20442 self.write_space();
20443 self.generate_expression(expression)?;
20444 }
20445 Ok(())
20446 }
20447
20448 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
20449 self.write_keyword("WITH");
20451 self.write_space();
20452 for (i, expr) in e.expressions.iter().enumerate() {
20453 if i > 0 {
20454 self.write(", ");
20455 }
20456 self.generate_expression(expr)?;
20457 }
20458 Ok(())
20459 }
20460
20461 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
20462 self.generate_expression(&e.this)?;
20465 self.write("(");
20466 for (i, arg) in e.expressions.iter().enumerate() {
20467 if i > 0 {
20468 self.write(", ");
20469 }
20470 self.generate_expression(arg)?;
20471 }
20472 self.write(")");
20473 Ok(())
20474 }
20475
20476 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
20477 self.generate_expression(&e.this)?;
20479 self.write("(");
20480 for (i, arg) in e.expressions.iter().enumerate() {
20481 if i > 0 {
20482 self.write(", ");
20483 }
20484 self.generate_expression(arg)?;
20485 }
20486 self.write(")");
20487 Ok(())
20488 }
20489
20490 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
20491 self.generate_expression(&e.this)?;
20493 self.write_space();
20494 self.write_keyword("APPLY");
20495 self.write("(");
20496 self.generate_expression(&e.expression)?;
20497 self.write(")");
20498 Ok(())
20499 }
20500
20501 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
20502 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
20504 self.write("(");
20505 self.generate_expression(&e.this)?;
20506 if let Some(percentile) = &e.percentile {
20507 self.write(", ");
20508 self.generate_expression(percentile)?;
20509 }
20510 self.write(")");
20511 Ok(())
20512 }
20513
20514 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
20515 self.write_keyword("APPROX_QUANTILE");
20517 self.write("(");
20518 self.generate_expression(&e.this)?;
20519 if let Some(quantile) = &e.quantile {
20520 self.write(", ");
20521 self.generate_expression(quantile)?;
20522 }
20523 if let Some(accuracy) = &e.accuracy {
20524 self.write(", ");
20525 self.generate_expression(accuracy)?;
20526 }
20527 if let Some(weight) = &e.weight {
20528 self.write(", ");
20529 self.generate_expression(weight)?;
20530 }
20531 self.write(")");
20532 Ok(())
20533 }
20534
20535 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
20536 self.write_keyword("APPROX_QUANTILES");
20538 self.write("(");
20539 self.generate_expression(&e.this)?;
20540 if let Some(expression) = &e.expression {
20541 self.write(", ");
20542 self.generate_expression(expression)?;
20543 }
20544 self.write(")");
20545 Ok(())
20546 }
20547
20548 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
20549 self.write_keyword("APPROX_TOP_K");
20551 self.write("(");
20552 self.generate_expression(&e.this)?;
20553 if let Some(expression) = &e.expression {
20554 self.write(", ");
20555 self.generate_expression(expression)?;
20556 }
20557 if let Some(counters) = &e.counters {
20558 self.write(", ");
20559 self.generate_expression(counters)?;
20560 }
20561 self.write(")");
20562 Ok(())
20563 }
20564
20565 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
20566 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
20568 self.write("(");
20569 self.generate_expression(&e.this)?;
20570 if let Some(expression) = &e.expression {
20571 self.write(", ");
20572 self.generate_expression(expression)?;
20573 }
20574 self.write(")");
20575 Ok(())
20576 }
20577
20578 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
20579 self.write_keyword("APPROX_TOP_K_COMBINE");
20581 self.write("(");
20582 self.generate_expression(&e.this)?;
20583 if let Some(expression) = &e.expression {
20584 self.write(", ");
20585 self.generate_expression(expression)?;
20586 }
20587 self.write(")");
20588 Ok(())
20589 }
20590
20591 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
20592 self.write_keyword("APPROX_TOP_K_ESTIMATE");
20594 self.write("(");
20595 self.generate_expression(&e.this)?;
20596 if let Some(expression) = &e.expression {
20597 self.write(", ");
20598 self.generate_expression(expression)?;
20599 }
20600 self.write(")");
20601 Ok(())
20602 }
20603
20604 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
20605 self.write_keyword("APPROX_TOP_SUM");
20607 self.write("(");
20608 self.generate_expression(&e.this)?;
20609 self.write(", ");
20610 self.generate_expression(&e.expression)?;
20611 if let Some(count) = &e.count {
20612 self.write(", ");
20613 self.generate_expression(count)?;
20614 }
20615 self.write(")");
20616 Ok(())
20617 }
20618
20619 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
20620 self.write_keyword("ARG_MAX");
20622 self.write("(");
20623 self.generate_expression(&e.this)?;
20624 self.write(", ");
20625 self.generate_expression(&e.expression)?;
20626 if let Some(count) = &e.count {
20627 self.write(", ");
20628 self.generate_expression(count)?;
20629 }
20630 self.write(")");
20631 Ok(())
20632 }
20633
20634 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
20635 self.write_keyword("ARG_MIN");
20637 self.write("(");
20638 self.generate_expression(&e.this)?;
20639 self.write(", ");
20640 self.generate_expression(&e.expression)?;
20641 if let Some(count) = &e.count {
20642 self.write(", ");
20643 self.generate_expression(count)?;
20644 }
20645 self.write(")");
20646 Ok(())
20647 }
20648
20649 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
20650 self.write_keyword("ARRAY_ALL");
20652 self.write("(");
20653 self.generate_expression(&e.this)?;
20654 self.write(", ");
20655 self.generate_expression(&e.expression)?;
20656 self.write(")");
20657 Ok(())
20658 }
20659
20660 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
20661 self.write_keyword("ARRAY_ANY");
20663 self.write("(");
20664 self.generate_expression(&e.this)?;
20665 self.write(", ");
20666 self.generate_expression(&e.expression)?;
20667 self.write(")");
20668 Ok(())
20669 }
20670
20671 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
20672 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
20674 self.write("(");
20675 for (i, expr) in e.expressions.iter().enumerate() {
20676 if i > 0 {
20677 self.write(", ");
20678 }
20679 self.generate_expression(expr)?;
20680 }
20681 self.write(")");
20682 Ok(())
20683 }
20684
20685 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
20686 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
20688 self.write("arraySum");
20689 } else {
20690 self.write_keyword("ARRAY_SUM");
20691 }
20692 self.write("(");
20693 self.generate_expression(&e.this)?;
20694 if let Some(expression) = &e.expression {
20695 self.write(", ");
20696 self.generate_expression(expression)?;
20697 }
20698 self.write(")");
20699 Ok(())
20700 }
20701
20702 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
20703 self.generate_expression(&e.this)?;
20705 self.write_space();
20706 self.write_keyword("AT");
20707 self.write_space();
20708 self.generate_expression(&e.expression)?;
20709 Ok(())
20710 }
20711
20712 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
20713 self.write_keyword("ATTACH");
20715 if e.exists {
20716 self.write_space();
20717 self.write_keyword("IF NOT EXISTS");
20718 }
20719 self.write_space();
20720 self.generate_expression(&e.this)?;
20721 if !e.expressions.is_empty() {
20722 self.write(" (");
20723 for (i, expr) in e.expressions.iter().enumerate() {
20724 if i > 0 {
20725 self.write(", ");
20726 }
20727 self.generate_expression(expr)?;
20728 }
20729 self.write(")");
20730 }
20731 Ok(())
20732 }
20733
20734 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
20735 self.generate_expression(&e.this)?;
20738 if let Some(expression) = &e.expression {
20739 self.write_space();
20740 self.generate_expression(expression)?;
20741 }
20742 Ok(())
20743 }
20744
20745 fn generate_auto_increment_keyword(&mut self, col: &crate::expressions::ColumnDef) -> Result<()> {
20749 use crate::dialects::DialectType;
20750 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
20751 self.write_keyword("IDENTITY");
20752 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
20753 self.write("(");
20754 if let Some(ref start) = col.auto_increment_start {
20755 self.generate_expression(start)?;
20756 } else {
20757 self.write("0");
20758 }
20759 self.write(", ");
20760 if let Some(ref inc) = col.auto_increment_increment {
20761 self.generate_expression(inc)?;
20762 } else {
20763 self.write("1");
20764 }
20765 self.write(")");
20766 }
20767 } else if matches!(self.config.dialect, Some(DialectType::Snowflake) | Some(DialectType::SQLite)) {
20768 self.write_keyword("AUTOINCREMENT");
20769 if let Some(ref start) = col.auto_increment_start {
20770 self.write_space();
20771 self.write_keyword("START");
20772 self.write_space();
20773 self.generate_expression(start)?;
20774 }
20775 if let Some(ref inc) = col.auto_increment_increment {
20776 self.write_space();
20777 self.write_keyword("INCREMENT");
20778 self.write_space();
20779 self.generate_expression(inc)?;
20780 }
20781 if let Some(order) = col.auto_increment_order {
20782 self.write_space();
20783 if order {
20784 self.write_keyword("ORDER");
20785 } else {
20786 self.write_keyword("NOORDER");
20787 }
20788 }
20789 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
20790 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
20791 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
20792 self.write(" (");
20793 let mut first = true;
20794 if let Some(ref start) = col.auto_increment_start {
20795 self.write_keyword("START WITH");
20796 self.write_space();
20797 self.generate_expression(start)?;
20798 first = false;
20799 }
20800 if let Some(ref inc) = col.auto_increment_increment {
20801 if !first { self.write_space(); }
20802 self.write_keyword("INCREMENT BY");
20803 self.write_space();
20804 self.generate_expression(inc)?;
20805 }
20806 self.write(")");
20807 }
20808 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
20809 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
20810 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
20811 self.write(" (");
20812 let mut first = true;
20813 if let Some(ref start) = col.auto_increment_start {
20814 self.write_keyword("START WITH");
20815 self.write_space();
20816 self.generate_expression(start)?;
20817 first = false;
20818 }
20819 if let Some(ref inc) = col.auto_increment_increment {
20820 if !first { self.write_space(); }
20821 self.write_keyword("INCREMENT BY");
20822 self.write_space();
20823 self.generate_expression(inc)?;
20824 }
20825 self.write(")");
20826 }
20827 } else if matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) {
20828 self.write_keyword("IDENTITY");
20829 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
20830 self.write("(");
20831 if let Some(ref start) = col.auto_increment_start {
20832 self.generate_expression(start)?;
20833 } else {
20834 self.write("0");
20835 }
20836 self.write(", ");
20837 if let Some(ref inc) = col.auto_increment_increment {
20838 self.generate_expression(inc)?;
20839 } else {
20840 self.write("1");
20841 }
20842 self.write(")");
20843 }
20844 } else {
20845 self.write_keyword("AUTO_INCREMENT");
20846 if let Some(ref start) = col.auto_increment_start {
20847 self.write_space();
20848 self.write_keyword("START");
20849 self.write_space();
20850 self.generate_expression(start)?;
20851 }
20852 if let Some(ref inc) = col.auto_increment_increment {
20853 self.write_space();
20854 self.write_keyword("INCREMENT");
20855 self.write_space();
20856 self.generate_expression(inc)?;
20857 }
20858 if let Some(order) = col.auto_increment_order {
20859 self.write_space();
20860 if order {
20861 self.write_keyword("ORDER");
20862 } else {
20863 self.write_keyword("NOORDER");
20864 }
20865 }
20866 }
20867 Ok(())
20868 }
20869
20870 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
20871 self.write_keyword("AUTO_INCREMENT");
20873 self.write("=");
20874 self.generate_expression(&e.this)?;
20875 Ok(())
20876 }
20877
20878 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
20879 self.write_keyword("AUTO_REFRESH");
20881 self.write("=");
20882 self.generate_expression(&e.this)?;
20883 Ok(())
20884 }
20885
20886 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
20887 self.write_keyword("BACKUP");
20889 self.write_space();
20890 self.generate_expression(&e.this)?;
20891 Ok(())
20892 }
20893
20894 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
20895 self.write_keyword("BASE64_DECODE_BINARY");
20897 self.write("(");
20898 self.generate_expression(&e.this)?;
20899 if let Some(alphabet) = &e.alphabet {
20900 self.write(", ");
20901 self.generate_expression(alphabet)?;
20902 }
20903 self.write(")");
20904 Ok(())
20905 }
20906
20907 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
20908 self.write_keyword("BASE64_DECODE_STRING");
20910 self.write("(");
20911 self.generate_expression(&e.this)?;
20912 if let Some(alphabet) = &e.alphabet {
20913 self.write(", ");
20914 self.generate_expression(alphabet)?;
20915 }
20916 self.write(")");
20917 Ok(())
20918 }
20919
20920 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
20921 self.write_keyword("BASE64_ENCODE");
20923 self.write("(");
20924 self.generate_expression(&e.this)?;
20925 if let Some(max_line_length) = &e.max_line_length {
20926 self.write(", ");
20927 self.generate_expression(max_line_length)?;
20928 }
20929 if let Some(alphabet) = &e.alphabet {
20930 self.write(", ");
20931 self.generate_expression(alphabet)?;
20932 }
20933 self.write(")");
20934 Ok(())
20935 }
20936
20937 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
20938 self.write_keyword("BLOCKCOMPRESSION");
20940 self.write("=");
20941 if let Some(autotemp) = &e.autotemp {
20942 self.write_keyword("AUTOTEMP");
20943 self.write("(");
20944 self.generate_expression(autotemp)?;
20945 self.write(")");
20946 }
20947 if let Some(always) = &e.always {
20948 self.generate_expression(always)?;
20949 }
20950 if let Some(default) = &e.default {
20951 self.generate_expression(default)?;
20952 }
20953 if let Some(manual) = &e.manual {
20954 self.generate_expression(manual)?;
20955 }
20956 if let Some(never) = &e.never {
20957 self.generate_expression(never)?;
20958 }
20959 Ok(())
20960 }
20961
20962 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
20963 self.write("((");
20965 self.generate_expression(&e.this)?;
20966 self.write(") ");
20967 self.write_keyword("AND");
20968 self.write(" (");
20969 self.generate_expression(&e.expression)?;
20970 self.write("))");
20971 Ok(())
20972 }
20973
20974 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
20975 self.write("((");
20977 self.generate_expression(&e.this)?;
20978 self.write(") ");
20979 self.write_keyword("OR");
20980 self.write(" (");
20981 self.generate_expression(&e.expression)?;
20982 self.write("))");
20983 Ok(())
20984 }
20985
20986 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
20987 self.write_keyword("BUILD");
20989 self.write_space();
20990 self.generate_expression(&e.this)?;
20991 Ok(())
20992 }
20993
20994 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
20995 self.generate_expression(&e.this)?;
20997 Ok(())
20998 }
20999
21000 fn generate_case_specific_column_constraint(&mut self, e: &CaseSpecificColumnConstraint) -> Result<()> {
21001 if e.not_.is_some() {
21003 self.write_keyword("NOT");
21004 self.write_space();
21005 }
21006 self.write_keyword("CASESPECIFIC");
21007 Ok(())
21008 }
21009
21010 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
21011 self.write_keyword("CAST");
21013 self.write("(");
21014 self.generate_expression(&e.this)?;
21015 if self.config.dialect == Some(DialectType::ClickHouse) {
21016 self.write(", ");
21018 } else {
21019 self.write_space();
21020 self.write_keyword("AS");
21021 self.write_space();
21022 }
21023 if let Some(to) = &e.to {
21024 self.generate_expression(to)?;
21025 }
21026 self.write(")");
21027 Ok(())
21028 }
21029
21030 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
21031 self.write_keyword("CHANGES");
21034 self.write(" (");
21035 if let Some(information) = &e.information {
21036 self.write_keyword("INFORMATION");
21037 self.write(" => ");
21038 self.generate_expression(information)?;
21039 }
21040 self.write(")");
21041 if let Some(at_before) = &e.at_before {
21043 self.write(" ");
21044 self.generate_expression(at_before)?;
21045 }
21046 if let Some(end) = &e.end {
21047 self.write(" ");
21048 self.generate_expression(end)?;
21049 }
21050 Ok(())
21051 }
21052
21053 fn generate_character_set_column_constraint(&mut self, e: &CharacterSetColumnConstraint) -> Result<()> {
21054 self.write_keyword("CHARACTER SET");
21056 self.write_space();
21057 self.generate_expression(&e.this)?;
21058 Ok(())
21059 }
21060
21061 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
21062 if e.default.is_some() {
21064 self.write_keyword("DEFAULT");
21065 self.write_space();
21066 }
21067 self.write_keyword("CHARACTER SET");
21068 self.write("=");
21069 self.generate_expression(&e.this)?;
21070 Ok(())
21071 }
21072
21073 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
21074 self.write_keyword("CHECK");
21076 self.write(" (");
21077 self.generate_expression(&e.this)?;
21078 self.write(")");
21079 if e.enforced.is_some() {
21080 self.write_space();
21081 self.write_keyword("ENFORCED");
21082 }
21083 Ok(())
21084 }
21085
21086 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
21087 self.write_keyword("CHECK_JSON");
21089 self.write("(");
21090 self.generate_expression(&e.this)?;
21091 self.write(")");
21092 Ok(())
21093 }
21094
21095 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
21096 self.write_keyword("CHECK_XML");
21098 self.write("(");
21099 self.generate_expression(&e.this)?;
21100 self.write(")");
21101 Ok(())
21102 }
21103
21104 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
21105 self.write_keyword("CHECKSUM");
21107 self.write("=");
21108 if e.on.is_some() {
21109 self.write_keyword("ON");
21110 } else if e.default.is_some() {
21111 self.write_keyword("DEFAULT");
21112 } else {
21113 self.write_keyword("OFF");
21114 }
21115 Ok(())
21116 }
21117
21118 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
21119 if e.shallow.is_some() {
21121 self.write_keyword("SHALLOW");
21122 self.write_space();
21123 }
21124 if e.copy.is_some() {
21125 self.write_keyword("COPY");
21126 } else {
21127 self.write_keyword("CLONE");
21128 }
21129 self.write_space();
21130 self.generate_expression(&e.this)?;
21131 Ok(())
21132 }
21133
21134 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
21135 self.write_keyword("CLUSTER BY");
21137 self.write(" (");
21138 for (i, ord) in e.expressions.iter().enumerate() {
21139 if i > 0 {
21140 self.write(", ");
21141 }
21142 self.generate_ordered(ord)?;
21143 }
21144 self.write(")");
21145 Ok(())
21146 }
21147
21148 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
21149 self.write_keyword("CLUSTERED BY");
21151 self.write(" (");
21152 for (i, expr) in e.expressions.iter().enumerate() {
21153 if i > 0 {
21154 self.write(", ");
21155 }
21156 self.generate_expression(expr)?;
21157 }
21158 self.write(")");
21159 if let Some(sorted_by) = &e.sorted_by {
21160 self.write_space();
21161 self.write_keyword("SORTED BY");
21162 self.write(" (");
21163 if let Expression::Tuple(t) = sorted_by.as_ref() {
21165 for (i, expr) in t.expressions.iter().enumerate() {
21166 if i > 0 {
21167 self.write(", ");
21168 }
21169 self.generate_expression(expr)?;
21170 }
21171 } else {
21172 self.generate_expression(sorted_by)?;
21173 }
21174 self.write(")");
21175 }
21176 if let Some(buckets) = &e.buckets {
21177 self.write_space();
21178 self.write_keyword("INTO");
21179 self.write_space();
21180 self.generate_expression(buckets)?;
21181 self.write_space();
21182 self.write_keyword("BUCKETS");
21183 }
21184 Ok(())
21185 }
21186
21187 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
21188 if e.default.is_some() {
21192 self.write_keyword("DEFAULT");
21193 self.write_space();
21194 }
21195 self.write_keyword("COLLATE");
21196 match self.config.dialect {
21198 Some(DialectType::BigQuery) => self.write_space(),
21199 _ => self.write("="),
21200 }
21201 self.generate_expression(&e.this)?;
21202 Ok(())
21203 }
21204
21205 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
21206 match e {
21208 ColumnConstraint::NotNull => {
21209 self.write_keyword("NOT NULL");
21210 }
21211 ColumnConstraint::Null => {
21212 self.write_keyword("NULL");
21213 }
21214 ColumnConstraint::Unique => {
21215 self.write_keyword("UNIQUE");
21216 }
21217 ColumnConstraint::PrimaryKey => {
21218 self.write_keyword("PRIMARY KEY");
21219 }
21220 ColumnConstraint::Default(expr) => {
21221 self.write_keyword("DEFAULT");
21222 self.write_space();
21223 self.generate_expression(expr)?;
21224 }
21225 ColumnConstraint::Check(expr) => {
21226 self.write_keyword("CHECK");
21227 self.write(" (");
21228 self.generate_expression(expr)?;
21229 self.write(")");
21230 }
21231 ColumnConstraint::References(fk_ref) => {
21232 if fk_ref.has_foreign_key_keywords {
21233 self.write_keyword("FOREIGN KEY");
21234 self.write_space();
21235 }
21236 self.write_keyword("REFERENCES");
21237 self.write_space();
21238 self.generate_table(&fk_ref.table)?;
21239 if !fk_ref.columns.is_empty() {
21240 self.write(" (");
21241 for (i, col) in fk_ref.columns.iter().enumerate() {
21242 if i > 0 {
21243 self.write(", ");
21244 }
21245 self.generate_identifier(col)?;
21246 }
21247 self.write(")");
21248 }
21249 }
21250 ColumnConstraint::GeneratedAsIdentity(gen) => {
21251 self.write_keyword("GENERATED");
21252 self.write_space();
21253 if gen.always {
21254 self.write_keyword("ALWAYS");
21255 } else {
21256 self.write_keyword("BY DEFAULT");
21257 if gen.on_null {
21258 self.write_space();
21259 self.write_keyword("ON NULL");
21260 }
21261 }
21262 self.write_space();
21263 self.write_keyword("AS IDENTITY");
21264 }
21265 ColumnConstraint::Collate(collation) => {
21266 self.write_keyword("COLLATE");
21267 self.write_space();
21268 self.generate_identifier(collation)?;
21269 }
21270 ColumnConstraint::Comment(comment) => {
21271 self.write_keyword("COMMENT");
21272 self.write(" '");
21273 self.write(comment);
21274 self.write("'");
21275 }
21276 ColumnConstraint::ComputedColumn(cc) => {
21277 self.generate_computed_column_inline(cc)?;
21278 }
21279 ColumnConstraint::GeneratedAsRow(gar) => {
21280 self.generate_generated_as_row_inline(gar)?;
21281 }
21282 ColumnConstraint::Tags(tags) => {
21283 self.write_keyword("TAG");
21284 self.write(" (");
21285 for (i, expr) in tags.expressions.iter().enumerate() {
21286 if i > 0 {
21287 self.write(", ");
21288 }
21289 self.generate_expression(expr)?;
21290 }
21291 self.write(")");
21292 }
21293 ColumnConstraint::Path(path_expr) => {
21294 self.write_keyword("PATH");
21295 self.write_space();
21296 self.generate_expression(path_expr)?;
21297 }
21298 }
21299 Ok(())
21300 }
21301
21302 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
21303 match e {
21305 ColumnPosition::First => {
21306 self.write_keyword("FIRST");
21307 }
21308 ColumnPosition::After(ident) => {
21309 self.write_keyword("AFTER");
21310 self.write_space();
21311 self.generate_identifier(ident)?;
21312 }
21313 }
21314 Ok(())
21315 }
21316
21317 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
21318 self.generate_expression(&e.this)?;
21320 self.write("(");
21321 self.generate_expression(&e.expression)?;
21322 self.write(")");
21323 Ok(())
21324 }
21325
21326 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
21327 if let Some(ref unpack) = e.unpack {
21330 if let Expression::Boolean(b) = unpack.as_ref() {
21331 if b.value {
21332 self.write("*");
21333 }
21334 }
21335 }
21336 self.write_keyword("COLUMNS");
21337 self.write("(");
21338 self.generate_expression(&e.this)?;
21339 self.write(")");
21340 Ok(())
21341 }
21342
21343 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
21344 self.generate_expression(&e.this)?;
21346 self.write("(");
21347 for (i, expr) in e.expressions.iter().enumerate() {
21348 if i > 0 {
21349 self.write(", ");
21350 }
21351 self.generate_expression(expr)?;
21352 }
21353 self.write(")");
21354 Ok(())
21355 }
21356
21357 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
21358 self.generate_expression(&e.this)?;
21360 self.write("(");
21361 for (i, param) in e.params.iter().enumerate() {
21362 if i > 0 {
21363 self.write(", ");
21364 }
21365 self.generate_expression(param)?;
21366 }
21367 self.write(")(");
21368 for (i, expr) in e.expressions.iter().enumerate() {
21369 if i > 0 {
21370 self.write(", ");
21371 }
21372 self.generate_expression(expr)?;
21373 }
21374 self.write(")");
21375 Ok(())
21376 }
21377
21378 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
21379 self.write_keyword("COMMIT");
21381
21382 if e.this.is_none() && matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) {
21384 self.write_space();
21385 self.write_keyword("TRANSACTION");
21386 }
21387
21388 if let Some(this) = &e.this {
21390 let is_transaction_marker = matches!(
21392 this.as_ref(),
21393 Expression::Identifier(id) if id.name == "TRANSACTION"
21394 );
21395
21396 self.write_space();
21397 self.write_keyword("TRANSACTION");
21398
21399 if !is_transaction_marker {
21401 self.write_space();
21402 self.generate_expression(this)?;
21403 }
21404 }
21405
21406 if let Some(durability) = &e.durability {
21408 self.write_space();
21409 self.write_keyword("WITH");
21410 self.write(" (");
21411 self.write_keyword("DELAYED_DURABILITY");
21412 self.write(" = ");
21413 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
21414 self.write_keyword("ON");
21415 } else {
21416 self.write_keyword("OFF");
21417 }
21418 self.write(")");
21419 }
21420
21421 if let Some(chain) = &e.chain {
21423 self.write_space();
21424 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
21425 self.write_keyword("AND NO CHAIN");
21426 } else {
21427 self.write_keyword("AND CHAIN");
21428 }
21429 }
21430 Ok(())
21431 }
21432
21433 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
21434 self.write("[");
21436 self.generate_expression(&e.this)?;
21437 self.write_space();
21438 self.write_keyword("FOR");
21439 self.write_space();
21440 self.generate_expression(&e.expression)?;
21441 if let Some(pos) = &e.position {
21443 self.write(", ");
21444 self.generate_expression(pos)?;
21445 }
21446 if let Some(iterator) = &e.iterator {
21447 self.write_space();
21448 self.write_keyword("IN");
21449 self.write_space();
21450 self.generate_expression(iterator)?;
21451 }
21452 if let Some(condition) = &e.condition {
21453 self.write_space();
21454 self.write_keyword("IF");
21455 self.write_space();
21456 self.generate_expression(condition)?;
21457 }
21458 self.write("]");
21459 Ok(())
21460 }
21461
21462 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
21463 self.write_keyword("COMPRESS");
21465 self.write("(");
21466 self.generate_expression(&e.this)?;
21467 if let Some(method) = &e.method {
21468 self.write(", '");
21469 self.write(method);
21470 self.write("'");
21471 }
21472 self.write(")");
21473 Ok(())
21474 }
21475
21476 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
21477 self.write_keyword("COMPRESS");
21479 if let Some(this) = &e.this {
21480 self.write_space();
21481 self.generate_expression(this)?;
21482 }
21483 Ok(())
21484 }
21485
21486 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
21487 self.write_keyword("AS");
21489 self.write_space();
21490 self.generate_expression(&e.this)?;
21491 if e.not_null.is_some() {
21492 self.write_space();
21493 self.write_keyword("PERSISTED NOT NULL");
21494 } else if e.persisted.is_some() {
21495 self.write_space();
21496 self.write_keyword("PERSISTED");
21497 }
21498 Ok(())
21499 }
21500
21501 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
21505 let computed_expr = if matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) {
21506 match &*cc.expression {
21507 Expression::Year(y)
21508 if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
21509 {
21510 let wrapped = Expression::Cast(Box::new(Cast {
21511 this: y.this.clone(),
21512 to: DataType::Date,
21513 trailing_comments: Vec::new(),
21514 double_colon_syntax: false,
21515 format: None,
21516 default: None,
21517 }));
21518 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
21519 }
21520 Expression::Function(f)
21521 if f.name.eq_ignore_ascii_case("YEAR")
21522 && f.args.len() == 1
21523 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
21524 {
21525 let wrapped = Expression::Cast(Box::new(Cast {
21526 this: f.args[0].clone(),
21527 to: DataType::Date,
21528 trailing_comments: Vec::new(),
21529 double_colon_syntax: false,
21530 format: None,
21531 default: None,
21532 }));
21533 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
21534 }
21535 _ => *cc.expression.clone(),
21536 }
21537 } else {
21538 *cc.expression.clone()
21539 };
21540
21541 match cc.persistence_kind.as_deref() {
21542 Some("STORED") | Some("VIRTUAL") => {
21543 self.write_keyword("GENERATED ALWAYS AS");
21545 self.write(" (");
21546 self.generate_expression(&computed_expr)?;
21547 self.write(")");
21548 self.write_space();
21549 if cc.persisted {
21550 self.write_keyword("STORED");
21551 } else {
21552 self.write_keyword("VIRTUAL");
21553 }
21554 }
21555 Some("PERSISTED") => {
21556 self.write_keyword("AS");
21558 self.write(" (");
21559 self.generate_expression(&computed_expr)?;
21560 self.write(")");
21561 self.write_space();
21562 self.write_keyword("PERSISTED");
21563 if let Some(ref dt) = cc.data_type {
21565 self.write_space();
21566 self.generate_data_type(dt)?;
21567 }
21568 if cc.not_null {
21569 self.write_space();
21570 self.write_keyword("NOT NULL");
21571 }
21572 }
21573 _ => {
21574 if matches!(
21577 self.config.dialect,
21578 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
21579 ) {
21580 self.write_keyword("GENERATED ALWAYS AS");
21581 self.write(" (");
21582 self.generate_expression(&computed_expr)?;
21583 self.write(")");
21584 } else if matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) {
21585 self.write_keyword("AS");
21586 let omit_parens = matches!(computed_expr, Expression::Year(_))
21587 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
21588 if omit_parens {
21589 self.write_space();
21590 self.generate_expression(&computed_expr)?;
21591 } else {
21592 self.write(" (");
21593 self.generate_expression(&computed_expr)?;
21594 self.write(")");
21595 }
21596 } else {
21597 self.write_keyword("AS");
21598 self.write(" (");
21599 self.generate_expression(&computed_expr)?;
21600 self.write(")");
21601 }
21602 }
21603 }
21604 Ok(())
21605 }
21606
21607 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
21610 self.write_keyword("GENERATED ALWAYS AS ROW ");
21611 if gar.start {
21612 self.write_keyword("START");
21613 } else {
21614 self.write_keyword("END");
21615 }
21616 if gar.hidden {
21617 self.write_space();
21618 self.write_keyword("HIDDEN");
21619 }
21620 Ok(())
21621 }
21622
21623 fn generate_system_versioning_content(&mut self, e: &WithSystemVersioningProperty) -> Result<()> {
21625 let mut parts = Vec::new();
21626
21627 if let Some(this) = &e.this {
21628 let mut s = String::from("HISTORY_TABLE=");
21629 let mut gen = Generator::new();
21630 gen.config = self.config.clone();
21631 gen.generate_expression(this)?;
21632 s.push_str(&gen.output);
21633 parts.push(s);
21634 }
21635
21636 if let Some(data_consistency) = &e.data_consistency {
21637 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
21638 let mut gen = Generator::new();
21639 gen.config = self.config.clone();
21640 gen.generate_expression(data_consistency)?;
21641 s.push_str(&gen.output);
21642 parts.push(s);
21643 }
21644
21645 if let Some(retention_period) = &e.retention_period {
21646 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
21647 let mut gen = Generator::new();
21648 gen.config = self.config.clone();
21649 gen.generate_expression(retention_period)?;
21650 s.push_str(&gen.output);
21651 parts.push(s);
21652 }
21653
21654 self.write_keyword("SYSTEM_VERSIONING");
21655 self.write("=");
21656
21657 if !parts.is_empty() {
21658 self.write_keyword("ON");
21659 self.write("(");
21660 self.write(&parts.join(", "));
21661 self.write(")");
21662 } else if e.on.is_some() {
21663 self.write_keyword("ON");
21664 } else {
21665 self.write_keyword("OFF");
21666 }
21667
21668 Ok(())
21669 }
21670
21671 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
21672 if e.else_.is_some() {
21675 self.write_keyword("ELSE");
21676 self.write_space();
21677 } else if let Some(expression) = &e.expression {
21678 self.write_keyword("WHEN");
21679 self.write_space();
21680 self.generate_expression(expression)?;
21681 self.write_space();
21682 self.write_keyword("THEN");
21683 self.write_space();
21684 }
21685
21686 if let Expression::Insert(insert) = e.this.as_ref() {
21689 self.write_keyword("INTO");
21690 self.write_space();
21691 self.generate_table(&insert.table)?;
21692
21693 if !insert.columns.is_empty() {
21695 self.write(" (");
21696 for (i, col) in insert.columns.iter().enumerate() {
21697 if i > 0 {
21698 self.write(", ");
21699 }
21700 self.generate_identifier(col)?;
21701 }
21702 self.write(")");
21703 }
21704
21705 if !insert.values.is_empty() {
21707 self.write_space();
21708 self.write_keyword("VALUES");
21709 for (row_idx, row) in insert.values.iter().enumerate() {
21710 if row_idx > 0 {
21711 self.write(", ");
21712 }
21713 self.write(" (");
21714 for (i, val) in row.iter().enumerate() {
21715 if i > 0 {
21716 self.write(", ");
21717 }
21718 self.generate_expression(val)?;
21719 }
21720 self.write(")");
21721 }
21722 }
21723 } else {
21724 self.generate_expression(&e.this)?;
21726 }
21727 Ok(())
21728 }
21729
21730 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
21731 self.write_keyword("CONSTRAINT");
21733 self.write_space();
21734 self.generate_expression(&e.this)?;
21735 if !e.expressions.is_empty() {
21736 self.write_space();
21737 for (i, expr) in e.expressions.iter().enumerate() {
21738 if i > 0 {
21739 self.write_space();
21740 }
21741 self.generate_expression(expr)?;
21742 }
21743 }
21744 Ok(())
21745 }
21746
21747 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
21748 self.write_keyword("CONVERT_TIMEZONE");
21750 self.write("(");
21751 let mut first = true;
21752 if let Some(source_tz) = &e.source_tz {
21753 self.generate_expression(source_tz)?;
21754 first = false;
21755 }
21756 if let Some(target_tz) = &e.target_tz {
21757 if !first {
21758 self.write(", ");
21759 }
21760 self.generate_expression(target_tz)?;
21761 first = false;
21762 }
21763 if let Some(timestamp) = &e.timestamp {
21764 if !first {
21765 self.write(", ");
21766 }
21767 self.generate_expression(timestamp)?;
21768 }
21769 self.write(")");
21770 Ok(())
21771 }
21772
21773 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
21774 self.write_keyword("CONVERT");
21776 self.write("(");
21777 self.generate_expression(&e.this)?;
21778 if let Some(dest) = &e.dest {
21779 self.write_space();
21780 self.write_keyword("USING");
21781 self.write_space();
21782 self.generate_expression(dest)?;
21783 }
21784 self.write(")");
21785 Ok(())
21786 }
21787
21788 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
21789 self.write_keyword("COPY");
21790 if e.is_into {
21791 self.write_space();
21792 self.write_keyword("INTO");
21793 }
21794 self.write_space();
21795
21796 if let Expression::Literal(Literal::String(s)) = &e.this {
21798 if s.starts_with('@') {
21799 self.write(s);
21800 } else {
21801 self.generate_expression(&e.this)?;
21802 }
21803 } else {
21804 self.generate_expression(&e.this)?;
21805 }
21806
21807 if e.kind {
21809 if self.config.pretty {
21811 self.write_newline();
21812 } else {
21813 self.write_space();
21814 }
21815 self.write_keyword("FROM");
21816 self.write_space();
21817 } else if !e.files.is_empty() {
21818 if self.config.pretty {
21820 self.write_newline();
21821 } else {
21822 self.write_space();
21823 }
21824 self.write_keyword("TO");
21825 self.write_space();
21826 }
21827
21828 for (i, file) in e.files.iter().enumerate() {
21830 if i > 0 {
21831 self.write_space();
21832 }
21833 if let Expression::Literal(Literal::String(s)) = file {
21835 if s.starts_with('@') {
21836 self.write(s);
21837 } else {
21838 self.generate_expression(file)?;
21839 }
21840 } else if let Expression::Identifier(id) = file {
21841 if id.quoted {
21843 self.write("`");
21844 self.write(&id.name);
21845 self.write("`");
21846 } else {
21847 self.generate_expression(file)?;
21848 }
21849 } else {
21850 self.generate_expression(file)?;
21851 }
21852 }
21853
21854 if !e.with_wrapped {
21856 if let Some(ref creds) = e.credentials {
21857 if let Some(ref storage) = creds.storage {
21858 if self.config.pretty { self.write_newline(); } else { self.write_space(); }
21859 self.write_keyword("STORAGE_INTEGRATION");
21860 self.write(" = ");
21861 self.write(storage);
21862 }
21863 if creds.credentials.is_empty() {
21864 if self.config.pretty { self.write_newline(); } else { self.write_space(); }
21866 self.write_keyword("CREDENTIALS");
21867 self.write(" = ()");
21868 } else {
21869 if self.config.pretty { self.write_newline(); } else { self.write_space(); }
21870 self.write_keyword("CREDENTIALS");
21871 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
21874 self.write(" '");
21876 self.write(&creds.credentials[0].1);
21877 self.write("'");
21878 } else {
21879 self.write(" = (");
21881 for (i, (k, v)) in creds.credentials.iter().enumerate() {
21882 if i > 0 {
21883 self.write_space();
21884 }
21885 self.write(k);
21886 self.write("='");
21887 self.write(v);
21888 self.write("'");
21889 }
21890 self.write(")");
21891 }
21892 }
21893 if let Some(ref encryption) = creds.encryption {
21894 self.write_space();
21895 self.write_keyword("ENCRYPTION");
21896 self.write(" = ");
21897 self.write(encryption);
21898 }
21899 }
21900 }
21901
21902 if !e.params.is_empty() {
21904 if e.with_wrapped {
21905 self.write_space();
21907 self.write_keyword("WITH");
21908 self.write(" (");
21909 for (i, param) in e.params.iter().enumerate() {
21910 if i > 0 {
21911 self.write(", ");
21912 }
21913 self.generate_copy_param_with_format(param)?;
21914 }
21915 self.write(")");
21916 } else {
21917 for param in &e.params {
21921 if self.config.pretty { self.write_newline(); } else { self.write_space(); }
21922 self.write(¶m.name);
21924 if let Some(ref value) = param.value {
21925 if param.eq {
21927 self.write(" = ");
21928 } else {
21929 self.write(" ");
21930 }
21931 if !param.values.is_empty() {
21932 self.write("(");
21933 for (i, v) in param.values.iter().enumerate() {
21934 if i > 0 {
21935 self.write_space();
21936 }
21937 self.generate_copy_nested_param(v)?;
21938 }
21939 self.write(")");
21940 } else {
21941 self.generate_copy_param_value(value)?;
21943 }
21944 } else if !param.values.is_empty() {
21945 if param.eq {
21947 self.write(" = (");
21948 } else {
21949 self.write(" (");
21950 }
21951 let is_key_value_pairs = param.values.first().map_or(false, |v| matches!(v, Expression::Eq(_)));
21956 let sep = if is_key_value_pairs && param.eq { " " } else { ", " };
21957 for (i, v) in param.values.iter().enumerate() {
21958 if i > 0 {
21959 self.write(sep);
21960 }
21961 self.generate_copy_nested_param(v)?;
21962 }
21963 self.write(")");
21964 }
21965 }
21966 }
21967 }
21968
21969 Ok(())
21970 }
21971
21972 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
21975 self.write_keyword(¶m.name);
21976 if !param.values.is_empty() {
21977 self.write(" = (");
21979 for (i, v) in param.values.iter().enumerate() {
21980 if i > 0 {
21981 self.write(", ");
21982 }
21983 self.generate_copy_nested_param(v)?;
21984 }
21985 self.write(")");
21986 } else if let Some(ref value) = param.value {
21987 if param.eq {
21988 self.write(" = ");
21989 } else {
21990 self.write(" ");
21991 }
21992 self.generate_expression(value)?;
21993 }
21994 Ok(())
21995 }
21996
21997 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
21999 match expr {
22000 Expression::Eq(eq) => {
22001 match &eq.left {
22003 Expression::Column(c) => self.write(&c.name.name),
22004 _ => self.generate_expression(&eq.left)?,
22005 }
22006 self.write("=");
22007 match &eq.right {
22009 Expression::Literal(Literal::String(s)) => {
22010 self.write("'");
22011 self.write(s);
22012 self.write("'");
22013 }
22014 Expression::Tuple(t) => {
22015 self.write("(");
22017 if self.config.pretty {
22018 self.write_newline();
22019 self.indent_level += 1;
22020 for (i, item) in t.expressions.iter().enumerate() {
22021 if i > 0 {
22022 self.write(", ");
22023 }
22024 self.write_indent();
22025 self.generate_expression(item)?;
22026 }
22027 self.write_newline();
22028 self.indent_level -= 1;
22029 } else {
22030 for (i, item) in t.expressions.iter().enumerate() {
22031 if i > 0 {
22032 self.write(", ");
22033 }
22034 self.generate_expression(item)?;
22035 }
22036 }
22037 self.write(")");
22038 }
22039 _ => self.generate_expression(&eq.right)?,
22040 }
22041 Ok(())
22042 }
22043 Expression::Column(c) => {
22044 self.write(&c.name.name);
22046 Ok(())
22047 }
22048 _ => self.generate_expression(expr),
22049 }
22050 }
22051
22052 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
22055 match expr {
22056 Expression::Column(c) => {
22057 if c.name.quoted {
22059 self.write("\"");
22060 self.write(&c.name.name);
22061 self.write("\"");
22062 } else {
22063 self.write(&c.name.name);
22064 }
22065 Ok(())
22066 }
22067 Expression::Identifier(id) => {
22068 if id.quoted {
22070 self.write("\"");
22071 self.write(&id.name);
22072 self.write("\"");
22073 } else {
22074 self.write(&id.name);
22075 }
22076 Ok(())
22077 }
22078 Expression::Literal(Literal::String(s)) => {
22079 self.write("'");
22081 self.write(s);
22082 self.write("'");
22083 Ok(())
22084 }
22085 _ => self.generate_expression(expr),
22086 }
22087 }
22088
22089 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
22090 self.write_keyword(&e.name);
22091 if let Some(ref value) = e.value {
22092 if e.eq {
22093 self.write(" = ");
22094 } else {
22095 self.write(" ");
22096 }
22097 self.generate_expression(value)?;
22098 }
22099 if !e.values.is_empty() {
22100 if e.eq {
22101 self.write(" = ");
22102 } else {
22103 self.write(" ");
22104 }
22105 self.write("(");
22106 for (i, v) in e.values.iter().enumerate() {
22107 if i > 0 {
22108 self.write(", ");
22109 }
22110 self.generate_expression(v)?;
22111 }
22112 self.write(")");
22113 }
22114 Ok(())
22115 }
22116
22117 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
22118 self.write_keyword("CORR");
22120 self.write("(");
22121 self.generate_expression(&e.this)?;
22122 self.write(", ");
22123 self.generate_expression(&e.expression)?;
22124 self.write(")");
22125 Ok(())
22126 }
22127
22128 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
22129 self.write_keyword("COSINE_DISTANCE");
22131 self.write("(");
22132 self.generate_expression(&e.this)?;
22133 self.write(", ");
22134 self.generate_expression(&e.expression)?;
22135 self.write(")");
22136 Ok(())
22137 }
22138
22139 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
22140 self.write_keyword("COVAR_POP");
22142 self.write("(");
22143 self.generate_expression(&e.this)?;
22144 self.write(", ");
22145 self.generate_expression(&e.expression)?;
22146 self.write(")");
22147 Ok(())
22148 }
22149
22150 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
22151 self.write_keyword("COVAR_SAMP");
22153 self.write("(");
22154 self.generate_expression(&e.this)?;
22155 self.write(", ");
22156 self.generate_expression(&e.expression)?;
22157 self.write(")");
22158 Ok(())
22159 }
22160
22161 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
22162 self.write_keyword("CREDENTIALS");
22164 self.write(" (");
22165 for (i, (key, value)) in e.credentials.iter().enumerate() {
22166 if i > 0 {
22167 self.write(", ");
22168 }
22169 self.write(key);
22170 self.write("='");
22171 self.write(value);
22172 self.write("'");
22173 }
22174 self.write(")");
22175 Ok(())
22176 }
22177
22178 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
22179 self.write_keyword("CREDENTIALS");
22181 self.write("=(");
22182 for (i, expr) in e.expressions.iter().enumerate() {
22183 if i > 0 {
22184 self.write(", ");
22185 }
22186 self.generate_expression(expr)?;
22187 }
22188 self.write(")");
22189 Ok(())
22190 }
22191
22192 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
22193 use crate::dialects::DialectType;
22194
22195 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
22198 self.generate_expression(&e.this)?;
22199 self.write_space();
22200 self.write_keyword("AS");
22201 self.write_space();
22202 self.generate_identifier(&e.alias)?;
22203 return Ok(());
22204 }
22205 self.write(&e.alias.name);
22206
22207 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
22209
22210 if !e.columns.is_empty() && !skip_cte_columns {
22211 self.write("(");
22212 for (i, col) in e.columns.iter().enumerate() {
22213 if i > 0 {
22214 self.write(", ");
22215 }
22216 self.write(&col.name);
22217 }
22218 self.write(")");
22219 }
22220 if !e.key_expressions.is_empty() {
22222 self.write_space();
22223 self.write_keyword("USING KEY");
22224 self.write(" (");
22225 for (i, key) in e.key_expressions.iter().enumerate() {
22226 if i > 0 {
22227 self.write(", ");
22228 }
22229 self.write(&key.name);
22230 }
22231 self.write(")");
22232 }
22233 self.write_space();
22234 self.write_keyword("AS");
22235 self.write_space();
22236 if let Some(materialized) = e.materialized {
22237 if materialized {
22238 self.write_keyword("MATERIALIZED");
22239 } else {
22240 self.write_keyword("NOT MATERIALIZED");
22241 }
22242 self.write_space();
22243 }
22244 self.write("(");
22245 self.generate_expression(&e.this)?;
22246 self.write(")");
22247 Ok(())
22248 }
22249
22250 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
22251 if e.expressions.is_empty() {
22253 self.write_keyword("WITH CUBE");
22254 } else {
22255 self.write_keyword("CUBE");
22256 self.write("(");
22257 for (i, expr) in e.expressions.iter().enumerate() {
22258 if i > 0 {
22259 self.write(", ");
22260 }
22261 self.generate_expression(expr)?;
22262 }
22263 self.write(")");
22264 }
22265 Ok(())
22266 }
22267
22268 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
22269 self.write_keyword("CURRENT_DATETIME");
22271 if let Some(this) = &e.this {
22272 self.write("(");
22273 self.generate_expression(this)?;
22274 self.write(")");
22275 }
22276 Ok(())
22277 }
22278
22279 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
22280 self.write_keyword("CURRENT_SCHEMA");
22282 Ok(())
22283 }
22284
22285 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
22286 self.write_keyword("CURRENT_SCHEMAS");
22288 self.write("(");
22289 if let Some(this) = &e.this {
22290 self.generate_expression(this)?;
22291 }
22292 self.write(")");
22293 Ok(())
22294 }
22295
22296 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
22297 self.write_keyword("CURRENT_USER");
22299 let needs_parens = e.this.is_some() || matches!(
22301 self.config.dialect,
22302 Some(DialectType::Snowflake) | Some(DialectType::Spark)
22303 | Some(DialectType::Hive) | Some(DialectType::DuckDB) | Some(DialectType::BigQuery)
22304 | Some(DialectType::MySQL) | Some(DialectType::Databricks)
22305 );
22306 if needs_parens {
22307 self.write("()");
22308 }
22309 Ok(())
22310 }
22311
22312 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
22313 if self.config.dialect == Some(DialectType::Solr) {
22315 self.generate_expression(&e.this)?;
22316 self.write(" ");
22317 self.write_keyword("OR");
22318 self.write(" ");
22319 self.generate_expression(&e.expression)?;
22320 } else {
22321 self.generate_expression(&e.this)?;
22323 self.write(" || ");
22324 self.generate_expression(&e.expression)?;
22325 }
22326 Ok(())
22327 }
22328
22329 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
22330 self.write_keyword("DATABLOCKSIZE");
22332 self.write("=");
22333 if let Some(size) = e.size {
22334 self.write(&size.to_string());
22335 if let Some(units) = &e.units {
22336 self.write_space();
22337 self.generate_expression(units)?;
22338 }
22339 } else if e.minimum.is_some() {
22340 self.write_keyword("MINIMUM");
22341 } else if e.maximum.is_some() {
22342 self.write_keyword("MAXIMUM");
22343 } else if e.default.is_some() {
22344 self.write_keyword("DEFAULT");
22345 }
22346 Ok(())
22347 }
22348
22349 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
22350 self.write_keyword("DATA_DELETION");
22352 self.write("=");
22353
22354 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
22355 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
22356
22357 if is_on {
22358 self.write_keyword("ON");
22359 if has_options {
22360 self.write("(");
22361 let mut first = true;
22362 if let Some(filter_column) = &e.filter_column {
22363 self.write_keyword("FILTER_COLUMN");
22364 self.write("=");
22365 self.generate_expression(filter_column)?;
22366 first = false;
22367 }
22368 if let Some(retention_period) = &e.retention_period {
22369 if !first {
22370 self.write(", ");
22371 }
22372 self.write_keyword("RETENTION_PERIOD");
22373 self.write("=");
22374 self.generate_expression(retention_period)?;
22375 }
22376 self.write(")");
22377 }
22378 } else {
22379 self.write_keyword("OFF");
22380 }
22381 Ok(())
22382 }
22383
22384 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
22388 use crate::dialects::DialectType;
22389 use crate::expressions::Literal;
22390
22391 match self.config.dialect {
22392 Some(DialectType::Exasol) => {
22394 self.write_keyword("TO_DATE");
22395 self.write("(");
22396 match &e.this {
22398 Expression::Literal(Literal::String(s)) => {
22399 self.write("'");
22400 self.write(s);
22401 self.write("'");
22402 }
22403 _ => {
22404 self.generate_expression(&e.this)?;
22405 }
22406 }
22407 self.write(")");
22408 }
22409 _ => {
22411 self.write_keyword("DATE");
22412 self.write("(");
22413 self.generate_expression(&e.this)?;
22414 self.write(")");
22415 }
22416 }
22417 Ok(())
22418 }
22419
22420 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
22421 self.write_keyword("DATE_BIN");
22423 self.write("(");
22424 self.generate_expression(&e.this)?;
22425 self.write(", ");
22426 self.generate_expression(&e.expression)?;
22427 if let Some(origin) = &e.origin {
22428 self.write(", ");
22429 self.generate_expression(origin)?;
22430 }
22431 self.write(")");
22432 Ok(())
22433 }
22434
22435 fn generate_date_format_column_constraint(&mut self, e: &DateFormatColumnConstraint) -> Result<()> {
22436 self.write_keyword("FORMAT");
22438 self.write_space();
22439 self.generate_expression(&e.this)?;
22440 Ok(())
22441 }
22442
22443 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
22444 self.write_keyword("DATE_FROM_PARTS");
22446 self.write("(");
22447 let mut first = true;
22448 if let Some(year) = &e.year {
22449 self.generate_expression(year)?;
22450 first = false;
22451 }
22452 if let Some(month) = &e.month {
22453 if !first {
22454 self.write(", ");
22455 }
22456 self.generate_expression(month)?;
22457 first = false;
22458 }
22459 if let Some(day) = &e.day {
22460 if !first {
22461 self.write(", ");
22462 }
22463 self.generate_expression(day)?;
22464 }
22465 self.write(")");
22466 Ok(())
22467 }
22468
22469 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
22470 self.write_keyword("DATETIME");
22472 self.write("(");
22473 self.generate_expression(&e.this)?;
22474 if let Some(expr) = &e.expression {
22475 self.write(", ");
22476 self.generate_expression(expr)?;
22477 }
22478 self.write(")");
22479 Ok(())
22480 }
22481
22482 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
22483 self.write_keyword("DATETIME_ADD");
22485 self.write("(");
22486 self.generate_expression(&e.this)?;
22487 self.write(", ");
22488 self.generate_expression(&e.expression)?;
22489 if let Some(unit) = &e.unit {
22490 self.write(", ");
22491 self.write_keyword(unit);
22492 }
22493 self.write(")");
22494 Ok(())
22495 }
22496
22497 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
22498 self.write_keyword("DATETIME_DIFF");
22500 self.write("(");
22501 self.generate_expression(&e.this)?;
22502 self.write(", ");
22503 self.generate_expression(&e.expression)?;
22504 if let Some(unit) = &e.unit {
22505 self.write(", ");
22506 self.write_keyword(unit);
22507 }
22508 self.write(")");
22509 Ok(())
22510 }
22511
22512 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
22513 self.write_keyword("DATETIME_SUB");
22515 self.write("(");
22516 self.generate_expression(&e.this)?;
22517 self.write(", ");
22518 self.generate_expression(&e.expression)?;
22519 if let Some(unit) = &e.unit {
22520 self.write(", ");
22521 self.write_keyword(unit);
22522 }
22523 self.write(")");
22524 Ok(())
22525 }
22526
22527 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
22528 self.write_keyword("DATETIME_TRUNC");
22530 self.write("(");
22531 self.generate_expression(&e.this)?;
22532 self.write(", ");
22533 self.write_keyword(&e.unit);
22534 if let Some(zone) = &e.zone {
22535 self.write(", ");
22536 self.generate_expression(zone)?;
22537 }
22538 self.write(")");
22539 Ok(())
22540 }
22541
22542 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
22543 self.write_keyword("DAYNAME");
22545 self.write("(");
22546 self.generate_expression(&e.this)?;
22547 self.write(")");
22548 Ok(())
22549 }
22550
22551 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
22552 self.write_keyword("DECLARE");
22554 self.write_space();
22555 for (i, expr) in e.expressions.iter().enumerate() {
22556 if i > 0 {
22557 self.write(", ");
22558 }
22559 self.generate_expression(expr)?;
22560 }
22561 Ok(())
22562 }
22563
22564 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
22565 use crate::dialects::DialectType;
22566
22567 self.generate_expression(&e.this)?;
22569 for name in &e.additional_names {
22571 self.write(", ");
22572 self.generate_expression(name)?;
22573 }
22574 if let Some(kind) = &e.kind {
22575 self.write_space();
22576 match self.config.dialect {
22580 Some(DialectType::BigQuery) => {
22581 self.write(kind);
22582 }
22583 Some(DialectType::TSQL) => {
22584 let is_complex_table = kind.starts_with("TABLE") &&
22588 (kind.contains("CLUSTERED") || kind.contains("INDEX"));
22589
22590 if is_complex_table {
22591 self.write(kind);
22593 } else {
22594 if !kind.starts_with("CURSOR") {
22596 self.write_keyword("AS");
22597 self.write_space();
22598 }
22599 if kind == "INT" {
22601 self.write("INTEGER");
22602 } else if kind.starts_with("TABLE") {
22603 let normalized = kind
22605 .replace(" INT ", " INTEGER ")
22606 .replace(" INT,", " INTEGER,")
22607 .replace(" INT)", " INTEGER)")
22608 .replace("(INT ", "(INTEGER ");
22609 self.write(&normalized);
22610 } else {
22611 self.write(kind);
22612 }
22613 }
22614 }
22615 _ => {
22616 if e.has_as {
22617 self.write_keyword("AS");
22618 self.write_space();
22619 }
22620 self.write(kind);
22621 }
22622 }
22623 }
22624 if let Some(default) = &e.default {
22625 match self.config.dialect {
22627 Some(DialectType::BigQuery) => {
22628 self.write_space();
22629 self.write_keyword("DEFAULT");
22630 self.write_space();
22631 }
22632 _ => {
22633 self.write(" = ");
22634 }
22635 }
22636 self.generate_expression(default)?;
22637 }
22638 Ok(())
22639 }
22640
22641 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
22642 self.write_keyword("DECODE");
22644 self.write("(");
22645 for (i, expr) in e.expressions.iter().enumerate() {
22646 if i > 0 {
22647 self.write(", ");
22648 }
22649 self.generate_expression(expr)?;
22650 }
22651 self.write(")");
22652 Ok(())
22653 }
22654
22655 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
22656 self.write_keyword("DECOMPRESS");
22658 self.write("(");
22659 self.generate_expression(&e.this)?;
22660 self.write(", '");
22661 self.write(&e.method);
22662 self.write("')");
22663 Ok(())
22664 }
22665
22666 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
22667 self.write_keyword("DECOMPRESS");
22669 self.write("(");
22670 self.generate_expression(&e.this)?;
22671 self.write(", '");
22672 self.write(&e.method);
22673 self.write("')");
22674 Ok(())
22675 }
22676
22677 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
22678 self.write_keyword("DECRYPT");
22680 self.write("(");
22681 self.generate_expression(&e.this)?;
22682 if let Some(passphrase) = &e.passphrase {
22683 self.write(", ");
22684 self.generate_expression(passphrase)?;
22685 }
22686 if let Some(aad) = &e.aad {
22687 self.write(", ");
22688 self.generate_expression(aad)?;
22689 }
22690 if let Some(method) = &e.encryption_method {
22691 self.write(", ");
22692 self.generate_expression(method)?;
22693 }
22694 self.write(")");
22695 Ok(())
22696 }
22697
22698 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
22699 self.write_keyword("DECRYPT_RAW");
22701 self.write("(");
22702 self.generate_expression(&e.this)?;
22703 if let Some(key) = &e.key {
22704 self.write(", ");
22705 self.generate_expression(key)?;
22706 }
22707 if let Some(iv) = &e.iv {
22708 self.write(", ");
22709 self.generate_expression(iv)?;
22710 }
22711 if let Some(aad) = &e.aad {
22712 self.write(", ");
22713 self.generate_expression(aad)?;
22714 }
22715 if let Some(method) = &e.encryption_method {
22716 self.write(", ");
22717 self.generate_expression(method)?;
22718 }
22719 self.write(")");
22720 Ok(())
22721 }
22722
22723 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
22724 self.write_keyword("DEFINER");
22726 self.write(" = ");
22727 self.generate_expression(&e.this)?;
22728 Ok(())
22729 }
22730
22731 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
22732 self.write_keyword("DETACH");
22734 if e.exists {
22735 self.write_keyword(" DATABASE IF EXISTS");
22736 }
22737 self.write_space();
22738 self.generate_expression(&e.this)?;
22739 Ok(())
22740 }
22741
22742 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
22743 let property_name = match e.this.as_ref() {
22744 Expression::Identifier(id) => id.name.as_str(),
22745 Expression::Var(v) => v.this.as_str(),
22746 _ => "DICTIONARY",
22747 };
22748 self.write_keyword(property_name);
22749 self.write("(");
22750 self.write(&e.kind);
22751 if let Some(settings) = &e.settings {
22752 self.write("(");
22753 if let Expression::Tuple(t) = settings.as_ref() {
22754 if self.config.pretty && !t.expressions.is_empty() {
22755 self.write_newline();
22756 self.indent_level += 1;
22757 for (i, pair) in t.expressions.iter().enumerate() {
22758 if i > 0 {
22759 self.write(",");
22760 self.write_newline();
22761 }
22762 self.write_indent();
22763 if let Expression::Tuple(pair_tuple) = pair {
22764 if let Some(k) = pair_tuple.expressions.first() {
22765 self.generate_expression(k)?;
22766 }
22767 if let Some(v) = pair_tuple.expressions.get(1) {
22768 self.write(" ");
22769 self.generate_expression(v)?;
22770 }
22771 } else {
22772 self.generate_expression(pair)?;
22773 }
22774 }
22775 self.indent_level -= 1;
22776 self.write_newline();
22777 self.write_indent();
22778 } else {
22779 for (i, pair) in t.expressions.iter().enumerate() {
22780 if i > 0 {
22781 self.write(", ");
22782 }
22783 if let Expression::Tuple(pair_tuple) = pair {
22784 if let Some(k) = pair_tuple.expressions.first() {
22785 self.generate_expression(k)?;
22786 }
22787 if let Some(v) = pair_tuple.expressions.get(1) {
22788 self.write(" ");
22789 self.generate_expression(v)?;
22790 }
22791 } else {
22792 self.generate_expression(pair)?;
22793 }
22794 }
22795 }
22796 } else {
22797 self.generate_expression(settings)?;
22798 }
22799 self.write(")");
22800 } else if property_name.eq_ignore_ascii_case("LAYOUT") {
22801 self.write("()");
22802 }
22803 self.write(")");
22804 Ok(())
22805 }
22806
22807 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
22808 let property_name = match e.this.as_ref() {
22809 Expression::Identifier(id) => id.name.as_str(),
22810 Expression::Var(v) => v.this.as_str(),
22811 _ => "RANGE",
22812 };
22813 self.write_keyword(property_name);
22814 self.write("(");
22815 if let Some(min) = &e.min {
22816 self.write_keyword("MIN");
22817 self.write_space();
22818 self.generate_expression(min)?;
22819 }
22820 if let Some(max) = &e.max {
22821 self.write_space();
22822 self.write_keyword("MAX");
22823 self.write_space();
22824 self.generate_expression(max)?;
22825 }
22826 self.write(")");
22827 Ok(())
22828 }
22829
22830 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
22831 if e.local.is_some() {
22833 self.write_keyword("LOCAL ");
22834 }
22835 self.write_keyword("DIRECTORY");
22836 self.write_space();
22837 self.generate_expression(&e.this)?;
22838 if let Some(row_format) = &e.row_format {
22839 self.write_space();
22840 self.generate_expression(row_format)?;
22841 }
22842 Ok(())
22843 }
22844
22845 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
22846 self.write_keyword("DISTKEY");
22848 self.write("(");
22849 self.generate_expression(&e.this)?;
22850 self.write(")");
22851 Ok(())
22852 }
22853
22854 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
22855 self.write_keyword("DISTSTYLE");
22857 self.write_space();
22858 self.generate_expression(&e.this)?;
22859 Ok(())
22860 }
22861
22862 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
22863 self.write_keyword("DISTRIBUTE BY");
22865 self.write_space();
22866 for (i, expr) in e.expressions.iter().enumerate() {
22867 if i > 0 {
22868 self.write(", ");
22869 }
22870 self.generate_expression(expr)?;
22871 }
22872 Ok(())
22873 }
22874
22875 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
22876 self.write_keyword("DISTRIBUTED BY");
22878 self.write_space();
22879 self.write(&e.kind);
22880 if !e.expressions.is_empty() {
22881 self.write(" (");
22882 for (i, expr) in e.expressions.iter().enumerate() {
22883 if i > 0 {
22884 self.write(", ");
22885 }
22886 self.generate_expression(expr)?;
22887 }
22888 self.write(")");
22889 }
22890 if let Some(buckets) = &e.buckets {
22891 self.write_space();
22892 self.write_keyword("BUCKETS");
22893 self.write_space();
22894 self.generate_expression(buckets)?;
22895 }
22896 if let Some(order) = &e.order {
22897 self.write_space();
22898 self.generate_expression(order)?;
22899 }
22900 Ok(())
22901 }
22902
22903 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
22904 self.write_keyword("DOT_PRODUCT");
22906 self.write("(");
22907 self.generate_expression(&e.this)?;
22908 self.write(", ");
22909 self.generate_expression(&e.expression)?;
22910 self.write(")");
22911 Ok(())
22912 }
22913
22914 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
22915 self.write_keyword("DROP");
22917 if e.exists {
22918 self.write_keyword(" IF EXISTS ");
22919 } else {
22920 self.write_space();
22921 }
22922 for (i, expr) in e.expressions.iter().enumerate() {
22923 if i > 0 {
22924 self.write(", ");
22925 }
22926 self.generate_expression(expr)?;
22927 }
22928 Ok(())
22929 }
22930
22931 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
22932 self.write_keyword("DUPLICATE KEY");
22934 self.write(" (");
22935 for (i, expr) in e.expressions.iter().enumerate() {
22936 if i > 0 {
22937 self.write(", ");
22938 }
22939 self.generate_expression(expr)?;
22940 }
22941 self.write(")");
22942 Ok(())
22943 }
22944
22945 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
22946 self.write_keyword("ELT");
22948 self.write("(");
22949 self.generate_expression(&e.this)?;
22950 for expr in &e.expressions {
22951 self.write(", ");
22952 self.generate_expression(expr)?;
22953 }
22954 self.write(")");
22955 Ok(())
22956 }
22957
22958 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
22959 self.write_keyword("ENCODE");
22961 self.write("(");
22962 self.generate_expression(&e.this)?;
22963 if let Some(charset) = &e.charset {
22964 self.write(", ");
22965 self.generate_expression(charset)?;
22966 }
22967 self.write(")");
22968 Ok(())
22969 }
22970
22971 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
22972 if e.key.is_some() {
22974 self.write_keyword("KEY ");
22975 }
22976 self.write_keyword("ENCODE");
22977 self.write_space();
22978 self.generate_expression(&e.this)?;
22979 if !e.properties.is_empty() {
22980 self.write(" (");
22981 for (i, prop) in e.properties.iter().enumerate() {
22982 if i > 0 {
22983 self.write(", ");
22984 }
22985 self.generate_expression(prop)?;
22986 }
22987 self.write(")");
22988 }
22989 Ok(())
22990 }
22991
22992 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
22993 self.write_keyword("ENCRYPT");
22995 self.write("(");
22996 self.generate_expression(&e.this)?;
22997 if let Some(passphrase) = &e.passphrase {
22998 self.write(", ");
22999 self.generate_expression(passphrase)?;
23000 }
23001 if let Some(aad) = &e.aad {
23002 self.write(", ");
23003 self.generate_expression(aad)?;
23004 }
23005 if let Some(method) = &e.encryption_method {
23006 self.write(", ");
23007 self.generate_expression(method)?;
23008 }
23009 self.write(")");
23010 Ok(())
23011 }
23012
23013 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
23014 self.write_keyword("ENCRYPT_RAW");
23016 self.write("(");
23017 self.generate_expression(&e.this)?;
23018 if let Some(key) = &e.key {
23019 self.write(", ");
23020 self.generate_expression(key)?;
23021 }
23022 if let Some(iv) = &e.iv {
23023 self.write(", ");
23024 self.generate_expression(iv)?;
23025 }
23026 if let Some(aad) = &e.aad {
23027 self.write(", ");
23028 self.generate_expression(aad)?;
23029 }
23030 if let Some(method) = &e.encryption_method {
23031 self.write(", ");
23032 self.generate_expression(method)?;
23033 }
23034 self.write(")");
23035 Ok(())
23036 }
23037
23038 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
23039 self.write_keyword("ENGINE");
23041 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23042 self.write("=");
23043 } else {
23044 self.write(" = ");
23045 }
23046 self.generate_expression(&e.this)?;
23047 Ok(())
23048 }
23049
23050 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
23051 self.write_keyword("ENVIRONMENT");
23053 self.write(" (");
23054 for (i, expr) in e.expressions.iter().enumerate() {
23055 if i > 0 {
23056 self.write(", ");
23057 }
23058 self.generate_expression(expr)?;
23059 }
23060 self.write(")");
23061 Ok(())
23062 }
23063
23064 fn generate_ephemeral_column_constraint(&mut self, e: &EphemeralColumnConstraint) -> Result<()> {
23065 self.write_keyword("EPHEMERAL");
23067 if let Some(this) = &e.this {
23068 self.write_space();
23069 self.generate_expression(this)?;
23070 }
23071 Ok(())
23072 }
23073
23074 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
23075 self.write_keyword("EQUAL_NULL");
23077 self.write("(");
23078 self.generate_expression(&e.this)?;
23079 self.write(", ");
23080 self.generate_expression(&e.expression)?;
23081 self.write(")");
23082 Ok(())
23083 }
23084
23085 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
23086 use crate::dialects::DialectType;
23087
23088 match self.config.dialect {
23090 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
23091 self.generate_expression(&e.this)?;
23092 self.write(" <-> ");
23093 self.generate_expression(&e.expression)?;
23094 }
23095 _ => {
23096 self.write_keyword("EUCLIDEAN_DISTANCE");
23098 self.write("(");
23099 self.generate_expression(&e.this)?;
23100 self.write(", ");
23101 self.generate_expression(&e.expression)?;
23102 self.write(")");
23103 }
23104 }
23105 Ok(())
23106 }
23107
23108 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
23109 self.write_keyword("EXECUTE AS");
23111 self.write_space();
23112 self.generate_expression(&e.this)?;
23113 Ok(())
23114 }
23115
23116 fn generate_export(&mut self, e: &Export) -> Result<()> {
23117 self.write_keyword("EXPORT DATA");
23119 if let Some(connection) = &e.connection {
23120 self.write_space();
23121 self.write_keyword("WITH CONNECTION");
23122 self.write_space();
23123 self.generate_expression(connection)?;
23124 }
23125 if !e.options.is_empty() {
23126 self.write_space();
23127 self.generate_options_clause(&e.options)?;
23128 }
23129 self.write_space();
23130 self.write_keyword("AS");
23131 self.write_space();
23132 self.generate_expression(&e.this)?;
23133 Ok(())
23134 }
23135
23136 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
23137 self.write_keyword("EXTERNAL");
23139 if let Some(this) = &e.this {
23140 self.write_space();
23141 self.generate_expression(this)?;
23142 }
23143 Ok(())
23144 }
23145
23146 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
23147 if e.no.is_some() {
23149 self.write_keyword("NO ");
23150 }
23151 self.write_keyword("FALLBACK");
23152 if e.protection.is_some() {
23153 self.write_keyword(" PROTECTION");
23154 }
23155 Ok(())
23156 }
23157
23158 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
23159 self.write_keyword("FARM_FINGERPRINT");
23161 self.write("(");
23162 for (i, expr) in e.expressions.iter().enumerate() {
23163 if i > 0 {
23164 self.write(", ");
23165 }
23166 self.generate_expression(expr)?;
23167 }
23168 self.write(")");
23169 Ok(())
23170 }
23171
23172 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
23173 self.write_keyword("FEATURES_AT_TIME");
23175 self.write("(");
23176 self.generate_expression(&e.this)?;
23177 if let Some(time) = &e.time {
23178 self.write(", ");
23179 self.generate_expression(time)?;
23180 }
23181 if let Some(num_rows) = &e.num_rows {
23182 self.write(", ");
23183 self.generate_expression(num_rows)?;
23184 }
23185 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
23186 self.write(", ");
23187 self.generate_expression(ignore_nulls)?;
23188 }
23189 self.write(")");
23190 Ok(())
23191 }
23192
23193 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
23194 let use_limit = !e.percent && !e.with_ties && e.count.is_some() && matches!(
23196 self.config.dialect,
23197 Some(DialectType::Spark) | Some(DialectType::Hive)
23198 | Some(DialectType::DuckDB) | Some(DialectType::SQLite) | Some(DialectType::MySQL)
23199 | Some(DialectType::BigQuery) | Some(DialectType::Databricks) | Some(DialectType::StarRocks)
23200 | Some(DialectType::Doris) | Some(DialectType::Athena) | Some(DialectType::ClickHouse)
23201 );
23202
23203 if use_limit {
23204 self.write_keyword("LIMIT");
23205 self.write_space();
23206 self.generate_expression(e.count.as_ref().unwrap())?;
23207 return Ok(());
23208 }
23209
23210 self.write_keyword("FETCH");
23212 if !e.direction.is_empty() {
23213 self.write_space();
23214 self.write_keyword(&e.direction);
23215 }
23216 if let Some(count) = &e.count {
23217 self.write_space();
23218 self.generate_expression(count)?;
23219 }
23220 if e.percent {
23222 self.write_keyword(" PERCENT");
23223 }
23224 if e.rows {
23225 self.write_keyword(" ROWS");
23226 }
23227 if e.with_ties {
23228 self.write_keyword(" WITH TIES");
23229 } else if e.rows {
23230 self.write_keyword(" ONLY");
23231 } else {
23232 self.write_keyword(" ROWS ONLY");
23233 }
23234 Ok(())
23235 }
23236
23237 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
23238 if e.hive_format.is_some() {
23242 self.write_keyword("STORED AS");
23244 self.write_space();
23245 if let Some(this) = &e.this {
23246 if let Expression::Identifier(id) = this.as_ref() {
23248 self.write_keyword(&id.name.to_uppercase());
23249 } else {
23250 self.generate_expression(this)?;
23251 }
23252 }
23253 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
23254 self.write_keyword("STORED AS");
23256 self.write_space();
23257 if let Some(this) = &e.this {
23258 if let Expression::Identifier(id) = this.as_ref() {
23259 self.write_keyword(&id.name.to_uppercase());
23260 } else {
23261 self.generate_expression(this)?;
23262 }
23263 }
23264 } else if matches!(self.config.dialect, Some(DialectType::Spark) | Some(DialectType::Databricks)) {
23265 self.write_keyword("USING");
23267 self.write_space();
23268 if let Some(this) = &e.this {
23269 self.generate_expression(this)?;
23270 }
23271 } else {
23272 self.write_keyword("FILE_FORMAT");
23274 self.write(" = ");
23275 if let Some(this) = &e.this {
23276 self.generate_expression(this)?;
23277 } else if !e.expressions.is_empty() {
23278 self.write("(");
23279 for (i, expr) in e.expressions.iter().enumerate() {
23280 if i > 0 {
23281 self.write(", ");
23282 }
23283 self.generate_expression(expr)?;
23284 }
23285 self.write(")");
23286 }
23287 }
23288 Ok(())
23289 }
23290
23291 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
23292 self.generate_expression(&e.this)?;
23294 self.write_space();
23295 self.write_keyword("FILTER");
23296 self.write("(");
23297 self.write_keyword("WHERE");
23298 self.write_space();
23299 self.generate_expression(&e.expression)?;
23300 self.write(")");
23301 Ok(())
23302 }
23303
23304 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
23305 self.write_keyword("FLOAT64");
23307 self.write("(");
23308 self.generate_expression(&e.this)?;
23309 if let Some(expr) = &e.expression {
23310 self.write(", ");
23311 self.generate_expression(expr)?;
23312 }
23313 self.write(")");
23314 Ok(())
23315 }
23316
23317 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
23318 self.write_keyword("FOR");
23320 self.write_space();
23321 self.generate_expression(&e.this)?;
23322 self.write_space();
23323 self.write_keyword("DO");
23324 self.write_space();
23325 self.generate_expression(&e.expression)?;
23326 Ok(())
23327 }
23328
23329 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
23330 self.write_keyword("FOREIGN KEY");
23332 if !e.expressions.is_empty() {
23333 self.write(" (");
23334 for (i, expr) in e.expressions.iter().enumerate() {
23335 if i > 0 {
23336 self.write(", ");
23337 }
23338 self.generate_expression(expr)?;
23339 }
23340 self.write(")");
23341 }
23342 if let Some(reference) = &e.reference {
23343 self.write_space();
23344 self.generate_expression(reference)?;
23345 }
23346 if let Some(delete) = &e.delete {
23347 self.write_space();
23348 self.write_keyword("ON DELETE");
23349 self.write_space();
23350 self.generate_expression(delete)?;
23351 }
23352 if let Some(update) = &e.update {
23353 self.write_space();
23354 self.write_keyword("ON UPDATE");
23355 self.write_space();
23356 self.generate_expression(update)?;
23357 }
23358 if !e.options.is_empty() {
23359 self.write_space();
23360 for (i, opt) in e.options.iter().enumerate() {
23361 if i > 0 {
23362 self.write_space();
23363 }
23364 self.generate_expression(opt)?;
23365 }
23366 }
23367 Ok(())
23368 }
23369
23370 fn generate_format(&mut self, e: &Format) -> Result<()> {
23371 self.write_keyword("FORMAT");
23373 self.write("(");
23374 self.generate_expression(&e.this)?;
23375 for expr in &e.expressions {
23376 self.write(", ");
23377 self.generate_expression(expr)?;
23378 }
23379 self.write(")");
23380 Ok(())
23381 }
23382
23383 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
23384 self.generate_expression(&e.this)?;
23386 self.write(" (");
23387 self.write_keyword("FORMAT");
23388 self.write(" '");
23389 self.write(&e.format);
23390 self.write("')");
23391 Ok(())
23392 }
23393
23394 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
23395 self.write_keyword("FREESPACE");
23397 self.write("=");
23398 self.generate_expression(&e.this)?;
23399 if e.percent.is_some() {
23400 self.write_keyword(" PERCENT");
23401 }
23402 Ok(())
23403 }
23404
23405 fn generate_from(&mut self, e: &From) -> Result<()> {
23406 self.write_keyword("FROM");
23408 self.write_space();
23409
23410 use crate::dialects::DialectType;
23413 let has_tablesample = e.expressions.iter().any(|expr| matches!(expr, Expression::TableSample(_)));
23414 let use_cross_join = !has_tablesample && matches!(
23415 self.config.dialect,
23416 Some(DialectType::BigQuery)
23417 | Some(DialectType::Hive)
23418 | Some(DialectType::Spark)
23419 | Some(DialectType::Databricks)
23420 | Some(DialectType::SQLite)
23421 | Some(DialectType::ClickHouse)
23422 );
23423
23424 let wrap_values_in_parens = matches!(
23426 self.config.dialect,
23427 Some(DialectType::Snowflake)
23428 );
23429
23430 for (i, expr) in e.expressions.iter().enumerate() {
23431 if i > 0 {
23432 if use_cross_join {
23433 self.write(" CROSS JOIN ");
23434 } else {
23435 self.write(", ");
23436 }
23437 }
23438 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
23439 self.write("(");
23440 self.generate_expression(expr)?;
23441 self.write(")");
23442 } else {
23443 self.generate_expression(expr)?;
23444 }
23445 }
23446 Ok(())
23447 }
23448
23449 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
23450 self.write_keyword("FROM_BASE");
23452 self.write("(");
23453 self.generate_expression(&e.this)?;
23454 self.write(", ");
23455 self.generate_expression(&e.expression)?;
23456 self.write(")");
23457 Ok(())
23458 }
23459
23460 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
23461 self.generate_expression(&e.this)?;
23463 if let Some(zone) = &e.zone {
23464 self.write_space();
23465 self.write_keyword("AT TIME ZONE");
23466 self.write_space();
23467 self.generate_expression(zone)?;
23468 self.write_space();
23469 self.write_keyword("AT TIME ZONE");
23470 self.write(" 'UTC'");
23471 }
23472 Ok(())
23473 }
23474
23475 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
23476 self.write_keyword("GAP_FILL");
23478 self.write("(");
23479 self.generate_expression(&e.this)?;
23480 if let Some(ts_column) = &e.ts_column {
23481 self.write(", ");
23482 self.generate_expression(ts_column)?;
23483 }
23484 if let Some(bucket_width) = &e.bucket_width {
23485 self.write(", ");
23486 self.generate_expression(bucket_width)?;
23487 }
23488 if let Some(partitioning_columns) = &e.partitioning_columns {
23489 self.write(", ");
23490 self.generate_expression(partitioning_columns)?;
23491 }
23492 if let Some(value_columns) = &e.value_columns {
23493 self.write(", ");
23494 self.generate_expression(value_columns)?;
23495 }
23496 self.write(")");
23497 Ok(())
23498 }
23499
23500 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
23501 self.write_keyword("GENERATE_DATE_ARRAY");
23503 self.write("(");
23504 let mut first = true;
23505 if let Some(start) = &e.start {
23506 self.generate_expression(start)?;
23507 first = false;
23508 }
23509 if let Some(end) = &e.end {
23510 if !first {
23511 self.write(", ");
23512 }
23513 self.generate_expression(end)?;
23514 first = false;
23515 }
23516 if let Some(step) = &e.step {
23517 if !first {
23518 self.write(", ");
23519 }
23520 self.generate_expression(step)?;
23521 }
23522 self.write(")");
23523 Ok(())
23524 }
23525
23526 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
23527 self.write_keyword("ML.GENERATE_EMBEDDING");
23529 self.write("(");
23530 self.generate_expression(&e.this)?;
23531 self.write(", ");
23532 self.generate_expression(&e.expression)?;
23533 if let Some(params) = &e.params_struct {
23534 self.write(", ");
23535 self.generate_expression(params)?;
23536 }
23537 self.write(")");
23538 Ok(())
23539 }
23540
23541 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
23542 self.write_keyword("GENERATE_SERIES");
23544 self.write("(");
23545 let mut first = true;
23546 if let Some(start) = &e.start {
23547 self.generate_expression(start)?;
23548 first = false;
23549 }
23550 if let Some(end) = &e.end {
23551 if !first {
23552 self.write(", ");
23553 }
23554 self.generate_expression(end)?;
23555 first = false;
23556 }
23557 if let Some(step) = &e.step {
23558 if !first {
23559 self.write(", ");
23560 }
23561 self.generate_expression(step)?;
23562 }
23563 self.write(")");
23564 Ok(())
23565 }
23566
23567 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
23568 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
23570 self.write("(");
23571 let mut first = true;
23572 if let Some(start) = &e.start {
23573 self.generate_expression(start)?;
23574 first = false;
23575 }
23576 if let Some(end) = &e.end {
23577 if !first {
23578 self.write(", ");
23579 }
23580 self.generate_expression(end)?;
23581 first = false;
23582 }
23583 if let Some(step) = &e.step {
23584 if !first {
23585 self.write(", ");
23586 }
23587 self.generate_expression(step)?;
23588 }
23589 self.write(")");
23590 Ok(())
23591 }
23592
23593 fn generate_generated_as_identity_column_constraint(&mut self, e: &GeneratedAsIdentityColumnConstraint) -> Result<()> {
23594 use crate::dialects::DialectType;
23595
23596 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
23598 self.write_keyword("AUTOINCREMENT");
23599 if let Some(start) = &e.start {
23600 self.write_keyword(" START ");
23601 self.generate_expression(start)?;
23602 }
23603 if let Some(increment) = &e.increment {
23604 self.write_keyword(" INCREMENT ");
23605 self.generate_expression(increment)?;
23606 }
23607 return Ok(());
23608 }
23609
23610 self.write_keyword("GENERATED");
23612 if let Some(this) = &e.this {
23613 if let Expression::Boolean(b) = this.as_ref() {
23615 if b.value {
23616 self.write_keyword(" ALWAYS");
23617 } else {
23618 self.write_keyword(" BY DEFAULT");
23619 if e.on_null.is_some() {
23620 self.write_keyword(" ON NULL");
23621 }
23622 }
23623 } else {
23624 self.write_keyword(" ALWAYS");
23625 }
23626 }
23627 self.write_keyword(" AS IDENTITY");
23628 let has_options = e.start.is_some() || e.increment.is_some() || e.minvalue.is_some() || e.maxvalue.is_some();
23630 if has_options {
23631 self.write(" (");
23632 let mut first = true;
23633 if let Some(start) = &e.start {
23634 self.write_keyword("START WITH ");
23635 self.generate_expression(start)?;
23636 first = false;
23637 }
23638 if let Some(increment) = &e.increment {
23639 if !first { self.write(" "); }
23640 self.write_keyword("INCREMENT BY ");
23641 self.generate_expression(increment)?;
23642 first = false;
23643 }
23644 if let Some(minvalue) = &e.minvalue {
23645 if !first { self.write(" "); }
23646 self.write_keyword("MINVALUE ");
23647 self.generate_expression(minvalue)?;
23648 first = false;
23649 }
23650 if let Some(maxvalue) = &e.maxvalue {
23651 if !first { self.write(" "); }
23652 self.write_keyword("MAXVALUE ");
23653 self.generate_expression(maxvalue)?;
23654 }
23655 self.write(")");
23656 }
23657 Ok(())
23658 }
23659
23660 fn generate_generated_as_row_column_constraint(&mut self, e: &GeneratedAsRowColumnConstraint) -> Result<()> {
23661 self.write_keyword("GENERATED ALWAYS AS ROW ");
23663 if e.start.is_some() {
23664 self.write_keyword("START");
23665 } else {
23666 self.write_keyword("END");
23667 }
23668 if e.hidden.is_some() {
23669 self.write_keyword(" HIDDEN");
23670 }
23671 Ok(())
23672 }
23673
23674 fn generate_get(&mut self, e: &Get) -> Result<()> {
23675 self.write_keyword("GET");
23677 self.write_space();
23678 self.generate_expression(&e.this)?;
23679 if let Some(target) = &e.target {
23680 self.write_space();
23681 self.generate_expression(target)?;
23682 }
23683 for prop in &e.properties {
23684 self.write_space();
23685 self.generate_expression(prop)?;
23686 }
23687 Ok(())
23688 }
23689
23690 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
23691 self.generate_expression(&e.this)?;
23693 self.write("[");
23694 self.generate_expression(&e.expression)?;
23695 self.write("]");
23696 Ok(())
23697 }
23698
23699 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
23700 self.write_keyword("GETBIT");
23702 self.write("(");
23703 self.generate_expression(&e.this)?;
23704 self.write(", ");
23705 self.generate_expression(&e.expression)?;
23706 self.write(")");
23707 Ok(())
23708 }
23709
23710 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
23711 if e.is_role {
23713 self.write_keyword("ROLE");
23714 self.write_space();
23715 } else if e.is_group {
23716 self.write_keyword("GROUP");
23717 self.write_space();
23718 }
23719 self.write(&e.name.name);
23720 Ok(())
23721 }
23722
23723 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
23724 self.generate_expression(&e.this)?;
23726 if !e.expressions.is_empty() {
23727 self.write("(");
23728 for (i, expr) in e.expressions.iter().enumerate() {
23729 if i > 0 {
23730 self.write(", ");
23731 }
23732 self.generate_expression(expr)?;
23733 }
23734 self.write(")");
23735 }
23736 Ok(())
23737 }
23738
23739 fn generate_group(&mut self, e: &Group) -> Result<()> {
23740 self.write_keyword("GROUP BY");
23742 match e.all {
23744 Some(true) => {
23745 self.write_space();
23746 self.write_keyword("ALL");
23747 }
23748 Some(false) => {
23749 self.write_space();
23750 self.write_keyword("DISTINCT");
23751 }
23752 None => {}
23753 }
23754 if !e.expressions.is_empty() {
23755 self.write_space();
23756 for (i, expr) in e.expressions.iter().enumerate() {
23757 if i > 0 {
23758 self.write(", ");
23759 }
23760 self.generate_expression(expr)?;
23761 }
23762 }
23763 if let Some(cube) = &e.cube {
23765 if !e.expressions.is_empty() {
23766 self.write(", ");
23767 } else {
23768 self.write_space();
23769 }
23770 self.generate_expression(cube)?;
23771 }
23772 if let Some(rollup) = &e.rollup {
23773 if !e.expressions.is_empty() || e.cube.is_some() {
23774 self.write(", ");
23775 } else {
23776 self.write_space();
23777 }
23778 self.generate_expression(rollup)?;
23779 }
23780 if let Some(grouping_sets) = &e.grouping_sets {
23781 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
23782 self.write(", ");
23783 } else {
23784 self.write_space();
23785 }
23786 self.generate_expression(grouping_sets)?;
23787 }
23788 if let Some(totals) = &e.totals {
23789 self.write_space();
23790 self.write_keyword("WITH TOTALS");
23791 self.generate_expression(totals)?;
23792 }
23793 Ok(())
23794 }
23795
23796 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
23797 self.write_keyword("GROUP BY");
23799 match e.all {
23801 Some(true) => {
23802 self.write_space();
23803 self.write_keyword("ALL");
23804 }
23805 Some(false) => {
23806 self.write_space();
23807 self.write_keyword("DISTINCT");
23808 }
23809 None => {}
23810 }
23811
23812 let mut trailing_cube = false;
23815 let mut trailing_rollup = false;
23816 let mut regular_expressions: Vec<&Expression> = Vec::new();
23817
23818 for expr in &e.expressions {
23819 match expr {
23820 Expression::Cube(c) if c.expressions.is_empty() => {
23821 trailing_cube = true;
23822 }
23823 Expression::Rollup(r) if r.expressions.is_empty() => {
23824 trailing_rollup = true;
23825 }
23826 _ => {
23827 regular_expressions.push(expr);
23828 }
23829 }
23830 }
23831
23832 if self.config.pretty {
23834 self.write_newline();
23835 self.indent_level += 1;
23836 for (i, expr) in regular_expressions.iter().enumerate() {
23837 if i > 0 {
23838 self.write(",");
23839 self.write_newline();
23840 }
23841 self.write_indent();
23842 self.generate_expression(expr)?;
23843 }
23844 self.indent_level -= 1;
23845 } else {
23846 self.write_space();
23847 for (i, expr) in regular_expressions.iter().enumerate() {
23848 if i > 0 {
23849 self.write(", ");
23850 }
23851 self.generate_expression(expr)?;
23852 }
23853 }
23854
23855 if trailing_cube {
23857 self.write_space();
23858 self.write_keyword("WITH CUBE");
23859 } else if trailing_rollup {
23860 self.write_space();
23861 self.write_keyword("WITH ROLLUP");
23862 }
23863
23864 if e.totals {
23866 self.write_space();
23867 self.write_keyword("WITH TOTALS");
23868 }
23869
23870 Ok(())
23871 }
23872
23873 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
23874 self.write_keyword("GROUPING");
23876 self.write("(");
23877 for (i, expr) in e.expressions.iter().enumerate() {
23878 if i > 0 {
23879 self.write(", ");
23880 }
23881 self.generate_expression(expr)?;
23882 }
23883 self.write(")");
23884 Ok(())
23885 }
23886
23887 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
23888 self.write_keyword("GROUPING_ID");
23890 self.write("(");
23891 for (i, expr) in e.expressions.iter().enumerate() {
23892 if i > 0 {
23893 self.write(", ");
23894 }
23895 self.generate_expression(expr)?;
23896 }
23897 self.write(")");
23898 Ok(())
23899 }
23900
23901 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
23902 self.write_keyword("GROUPING SETS");
23904 self.write(" (");
23905 for (i, expr) in e.expressions.iter().enumerate() {
23906 if i > 0 {
23907 self.write(", ");
23908 }
23909 self.generate_expression(expr)?;
23910 }
23911 self.write(")");
23912 Ok(())
23913 }
23914
23915 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
23916 self.write_keyword("HASH_AGG");
23918 self.write("(");
23919 self.generate_expression(&e.this)?;
23920 for expr in &e.expressions {
23921 self.write(", ");
23922 self.generate_expression(expr)?;
23923 }
23924 self.write(")");
23925 Ok(())
23926 }
23927
23928 fn generate_having(&mut self, e: &Having) -> Result<()> {
23929 self.write_keyword("HAVING");
23931 self.write_space();
23932 self.generate_expression(&e.this)?;
23933 Ok(())
23934 }
23935
23936 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
23937 self.generate_expression(&e.this)?;
23939 self.write_space();
23940 self.write_keyword("HAVING");
23941 self.write_space();
23942 if e.max.is_some() {
23943 self.write_keyword("MAX");
23944 } else {
23945 self.write_keyword("MIN");
23946 }
23947 self.write_space();
23948 self.generate_expression(&e.expression)?;
23949 Ok(())
23950 }
23951
23952 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
23953 use crate::dialects::DialectType;
23954 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
23956 if let Expression::Literal(Literal::String(ref s)) = *e.this {
23958 return self.generate_string_literal(s);
23959 }
23960 }
23961 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) {
23963 self.write("$");
23964 if let Some(tag) = &e.tag {
23965 self.generate_expression(tag)?;
23966 }
23967 self.write("$");
23968 self.generate_expression(&e.this)?;
23969 self.write("$");
23970 if let Some(tag) = &e.tag {
23971 self.generate_expression(tag)?;
23972 }
23973 self.write("$");
23974 return Ok(());
23975 }
23976 self.write("$");
23978 if let Some(tag) = &e.tag {
23979 self.generate_expression(tag)?;
23980 }
23981 self.write("$");
23982 self.generate_expression(&e.this)?;
23983 self.write("$");
23984 if let Some(tag) = &e.tag {
23985 self.generate_expression(tag)?;
23986 }
23987 self.write("$");
23988 Ok(())
23989 }
23990
23991 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
23992 self.write_keyword("HEX_ENCODE");
23994 self.write("(");
23995 self.generate_expression(&e.this)?;
23996 self.write(")");
23997 Ok(())
23998 }
23999
24000 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
24001 match e.this.as_ref() {
24004 Expression::Identifier(id) => self.write(&id.name),
24005 other => self.generate_expression(other)?,
24006 }
24007 self.write(" (");
24008 self.write(&e.kind);
24009 self.write(" => ");
24010 self.generate_expression(&e.expression)?;
24011 self.write(")");
24012 Ok(())
24013 }
24014
24015 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
24016 self.write_keyword("HLL");
24018 self.write("(");
24019 self.generate_expression(&e.this)?;
24020 for expr in &e.expressions {
24021 self.write(", ");
24022 self.generate_expression(expr)?;
24023 }
24024 self.write(")");
24025 Ok(())
24026 }
24027
24028 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
24029 if e.input_.is_some() && e.output.is_some() {
24031 self.write_keyword("IN OUT");
24032 } else if e.input_.is_some() {
24033 self.write_keyword("IN");
24034 } else if e.output.is_some() {
24035 self.write_keyword("OUT");
24036 }
24037 Ok(())
24038 }
24039
24040 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
24041 self.write_keyword("INCLUDE");
24043 self.write_space();
24044 self.generate_expression(&e.this)?;
24045 if let Some(column_def) = &e.column_def {
24046 self.write_space();
24047 self.generate_expression(column_def)?;
24048 }
24049 if let Some(alias) = &e.alias {
24050 self.write_space();
24051 self.write_keyword("AS");
24052 self.write_space();
24053 self.write(alias);
24054 }
24055 Ok(())
24056 }
24057
24058 fn generate_index(&mut self, e: &Index) -> Result<()> {
24059 if e.unique {
24061 self.write_keyword("UNIQUE");
24062 self.write_space();
24063 }
24064 if e.primary.is_some() {
24065 self.write_keyword("PRIMARY");
24066 self.write_space();
24067 }
24068 if e.amp.is_some() {
24069 self.write_keyword("AMP");
24070 self.write_space();
24071 }
24072 if e.table.is_none() {
24073 self.write_keyword("INDEX");
24074 self.write_space();
24075 }
24076 if let Some(name) = &e.this {
24077 self.generate_expression(name)?;
24078 self.write_space();
24079 }
24080 if let Some(table) = &e.table {
24081 self.write_keyword("ON");
24082 self.write_space();
24083 self.generate_expression(table)?;
24084 }
24085 if !e.params.is_empty() {
24086 self.write("(");
24087 for (i, param) in e.params.iter().enumerate() {
24088 if i > 0 {
24089 self.write(", ");
24090 }
24091 self.generate_expression(param)?;
24092 }
24093 self.write(")");
24094 }
24095 Ok(())
24096 }
24097
24098 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
24099 if let Some(kind) = &e.kind {
24101 self.write(kind);
24102 self.write_space();
24103 }
24104 self.write_keyword("INDEX");
24105 if let Some(this) = &e.this {
24106 self.write_space();
24107 self.generate_expression(this)?;
24108 }
24109 if let Some(index_type) = &e.index_type {
24110 self.write_space();
24111 self.write_keyword("USING");
24112 self.write_space();
24113 self.generate_expression(index_type)?;
24114 }
24115 if !e.expressions.is_empty() {
24116 self.write(" (");
24117 for (i, expr) in e.expressions.iter().enumerate() {
24118 if i > 0 {
24119 self.write(", ");
24120 }
24121 self.generate_expression(expr)?;
24122 }
24123 self.write(")");
24124 }
24125 for opt in &e.options {
24126 self.write_space();
24127 self.generate_expression(opt)?;
24128 }
24129 Ok(())
24130 }
24131
24132 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
24133 if let Some(key_block_size) = &e.key_block_size {
24135 self.write_keyword("KEY_BLOCK_SIZE");
24136 self.write(" = ");
24137 self.generate_expression(key_block_size)?;
24138 } else if let Some(using) = &e.using {
24139 self.write_keyword("USING");
24140 self.write_space();
24141 self.generate_expression(using)?;
24142 } else if let Some(parser) = &e.parser {
24143 self.write_keyword("WITH PARSER");
24144 self.write_space();
24145 self.generate_expression(parser)?;
24146 } else if let Some(comment) = &e.comment {
24147 self.write_keyword("COMMENT");
24148 self.write_space();
24149 self.generate_expression(comment)?;
24150 } else if let Some(visible) = &e.visible {
24151 self.generate_expression(visible)?;
24152 } else if let Some(engine_attr) = &e.engine_attr {
24153 self.write_keyword("ENGINE_ATTRIBUTE");
24154 self.write(" = ");
24155 self.generate_expression(engine_attr)?;
24156 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
24157 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
24158 self.write(" = ");
24159 self.generate_expression(secondary_engine_attr)?;
24160 }
24161 Ok(())
24162 }
24163
24164 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
24165 if let Some(using) = &e.using {
24167 self.write_keyword("USING");
24168 self.write_space();
24169 self.generate_expression(using)?;
24170 }
24171 if !e.columns.is_empty() {
24172 self.write("(");
24173 for (i, col) in e.columns.iter().enumerate() {
24174 if i > 0 {
24175 self.write(", ");
24176 }
24177 self.generate_expression(col)?;
24178 }
24179 self.write(")");
24180 }
24181 if let Some(partition_by) = &e.partition_by {
24182 self.write_space();
24183 self.write_keyword("PARTITION BY");
24184 self.write_space();
24185 self.generate_expression(partition_by)?;
24186 }
24187 if let Some(where_) = &e.where_ {
24188 self.write_space();
24189 self.generate_expression(where_)?;
24190 }
24191 if let Some(include) = &e.include {
24192 self.write_space();
24193 self.write_keyword("INCLUDE");
24194 self.write(" (");
24195 self.generate_expression(include)?;
24196 self.write(")");
24197 }
24198 if let Some(with_storage) = &e.with_storage {
24199 self.write_space();
24200 self.write_keyword("WITH");
24201 self.write(" (");
24202 self.generate_expression(with_storage)?;
24203 self.write(")");
24204 }
24205 if let Some(tablespace) = &e.tablespace {
24206 self.write_space();
24207 self.write_keyword("USING INDEX TABLESPACE");
24208 self.write_space();
24209 self.generate_expression(tablespace)?;
24210 }
24211 Ok(())
24212 }
24213
24214 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
24215 if let Expression::Identifier(id) = &*e.this {
24219 self.write_keyword(&id.name);
24220 } else {
24221 self.generate_expression(&e.this)?;
24222 }
24223 self.write_space();
24224 self.write_keyword("INDEX");
24225 if let Some(target) = &e.target {
24226 self.write_space();
24227 self.write_keyword("FOR");
24228 self.write_space();
24229 if let Expression::Identifier(id) = &**target {
24230 self.write_keyword(&id.name);
24231 } else {
24232 self.generate_expression(target)?;
24233 }
24234 }
24235 self.write(" (");
24237 for (i, expr) in e.expressions.iter().enumerate() {
24238 if i > 0 {
24239 self.write(", ");
24240 }
24241 self.generate_expression(expr)?;
24242 }
24243 self.write(")");
24244 Ok(())
24245 }
24246
24247 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
24248 self.write_keyword("INHERITS");
24250 self.write(" (");
24251 for (i, expr) in e.expressions.iter().enumerate() {
24252 if i > 0 {
24253 self.write(", ");
24254 }
24255 self.generate_expression(expr)?;
24256 }
24257 self.write(")");
24258 Ok(())
24259 }
24260
24261 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
24262 self.write_keyword("INPUT");
24264 self.write("(");
24265 self.generate_expression(&e.this)?;
24266 self.write(")");
24267 Ok(())
24268 }
24269
24270 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
24271 if let Some(input_format) = &e.input_format {
24273 self.write_keyword("INPUTFORMAT");
24274 self.write_space();
24275 self.generate_expression(input_format)?;
24276 }
24277 if let Some(output_format) = &e.output_format {
24278 if e.input_format.is_some() {
24279 self.write(" ");
24280 }
24281 self.write_keyword("OUTPUTFORMAT");
24282 self.write_space();
24283 self.generate_expression(output_format)?;
24284 }
24285 Ok(())
24286 }
24287
24288 fn generate_install(&mut self, e: &Install) -> Result<()> {
24289 if e.force.is_some() {
24291 self.write_keyword("FORCE");
24292 self.write_space();
24293 }
24294 self.write_keyword("INSTALL");
24295 self.write_space();
24296 self.generate_expression(&e.this)?;
24297 if let Some(from) = &e.from_ {
24298 self.write_space();
24299 self.write_keyword("FROM");
24300 self.write_space();
24301 self.generate_expression(from)?;
24302 }
24303 Ok(())
24304 }
24305
24306 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
24307 self.write_keyword("INTERVAL");
24309 self.write_space();
24310 self.generate_expression(&e.expression)?;
24312 if let Some(unit) = &e.unit {
24313 self.write_space();
24314 self.write(unit);
24315 }
24316 Ok(())
24317 }
24318
24319 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
24320 self.write(&format!("{:?}", e.this).to_uppercase());
24322 self.write_space();
24323 self.write_keyword("TO");
24324 self.write_space();
24325 self.write(&format!("{:?}", e.expression).to_uppercase());
24326 Ok(())
24327 }
24328
24329 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
24330 self.write_keyword("INTO");
24332 if e.temporary {
24333 self.write_keyword(" TEMPORARY");
24334 }
24335 if e.unlogged.is_some() {
24336 self.write_keyword(" UNLOGGED");
24337 }
24338 if let Some(this) = &e.this {
24339 self.write_space();
24340 self.generate_expression(this)?;
24341 }
24342 if !e.expressions.is_empty() {
24343 self.write(" (");
24344 for (i, expr) in e.expressions.iter().enumerate() {
24345 if i > 0 {
24346 self.write(", ");
24347 }
24348 self.generate_expression(expr)?;
24349 }
24350 self.write(")");
24351 }
24352 Ok(())
24353 }
24354
24355 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
24356 self.generate_expression(&e.this)?;
24358 self.write_space();
24359 self.generate_expression(&e.expression)?;
24360 Ok(())
24361 }
24362
24363 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
24364 self.write_keyword("WITH");
24366 if e.no.is_some() {
24367 self.write_keyword(" NO");
24368 }
24369 if e.concurrent.is_some() {
24370 self.write_keyword(" CONCURRENT");
24371 }
24372 self.write_keyword(" ISOLATED LOADING");
24373 if let Some(target) = &e.target {
24374 self.write_space();
24375 self.generate_expression(target)?;
24376 }
24377 Ok(())
24378 }
24379
24380 fn generate_json(&mut self, e: &JSON) -> Result<()> {
24381 self.write_keyword("JSON");
24383 if let Some(this) = &e.this {
24384 self.write_space();
24385 self.generate_expression(this)?;
24386 }
24387 if let Some(with_) = &e.with_ {
24388 if let Expression::Boolean(b) = with_.as_ref() {
24390 if b.value {
24391 self.write_keyword(" WITH");
24392 } else {
24393 self.write_keyword(" WITHOUT");
24394 }
24395 }
24396 }
24397 if e.unique {
24398 self.write_keyword(" UNIQUE KEYS");
24399 }
24400 Ok(())
24401 }
24402
24403 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
24404 self.write_keyword("JSON_ARRAY");
24406 self.write("(");
24407 for (i, expr) in e.expressions.iter().enumerate() {
24408 if i > 0 {
24409 self.write(", ");
24410 }
24411 self.generate_expression(expr)?;
24412 }
24413 if let Some(null_handling) = &e.null_handling {
24414 self.write_space();
24415 self.generate_expression(null_handling)?;
24416 }
24417 if let Some(return_type) = &e.return_type {
24418 self.write_space();
24419 self.write_keyword("RETURNING");
24420 self.write_space();
24421 self.generate_expression(return_type)?;
24422 }
24423 if e.strict.is_some() {
24424 self.write_space();
24425 self.write_keyword("STRICT");
24426 }
24427 self.write(")");
24428 Ok(())
24429 }
24430
24431 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
24432 self.write_keyword("JSON_ARRAYAGG");
24434 self.write("(");
24435 self.generate_expression(&e.this)?;
24436 if let Some(order) = &e.order {
24437 self.write_space();
24438 if let Expression::OrderBy(ob) = order.as_ref() {
24440 self.write_keyword("ORDER BY");
24441 self.write_space();
24442 for (i, ord) in ob.expressions.iter().enumerate() {
24443 if i > 0 {
24444 self.write(", ");
24445 }
24446 self.generate_ordered(ord)?;
24447 }
24448 } else {
24449 self.generate_expression(order)?;
24451 }
24452 }
24453 if let Some(null_handling) = &e.null_handling {
24454 self.write_space();
24455 self.generate_expression(null_handling)?;
24456 }
24457 if let Some(return_type) = &e.return_type {
24458 self.write_space();
24459 self.write_keyword("RETURNING");
24460 self.write_space();
24461 self.generate_expression(return_type)?;
24462 }
24463 if e.strict.is_some() {
24464 self.write_space();
24465 self.write_keyword("STRICT");
24466 }
24467 self.write(")");
24468 Ok(())
24469 }
24470
24471 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
24472 self.write_keyword("JSON_OBJECTAGG");
24474 self.write("(");
24475 for (i, expr) in e.expressions.iter().enumerate() {
24476 if i > 0 {
24477 self.write(", ");
24478 }
24479 self.generate_expression(expr)?;
24480 }
24481 if let Some(null_handling) = &e.null_handling {
24482 self.write_space();
24483 self.generate_expression(null_handling)?;
24484 }
24485 if let Some(unique_keys) = &e.unique_keys {
24486 self.write_space();
24487 if let Expression::Boolean(b) = unique_keys.as_ref() {
24488 if b.value {
24489 self.write_keyword("WITH UNIQUE KEYS");
24490 } else {
24491 self.write_keyword("WITHOUT UNIQUE KEYS");
24492 }
24493 }
24494 }
24495 if let Some(return_type) = &e.return_type {
24496 self.write_space();
24497 self.write_keyword("RETURNING");
24498 self.write_space();
24499 self.generate_expression(return_type)?;
24500 }
24501 self.write(")");
24502 Ok(())
24503 }
24504
24505 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
24506 self.write_keyword("JSON_ARRAY_APPEND");
24508 self.write("(");
24509 self.generate_expression(&e.this)?;
24510 for expr in &e.expressions {
24511 self.write(", ");
24512 self.generate_expression(expr)?;
24513 }
24514 self.write(")");
24515 Ok(())
24516 }
24517
24518 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
24519 self.write_keyword("JSON_ARRAY_CONTAINS");
24521 self.write("(");
24522 self.generate_expression(&e.this)?;
24523 self.write(", ");
24524 self.generate_expression(&e.expression)?;
24525 self.write(")");
24526 Ok(())
24527 }
24528
24529 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
24530 self.write_keyword("JSON_ARRAY_INSERT");
24532 self.write("(");
24533 self.generate_expression(&e.this)?;
24534 for expr in &e.expressions {
24535 self.write(", ");
24536 self.generate_expression(expr)?;
24537 }
24538 self.write(")");
24539 Ok(())
24540 }
24541
24542 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
24543 self.write_keyword("JSONB_EXISTS");
24545 self.write("(");
24546 self.generate_expression(&e.this)?;
24547 if let Some(path) = &e.path {
24548 self.write(", ");
24549 self.generate_expression(path)?;
24550 }
24551 self.write(")");
24552 Ok(())
24553 }
24554
24555 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
24556 self.write_keyword("JSONB_EXTRACT_SCALAR");
24558 self.write("(");
24559 self.generate_expression(&e.this)?;
24560 self.write(", ");
24561 self.generate_expression(&e.expression)?;
24562 self.write(")");
24563 Ok(())
24564 }
24565
24566 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
24567 self.write_keyword("JSONB_OBJECT_AGG");
24569 self.write("(");
24570 self.generate_expression(&e.this)?;
24571 self.write(", ");
24572 self.generate_expression(&e.expression)?;
24573 self.write(")");
24574 Ok(())
24575 }
24576
24577 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
24578 if let Some(nested_schema) = &e.nested_schema {
24580 self.write_keyword("NESTED");
24581 if let Some(path) = &e.path {
24582 self.write_space();
24583 self.write_keyword("PATH");
24584 self.write_space();
24585 self.generate_expression(path)?;
24586 }
24587 self.write_space();
24588 self.generate_expression(nested_schema)?;
24589 } else {
24590 if let Some(this) = &e.this {
24591 self.generate_expression(this)?;
24592 }
24593 if let Some(kind) = &e.kind {
24594 self.write_space();
24595 self.write(kind);
24596 }
24597 if let Some(path) = &e.path {
24598 self.write_space();
24599 self.write_keyword("PATH");
24600 self.write_space();
24601 self.generate_expression(path)?;
24602 }
24603 if e.ordinality.is_some() {
24604 self.write_keyword(" FOR ORDINALITY");
24605 }
24606 }
24607 Ok(())
24608 }
24609
24610 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
24611 self.write_keyword("JSON_EXISTS");
24613 self.write("(");
24614 self.generate_expression(&e.this)?;
24615 if let Some(path) = &e.path {
24616 self.write(", ");
24617 self.generate_expression(path)?;
24618 }
24619 if let Some(passing) = &e.passing {
24620 self.write_space();
24621 self.write_keyword("PASSING");
24622 self.write_space();
24623 self.generate_expression(passing)?;
24624 }
24625 if let Some(on_condition) = &e.on_condition {
24626 self.write_space();
24627 self.generate_expression(on_condition)?;
24628 }
24629 self.write(")");
24630 Ok(())
24631 }
24632
24633 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
24634 self.generate_expression(&e.this)?;
24635 self.write(".:");
24636 self.generate_data_type(&e.to)?;
24637 Ok(())
24638 }
24639
24640 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
24641 self.write_keyword("JSON_EXTRACT_ARRAY");
24643 self.write("(");
24644 self.generate_expression(&e.this)?;
24645 if let Some(expr) = &e.expression {
24646 self.write(", ");
24647 self.generate_expression(expr)?;
24648 }
24649 self.write(")");
24650 Ok(())
24651 }
24652
24653 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
24654 if let Some(option) = &e.option {
24656 self.generate_expression(option)?;
24657 self.write_space();
24658 }
24659 self.write_keyword("QUOTES");
24660 if e.scalar.is_some() {
24661 self.write_keyword(" SCALAR_ONLY");
24662 }
24663 Ok(())
24664 }
24665
24666 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
24667 self.write_keyword("JSON_EXTRACT_SCALAR");
24669 self.write("(");
24670 self.generate_expression(&e.this)?;
24671 self.write(", ");
24672 self.generate_expression(&e.expression)?;
24673 self.write(")");
24674 Ok(())
24675 }
24676
24677 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
24678 if e.variant_extract.is_some() {
24682 use crate::dialects::DialectType;
24683 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
24684 self.generate_expression(&e.this)?;
24686 self.write(":");
24687 match e.expression.as_ref() {
24690 Expression::Literal(Literal::String(s)) => {
24691 self.write(s);
24692 }
24693 _ => {
24694 self.generate_expression(&e.expression)?;
24696 }
24697 }
24698 } else {
24699 self.write_keyword("GET_PATH");
24701 self.write("(");
24702 self.generate_expression(&e.this)?;
24703 self.write(", ");
24704 self.generate_expression(&e.expression)?;
24705 self.write(")");
24706 }
24707 } else {
24708 self.write_keyword("JSON_EXTRACT");
24709 self.write("(");
24710 self.generate_expression(&e.this)?;
24711 self.write(", ");
24712 self.generate_expression(&e.expression)?;
24713 for expr in &e.expressions {
24714 self.write(", ");
24715 self.generate_expression(expr)?;
24716 }
24717 self.write(")");
24718 }
24719 Ok(())
24720 }
24721
24722 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
24723 if let Some(this) = &e.this {
24726 self.generate_expression(this)?;
24727 self.write_space();
24728 }
24729 self.write_keyword("FORMAT JSON");
24730 Ok(())
24731 }
24732
24733 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
24734 self.generate_expression(&e.this)?;
24736 self.write(": ");
24737 self.generate_expression(&e.expression)?;
24738 Ok(())
24739 }
24740
24741 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
24742 self.write_keyword("JSON_KEYS");
24744 self.write("(");
24745 self.generate_expression(&e.this)?;
24746 if let Some(expr) = &e.expression {
24747 self.write(", ");
24748 self.generate_expression(expr)?;
24749 }
24750 for expr in &e.expressions {
24751 self.write(", ");
24752 self.generate_expression(expr)?;
24753 }
24754 self.write(")");
24755 Ok(())
24756 }
24757
24758 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
24759 self.write_keyword("JSON_KEYS");
24761 self.write("(");
24762 self.generate_expression(&e.this)?;
24763 if let Some(expr) = &e.expression {
24764 self.write(", ");
24765 self.generate_expression(expr)?;
24766 }
24767 self.write(")");
24768 Ok(())
24769 }
24770
24771 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
24772 let mut path_str = String::new();
24775 for expr in &e.expressions {
24776 match expr {
24777 Expression::JSONPathRoot(_) => {
24778 path_str.push('$');
24779 }
24780 Expression::JSONPathKey(k) => {
24781 if let Expression::Literal(crate::expressions::Literal::String(s)) = k.this.as_ref() {
24783 path_str.push('.');
24784 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
24786 if needs_quoting {
24787 path_str.push('"');
24788 path_str.push_str(s);
24789 path_str.push('"');
24790 } else {
24791 path_str.push_str(s);
24792 }
24793 }
24794 }
24795 Expression::JSONPathSubscript(s) => {
24796 if let Expression::Literal(crate::expressions::Literal::Number(n)) = s.this.as_ref() {
24798 path_str.push('[');
24799 path_str.push_str(n);
24800 path_str.push(']');
24801 }
24802 }
24803 _ => {
24804 let mut temp_gen = Self::with_config(self.config.clone());
24806 temp_gen.generate_expression(expr)?;
24807 path_str.push_str(&temp_gen.output);
24808 }
24809 }
24810 }
24811 self.write("'");
24813 self.write(&path_str);
24814 self.write("'");
24815 Ok(())
24816 }
24817
24818 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
24819 self.write("?(");
24821 self.generate_expression(&e.this)?;
24822 self.write(")");
24823 Ok(())
24824 }
24825
24826 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
24827 self.write(".");
24829 self.generate_expression(&e.this)?;
24830 Ok(())
24831 }
24832
24833 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
24834 self.write("..");
24836 if let Some(this) = &e.this {
24837 self.generate_expression(this)?;
24838 }
24839 Ok(())
24840 }
24841
24842 fn generate_json_path_root(&mut self) -> Result<()> {
24843 self.write("$");
24845 Ok(())
24846 }
24847
24848 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
24849 self.write("(");
24851 self.generate_expression(&e.this)?;
24852 self.write(")");
24853 Ok(())
24854 }
24855
24856 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
24857 self.generate_expression(&e.this)?;
24859 Ok(())
24860 }
24861
24862 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
24863 self.write("[");
24865 if let Some(start) = &e.start {
24866 self.generate_expression(start)?;
24867 }
24868 self.write(":");
24869 if let Some(end) = &e.end {
24870 self.generate_expression(end)?;
24871 }
24872 if let Some(step) = &e.step {
24873 self.write(":");
24874 self.generate_expression(step)?;
24875 }
24876 self.write("]");
24877 Ok(())
24878 }
24879
24880 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
24881 self.write("[");
24883 self.generate_expression(&e.this)?;
24884 self.write("]");
24885 Ok(())
24886 }
24887
24888 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
24889 self.write("[");
24891 for (i, expr) in e.expressions.iter().enumerate() {
24892 if i > 0 {
24893 self.write(", ");
24894 }
24895 self.generate_expression(expr)?;
24896 }
24897 self.write("]");
24898 Ok(())
24899 }
24900
24901 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
24902 self.write_keyword("JSON_REMOVE");
24904 self.write("(");
24905 self.generate_expression(&e.this)?;
24906 for expr in &e.expressions {
24907 self.write(", ");
24908 self.generate_expression(expr)?;
24909 }
24910 self.write(")");
24911 Ok(())
24912 }
24913
24914 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
24915 self.write_keyword("COLUMNS");
24918 self.write("(");
24919
24920 if self.config.pretty && !e.expressions.is_empty() {
24921 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
24923 for expr in &e.expressions {
24924 let mut temp_gen = Generator::with_config(self.config.clone());
24925 temp_gen.generate_expression(expr)?;
24926 expr_strings.push(temp_gen.output);
24927 }
24928
24929 if self.too_wide(&expr_strings) {
24931 self.write_newline();
24933 self.indent_level += 1;
24934 for (i, expr_str) in expr_strings.iter().enumerate() {
24935 if i > 0 {
24936 self.write(",");
24937 self.write_newline();
24938 }
24939 self.write_indent();
24940 self.write(expr_str);
24941 }
24942 self.write_newline();
24943 self.indent_level -= 1;
24944 self.write_indent();
24945 } else {
24946 for (i, expr_str) in expr_strings.iter().enumerate() {
24948 if i > 0 {
24949 self.write(", ");
24950 }
24951 self.write(expr_str);
24952 }
24953 }
24954 } else {
24955 for (i, expr) in e.expressions.iter().enumerate() {
24957 if i > 0 {
24958 self.write(", ");
24959 }
24960 self.generate_expression(expr)?;
24961 }
24962 }
24963 self.write(")");
24964 Ok(())
24965 }
24966
24967 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
24968 self.write_keyword("JSON_SET");
24970 self.write("(");
24971 self.generate_expression(&e.this)?;
24972 for expr in &e.expressions {
24973 self.write(", ");
24974 self.generate_expression(expr)?;
24975 }
24976 self.write(")");
24977 Ok(())
24978 }
24979
24980 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
24981 self.write_keyword("JSON_STRIP_NULLS");
24983 self.write("(");
24984 self.generate_expression(&e.this)?;
24985 if let Some(expr) = &e.expression {
24986 self.write(", ");
24987 self.generate_expression(expr)?;
24988 }
24989 self.write(")");
24990 Ok(())
24991 }
24992
24993 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
24994 self.write_keyword("JSON_TABLE");
24996 self.write("(");
24997 self.generate_expression(&e.this)?;
24998 if let Some(path) = &e.path {
24999 self.write(", ");
25000 self.generate_expression(path)?;
25001 }
25002 if let Some(error_handling) = &e.error_handling {
25003 self.write_space();
25004 self.generate_expression(error_handling)?;
25005 }
25006 if let Some(empty_handling) = &e.empty_handling {
25007 self.write_space();
25008 self.generate_expression(empty_handling)?;
25009 }
25010 if let Some(schema) = &e.schema {
25011 self.write_space();
25012 self.generate_expression(schema)?;
25013 }
25014 self.write(")");
25015 Ok(())
25016 }
25017
25018 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
25019 self.write_keyword("JSON_TYPE");
25021 self.write("(");
25022 self.generate_expression(&e.this)?;
25023 self.write(")");
25024 Ok(())
25025 }
25026
25027 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
25028 self.write_keyword("JSON_VALUE");
25030 self.write("(");
25031 self.generate_expression(&e.this)?;
25032 if let Some(path) = &e.path {
25033 self.write(", ");
25034 self.generate_expression(path)?;
25035 }
25036 if let Some(returning) = &e.returning {
25037 self.write_space();
25038 self.write_keyword("RETURNING");
25039 self.write_space();
25040 self.generate_expression(returning)?;
25041 }
25042 if let Some(on_condition) = &e.on_condition {
25043 self.write_space();
25044 self.generate_expression(on_condition)?;
25045 }
25046 self.write(")");
25047 Ok(())
25048 }
25049
25050 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
25051 self.write_keyword("JSON_VALUE_ARRAY");
25053 self.write("(");
25054 self.generate_expression(&e.this)?;
25055 self.write(")");
25056 Ok(())
25057 }
25058
25059 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
25060 self.write_keyword("JAROWINKLER_SIMILARITY");
25062 self.write("(");
25063 self.generate_expression(&e.this)?;
25064 self.write(", ");
25065 self.generate_expression(&e.expression)?;
25066 self.write(")");
25067 Ok(())
25068 }
25069
25070 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
25071 self.generate_expression(&e.this)?;
25073 self.write("(");
25074 for (i, expr) in e.expressions.iter().enumerate() {
25075 if i > 0 {
25076 self.write(", ");
25077 }
25078 self.generate_expression(expr)?;
25079 }
25080 self.write(")");
25081 Ok(())
25082 }
25083
25084 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
25085 if e.no.is_some() {
25087 self.write_keyword("NO ");
25088 }
25089 if let Some(local) = &e.local {
25090 self.generate_expression(local)?;
25091 self.write_space();
25092 }
25093 if e.dual.is_some() {
25094 self.write_keyword("DUAL ");
25095 }
25096 if e.before.is_some() {
25097 self.write_keyword("BEFORE ");
25098 }
25099 if e.after.is_some() {
25100 self.write_keyword("AFTER ");
25101 }
25102 self.write_keyword("JOURNAL");
25103 Ok(())
25104 }
25105
25106 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
25107 self.write_keyword("LANGUAGE");
25109 self.write_space();
25110 self.generate_expression(&e.this)?;
25111 Ok(())
25112 }
25113
25114 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
25115 if e.view.is_some() {
25117 self.write_keyword("LATERAL VIEW");
25119 if e.outer.is_some() {
25120 self.write_space();
25121 self.write_keyword("OUTER");
25122 }
25123 self.write_space();
25124 self.generate_expression(&e.this)?;
25125 if let Some(alias) = &e.alias {
25126 self.write_space();
25127 self.write(alias);
25128 }
25129 } else {
25130 self.write_keyword("LATERAL");
25132 self.write_space();
25133 self.generate_expression(&e.this)?;
25134 if e.ordinality.is_some() {
25135 self.write_space();
25136 self.write_keyword("WITH ORDINALITY");
25137 }
25138 if let Some(alias) = &e.alias {
25139 self.write_space();
25140 self.write_keyword("AS");
25141 self.write_space();
25142 self.write(alias);
25143 if !e.column_aliases.is_empty() {
25144 self.write("(");
25145 for (i, col) in e.column_aliases.iter().enumerate() {
25146 if i > 0 {
25147 self.write(", ");
25148 }
25149 self.write(col);
25150 }
25151 self.write(")");
25152 }
25153 }
25154 }
25155 Ok(())
25156 }
25157
25158 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
25159 self.write_keyword("LIKE");
25161 self.write_space();
25162 self.generate_expression(&e.this)?;
25163 for expr in &e.expressions {
25164 self.write_space();
25165 self.generate_expression(expr)?;
25166 }
25167 Ok(())
25168 }
25169
25170 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
25171 self.write_keyword("LIMIT");
25172 self.write_space();
25173 self.write_limit_expr(&e.this)?;
25174 if e.percent {
25175 self.write_space();
25176 self.write_keyword("PERCENT");
25177 }
25178 Ok(())
25179 }
25180
25181 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
25182 if e.percent.is_some() {
25184 self.write_keyword(" PERCENT");
25185 }
25186 if e.rows.is_some() {
25187 self.write_keyword(" ROWS");
25188 }
25189 if e.with_ties.is_some() {
25190 self.write_keyword(" WITH TIES");
25191 } else if e.rows.is_some() {
25192 self.write_keyword(" ONLY");
25193 }
25194 Ok(())
25195 }
25196
25197 fn generate_list(&mut self, e: &List) -> Result<()> {
25198 use crate::dialects::DialectType;
25199 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
25200
25201 if e.expressions.len() == 1 {
25203 if let Expression::Select(_) = &e.expressions[0] {
25204 self.write_keyword("LIST");
25205 self.write("(");
25206 self.generate_expression(&e.expressions[0])?;
25207 self.write(")");
25208 return Ok(());
25209 }
25210 }
25211
25212 if is_materialize {
25214 self.write_keyword("LIST");
25215 self.write("[");
25216 for (i, expr) in e.expressions.iter().enumerate() {
25217 if i > 0 {
25218 self.write(", ");
25219 }
25220 self.generate_expression(expr)?;
25221 }
25222 self.write("]");
25223 } else {
25224 self.write_keyword("LIST");
25226 self.write("(");
25227 for (i, expr) in e.expressions.iter().enumerate() {
25228 if i > 0 {
25229 self.write(", ");
25230 }
25231 self.generate_expression(expr)?;
25232 }
25233 self.write(")");
25234 }
25235 Ok(())
25236 }
25237
25238 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
25239 if let Expression::Select(_) = &*e.this {
25241 self.write_keyword("MAP");
25242 self.write("(");
25243 self.generate_expression(&e.this)?;
25244 self.write(")");
25245 return Ok(());
25246 }
25247
25248 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
25249
25250 self.write_keyword("MAP");
25252 if is_duckdb {
25253 self.write(" {");
25254 } else {
25255 self.write("[");
25256 }
25257 if let Expression::Struct(s) = &*e.this {
25258 for (i, (_, expr)) in s.fields.iter().enumerate() {
25259 if i > 0 {
25260 self.write(", ");
25261 }
25262 if let Expression::PropertyEQ(op) = expr {
25263 self.generate_expression(&op.left)?;
25264 if is_duckdb {
25265 self.write(": ");
25266 } else {
25267 self.write(" => ");
25268 }
25269 self.generate_expression(&op.right)?;
25270 } else {
25271 self.generate_expression(expr)?;
25272 }
25273 }
25274 }
25275 if is_duckdb {
25276 self.write("}");
25277 } else {
25278 self.write("]");
25279 }
25280 Ok(())
25281 }
25282
25283 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
25284 self.write_keyword("LOCALTIME");
25286 if let Some(precision) = &e.this {
25287 self.write("(");
25288 self.generate_expression(precision)?;
25289 self.write(")");
25290 }
25291 Ok(())
25292 }
25293
25294 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
25295 self.write_keyword("LOCALTIMESTAMP");
25297 if let Some(precision) = &e.this {
25298 self.write("(");
25299 self.generate_expression(precision)?;
25300 self.write(")");
25301 }
25302 Ok(())
25303 }
25304
25305 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
25306 self.write_keyword("LOCATION");
25308 self.write_space();
25309 self.generate_expression(&e.this)?;
25310 Ok(())
25311 }
25312
25313 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
25314 if e.update.is_some() {
25316 if e.key.is_some() {
25317 self.write_keyword("FOR NO KEY UPDATE");
25318 } else {
25319 self.write_keyword("FOR UPDATE");
25320 }
25321 } else {
25322 if e.key.is_some() {
25323 self.write_keyword("FOR KEY SHARE");
25324 } else {
25325 self.write_keyword("FOR SHARE");
25326 }
25327 }
25328 if !e.expressions.is_empty() {
25329 self.write_keyword(" OF ");
25330 for (i, expr) in e.expressions.iter().enumerate() {
25331 if i > 0 {
25332 self.write(", ");
25333 }
25334 self.generate_expression(expr)?;
25335 }
25336 }
25337 if let Some(wait) = &e.wait {
25342 match wait.as_ref() {
25343 Expression::Boolean(b) => {
25344 if b.value {
25345 self.write_keyword(" NOWAIT");
25346 } else {
25347 self.write_keyword(" SKIP LOCKED");
25348 }
25349 }
25350 _ => {
25351 self.write_keyword(" WAIT ");
25353 self.generate_expression(wait)?;
25354 }
25355 }
25356 }
25357 Ok(())
25358 }
25359
25360 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
25361 self.write_keyword("LOCK");
25363 self.write_space();
25364 self.generate_expression(&e.this)?;
25365 Ok(())
25366 }
25367
25368 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
25369 self.write_keyword("LOCKING");
25371 self.write_space();
25372 self.write(&e.kind);
25373 if let Some(this) = &e.this {
25374 self.write_space();
25375 self.generate_expression(this)?;
25376 }
25377 if let Some(for_or_in) = &e.for_or_in {
25378 self.write_space();
25379 self.generate_expression(for_or_in)?;
25380 }
25381 if let Some(lock_type) = &e.lock_type {
25382 self.write_space();
25383 self.generate_expression(lock_type)?;
25384 }
25385 if e.override_.is_some() {
25386 self.write_keyword(" OVERRIDE");
25387 }
25388 Ok(())
25389 }
25390
25391 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
25392 self.generate_expression(&e.this)?;
25394 self.write_space();
25395 self.generate_expression(&e.expression)?;
25396 Ok(())
25397 }
25398
25399 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
25400 if e.no.is_some() {
25402 self.write_keyword("NO ");
25403 }
25404 self.write_keyword("LOG");
25405 Ok(())
25406 }
25407
25408 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
25409 self.write_keyword("MD5");
25411 self.write("(");
25412 self.generate_expression(&e.this)?;
25413 for expr in &e.expressions {
25414 self.write(", ");
25415 self.generate_expression(expr)?;
25416 }
25417 self.write(")");
25418 Ok(())
25419 }
25420
25421 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
25422 self.write_keyword("ML.FORECAST");
25424 self.write("(");
25425 self.generate_expression(&e.this)?;
25426 if let Some(expression) = &e.expression {
25427 self.write(", ");
25428 self.generate_expression(expression)?;
25429 }
25430 if let Some(params) = &e.params_struct {
25431 self.write(", ");
25432 self.generate_expression(params)?;
25433 }
25434 self.write(")");
25435 Ok(())
25436 }
25437
25438 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
25439 self.write_keyword("ML.TRANSLATE");
25441 self.write("(");
25442 self.generate_expression(&e.this)?;
25443 self.write(", ");
25444 self.generate_expression(&e.expression)?;
25445 if let Some(params) = &e.params_struct {
25446 self.write(", ");
25447 self.generate_expression(params)?;
25448 }
25449 self.write(")");
25450 Ok(())
25451 }
25452
25453 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
25454 self.write_keyword("MAKE_INTERVAL");
25456 self.write("(");
25457 let mut first = true;
25458 if let Some(year) = &e.year {
25459 self.write("years => ");
25460 self.generate_expression(year)?;
25461 first = false;
25462 }
25463 if let Some(month) = &e.month {
25464 if !first { self.write(", "); }
25465 self.write("months => ");
25466 self.generate_expression(month)?;
25467 first = false;
25468 }
25469 if let Some(week) = &e.week {
25470 if !first { self.write(", "); }
25471 self.write("weeks => ");
25472 self.generate_expression(week)?;
25473 first = false;
25474 }
25475 if let Some(day) = &e.day {
25476 if !first { self.write(", "); }
25477 self.write("days => ");
25478 self.generate_expression(day)?;
25479 first = false;
25480 }
25481 if let Some(hour) = &e.hour {
25482 if !first { self.write(", "); }
25483 self.write("hours => ");
25484 self.generate_expression(hour)?;
25485 first = false;
25486 }
25487 if let Some(minute) = &e.minute {
25488 if !first { self.write(", "); }
25489 self.write("mins => ");
25490 self.generate_expression(minute)?;
25491 first = false;
25492 }
25493 if let Some(second) = &e.second {
25494 if !first { self.write(", "); }
25495 self.write("secs => ");
25496 self.generate_expression(second)?;
25497 }
25498 self.write(")");
25499 Ok(())
25500 }
25501
25502 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
25503 self.write_keyword("MANHATTAN_DISTANCE");
25505 self.write("(");
25506 self.generate_expression(&e.this)?;
25507 self.write(", ");
25508 self.generate_expression(&e.expression)?;
25509 self.write(")");
25510 Ok(())
25511 }
25512
25513 fn generate_map(&mut self, e: &Map) -> Result<()> {
25514 self.write_keyword("MAP");
25516 self.write("(");
25517 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
25518 if i > 0 {
25519 self.write(", ");
25520 }
25521 self.generate_expression(key)?;
25522 self.write(", ");
25523 self.generate_expression(value)?;
25524 }
25525 self.write(")");
25526 Ok(())
25527 }
25528
25529 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
25530 self.write_keyword("MAP_CAT");
25532 self.write("(");
25533 self.generate_expression(&e.this)?;
25534 self.write(", ");
25535 self.generate_expression(&e.expression)?;
25536 self.write(")");
25537 Ok(())
25538 }
25539
25540 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
25541 self.write_keyword("MAP_DELETE");
25543 self.write("(");
25544 self.generate_expression(&e.this)?;
25545 for expr in &e.expressions {
25546 self.write(", ");
25547 self.generate_expression(expr)?;
25548 }
25549 self.write(")");
25550 Ok(())
25551 }
25552
25553 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
25554 self.write_keyword("MAP_INSERT");
25556 self.write("(");
25557 self.generate_expression(&e.this)?;
25558 if let Some(key) = &e.key {
25559 self.write(", ");
25560 self.generate_expression(key)?;
25561 }
25562 if let Some(value) = &e.value {
25563 self.write(", ");
25564 self.generate_expression(value)?;
25565 }
25566 if let Some(update_flag) = &e.update_flag {
25567 self.write(", ");
25568 self.generate_expression(update_flag)?;
25569 }
25570 self.write(")");
25571 Ok(())
25572 }
25573
25574 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
25575 self.write_keyword("MAP_PICK");
25577 self.write("(");
25578 self.generate_expression(&e.this)?;
25579 for expr in &e.expressions {
25580 self.write(", ");
25581 self.generate_expression(expr)?;
25582 }
25583 self.write(")");
25584 Ok(())
25585 }
25586
25587 fn generate_masking_policy_column_constraint(&mut self, e: &MaskingPolicyColumnConstraint) -> Result<()> {
25588 self.write_keyword("MASKING POLICY");
25590 self.write_space();
25591 self.generate_expression(&e.this)?;
25592 if !e.expressions.is_empty() {
25593 self.write_keyword(" USING");
25594 self.write(" (");
25595 for (i, expr) in e.expressions.iter().enumerate() {
25596 if i > 0 {
25597 self.write(", ");
25598 }
25599 self.generate_expression(expr)?;
25600 }
25601 self.write(")");
25602 }
25603 Ok(())
25604 }
25605
25606 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
25607 if matches!(
25608 self.config.dialect,
25609 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
25610 ) {
25611 if e.expressions.len() > 1 {
25612 self.write("(");
25613 }
25614 for (i, expr) in e.expressions.iter().enumerate() {
25615 if i > 0 {
25616 self.write_keyword(" OR ");
25617 }
25618 self.generate_expression(expr)?;
25619 self.write_space();
25620 self.write("@@");
25621 self.write_space();
25622 self.generate_expression(&e.this)?;
25623 }
25624 if e.expressions.len() > 1 {
25625 self.write(")");
25626 }
25627 return Ok(());
25628 }
25629
25630 self.write_keyword("MATCH");
25632 self.write("(");
25633 for (i, expr) in e.expressions.iter().enumerate() {
25634 if i > 0 {
25635 self.write(", ");
25636 }
25637 self.generate_expression(expr)?;
25638 }
25639 self.write(")");
25640 self.write_keyword(" AGAINST");
25641 self.write("(");
25642 self.generate_expression(&e.this)?;
25643 if let Some(modifier) = &e.modifier {
25644 self.write_space();
25645 self.generate_expression(modifier)?;
25646 }
25647 self.write(")");
25648 Ok(())
25649 }
25650
25651 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
25652 if let Some(window_frame) = &e.window_frame {
25654 self.write(&format!("{:?}", window_frame).to_uppercase());
25655 self.write_space();
25656 }
25657 self.generate_expression(&e.this)?;
25658 Ok(())
25659 }
25660
25661 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
25662 self.write_keyword("MATERIALIZED");
25664 if let Some(this) = &e.this {
25665 self.write_space();
25666 self.generate_expression(this)?;
25667 }
25668 Ok(())
25669 }
25670
25671 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
25672 if let Some(with_) = &e.with_ {
25675 self.generate_expression(with_)?;
25676 self.write_space();
25677 }
25678 self.write_keyword("MERGE INTO");
25679 self.write_space();
25680 self.generate_expression(&e.this)?;
25681
25682 if self.config.pretty {
25684 self.write_newline();
25685 self.write_indent();
25686 } else {
25687 self.write_space();
25688 }
25689 self.write_keyword("USING");
25690 self.write_space();
25691 self.generate_expression(&e.using)?;
25692
25693 if let Some(on) = &e.on {
25695 if self.config.pretty {
25696 self.write_newline();
25697 self.write_indent();
25698 } else {
25699 self.write_space();
25700 }
25701 self.write_keyword("ON");
25702 self.write_space();
25703 self.generate_expression(on)?;
25704 }
25705 if let Some(using_cond) = &e.using_cond {
25707 self.write_space();
25708 self.write_keyword("USING");
25709 self.write_space();
25710 self.write("(");
25711 if let Expression::Tuple(tuple) = using_cond.as_ref() {
25713 for (i, col) in tuple.expressions.iter().enumerate() {
25714 if i > 0 {
25715 self.write(", ");
25716 }
25717 self.generate_expression(col)?;
25718 }
25719 } else {
25720 self.generate_expression(using_cond)?;
25721 }
25722 self.write(")");
25723 }
25724 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
25726 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)) {
25727 let mut names = Vec::new();
25728 match e.this.as_ref() {
25729 Expression::Alias(a) => {
25730 if let Expression::Table(t) = &a.this {
25732 names.push(t.name.name.clone());
25733 } else if let Expression::Identifier(id) = &a.this {
25734 names.push(id.name.clone());
25735 }
25736 names.push(a.alias.name.clone());
25737 }
25738 Expression::Table(t) => {
25739 names.push(t.name.name.clone());
25740 }
25741 Expression::Identifier(id) => {
25742 names.push(id.name.clone());
25743 }
25744 _ => {}
25745 }
25746 self.merge_strip_qualifiers = names;
25747 }
25748
25749 if let Some(whens) = &e.whens {
25751 if self.config.pretty {
25752 self.write_newline();
25753 self.write_indent();
25754 } else {
25755 self.write_space();
25756 }
25757 self.generate_expression(whens)?;
25758 }
25759
25760 self.merge_strip_qualifiers = saved_merge_strip;
25762
25763 if let Some(returning) = &e.returning {
25765 if self.config.pretty {
25766 self.write_newline();
25767 self.write_indent();
25768 } else {
25769 self.write_space();
25770 }
25771 self.generate_expression(returning)?;
25772 }
25773 Ok(())
25774 }
25775
25776 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
25777 if e.no.is_some() {
25779 self.write_keyword("NO MERGEBLOCKRATIO");
25780 } else if e.default.is_some() {
25781 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
25782 } else {
25783 self.write_keyword("MERGEBLOCKRATIO");
25784 self.write("=");
25785 if let Some(this) = &e.this {
25786 self.generate_expression(this)?;
25787 }
25788 if e.percent.is_some() {
25789 self.write_keyword(" PERCENT");
25790 }
25791 }
25792 Ok(())
25793 }
25794
25795 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
25796 self.write_keyword("TTL");
25798 let pretty_clickhouse = self.config.pretty
25799 && matches!(self.config.dialect, Some(crate::dialects::DialectType::ClickHouse));
25800
25801 if pretty_clickhouse {
25802 self.write_newline();
25803 self.indent_level += 1;
25804 for (i, expr) in e.expressions.iter().enumerate() {
25805 if i > 0 {
25806 self.write(",");
25807 self.write_newline();
25808 }
25809 self.write_indent();
25810 self.generate_expression(expr)?;
25811 }
25812 self.indent_level -= 1;
25813 } else {
25814 self.write_space();
25815 for (i, expr) in e.expressions.iter().enumerate() {
25816 if i > 0 {
25817 self.write(", ");
25818 }
25819 self.generate_expression(expr)?;
25820 }
25821 }
25822
25823 if let Some(where_) = &e.where_ {
25824 if pretty_clickhouse {
25825 self.write_newline();
25826 if let Expression::Where(w) = where_.as_ref() {
25827 self.write_indent();
25828 self.write_keyword("WHERE");
25829 self.write_newline();
25830 self.indent_level += 1;
25831 self.write_indent();
25832 self.generate_expression(&w.this)?;
25833 self.indent_level -= 1;
25834 } else {
25835 self.write_indent();
25836 self.generate_expression(where_)?;
25837 }
25838 } else {
25839 self.write_space();
25840 self.generate_expression(where_)?;
25841 }
25842 }
25843 if let Some(group) = &e.group {
25844 if pretty_clickhouse {
25845 self.write_newline();
25846 if let Expression::Group(g) = group.as_ref() {
25847 self.write_indent();
25848 self.write_keyword("GROUP BY");
25849 self.write_newline();
25850 self.indent_level += 1;
25851 for (i, expr) in g.expressions.iter().enumerate() {
25852 if i > 0 {
25853 self.write(",");
25854 self.write_newline();
25855 }
25856 self.write_indent();
25857 self.generate_expression(expr)?;
25858 }
25859 self.indent_level -= 1;
25860 } else {
25861 self.write_indent();
25862 self.generate_expression(group)?;
25863 }
25864 } else {
25865 self.write_space();
25866 self.generate_expression(group)?;
25867 }
25868 }
25869 if let Some(aggregates) = &e.aggregates {
25870 if pretty_clickhouse {
25871 self.write_newline();
25872 self.write_indent();
25873 self.write_keyword("SET");
25874 self.write_newline();
25875 self.indent_level += 1;
25876 if let Expression::Tuple(t) = aggregates.as_ref() {
25877 for (i, agg) in t.expressions.iter().enumerate() {
25878 if i > 0 {
25879 self.write(",");
25880 self.write_newline();
25881 }
25882 self.write_indent();
25883 self.generate_expression(agg)?;
25884 }
25885 } else {
25886 self.write_indent();
25887 self.generate_expression(aggregates)?;
25888 }
25889 self.indent_level -= 1;
25890 } else {
25891 self.write_space();
25892 self.write_keyword("SET");
25893 self.write_space();
25894 self.generate_expression(aggregates)?;
25895 }
25896 }
25897 Ok(())
25898 }
25899
25900 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
25901 self.generate_expression(&e.this)?;
25903 if e.delete.is_some() {
25904 self.write_keyword(" DELETE");
25905 }
25906 if let Some(recompress) = &e.recompress {
25907 self.write_keyword(" RECOMPRESS ");
25908 self.generate_expression(recompress)?;
25909 }
25910 if let Some(to_disk) = &e.to_disk {
25911 self.write_keyword(" TO DISK ");
25912 self.generate_expression(to_disk)?;
25913 }
25914 if let Some(to_volume) = &e.to_volume {
25915 self.write_keyword(" TO VOLUME ");
25916 self.generate_expression(to_volume)?;
25917 }
25918 Ok(())
25919 }
25920
25921 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
25922 self.write_keyword("MINHASH");
25924 self.write("(");
25925 self.generate_expression(&e.this)?;
25926 for expr in &e.expressions {
25927 self.write(", ");
25928 self.generate_expression(expr)?;
25929 }
25930 self.write(")");
25931 Ok(())
25932 }
25933
25934 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
25935 self.generate_expression(&e.this)?;
25937 self.write("!");
25938 self.generate_expression(&e.expression)?;
25939 Ok(())
25940 }
25941
25942 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
25943 self.write_keyword("MONTHNAME");
25945 self.write("(");
25946 self.generate_expression(&e.this)?;
25947 self.write(")");
25948 Ok(())
25949 }
25950
25951 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
25952 for comment in &e.leading_comments {
25954 self.write_formatted_comment(comment);
25955 self.write_space();
25956 }
25957 self.write_keyword("INSERT");
25959 self.write_space();
25960 self.write(&e.kind);
25961 for expr in &e.expressions {
25962 self.write_space();
25963 self.generate_expression(expr)?;
25964 }
25965 if let Some(source) = &e.source {
25966 self.write_space();
25967 self.generate_expression(source)?;
25968 }
25969 Ok(())
25970 }
25971
25972 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
25973 self.write_keyword("NEXT VALUE FOR");
25975 self.write_space();
25976 self.generate_expression(&e.this)?;
25977 if let Some(order) = &e.order {
25978 self.write_space();
25979 self.write_keyword("OVER");
25980 self.write(" (");
25981 self.generate_expression(order)?;
25982 self.write(")");
25983 }
25984 Ok(())
25985 }
25986
25987 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
25988 self.write_keyword("NORMAL");
25990 self.write("(");
25991 self.generate_expression(&e.this)?;
25992 if let Some(stddev) = &e.stddev {
25993 self.write(", ");
25994 self.generate_expression(stddev)?;
25995 }
25996 if let Some(gen) = &e.gen {
25997 self.write(", ");
25998 self.generate_expression(gen)?;
25999 }
26000 self.write(")");
26001 Ok(())
26002 }
26003
26004 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
26005 if e.is_casefold.is_some() {
26007 self.write_keyword("NORMALIZE_AND_CASEFOLD");
26008 } else {
26009 self.write_keyword("NORMALIZE");
26010 }
26011 self.write("(");
26012 self.generate_expression(&e.this)?;
26013 if let Some(form) = &e.form {
26014 self.write(", ");
26015 self.generate_expression(form)?;
26016 }
26017 self.write(")");
26018 Ok(())
26019 }
26020
26021 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
26022 if e.allow_null.is_none() {
26024 self.write_keyword("NOT ");
26025 }
26026 self.write_keyword("NULL");
26027 Ok(())
26028 }
26029
26030 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
26031 self.write_keyword("NULLIF");
26033 self.write("(");
26034 self.generate_expression(&e.this)?;
26035 self.write(", ");
26036 self.generate_expression(&e.expression)?;
26037 self.write(")");
26038 Ok(())
26039 }
26040
26041 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
26042 self.write_keyword("FORMAT");
26044 self.write("(");
26045 self.generate_expression(&e.this)?;
26046 self.write(", '");
26047 self.write(&e.format);
26048 self.write("'");
26049 if let Some(culture) = &e.culture {
26050 self.write(", ");
26051 self.generate_expression(culture)?;
26052 }
26053 self.write(")");
26054 Ok(())
26055 }
26056
26057 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
26058 self.write_keyword("OBJECT_AGG");
26060 self.write("(");
26061 self.generate_expression(&e.this)?;
26062 self.write(", ");
26063 self.generate_expression(&e.expression)?;
26064 self.write(")");
26065 Ok(())
26066 }
26067
26068 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
26069 self.generate_expression(&e.this)?;
26071 Ok(())
26072 }
26073
26074 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
26075 self.write_keyword("OBJECT_INSERT");
26077 self.write("(");
26078 self.generate_expression(&e.this)?;
26079 if let Some(key) = &e.key {
26080 self.write(", ");
26081 self.generate_expression(key)?;
26082 }
26083 if let Some(value) = &e.value {
26084 self.write(", ");
26085 self.generate_expression(value)?;
26086 }
26087 if let Some(update_flag) = &e.update_flag {
26088 self.write(", ");
26089 self.generate_expression(update_flag)?;
26090 }
26091 self.write(")");
26092 Ok(())
26093 }
26094
26095 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
26096 self.write_keyword("OFFSET");
26098 self.write_space();
26099 self.generate_expression(&e.this)?;
26100 if e.rows == Some(true) && matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL) | Some(crate::dialects::DialectType::Oracle)) {
26102 self.write_space();
26103 self.write_keyword("ROWS");
26104 }
26105 Ok(())
26106 }
26107
26108 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
26109 self.write_keyword("QUALIFY");
26111 self.write_space();
26112 self.generate_expression(&e.this)?;
26113 Ok(())
26114 }
26115
26116 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
26117 self.write_keyword("ON CLUSTER");
26119 self.write_space();
26120 self.generate_expression(&e.this)?;
26121 Ok(())
26122 }
26123
26124 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
26125 self.write_keyword("ON COMMIT");
26127 if e.delete.is_some() {
26128 self.write_keyword(" DELETE ROWS");
26129 } else {
26130 self.write_keyword(" PRESERVE ROWS");
26131 }
26132 Ok(())
26133 }
26134
26135 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
26136 if let Some(empty) = &e.empty {
26138 self.generate_expression(empty)?;
26139 self.write_keyword(" ON EMPTY");
26140 }
26141 if let Some(error) = &e.error {
26142 if e.empty.is_some() {
26143 self.write_space();
26144 }
26145 self.generate_expression(error)?;
26146 self.write_keyword(" ON ERROR");
26147 }
26148 if let Some(null) = &e.null {
26149 if e.empty.is_some() || e.error.is_some() {
26150 self.write_space();
26151 }
26152 self.generate_expression(null)?;
26153 self.write_keyword(" ON NULL");
26154 }
26155 Ok(())
26156 }
26157
26158 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
26159 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
26161 return Ok(());
26162 }
26163 if e.duplicate.is_some() {
26165 self.write_keyword("ON DUPLICATE KEY UPDATE");
26167 for (i, expr) in e.expressions.iter().enumerate() {
26168 if i > 0 {
26169 self.write(",");
26170 }
26171 self.write_space();
26172 self.generate_expression(expr)?;
26173 }
26174 return Ok(());
26175 } else {
26176 self.write_keyword("ON CONFLICT");
26177 }
26178 if let Some(constraint) = &e.constraint {
26179 self.write_keyword(" ON CONSTRAINT ");
26180 self.generate_expression(constraint)?;
26181 }
26182 if let Some(conflict_keys) = &e.conflict_keys {
26183 if let Expression::Tuple(t) = conflict_keys.as_ref() {
26185 self.write("(");
26186 for (i, expr) in t.expressions.iter().enumerate() {
26187 if i > 0 {
26188 self.write(", ");
26189 }
26190 self.generate_expression(expr)?;
26191 }
26192 self.write(")");
26193 } else {
26194 self.write("(");
26195 self.generate_expression(conflict_keys)?;
26196 self.write(")");
26197 }
26198 }
26199 if let Some(index_predicate) = &e.index_predicate {
26200 self.write_keyword(" WHERE ");
26201 self.generate_expression(index_predicate)?;
26202 }
26203 if let Some(action) = &e.action {
26204 if let Expression::Identifier(id) = action.as_ref() {
26206 if id.name == "NOTHING" || id.name.to_uppercase() == "NOTHING" {
26207 self.write_keyword(" DO NOTHING");
26208 } else {
26209 self.write_keyword(" DO ");
26210 self.generate_expression(action)?;
26211 }
26212 } else if let Expression::Tuple(t) = action.as_ref() {
26213 self.write_keyword(" DO UPDATE SET ");
26215 for (i, expr) in t.expressions.iter().enumerate() {
26216 if i > 0 {
26217 self.write(", ");
26218 }
26219 self.generate_expression(expr)?;
26220 }
26221 } else {
26222 self.write_keyword(" DO ");
26223 self.generate_expression(action)?;
26224 }
26225 }
26226 if let Some(where_) = &e.where_ {
26228 self.write_keyword(" WHERE ");
26229 self.generate_expression(where_)?;
26230 }
26231 Ok(())
26232 }
26233
26234 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
26235 self.write_keyword("ON");
26237 self.write_space();
26238 self.generate_expression(&e.this)?;
26239 Ok(())
26240 }
26241
26242 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
26243 self.generate_expression(&e.this)?;
26245 self.write_space();
26246 self.generate_expression(&e.expression)?;
26247 Ok(())
26248 }
26249
26250 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
26251 self.write_keyword("OPENJSON");
26253 self.write("(");
26254 self.generate_expression(&e.this)?;
26255 if let Some(path) = &e.path {
26256 self.write(", ");
26257 self.generate_expression(path)?;
26258 }
26259 self.write(")");
26260 if !e.expressions.is_empty() {
26261 self.write_keyword(" WITH");
26262 if self.config.pretty {
26263 self.write(" (\n");
26264 self.indent_level += 2;
26265 for (i, expr) in e.expressions.iter().enumerate() {
26266 if i > 0 {
26267 self.write(",\n");
26268 }
26269 self.write_indent();
26270 self.generate_expression(expr)?;
26271 }
26272 self.write("\n");
26273 self.indent_level -= 2;
26274 self.write(")");
26275 } else {
26276 self.write(" (");
26277 for (i, expr) in e.expressions.iter().enumerate() {
26278 if i > 0 {
26279 self.write(", ");
26280 }
26281 self.generate_expression(expr)?;
26282 }
26283 self.write(")");
26284 }
26285 }
26286 Ok(())
26287 }
26288
26289 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
26290 self.generate_expression(&e.this)?;
26292 self.write_space();
26293 if let Some(ref dt) = e.data_type {
26295 self.generate_data_type(dt)?;
26296 } else if !e.kind.is_empty() {
26297 self.write(&e.kind);
26298 }
26299 if let Some(path) = &e.path {
26300 self.write_space();
26301 self.generate_expression(path)?;
26302 }
26303 if e.as_json.is_some() {
26304 self.write_keyword(" AS JSON");
26305 }
26306 Ok(())
26307 }
26308
26309 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
26310 self.generate_expression(&e.this)?;
26312 self.write_space();
26313 if let Some(op) = &e.operator {
26314 self.write_keyword("OPERATOR");
26315 self.write("(");
26316 self.generate_expression(op)?;
26317 self.write(")");
26318 }
26319 self.write_space();
26320 self.generate_expression(&e.expression)?;
26321 Ok(())
26322 }
26323
26324 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
26325 self.write_keyword("ORDER BY");
26327 let pretty_clickhouse_single_paren = self.config.pretty
26328 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
26329 && e.expressions.len() == 1
26330 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
26331 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
26332 && e.expressions.len() == 1
26333 && matches!(e.expressions[0].this, Expression::Tuple(_))
26334 && !e.expressions[0].desc
26335 && e.expressions[0].nulls_first.is_none();
26336
26337 if pretty_clickhouse_single_paren {
26338 self.write_space();
26339 if let Expression::Paren(p) = &e.expressions[0].this {
26340 self.write("(");
26341 self.write_newline();
26342 self.indent_level += 1;
26343 self.write_indent();
26344 self.generate_expression(&p.this)?;
26345 self.indent_level -= 1;
26346 self.write_newline();
26347 self.write(")");
26348 }
26349 return Ok(());
26350 }
26351
26352 if clickhouse_single_tuple {
26353 self.write_space();
26354 if let Expression::Tuple(t) = &e.expressions[0].this {
26355 self.write("(");
26356 for (i, expr) in t.expressions.iter().enumerate() {
26357 if i > 0 {
26358 self.write(", ");
26359 }
26360 self.generate_expression(expr)?;
26361 }
26362 self.write(")");
26363 }
26364 return Ok(());
26365 }
26366
26367 self.write_space();
26368 for (i, ordered) in e.expressions.iter().enumerate() {
26369 if i > 0 {
26370 self.write(", ");
26371 }
26372 self.generate_expression(&ordered.this)?;
26373 if ordered.desc {
26374 self.write_space();
26375 self.write_keyword("DESC");
26376 } else if ordered.explicit_asc {
26377 self.write_space();
26378 self.write_keyword("ASC");
26379 }
26380 if let Some(nulls_first) = ordered.nulls_first {
26381 let skip_nulls_last = !nulls_first
26383 && matches!(self.config.dialect, Some(DialectType::Dremio));
26384 if !skip_nulls_last {
26385 self.write_space();
26386 self.write_keyword("NULLS");
26387 self.write_space();
26388 if nulls_first {
26389 self.write_keyword("FIRST");
26390 } else {
26391 self.write_keyword("LAST");
26392 }
26393 }
26394 }
26395 }
26396 Ok(())
26397 }
26398
26399 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
26400 self.write_keyword("OUTPUT");
26402 self.write("(");
26403 if self.config.pretty {
26404 self.indent_level += 1;
26405 self.write_newline();
26406 self.write_indent();
26407 self.generate_expression(&e.this)?;
26408 self.indent_level -= 1;
26409 self.write_newline();
26410 } else {
26411 self.generate_expression(&e.this)?;
26412 }
26413 self.write(")");
26414 Ok(())
26415 }
26416
26417 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
26418 self.write_keyword("TRUNCATE");
26420 if let Some(this) = &e.this {
26421 self.write_space();
26422 self.generate_expression(this)?;
26423 }
26424 if e.with_count.is_some() {
26425 self.write_keyword(" WITH COUNT");
26426 } else {
26427 self.write_keyword(" WITHOUT COUNT");
26428 }
26429 Ok(())
26430 }
26431
26432 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
26433 self.generate_expression(&e.this)?;
26435 self.write("(");
26436 for (i, expr) in e.expressions.iter().enumerate() {
26437 if i > 0 {
26438 self.write(", ");
26439 }
26440 self.generate_expression(expr)?;
26441 }
26442 self.write(")(");
26443 for (i, param) in e.params.iter().enumerate() {
26444 if i > 0 {
26445 self.write(", ");
26446 }
26447 self.generate_expression(param)?;
26448 }
26449 self.write(")");
26450 Ok(())
26451 }
26452
26453 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
26454 self.write_keyword("PARSE_DATETIME");
26456 self.write("(");
26457 if let Some(format) = &e.format {
26458 self.write("'");
26459 self.write(format);
26460 self.write("', ");
26461 }
26462 self.generate_expression(&e.this)?;
26463 if let Some(zone) = &e.zone {
26464 self.write(", ");
26465 self.generate_expression(zone)?;
26466 }
26467 self.write(")");
26468 Ok(())
26469 }
26470
26471 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
26472 self.write_keyword("PARSE_IP");
26474 self.write("(");
26475 self.generate_expression(&e.this)?;
26476 if let Some(type_) = &e.type_ {
26477 self.write(", ");
26478 self.generate_expression(type_)?;
26479 }
26480 if let Some(permissive) = &e.permissive {
26481 self.write(", ");
26482 self.generate_expression(permissive)?;
26483 }
26484 self.write(")");
26485 Ok(())
26486 }
26487
26488 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
26489 self.write_keyword("PARSE_JSON");
26491 self.write("(");
26492 self.generate_expression(&e.this)?;
26493 if let Some(expression) = &e.expression {
26494 self.write(", ");
26495 self.generate_expression(expression)?;
26496 }
26497 self.write(")");
26498 Ok(())
26499 }
26500
26501 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
26502 self.write_keyword("PARSE_TIME");
26504 self.write("(");
26505 self.write(&format!("'{}'", e.format));
26506 self.write(", ");
26507 self.generate_expression(&e.this)?;
26508 self.write(")");
26509 Ok(())
26510 }
26511
26512 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
26513 self.write_keyword("PARSE_URL");
26515 self.write("(");
26516 self.generate_expression(&e.this)?;
26517 if let Some(part) = &e.part_to_extract {
26518 self.write(", ");
26519 self.generate_expression(part)?;
26520 }
26521 if let Some(key) = &e.key {
26522 self.write(", ");
26523 self.generate_expression(key)?;
26524 }
26525 if let Some(permissive) = &e.permissive {
26526 self.write(", ");
26527 self.generate_expression(permissive)?;
26528 }
26529 self.write(")");
26530 Ok(())
26531 }
26532
26533 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
26534 if e.subpartition {
26536 self.write_keyword("SUBPARTITION");
26537 } else {
26538 self.write_keyword("PARTITION");
26539 }
26540 self.write("(");
26541 for (i, expr) in e.expressions.iter().enumerate() {
26542 if i > 0 {
26543 self.write(", ");
26544 }
26545 self.generate_expression(expr)?;
26546 }
26547 self.write(")");
26548 Ok(())
26549 }
26550
26551 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
26552 if let Some(this) = &e.this {
26554 if let Some(expression) = &e.expression {
26555 self.write_keyword("WITH");
26557 self.write(" (");
26558 self.write_keyword("MODULUS");
26559 self.write_space();
26560 self.generate_expression(this)?;
26561 self.write(", ");
26562 self.write_keyword("REMAINDER");
26563 self.write_space();
26564 self.generate_expression(expression)?;
26565 self.write(")");
26566 } else {
26567 self.write_keyword("IN");
26569 self.write(" (");
26570 self.generate_partition_bound_values(this)?;
26571 self.write(")");
26572 }
26573 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
26574 self.write_keyword("FROM");
26576 self.write(" (");
26577 self.generate_partition_bound_values(from)?;
26578 self.write(") ");
26579 self.write_keyword("TO");
26580 self.write(" (");
26581 self.generate_partition_bound_values(to)?;
26582 self.write(")");
26583 }
26584 Ok(())
26585 }
26586
26587 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
26590 if let Expression::Tuple(t) = expr {
26591 for (i, e) in t.expressions.iter().enumerate() {
26592 if i > 0 {
26593 self.write(", ");
26594 }
26595 self.generate_expression(e)?;
26596 }
26597 Ok(())
26598 } else {
26599 self.generate_expression(expr)
26600 }
26601 }
26602
26603 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
26604 self.write_keyword("PARTITION BY LIST");
26606 if let Some(partition_exprs) = &e.partition_expressions {
26607 self.write(" (");
26608 self.generate_doris_partition_expressions(partition_exprs)?;
26610 self.write(")");
26611 }
26612 if let Some(create_exprs) = &e.create_expressions {
26613 self.write(" (");
26614 self.generate_doris_partition_definitions(create_exprs)?;
26616 self.write(")");
26617 }
26618 Ok(())
26619 }
26620
26621 fn generate_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
26622 self.write_keyword("PARTITION BY RANGE");
26624 if let Some(partition_exprs) = &e.partition_expressions {
26625 self.write(" (");
26626 self.generate_doris_partition_expressions(partition_exprs)?;
26628 self.write(")");
26629 }
26630 if let Some(create_exprs) = &e.create_expressions {
26631 self.write(" (");
26632 self.generate_doris_partition_definitions(create_exprs)?;
26634 self.write(")");
26635 }
26636 Ok(())
26637 }
26638
26639 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
26641 if let Expression::Tuple(t) = expr {
26642 for (i, e) in t.expressions.iter().enumerate() {
26643 if i > 0 {
26644 self.write(", ");
26645 }
26646 self.generate_expression(e)?;
26647 }
26648 } else {
26649 self.generate_expression(expr)?;
26650 }
26651 Ok(())
26652 }
26653
26654 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
26656 match expr {
26657 Expression::Tuple(t) => {
26658 for (i, part) in t.expressions.iter().enumerate() {
26660 if i > 0 {
26661 self.write(", ");
26662 }
26663 if let Expression::Partition(p) = part {
26665 for (j, inner) in p.expressions.iter().enumerate() {
26666 if j > 0 {
26667 self.write(", ");
26668 }
26669 self.generate_expression(inner)?;
26670 }
26671 } else {
26672 self.generate_expression(part)?;
26673 }
26674 }
26675 }
26676 Expression::PartitionByRangePropertyDynamic(_) => {
26677 self.generate_expression(expr)?;
26679 }
26680 _ => {
26681 self.generate_expression(expr)?;
26682 }
26683 }
26684 Ok(())
26685 }
26686
26687 fn generate_partition_by_range_property_dynamic(&mut self, e: &PartitionByRangePropertyDynamic) -> Result<()> {
26688 if let Some(start) = &e.start {
26690 self.write_keyword("FROM");
26691 self.write(" (");
26692 self.generate_expression(start)?;
26693 self.write(")");
26694 }
26695 if let Some(end) = &e.end {
26696 self.write_space();
26697 self.write_keyword("TO");
26698 self.write(" (");
26699 self.generate_expression(end)?;
26700 self.write(")");
26701 }
26702 if let Some(every) = &e.every {
26703 self.write_space();
26704 self.generate_doris_interval(every)?;
26706 }
26707 Ok(())
26708 }
26709
26710 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
26712 if let Expression::Interval(interval) = expr {
26713 self.write_keyword("INTERVAL");
26714 if let Some(ref value) = interval.this {
26715 self.write_space();
26716 self.generate_expression(value)?;
26718 }
26719 if let Some(ref unit_spec) = interval.unit {
26720 self.write_space();
26721 self.write_interval_unit_spec(unit_spec)?;
26722 }
26723 Ok(())
26724 } else {
26725 self.generate_expression(expr)
26726 }
26727 }
26728
26729 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
26730 self.write_keyword("TRUNCATE");
26732 self.write("(");
26733 self.generate_expression(&e.expression)?;
26734 self.write(", ");
26735 self.generate_expression(&e.this)?;
26736 self.write(")");
26737 Ok(())
26738 }
26739
26740 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
26741 self.write_keyword("PARTITION");
26743 self.write_space();
26744 self.generate_expression(&e.this)?;
26745 self.write_space();
26746 self.write_keyword("VALUES IN");
26747 self.write(" (");
26748 for (i, expr) in e.expressions.iter().enumerate() {
26749 if i > 0 {
26750 self.write(", ");
26751 }
26752 self.generate_expression(expr)?;
26753 }
26754 self.write(")");
26755 Ok(())
26756 }
26757
26758 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
26759 if e.expressions.is_empty() && e.expression.is_some() {
26762 self.generate_expression(&e.this)?;
26764 self.write_space();
26765 self.write_keyword("TO");
26766 self.write_space();
26767 self.generate_expression(e.expression.as_ref().unwrap())?;
26768 return Ok(());
26769 }
26770
26771 self.write_keyword("PARTITION");
26773 self.write_space();
26774 self.generate_expression(&e.this)?;
26775 self.write_space();
26776
26777 if e.expressions.len() == 1 {
26779 self.write_keyword("VALUES LESS THAN");
26781 self.write(" (");
26782 self.generate_expression(&e.expressions[0])?;
26783 self.write(")");
26784 } else if !e.expressions.is_empty() {
26785 self.write_keyword("VALUES");
26787 self.write(" [");
26788 for (i, expr) in e.expressions.iter().enumerate() {
26789 if i > 0 {
26790 self.write(", ");
26791 }
26792 if let Expression::Tuple(t) = expr {
26794 self.write("(");
26795 for (j, inner) in t.expressions.iter().enumerate() {
26796 if j > 0 {
26797 self.write(", ");
26798 }
26799 self.generate_expression(inner)?;
26800 }
26801 self.write(")");
26802 } else {
26803 self.write("(");
26804 self.generate_expression(expr)?;
26805 self.write(")");
26806 }
26807 }
26808 self.write(")");
26809 }
26810 Ok(())
26811 }
26812
26813 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
26814 self.write_keyword("BUCKET");
26816 self.write("(");
26817 self.generate_expression(&e.this)?;
26818 self.write(", ");
26819 self.generate_expression(&e.expression)?;
26820 self.write(")");
26821 Ok(())
26822 }
26823
26824 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
26825 if matches!(
26827 self.config.dialect,
26828 Some(crate::dialects::DialectType::Teradata) | Some(crate::dialects::DialectType::ClickHouse)
26829 ) {
26830 self.write_keyword("PARTITION BY");
26831 } else {
26832 self.write_keyword("PARTITIONED BY");
26833 }
26834 self.write_space();
26835 if self.config.pretty {
26837 if let Expression::Tuple(ref tuple) = *e.this {
26838 self.write("(");
26839 self.write_newline();
26840 self.indent_level += 1;
26841 for (i, expr) in tuple.expressions.iter().enumerate() {
26842 if i > 0 {
26843 self.write(",");
26844 self.write_newline();
26845 }
26846 self.write_indent();
26847 self.generate_expression(expr)?;
26848 }
26849 self.indent_level -= 1;
26850 self.write_newline();
26851 self.write(")");
26852 } else {
26853 self.generate_expression(&e.this)?;
26854 }
26855 } else {
26856 self.generate_expression(&e.this)?;
26857 }
26858 Ok(())
26859 }
26860
26861 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
26862 self.write_keyword("PARTITION OF");
26864 self.write_space();
26865 self.generate_expression(&e.this)?;
26866 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
26868 self.write_space();
26869 self.write_keyword("FOR VALUES");
26870 self.write_space();
26871 self.generate_expression(&e.expression)?;
26872 } else {
26873 self.write_space();
26874 self.write_keyword("DEFAULT");
26875 }
26876 Ok(())
26877 }
26878
26879 fn generate_period_for_system_time_constraint(&mut self, e: &PeriodForSystemTimeConstraint) -> Result<()> {
26880 self.write_keyword("PERIOD FOR SYSTEM_TIME");
26882 self.write(" (");
26883 self.generate_expression(&e.this)?;
26884 self.write(", ");
26885 self.generate_expression(&e.expression)?;
26886 self.write(")");
26887 Ok(())
26888 }
26889
26890 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
26891 self.generate_expression(&e.this)?;
26894 self.write_space();
26895 self.write_keyword("AS");
26896 self.write_space();
26897 if self.config.unpivot_aliases_are_identifiers {
26899 match &e.alias {
26900 Expression::Literal(Literal::String(s)) => {
26901 self.generate_identifier(&Identifier::new(s.clone()))?;
26903 }
26904 Expression::Literal(Literal::Number(n)) => {
26905 let mut id = Identifier::new(n.clone());
26907 id.quoted = true;
26908 self.generate_identifier(&id)?;
26909 }
26910 other => {
26911 self.generate_expression(other)?;
26912 }
26913 }
26914 } else {
26915 self.generate_expression(&e.alias)?;
26916 }
26917 Ok(())
26918 }
26919
26920 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
26921 self.write_keyword("ANY");
26923 if let Some(this) = &e.this {
26924 self.write_space();
26925 self.generate_expression(this)?;
26926 }
26927 Ok(())
26928 }
26929
26930 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
26931 self.write_keyword("ML.PREDICT");
26933 self.write("(");
26934 self.write_keyword("MODEL");
26935 self.write_space();
26936 self.generate_expression(&e.this)?;
26937 self.write(", ");
26938 self.generate_expression(&e.expression)?;
26939 if let Some(params) = &e.params_struct {
26940 self.write(", ");
26941 self.generate_expression(params)?;
26942 }
26943 self.write(")");
26944 Ok(())
26945 }
26946
26947 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
26948 self.write_keyword("PREVIOUS_DAY");
26950 self.write("(");
26951 self.generate_expression(&e.this)?;
26952 self.write(", ");
26953 self.generate_expression(&e.expression)?;
26954 self.write(")");
26955 Ok(())
26956 }
26957
26958 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
26959 self.write_keyword("PRIMARY KEY");
26961 if let Some(name) = &e.this {
26962 self.write_space();
26963 self.generate_expression(name)?;
26964 }
26965 if !e.expressions.is_empty() {
26966 self.write(" (");
26967 for (i, expr) in e.expressions.iter().enumerate() {
26968 if i > 0 {
26969 self.write(", ");
26970 }
26971 self.generate_expression(expr)?;
26972 }
26973 self.write(")");
26974 }
26975 if let Some(include) = &e.include {
26976 self.write_space();
26977 self.generate_expression(include)?;
26978 }
26979 if !e.options.is_empty() {
26980 self.write_space();
26981 for (i, opt) in e.options.iter().enumerate() {
26982 if i > 0 {
26983 self.write_space();
26984 }
26985 self.generate_expression(opt)?;
26986 }
26987 }
26988 Ok(())
26989 }
26990
26991 fn generate_primary_key_column_constraint(&mut self, _e: &PrimaryKeyColumnConstraint) -> Result<()> {
26992 self.write_keyword("PRIMARY KEY");
26994 Ok(())
26995 }
26996
26997 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
26998 self.write_keyword("PATH");
27000 self.write_space();
27001 self.generate_expression(&e.this)?;
27002 Ok(())
27003 }
27004
27005 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
27006 self.write_keyword("PROJECTION");
27008 self.write_space();
27009 self.generate_expression(&e.this)?;
27010 self.write(" (");
27011 self.generate_expression(&e.expression)?;
27012 self.write(")");
27013 Ok(())
27014 }
27015
27016 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
27017 for (i, prop) in e.expressions.iter().enumerate() {
27019 if i > 0 {
27020 self.write(", ");
27021 }
27022 self.generate_expression(prop)?;
27023 }
27024 Ok(())
27025 }
27026
27027 fn generate_property(&mut self, e: &Property) -> Result<()> {
27028 self.generate_expression(&e.this)?;
27030 if let Some(value) = &e.value {
27031 self.write("=");
27032 self.generate_expression(value)?;
27033 }
27034 Ok(())
27035 }
27036
27037 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
27039 self.write_keyword("OPTIONS");
27040 self.write(" (");
27041 for (i, opt) in options.iter().enumerate() {
27042 if i > 0 {
27043 self.write(", ");
27044 }
27045 self.generate_option_expression(opt)?;
27046 }
27047 self.write(")");
27048 Ok(())
27049 }
27050
27051 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
27053 self.write_keyword("PROPERTIES");
27054 self.write(" (");
27055 for (i, prop) in properties.iter().enumerate() {
27056 if i > 0 {
27057 self.write(", ");
27058 }
27059 self.generate_option_expression(prop)?;
27060 }
27061 self.write(")");
27062 Ok(())
27063 }
27064
27065 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
27067 self.write_keyword("ENVIRONMENT");
27068 self.write(" (");
27069 for (i, env_item) in environment.iter().enumerate() {
27070 if i > 0 {
27071 self.write(", ");
27072 }
27073 self.generate_environment_expression(env_item)?;
27074 }
27075 self.write(")");
27076 Ok(())
27077 }
27078
27079 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
27081 match expr {
27082 Expression::Eq(eq) => {
27083 self.generate_expression(&eq.left)?;
27085 self.write(" = ");
27086 self.generate_expression(&eq.right)?;
27087 Ok(())
27088 }
27089 _ => self.generate_expression(expr),
27090 }
27091 }
27092
27093 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
27095 self.write_keyword("TBLPROPERTIES");
27096 if self.config.pretty {
27097 self.write(" (");
27098 self.write_newline();
27099 self.indent_level += 1;
27100 for (i, opt) in options.iter().enumerate() {
27101 if i > 0 {
27102 self.write(",");
27103 self.write_newline();
27104 }
27105 self.write_indent();
27106 self.generate_option_expression(opt)?;
27107 }
27108 self.indent_level -= 1;
27109 self.write_newline();
27110 self.write(")");
27111 } else {
27112 self.write(" (");
27113 for (i, opt) in options.iter().enumerate() {
27114 if i > 0 {
27115 self.write(", ");
27116 }
27117 self.generate_option_expression(opt)?;
27118 }
27119 self.write(")");
27120 }
27121 Ok(())
27122 }
27123
27124 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
27126 match expr {
27127 Expression::Eq(eq) => {
27128 self.generate_expression(&eq.left)?;
27130 self.write("=");
27131 self.generate_expression(&eq.right)?;
27132 Ok(())
27133 }
27134 _ => self.generate_expression(expr),
27135 }
27136 }
27137
27138 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
27139 self.generate_expression(&e.this)?;
27141 Ok(())
27142 }
27143
27144 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
27145 self.write_keyword("PUT");
27147 self.write_space();
27148
27149 if e.source_quoted {
27151 self.write("'");
27152 self.write(&e.source);
27153 self.write("'");
27154 } else {
27155 self.write(&e.source);
27156 }
27157
27158 self.write_space();
27159
27160 if let Expression::Literal(Literal::String(s)) = &e.target {
27162 self.write(s);
27163 } else {
27164 self.generate_expression(&e.target)?;
27165 }
27166
27167 for param in &e.params {
27169 self.write_space();
27170 self.write(¶m.name);
27171 if let Some(ref value) = param.value {
27172 self.write("=");
27173 self.generate_expression(value)?;
27174 }
27175 }
27176
27177 Ok(())
27178 }
27179
27180 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
27181 self.write_keyword("QUANTILE");
27183 self.write("(");
27184 self.generate_expression(&e.this)?;
27185 if let Some(quantile) = &e.quantile {
27186 self.write(", ");
27187 self.generate_expression(quantile)?;
27188 }
27189 self.write(")");
27190 Ok(())
27191 }
27192
27193 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
27194 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Teradata)) {
27196 self.write_keyword("SET");
27197 self.write_space();
27198 }
27199 self.write_keyword("QUERY_BAND");
27200 self.write(" = ");
27201 self.generate_expression(&e.this)?;
27202 if e.update.is_some() {
27203 self.write_space();
27204 self.write_keyword("UPDATE");
27205 }
27206 if let Some(scope) = &e.scope {
27207 self.write_space();
27208 self.write_keyword("FOR");
27209 self.write_space();
27210 self.generate_expression(scope)?;
27211 }
27212 Ok(())
27213 }
27214
27215 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
27216 self.generate_expression(&e.this)?;
27218 if let Some(expression) = &e.expression {
27219 self.write(" = ");
27220 self.generate_expression(expression)?;
27221 }
27222 Ok(())
27223 }
27224
27225 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
27226 self.write_keyword("TRANSFORM");
27228 self.write("(");
27229 for (i, expr) in e.expressions.iter().enumerate() {
27230 if i > 0 {
27231 self.write(", ");
27232 }
27233 self.generate_expression(expr)?;
27234 }
27235 self.write(")");
27236 if let Some(row_format_before) = &e.row_format_before {
27237 self.write_space();
27238 self.generate_expression(row_format_before)?;
27239 }
27240 if let Some(record_writer) = &e.record_writer {
27241 self.write_space();
27242 self.write_keyword("RECORDWRITER");
27243 self.write_space();
27244 self.generate_expression(record_writer)?;
27245 }
27246 if let Some(command_script) = &e.command_script {
27247 self.write_space();
27248 self.write_keyword("USING");
27249 self.write_space();
27250 self.generate_expression(command_script)?;
27251 }
27252 if let Some(schema) = &e.schema {
27253 self.write_space();
27254 self.write_keyword("AS");
27255 self.write_space();
27256 self.generate_expression(schema)?;
27257 }
27258 if let Some(row_format_after) = &e.row_format_after {
27259 self.write_space();
27260 self.generate_expression(row_format_after)?;
27261 }
27262 if let Some(record_reader) = &e.record_reader {
27263 self.write_space();
27264 self.write_keyword("RECORDREADER");
27265 self.write_space();
27266 self.generate_expression(record_reader)?;
27267 }
27268 Ok(())
27269 }
27270
27271 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
27272 self.write_keyword("RANDN");
27274 self.write("(");
27275 if let Some(this) = &e.this {
27276 self.generate_expression(this)?;
27277 }
27278 self.write(")");
27279 Ok(())
27280 }
27281
27282 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
27283 self.write_keyword("RANDSTR");
27285 self.write("(");
27286 self.generate_expression(&e.this)?;
27287 if let Some(generator) = &e.generator {
27288 self.write(", ");
27289 self.generate_expression(generator)?;
27290 }
27291 self.write(")");
27292 Ok(())
27293 }
27294
27295 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
27296 self.write_keyword("RANGE_BUCKET");
27298 self.write("(");
27299 self.generate_expression(&e.this)?;
27300 self.write(", ");
27301 self.generate_expression(&e.expression)?;
27302 self.write(")");
27303 Ok(())
27304 }
27305
27306 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
27307 self.write_keyword("RANGE_N");
27309 self.write("(");
27310 self.generate_expression(&e.this)?;
27311 self.write_space();
27312 self.write_keyword("BETWEEN");
27313 self.write_space();
27314 for (i, expr) in e.expressions.iter().enumerate() {
27315 if i > 0 {
27316 self.write(", ");
27317 }
27318 self.generate_expression(expr)?;
27319 }
27320 if let Some(each) = &e.each {
27321 self.write_space();
27322 self.write_keyword("EACH");
27323 self.write_space();
27324 self.generate_expression(each)?;
27325 }
27326 self.write(")");
27327 Ok(())
27328 }
27329
27330 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
27331 self.write_keyword("READ_CSV");
27333 self.write("(");
27334 self.generate_expression(&e.this)?;
27335 for expr in &e.expressions {
27336 self.write(", ");
27337 self.generate_expression(expr)?;
27338 }
27339 self.write(")");
27340 Ok(())
27341 }
27342
27343 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
27344 self.write_keyword("READ_PARQUET");
27346 self.write("(");
27347 for (i, expr) in e.expressions.iter().enumerate() {
27348 if i > 0 {
27349 self.write(", ");
27350 }
27351 self.generate_expression(expr)?;
27352 }
27353 self.write(")");
27354 Ok(())
27355 }
27356
27357 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
27358 if e.kind == "CYCLE" {
27361 self.write_keyword("CYCLE");
27362 } else {
27363 self.write_keyword("SEARCH");
27364 self.write_space();
27365 self.write(&e.kind);
27366 self.write_space();
27367 self.write_keyword("FIRST BY");
27368 }
27369 self.write_space();
27370 self.generate_expression(&e.this)?;
27371 self.write_space();
27372 self.write_keyword("SET");
27373 self.write_space();
27374 self.generate_expression(&e.expression)?;
27375 if let Some(using) = &e.using {
27376 self.write_space();
27377 self.write_keyword("USING");
27378 self.write_space();
27379 self.generate_expression(using)?;
27380 }
27381 Ok(())
27382 }
27383
27384 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
27385 self.write_keyword("REDUCE");
27387 self.write("(");
27388 self.generate_expression(&e.this)?;
27389 if let Some(initial) = &e.initial {
27390 self.write(", ");
27391 self.generate_expression(initial)?;
27392 }
27393 if let Some(merge) = &e.merge {
27394 self.write(", ");
27395 self.generate_expression(merge)?;
27396 }
27397 if let Some(finish) = &e.finish {
27398 self.write(", ");
27399 self.generate_expression(finish)?;
27400 }
27401 self.write(")");
27402 Ok(())
27403 }
27404
27405 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
27406 self.write_keyword("REFERENCES");
27408 self.write_space();
27409 self.generate_expression(&e.this)?;
27410 if !e.expressions.is_empty() {
27411 self.write(" (");
27412 for (i, expr) in e.expressions.iter().enumerate() {
27413 if i > 0 {
27414 self.write(", ");
27415 }
27416 self.generate_expression(expr)?;
27417 }
27418 self.write(")");
27419 }
27420 for opt in &e.options {
27421 self.write_space();
27422 self.generate_expression(opt)?;
27423 }
27424 Ok(())
27425 }
27426
27427 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
27428 self.write_keyword("REFRESH");
27430 if !e.kind.is_empty() {
27431 self.write_space();
27432 self.write_keyword(&e.kind);
27433 }
27434 self.write_space();
27435 self.generate_expression(&e.this)?;
27436 Ok(())
27437 }
27438
27439 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
27440 self.write_keyword("REFRESH");
27442 self.write_space();
27443 self.write_keyword(&e.method);
27444
27445 if let Some(ref kind) = e.kind {
27446 self.write_space();
27447 self.write_keyword("ON");
27448 self.write_space();
27449 self.write_keyword(kind);
27450
27451 if let Some(ref every) = e.every {
27453 self.write_space();
27454 self.write_keyword("EVERY");
27455 self.write_space();
27456 self.generate_expression(every)?;
27457 if let Some(ref unit) = e.unit {
27458 self.write_space();
27459 self.write_keyword(unit);
27460 }
27461 }
27462
27463 if let Some(ref starts) = e.starts {
27465 self.write_space();
27466 self.write_keyword("STARTS");
27467 self.write_space();
27468 self.generate_expression(starts)?;
27469 }
27470 }
27471 Ok(())
27472 }
27473
27474 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
27475 self.write_keyword("REGEXP_COUNT");
27477 self.write("(");
27478 self.generate_expression(&e.this)?;
27479 self.write(", ");
27480 self.generate_expression(&e.expression)?;
27481 if let Some(position) = &e.position {
27482 self.write(", ");
27483 self.generate_expression(position)?;
27484 }
27485 if let Some(parameters) = &e.parameters {
27486 self.write(", ");
27487 self.generate_expression(parameters)?;
27488 }
27489 self.write(")");
27490 Ok(())
27491 }
27492
27493 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
27494 self.write_keyword("REGEXP_EXTRACT_ALL");
27496 self.write("(");
27497 self.generate_expression(&e.this)?;
27498 self.write(", ");
27499 self.generate_expression(&e.expression)?;
27500 if let Some(group) = &e.group {
27501 self.write(", ");
27502 self.generate_expression(group)?;
27503 }
27504 self.write(")");
27505 Ok(())
27506 }
27507
27508 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
27509 self.write_keyword("REGEXP_FULL_MATCH");
27511 self.write("(");
27512 self.generate_expression(&e.this)?;
27513 self.write(", ");
27514 self.generate_expression(&e.expression)?;
27515 self.write(")");
27516 Ok(())
27517 }
27518
27519 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
27520 use crate::dialects::DialectType;
27521 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) && e.flag.is_none() {
27523 self.generate_expression(&e.this)?;
27524 self.write(" ~* ");
27525 self.generate_expression(&e.expression)?;
27526 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
27527 self.write_keyword("REGEXP_LIKE");
27529 self.write("(");
27530 self.generate_expression(&e.this)?;
27531 self.write(", ");
27532 self.generate_expression(&e.expression)?;
27533 self.write(", ");
27534 if let Some(flag) = &e.flag {
27535 self.generate_expression(flag)?;
27536 } else {
27537 self.write("'i'");
27538 }
27539 self.write(")");
27540 } else {
27541 self.generate_expression(&e.this)?;
27543 self.write_space();
27544 self.write_keyword("REGEXP_ILIKE");
27545 self.write_space();
27546 self.generate_expression(&e.expression)?;
27547 if let Some(flag) = &e.flag {
27548 self.write(", ");
27549 self.generate_expression(flag)?;
27550 }
27551 }
27552 Ok(())
27553 }
27554
27555 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
27556 self.write_keyword("REGEXP_INSTR");
27558 self.write("(");
27559 self.generate_expression(&e.this)?;
27560 self.write(", ");
27561 self.generate_expression(&e.expression)?;
27562 if let Some(position) = &e.position {
27563 self.write(", ");
27564 self.generate_expression(position)?;
27565 }
27566 if let Some(occurrence) = &e.occurrence {
27567 self.write(", ");
27568 self.generate_expression(occurrence)?;
27569 }
27570 if let Some(option) = &e.option {
27571 self.write(", ");
27572 self.generate_expression(option)?;
27573 }
27574 if let Some(parameters) = &e.parameters {
27575 self.write(", ");
27576 self.generate_expression(parameters)?;
27577 }
27578 if let Some(group) = &e.group {
27579 self.write(", ");
27580 self.generate_expression(group)?;
27581 }
27582 self.write(")");
27583 Ok(())
27584 }
27585
27586 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
27587 self.write_keyword("REGEXP_SPLIT");
27589 self.write("(");
27590 self.generate_expression(&e.this)?;
27591 self.write(", ");
27592 self.generate_expression(&e.expression)?;
27593 if let Some(limit) = &e.limit {
27594 self.write(", ");
27595 self.generate_expression(limit)?;
27596 }
27597 self.write(")");
27598 Ok(())
27599 }
27600
27601 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
27602 self.write_keyword("REGR_AVGX");
27604 self.write("(");
27605 self.generate_expression(&e.this)?;
27606 self.write(", ");
27607 self.generate_expression(&e.expression)?;
27608 self.write(")");
27609 Ok(())
27610 }
27611
27612 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
27613 self.write_keyword("REGR_AVGY");
27615 self.write("(");
27616 self.generate_expression(&e.this)?;
27617 self.write(", ");
27618 self.generate_expression(&e.expression)?;
27619 self.write(")");
27620 Ok(())
27621 }
27622
27623 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
27624 self.write_keyword("REGR_COUNT");
27626 self.write("(");
27627 self.generate_expression(&e.this)?;
27628 self.write(", ");
27629 self.generate_expression(&e.expression)?;
27630 self.write(")");
27631 Ok(())
27632 }
27633
27634 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
27635 self.write_keyword("REGR_INTERCEPT");
27637 self.write("(");
27638 self.generate_expression(&e.this)?;
27639 self.write(", ");
27640 self.generate_expression(&e.expression)?;
27641 self.write(")");
27642 Ok(())
27643 }
27644
27645 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
27646 self.write_keyword("REGR_R2");
27648 self.write("(");
27649 self.generate_expression(&e.this)?;
27650 self.write(", ");
27651 self.generate_expression(&e.expression)?;
27652 self.write(")");
27653 Ok(())
27654 }
27655
27656 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
27657 self.write_keyword("REGR_SLOPE");
27659 self.write("(");
27660 self.generate_expression(&e.this)?;
27661 self.write(", ");
27662 self.generate_expression(&e.expression)?;
27663 self.write(")");
27664 Ok(())
27665 }
27666
27667 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
27668 self.write_keyword("REGR_SXX");
27670 self.write("(");
27671 self.generate_expression(&e.this)?;
27672 self.write(", ");
27673 self.generate_expression(&e.expression)?;
27674 self.write(")");
27675 Ok(())
27676 }
27677
27678 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
27679 self.write_keyword("REGR_SXY");
27681 self.write("(");
27682 self.generate_expression(&e.this)?;
27683 self.write(", ");
27684 self.generate_expression(&e.expression)?;
27685 self.write(")");
27686 Ok(())
27687 }
27688
27689 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
27690 self.write_keyword("REGR_SYY");
27692 self.write("(");
27693 self.generate_expression(&e.this)?;
27694 self.write(", ");
27695 self.generate_expression(&e.expression)?;
27696 self.write(")");
27697 Ok(())
27698 }
27699
27700 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
27701 self.write_keyword("REGR_VALX");
27703 self.write("(");
27704 self.generate_expression(&e.this)?;
27705 self.write(", ");
27706 self.generate_expression(&e.expression)?;
27707 self.write(")");
27708 Ok(())
27709 }
27710
27711 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
27712 self.write_keyword("REGR_VALY");
27714 self.write("(");
27715 self.generate_expression(&e.this)?;
27716 self.write(", ");
27717 self.generate_expression(&e.expression)?;
27718 self.write(")");
27719 Ok(())
27720 }
27721
27722 fn generate_remote_with_connection_model_property(&mut self, e: &RemoteWithConnectionModelProperty) -> Result<()> {
27723 self.write_keyword("REMOTE WITH CONNECTION");
27725 self.write_space();
27726 self.generate_expression(&e.this)?;
27727 Ok(())
27728 }
27729
27730 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
27731 self.write_keyword("RENAME COLUMN");
27733 if e.exists {
27734 self.write_space();
27735 self.write_keyword("IF EXISTS");
27736 }
27737 self.write_space();
27738 self.generate_expression(&e.this)?;
27739 if let Some(to) = &e.to {
27740 self.write_space();
27741 self.write_keyword("TO");
27742 self.write_space();
27743 self.generate_expression(to)?;
27744 }
27745 Ok(())
27746 }
27747
27748 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
27749 self.write_keyword("REPLACE PARTITION");
27751 self.write_space();
27752 self.generate_expression(&e.expression)?;
27753 if let Some(source) = &e.source {
27754 self.write_space();
27755 self.write_keyword("FROM");
27756 self.write_space();
27757 self.generate_expression(source)?;
27758 }
27759 Ok(())
27760 }
27761
27762 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
27763 let keyword = match self.config.dialect {
27766 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
27767 _ => "RETURNING",
27768 };
27769 self.write_keyword(keyword);
27770 self.write_space();
27771 for (i, expr) in e.expressions.iter().enumerate() {
27772 if i > 0 {
27773 self.write(", ");
27774 }
27775 self.generate_expression(expr)?;
27776 }
27777 if let Some(into) = &e.into {
27778 self.write_space();
27779 self.write_keyword("INTO");
27780 self.write_space();
27781 self.generate_expression(into)?;
27782 }
27783 Ok(())
27784 }
27785
27786 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
27787 self.write_space();
27789 self.write_keyword("OUTPUT");
27790 self.write_space();
27791 for (i, expr) in output.columns.iter().enumerate() {
27792 if i > 0 {
27793 self.write(", ");
27794 }
27795 self.generate_expression(expr)?;
27796 }
27797 if let Some(into_table) = &output.into_table {
27798 self.write_space();
27799 self.write_keyword("INTO");
27800 self.write_space();
27801 self.generate_expression(into_table)?;
27802 }
27803 Ok(())
27804 }
27805
27806 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
27807 self.write_keyword("RETURNS");
27809 if e.is_table.is_some() {
27810 self.write_space();
27811 self.write_keyword("TABLE");
27812 }
27813 if let Some(table) = &e.table {
27814 self.write_space();
27815 self.generate_expression(table)?;
27816 } else if let Some(this) = &e.this {
27817 self.write_space();
27818 self.generate_expression(this)?;
27819 }
27820 if e.null.is_some() {
27821 self.write_space();
27822 self.write_keyword("NULL ON NULL INPUT");
27823 }
27824 Ok(())
27825 }
27826
27827 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
27828 self.write_keyword("ROLLBACK");
27830
27831 if e.this.is_none() && matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) {
27833 self.write_space();
27834 self.write_keyword("TRANSACTION");
27835 }
27836
27837 if let Some(this) = &e.this {
27839 let is_transaction_marker = matches!(
27841 this.as_ref(),
27842 Expression::Identifier(id) if id.name == "TRANSACTION"
27843 );
27844
27845 self.write_space();
27846 self.write_keyword("TRANSACTION");
27847
27848 if !is_transaction_marker {
27850 self.write_space();
27851 self.generate_expression(this)?;
27852 }
27853 }
27854
27855 if let Some(savepoint) = &e.savepoint {
27857 self.write_space();
27858 self.write_keyword("TO");
27859 self.write_space();
27860 self.generate_expression(savepoint)?;
27861 }
27862 Ok(())
27863 }
27864
27865 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
27866 if e.expressions.is_empty() {
27868 self.write_keyword("WITH ROLLUP");
27869 } else {
27870 self.write_keyword("ROLLUP");
27871 self.write("(");
27872 for (i, expr) in e.expressions.iter().enumerate() {
27873 if i > 0 {
27874 self.write(", ");
27875 }
27876 self.generate_expression(expr)?;
27877 }
27878 self.write(")");
27879 }
27880 Ok(())
27881 }
27882
27883 fn generate_row_format_delimited_property(&mut self, e: &RowFormatDelimitedProperty) -> Result<()> {
27884 self.write_keyword("ROW FORMAT DELIMITED");
27886 if let Some(fields) = &e.fields {
27887 self.write_space();
27888 self.write_keyword("FIELDS TERMINATED BY");
27889 self.write_space();
27890 self.generate_expression(fields)?;
27891 }
27892 if let Some(escaped) = &e.escaped {
27893 self.write_space();
27894 self.write_keyword("ESCAPED BY");
27895 self.write_space();
27896 self.generate_expression(escaped)?;
27897 }
27898 if let Some(items) = &e.collection_items {
27899 self.write_space();
27900 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
27901 self.write_space();
27902 self.generate_expression(items)?;
27903 }
27904 if let Some(keys) = &e.map_keys {
27905 self.write_space();
27906 self.write_keyword("MAP KEYS TERMINATED BY");
27907 self.write_space();
27908 self.generate_expression(keys)?;
27909 }
27910 if let Some(lines) = &e.lines {
27911 self.write_space();
27912 self.write_keyword("LINES TERMINATED BY");
27913 self.write_space();
27914 self.generate_expression(lines)?;
27915 }
27916 if let Some(null) = &e.null {
27917 self.write_space();
27918 self.write_keyword("NULL DEFINED AS");
27919 self.write_space();
27920 self.generate_expression(null)?;
27921 }
27922 if let Some(serde) = &e.serde {
27923 self.write_space();
27924 self.generate_expression(serde)?;
27925 }
27926 Ok(())
27927 }
27928
27929 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
27930 self.write_keyword("ROW FORMAT");
27932 self.write_space();
27933 self.generate_expression(&e.this)?;
27934 Ok(())
27935 }
27936
27937 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
27938 self.write_keyword("ROW FORMAT SERDE");
27940 self.write_space();
27941 self.generate_expression(&e.this)?;
27942 if let Some(props) = &e.serde_properties {
27943 self.write_space();
27944 self.generate_expression(props)?;
27946 }
27947 Ok(())
27948 }
27949
27950 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
27951 self.write_keyword("SHA2");
27953 self.write("(");
27954 self.generate_expression(&e.this)?;
27955 if let Some(length) = e.length {
27956 self.write(", ");
27957 self.write(&length.to_string());
27958 }
27959 self.write(")");
27960 Ok(())
27961 }
27962
27963 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
27964 self.write_keyword("SHA2_DIGEST");
27966 self.write("(");
27967 self.generate_expression(&e.this)?;
27968 if let Some(length) = e.length {
27969 self.write(", ");
27970 self.write(&length.to_string());
27971 }
27972 self.write(")");
27973 Ok(())
27974 }
27975
27976 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
27977 let name = if matches!(self.config.dialect, Some(crate::dialects::DialectType::Spark) | Some(crate::dialects::DialectType::Databricks)) {
27978 "TRY_ADD"
27979 } else {
27980 "SAFE_ADD"
27981 };
27982 self.write_keyword(name);
27983 self.write("(");
27984 self.generate_expression(&e.this)?;
27985 self.write(", ");
27986 self.generate_expression(&e.expression)?;
27987 self.write(")");
27988 Ok(())
27989 }
27990
27991 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
27992 self.write_keyword("SAFE_DIVIDE");
27994 self.write("(");
27995 self.generate_expression(&e.this)?;
27996 self.write(", ");
27997 self.generate_expression(&e.expression)?;
27998 self.write(")");
27999 Ok(())
28000 }
28001
28002 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
28003 let name = if matches!(self.config.dialect, Some(crate::dialects::DialectType::Spark) | Some(crate::dialects::DialectType::Databricks)) {
28004 "TRY_MULTIPLY"
28005 } else {
28006 "SAFE_MULTIPLY"
28007 };
28008 self.write_keyword(name);
28009 self.write("(");
28010 self.generate_expression(&e.this)?;
28011 self.write(", ");
28012 self.generate_expression(&e.expression)?;
28013 self.write(")");
28014 Ok(())
28015 }
28016
28017 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
28018 let name = if matches!(self.config.dialect, Some(crate::dialects::DialectType::Spark) | Some(crate::dialects::DialectType::Databricks)) {
28019 "TRY_SUBTRACT"
28020 } else {
28021 "SAFE_SUBTRACT"
28022 };
28023 self.write_keyword(name);
28024 self.write("(");
28025 self.generate_expression(&e.this)?;
28026 self.write(", ");
28027 self.generate_expression(&e.expression)?;
28028 self.write(")");
28029 Ok(())
28030 }
28031
28032 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
28035 if matches!(sample.method, SampleMethod::Bucket) {
28037 self.write(" (");
28038 self.write_keyword("BUCKET");
28039 self.write_space();
28040 if let Some(ref num) = sample.bucket_numerator {
28041 self.generate_expression(num)?;
28042 }
28043 self.write_space();
28044 self.write_keyword("OUT OF");
28045 self.write_space();
28046 if let Some(ref denom) = sample.bucket_denominator {
28047 self.generate_expression(denom)?;
28048 }
28049 if let Some(ref field) = sample.bucket_field {
28050 self.write_space();
28051 self.write_keyword("ON");
28052 self.write_space();
28053 self.generate_expression(field)?;
28054 }
28055 self.write(")");
28056 return Ok(());
28057 }
28058
28059 let is_snowflake = matches!(self.config.dialect, Some(crate::dialects::DialectType::Snowflake));
28061 let is_postgres = matches!(self.config.dialect, Some(crate::dialects::DialectType::PostgreSQL) | Some(crate::dialects::DialectType::Redshift));
28062 let is_databricks = matches!(self.config.dialect, Some(crate::dialects::DialectType::Databricks));
28064 let is_spark = matches!(self.config.dialect, Some(crate::dialects::DialectType::Spark));
28065 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
28066 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
28068 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
28069 self.write_space();
28070 if !sample.explicit_method && (is_snowflake || force_method) {
28071 self.write_keyword("BERNOULLI");
28073 } else {
28074 match sample.method {
28075 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
28076 SampleMethod::System => self.write_keyword("SYSTEM"),
28077 SampleMethod::Block => self.write_keyword("BLOCK"),
28078 SampleMethod::Row => self.write_keyword("ROW"),
28079 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
28080 SampleMethod::Percent => self.write_keyword("SYSTEM"),
28081 SampleMethod::Bucket => {} }
28083 }
28084 }
28085
28086 let emit_size_no_parens = !self.config.tablesample_requires_parens;
28088 if emit_size_no_parens {
28089 self.write_space();
28090 match &sample.size {
28091 Expression::Tuple(tuple) => {
28092 for (i, expr) in tuple.expressions.iter().enumerate() {
28093 if i > 0 {
28094 self.write(", ");
28095 }
28096 self.generate_expression(expr)?;
28097 }
28098 }
28099 expr => self.generate_expression(expr)?,
28100 }
28101 } else {
28102 self.write(" (");
28103 self.generate_expression(&sample.size)?;
28104 }
28105
28106 let is_rows_method = matches!(sample.method, SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket);
28108 let is_percent = matches!(sample.method, SampleMethod::Percent | SampleMethod::System | SampleMethod::Bernoulli | SampleMethod::Block);
28109
28110 let is_presto = matches!(self.config.dialect, Some(crate::dialects::DialectType::Presto) | Some(crate::dialects::DialectType::Trino) | Some(crate::dialects::DialectType::Athena));
28114 let should_output_unit = if is_databricks || is_spark {
28115 is_percent || is_rows_method || sample.unit_after_size
28117 } else if is_snowflake || is_postgres || is_presto {
28118 sample.unit_after_size
28119 } else {
28120 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
28121 };
28122
28123 if should_output_unit {
28124 self.write_space();
28125 if sample.is_percent {
28126 self.write_keyword("PERCENT");
28127 } else if is_rows_method && !sample.unit_after_size {
28128 self.write_keyword("ROWS");
28129 } else if sample.unit_after_size {
28130 match sample.method {
28131 SampleMethod::Percent | SampleMethod::System | SampleMethod::Bernoulli | SampleMethod::Block => {
28132 self.write_keyword("PERCENT");
28133 }
28134 SampleMethod::Row | SampleMethod::Reservoir => {
28135 self.write_keyword("ROWS");
28136 }
28137 _ => self.write_keyword("ROWS"),
28138 }
28139 } else {
28140 self.write_keyword("PERCENT");
28141 }
28142 }
28143
28144 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
28145 if let Some(ref offset) = sample.offset {
28146 self.write_space();
28147 self.write_keyword("OFFSET");
28148 self.write_space();
28149 self.generate_expression(offset)?;
28150 }
28151 }
28152 if !emit_size_no_parens {
28153 self.write(")");
28154 }
28155
28156 Ok(())
28157 }
28158
28159 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
28160 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
28162 self.write_keyword("SAMPLE BY");
28163 } else {
28164 self.write_keyword("SAMPLE");
28165 }
28166 self.write_space();
28167 self.generate_expression(&e.this)?;
28168 Ok(())
28169 }
28170
28171 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
28172 if let Some(this) = &e.this {
28174 self.generate_expression(this)?;
28175 }
28176 if !e.expressions.is_empty() {
28177 if e.this.is_some() {
28179 self.write_space();
28180 }
28181 self.write("(");
28182 for (i, expr) in e.expressions.iter().enumerate() {
28183 if i > 0 {
28184 self.write(", ");
28185 }
28186 self.generate_expression(expr)?;
28187 }
28188 self.write(")");
28189 }
28190 Ok(())
28191 }
28192
28193 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
28194 self.write_keyword("COMMENT");
28196 self.write_space();
28197 self.generate_expression(&e.this)?;
28198 Ok(())
28199 }
28200
28201 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
28202 if let Some(this) = &e.this {
28204 self.generate_expression(this)?;
28205 self.write("::");
28206 }
28207 self.generate_expression(&e.expression)?;
28208 Ok(())
28209 }
28210
28211 fn generate_search(&mut self, e: &Search) -> Result<()> {
28212 self.write_keyword("SEARCH");
28214 self.write("(");
28215 self.generate_expression(&e.this)?;
28216 self.write(", ");
28217 self.generate_expression(&e.expression)?;
28218 if let Some(json_scope) = &e.json_scope {
28219 self.write(", ");
28220 self.generate_expression(json_scope)?;
28221 }
28222 if let Some(analyzer) = &e.analyzer {
28223 self.write(", ");
28224 self.generate_expression(analyzer)?;
28225 }
28226 if let Some(analyzer_options) = &e.analyzer_options {
28227 self.write(", ");
28228 self.generate_expression(analyzer_options)?;
28229 }
28230 if let Some(search_mode) = &e.search_mode {
28231 self.write(", ");
28232 self.generate_expression(search_mode)?;
28233 }
28234 self.write(")");
28235 Ok(())
28236 }
28237
28238 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
28239 self.write_keyword("SEARCH_IP");
28241 self.write("(");
28242 self.generate_expression(&e.this)?;
28243 self.write(", ");
28244 self.generate_expression(&e.expression)?;
28245 self.write(")");
28246 Ok(())
28247 }
28248
28249 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
28250 self.write_keyword("SECURITY");
28252 self.write_space();
28253 self.generate_expression(&e.this)?;
28254 Ok(())
28255 }
28256
28257 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
28258 self.write("SEMANTIC_VIEW(");
28260
28261 if self.config.pretty {
28262 self.write_newline();
28264 self.indent_level += 1;
28265 self.write_indent();
28266 self.generate_expression(&e.this)?;
28267
28268 if let Some(metrics) = &e.metrics {
28269 self.write_newline();
28270 self.write_indent();
28271 self.write_keyword("METRICS");
28272 self.write_space();
28273 self.generate_semantic_view_tuple(metrics)?;
28274 }
28275 if let Some(dimensions) = &e.dimensions {
28276 self.write_newline();
28277 self.write_indent();
28278 self.write_keyword("DIMENSIONS");
28279 self.write_space();
28280 self.generate_semantic_view_tuple(dimensions)?;
28281 }
28282 if let Some(facts) = &e.facts {
28283 self.write_newline();
28284 self.write_indent();
28285 self.write_keyword("FACTS");
28286 self.write_space();
28287 self.generate_semantic_view_tuple(facts)?;
28288 }
28289 if let Some(where_) = &e.where_ {
28290 self.write_newline();
28291 self.write_indent();
28292 self.write_keyword("WHERE");
28293 self.write_space();
28294 self.generate_expression(where_)?;
28295 }
28296 self.write_newline();
28297 self.indent_level -= 1;
28298 self.write_indent();
28299 } else {
28300 self.generate_expression(&e.this)?;
28302 if let Some(metrics) = &e.metrics {
28303 self.write_space();
28304 self.write_keyword("METRICS");
28305 self.write_space();
28306 self.generate_semantic_view_tuple(metrics)?;
28307 }
28308 if let Some(dimensions) = &e.dimensions {
28309 self.write_space();
28310 self.write_keyword("DIMENSIONS");
28311 self.write_space();
28312 self.generate_semantic_view_tuple(dimensions)?;
28313 }
28314 if let Some(facts) = &e.facts {
28315 self.write_space();
28316 self.write_keyword("FACTS");
28317 self.write_space();
28318 self.generate_semantic_view_tuple(facts)?;
28319 }
28320 if let Some(where_) = &e.where_ {
28321 self.write_space();
28322 self.write_keyword("WHERE");
28323 self.write_space();
28324 self.generate_expression(where_)?;
28325 }
28326 }
28327 self.write(")");
28328 Ok(())
28329 }
28330
28331 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
28333 if let Expression::Tuple(t) = expr {
28334 for (i, e) in t.expressions.iter().enumerate() {
28335 if i > 0 {
28336 self.write(", ");
28337 }
28338 self.generate_expression(e)?;
28339 }
28340 } else {
28341 self.generate_expression(expr)?;
28342 }
28343 Ok(())
28344 }
28345
28346 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
28347 if let Some(start) = &e.start {
28349 self.write_keyword("START WITH");
28350 self.write_space();
28351 self.generate_expression(start)?;
28352 }
28353 if let Some(increment) = &e.increment {
28354 self.write_space();
28355 self.write_keyword("INCREMENT BY");
28356 self.write_space();
28357 self.generate_expression(increment)?;
28358 }
28359 if let Some(minvalue) = &e.minvalue {
28360 self.write_space();
28361 self.write_keyword("MINVALUE");
28362 self.write_space();
28363 self.generate_expression(minvalue)?;
28364 }
28365 if let Some(maxvalue) = &e.maxvalue {
28366 self.write_space();
28367 self.write_keyword("MAXVALUE");
28368 self.write_space();
28369 self.generate_expression(maxvalue)?;
28370 }
28371 if let Some(cache) = &e.cache {
28372 self.write_space();
28373 self.write_keyword("CACHE");
28374 self.write_space();
28375 self.generate_expression(cache)?;
28376 }
28377 if let Some(owned) = &e.owned {
28378 self.write_space();
28379 self.write_keyword("OWNED BY");
28380 self.write_space();
28381 self.generate_expression(owned)?;
28382 }
28383 for opt in &e.options {
28384 self.write_space();
28385 self.generate_expression(opt)?;
28386 }
28387 Ok(())
28388 }
28389
28390 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
28391 if e.with_.is_some() {
28393 self.write_keyword("WITH");
28394 self.write_space();
28395 }
28396 self.write_keyword("SERDEPROPERTIES");
28397 self.write(" (");
28398 for (i, expr) in e.expressions.iter().enumerate() {
28399 if i > 0 {
28400 self.write(", ");
28401 }
28402 match expr {
28404 Expression::Eq(eq) => {
28405 self.generate_expression(&eq.left)?;
28406 self.write("=");
28407 self.generate_expression(&eq.right)?;
28408 }
28409 _ => self.generate_expression(expr)?,
28410 }
28411 }
28412 self.write(")");
28413 Ok(())
28414 }
28415
28416 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
28417 self.write("@@");
28419 if let Some(kind) = &e.kind {
28420 self.write(kind);
28421 self.write(".");
28422 }
28423 self.generate_expression(&e.this)?;
28424 Ok(())
28425 }
28426
28427 fn generate_set(&mut self, e: &Set) -> Result<()> {
28428 if e.unset.is_some() {
28430 self.write_keyword("UNSET");
28431 } else {
28432 self.write_keyword("SET");
28433 }
28434 if e.tag.is_some() {
28435 self.write_space();
28436 self.write_keyword("TAG");
28437 }
28438 if !e.expressions.is_empty() {
28439 self.write_space();
28440 for (i, expr) in e.expressions.iter().enumerate() {
28441 if i > 0 {
28442 self.write(", ");
28443 }
28444 self.generate_expression(expr)?;
28445 }
28446 }
28447 Ok(())
28448 }
28449
28450 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
28451 self.write_keyword("SET");
28453 self.write_space();
28454 self.generate_expression(&e.this)?;
28455 Ok(())
28456 }
28457
28458 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
28459 if let Some(kind) = &e.kind {
28461 self.write_keyword(kind);
28462 self.write_space();
28463 }
28464 self.generate_expression(&e.name)?;
28465 self.write(" = ");
28466 self.generate_expression(&e.value)?;
28467 Ok(())
28468 }
28469
28470 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
28471 if let Some(with_) = &e.with_ {
28473 self.generate_expression(with_)?;
28474 self.write_space();
28475 }
28476 self.generate_expression(&e.this)?;
28477 self.write_space();
28478 if let Some(kind) = &e.kind {
28480 self.write_keyword(kind);
28481 }
28482 if e.distinct {
28483 self.write_space();
28484 self.write_keyword("DISTINCT");
28485 } else {
28486 self.write_space();
28487 self.write_keyword("ALL");
28488 }
28489 if e.by_name.is_some() {
28490 self.write_space();
28491 self.write_keyword("BY NAME");
28492 }
28493 self.write_space();
28494 self.generate_expression(&e.expression)?;
28495 Ok(())
28496 }
28497
28498 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
28499 if e.multi.is_some() {
28501 self.write_keyword("MULTISET");
28502 } else {
28503 self.write_keyword("SET");
28504 }
28505 Ok(())
28506 }
28507
28508 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
28509 self.write_keyword("SETTINGS");
28511 if self.config.pretty && e.expressions.len() > 1 {
28512 self.indent_level += 1;
28514 for (i, expr) in e.expressions.iter().enumerate() {
28515 if i > 0 {
28516 self.write(",");
28517 }
28518 self.write_newline();
28519 self.write_indent();
28520 self.generate_expression(expr)?;
28521 }
28522 self.indent_level -= 1;
28523 } else {
28524 self.write_space();
28525 for (i, expr) in e.expressions.iter().enumerate() {
28526 if i > 0 {
28527 self.write(", ");
28528 }
28529 self.generate_expression(expr)?;
28530 }
28531 }
28532 Ok(())
28533 }
28534
28535 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
28536 self.write_keyword("SHARING");
28538 if let Some(this) = &e.this {
28539 self.write(" = ");
28540 self.generate_expression(this)?;
28541 }
28542 Ok(())
28543 }
28544
28545 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
28546 if let Some(begin) = &e.this {
28548 self.generate_expression(begin)?;
28549 }
28550 self.write(":");
28551 if let Some(end) = &e.expression {
28552 self.generate_expression(end)?;
28553 }
28554 if let Some(step) = &e.step {
28555 self.write(":");
28556 self.generate_expression(step)?;
28557 }
28558 Ok(())
28559 }
28560
28561 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
28562 self.write_keyword("SORT_ARRAY");
28564 self.write("(");
28565 self.generate_expression(&e.this)?;
28566 if let Some(asc) = &e.asc {
28567 self.write(", ");
28568 self.generate_expression(asc)?;
28569 }
28570 self.write(")");
28571 Ok(())
28572 }
28573
28574 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
28575 self.write_keyword("SORT BY");
28577 self.write_space();
28578 for (i, expr) in e.expressions.iter().enumerate() {
28579 if i > 0 {
28580 self.write(", ");
28581 }
28582 self.generate_ordered(expr)?;
28583 }
28584 Ok(())
28585 }
28586
28587 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
28588 if e.compound.is_some() {
28590 self.write_keyword("COMPOUND");
28591 self.write_space();
28592 }
28593 self.write_keyword("SORTKEY");
28594 self.write("(");
28595 if let Expression::Tuple(t) = e.this.as_ref() {
28597 for (i, expr) in t.expressions.iter().enumerate() {
28598 if i > 0 {
28599 self.write(", ");
28600 }
28601 self.generate_expression(expr)?;
28602 }
28603 } else {
28604 self.generate_expression(&e.this)?;
28605 }
28606 self.write(")");
28607 Ok(())
28608 }
28609
28610 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
28611 self.write_keyword("SPLIT_PART");
28613 self.write("(");
28614 self.generate_expression(&e.this)?;
28615 if let Some(delimiter) = &e.delimiter {
28616 self.write(", ");
28617 self.generate_expression(delimiter)?;
28618 }
28619 if let Some(part_index) = &e.part_index {
28620 self.write(", ");
28621 self.generate_expression(part_index)?;
28622 }
28623 self.write(")");
28624 Ok(())
28625 }
28626
28627 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
28628 self.generate_expression(&e.this)?;
28630 Ok(())
28631 }
28632
28633 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
28634 self.write_keyword("SQL SECURITY");
28636 self.write_space();
28637 self.generate_expression(&e.this)?;
28638 Ok(())
28639 }
28640
28641 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
28642 self.write_keyword("ST_DISTANCE");
28644 self.write("(");
28645 self.generate_expression(&e.this)?;
28646 self.write(", ");
28647 self.generate_expression(&e.expression)?;
28648 if let Some(use_spheroid) = &e.use_spheroid {
28649 self.write(", ");
28650 self.generate_expression(use_spheroid)?;
28651 }
28652 self.write(")");
28653 Ok(())
28654 }
28655
28656 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
28657 self.write_keyword("ST_POINT");
28659 self.write("(");
28660 self.generate_expression(&e.this)?;
28661 self.write(", ");
28662 self.generate_expression(&e.expression)?;
28663 self.write(")");
28664 Ok(())
28665 }
28666
28667 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
28668 self.generate_expression(&e.this)?;
28670 Ok(())
28671 }
28672
28673 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
28674 self.write_keyword("STANDARD_HASH");
28676 self.write("(");
28677 self.generate_expression(&e.this)?;
28678 if let Some(expression) = &e.expression {
28679 self.write(", ");
28680 self.generate_expression(expression)?;
28681 }
28682 self.write(")");
28683 Ok(())
28684 }
28685
28686 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
28687 self.write_keyword("STORED BY");
28689 self.write_space();
28690 self.generate_expression(&e.this)?;
28691 Ok(())
28692 }
28693
28694 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
28695 use crate::dialects::DialectType;
28698 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
28699 self.write_keyword("CHARINDEX");
28701 self.write("(");
28702 if let Some(substr) = &e.substr {
28703 self.generate_expression(substr)?;
28704 self.write(", ");
28705 }
28706 self.generate_expression(&e.this)?;
28707 if let Some(position) = &e.position {
28708 self.write(", ");
28709 self.generate_expression(position)?;
28710 }
28711 self.write(")");
28712 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
28713 self.write_keyword("POSITION");
28714 self.write("(");
28715 self.generate_expression(&e.this)?;
28716 if let Some(substr) = &e.substr {
28717 self.write(", ");
28718 self.generate_expression(substr)?;
28719 }
28720 if let Some(position) = &e.position {
28721 self.write(", ");
28722 self.generate_expression(position)?;
28723 }
28724 if let Some(occurrence) = &e.occurrence {
28725 self.write(", ");
28726 self.generate_expression(occurrence)?;
28727 }
28728 self.write(")");
28729 } else if matches!(self.config.dialect, Some(DialectType::SQLite) | Some(DialectType::Oracle) | Some(DialectType::BigQuery) | Some(DialectType::Teradata)) {
28730 self.write_keyword("INSTR");
28731 self.write("(");
28732 self.generate_expression(&e.this)?;
28733 if let Some(substr) = &e.substr {
28734 self.write(", ");
28735 self.generate_expression(substr)?;
28736 }
28737 if let Some(position) = &e.position {
28738 self.write(", ");
28739 self.generate_expression(position)?;
28740 } else if e.occurrence.is_some() {
28741 self.write(", 1");
28744 }
28745 if let Some(occurrence) = &e.occurrence {
28746 self.write(", ");
28747 self.generate_expression(occurrence)?;
28748 }
28749 self.write(")");
28750 } else if matches!(self.config.dialect, Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::Doris) | Some(DialectType::StarRocks)
28751 | Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)) {
28752 self.write_keyword("LOCATE");
28754 self.write("(");
28755 if let Some(substr) = &e.substr {
28756 self.generate_expression(substr)?;
28757 self.write(", ");
28758 }
28759 self.generate_expression(&e.this)?;
28760 if let Some(position) = &e.position {
28761 self.write(", ");
28762 self.generate_expression(position)?;
28763 }
28764 self.write(")");
28765 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
28766 self.write_keyword("CHARINDEX");
28768 self.write("(");
28769 if let Some(substr) = &e.substr {
28770 self.generate_expression(substr)?;
28771 self.write(", ");
28772 }
28773 self.generate_expression(&e.this)?;
28774 if let Some(position) = &e.position {
28775 self.write(", ");
28776 self.generate_expression(position)?;
28777 }
28778 self.write(")");
28779 } else {
28780 self.write_keyword("STRPOS");
28781 self.write("(");
28782 self.generate_expression(&e.this)?;
28783 if let Some(substr) = &e.substr {
28784 self.write(", ");
28785 self.generate_expression(substr)?;
28786 }
28787 if let Some(position) = &e.position {
28788 self.write(", ");
28789 self.generate_expression(position)?;
28790 }
28791 if let Some(occurrence) = &e.occurrence {
28792 self.write(", ");
28793 self.generate_expression(occurrence)?;
28794 }
28795 self.write(")");
28796 }
28797 Ok(())
28798 }
28799
28800 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
28801 match self.config.dialect {
28802 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
28803 self.write_keyword("TO_DATE");
28805 self.write("(");
28806 self.generate_expression(&e.this)?;
28807 if let Some(format) = &e.format {
28808 self.write(", '");
28809 self.write(&Self::strftime_to_java_format(format));
28810 self.write("'");
28811 }
28812 self.write(")");
28813 }
28814 Some(DialectType::DuckDB) => {
28815 self.write_keyword("CAST");
28817 self.write("(");
28818 self.write_keyword("STRPTIME");
28819 self.write("(");
28820 self.generate_expression(&e.this)?;
28821 if let Some(format) = &e.format {
28822 self.write(", '");
28823 self.write(format);
28824 self.write("'");
28825 }
28826 self.write(")");
28827 self.write_keyword(" AS ");
28828 self.write_keyword("DATE");
28829 self.write(")");
28830 }
28831 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
28832 self.write_keyword("TO_DATE");
28834 self.write("(");
28835 self.generate_expression(&e.this)?;
28836 if let Some(format) = &e.format {
28837 self.write(", '");
28838 self.write(&Self::strftime_to_postgres_format(format));
28839 self.write("'");
28840 }
28841 self.write(")");
28842 }
28843 Some(DialectType::BigQuery) => {
28844 self.write_keyword("PARSE_DATE");
28846 self.write("(");
28847 if let Some(format) = &e.format {
28848 self.write("'");
28849 self.write(format);
28850 self.write("'");
28851 self.write(", ");
28852 }
28853 self.generate_expression(&e.this)?;
28854 self.write(")");
28855 }
28856 Some(DialectType::Teradata) => {
28857 self.write_keyword("CAST");
28859 self.write("(");
28860 self.generate_expression(&e.this)?;
28861 self.write_keyword(" AS ");
28862 self.write_keyword("DATE");
28863 if let Some(format) = &e.format {
28864 self.write_keyword(" FORMAT ");
28865 self.write("'");
28866 self.write(&Self::strftime_to_teradata_format(format));
28867 self.write("'");
28868 }
28869 self.write(")");
28870 }
28871 _ => {
28872 self.write_keyword("STR_TO_DATE");
28874 self.write("(");
28875 self.generate_expression(&e.this)?;
28876 if let Some(format) = &e.format {
28877 self.write(", '");
28878 self.write(format);
28879 self.write("'");
28880 }
28881 self.write(")");
28882 }
28883 }
28884 Ok(())
28885 }
28886
28887 fn strftime_to_teradata_format(fmt: &str) -> String {
28889 let mut result = fmt.to_string();
28890 result = result.replace("%Y", "YYYY");
28891 result = result.replace("%y", "YY");
28892 result = result.replace("%m", "MM");
28893 result = result.replace("%B", "MMMM");
28894 result = result.replace("%b", "MMM");
28895 result = result.replace("%d", "DD");
28896 result = result.replace("%j", "DDD");
28897 result = result.replace("%H", "HH");
28898 result = result.replace("%M", "MI");
28899 result = result.replace("%S", "SS");
28900 result = result.replace("%f", "SSSSSS");
28901 result = result.replace("%A", "EEEE");
28902 result = result.replace("%a", "EEE");
28903 result
28904 }
28905
28906 fn strftime_to_java_format(fmt: &str) -> String {
28908 let mut result = fmt.to_string();
28909 result = result.replace("%Y", "yyyy");
28910 result = result.replace("%y", "yy");
28911 result = result.replace("%m", "MM");
28912 result = result.replace("%B", "MMMM");
28913 result = result.replace("%b", "MMM");
28914 result = result.replace("%d", "dd");
28915 result = result.replace("%j", "DDD");
28916 result = result.replace("%H", "HH");
28917 result = result.replace("%M", "mm");
28918 result = result.replace("%S", "ss");
28919 result = result.replace("%f", "SSSSSS");
28920 result = result.replace("%A", "EEEE");
28921 result = result.replace("%a", "EEE");
28922 result
28923 }
28924
28925 fn strftime_to_postgres_format(fmt: &str) -> String {
28927 let mut result = fmt.to_string();
28928 result = result.replace("%Y", "YYYY");
28929 result = result.replace("%y", "YY");
28930 result = result.replace("%m", "MM");
28931 result = result.replace("%B", "Month");
28932 result = result.replace("%b", "Mon");
28933 result = result.replace("%d", "DD");
28934 result = result.replace("%j", "DDD");
28935 result = result.replace("%H", "HH24");
28936 result = result.replace("%M", "MI");
28937 result = result.replace("%S", "SS");
28938 result = result.replace("%f", "US");
28939 result = result.replace("%A", "Day");
28940 result = result.replace("%a", "Dy");
28941 result
28942 }
28943
28944 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
28945 self.write_keyword("STR_TO_MAP");
28947 self.write("(");
28948 self.generate_expression(&e.this)?;
28949 let needs_defaults = matches!(
28951 self.config.dialect,
28952 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
28953 );
28954 if let Some(pair_delim) = &e.pair_delim {
28955 self.write(", ");
28956 self.generate_expression(pair_delim)?;
28957 } else if needs_defaults {
28958 self.write(", ','");
28959 }
28960 if let Some(key_value_delim) = &e.key_value_delim {
28961 self.write(", ");
28962 self.generate_expression(key_value_delim)?;
28963 } else if needs_defaults {
28964 self.write(", ':'");
28965 }
28966 self.write(")");
28967 Ok(())
28968 }
28969
28970 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
28971 match self.config.dialect {
28972 Some(DialectType::Exasol) => {
28973 self.write_keyword("TO_DATE");
28974 self.write("(");
28975 self.generate_expression(&e.this)?;
28976 self.write(", '");
28977 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
28978 self.write("'");
28979 self.write(")");
28980 }
28981 Some(DialectType::BigQuery) => {
28982 let fmt = Self::snowflake_format_to_strftime(&e.format);
28984 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
28986 self.write_keyword("PARSE_TIMESTAMP");
28987 self.write("('");
28988 self.write(&fmt);
28989 self.write("', ");
28990 self.generate_expression(&e.this)?;
28991 self.write(")");
28992 }
28993 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
28994 let fmt = Self::snowflake_format_to_spark(&e.format);
28996 self.write_keyword("TO_TIMESTAMP");
28997 self.write("(");
28998 self.generate_expression(&e.this)?;
28999 self.write(", '");
29000 self.write(&fmt);
29001 self.write("')");
29002 }
29003 Some(DialectType::Presto) | Some(DialectType::Trino) => {
29004 let fmt = Self::snowflake_format_to_strftime(&e.format);
29006 self.write_keyword("DATE_PARSE");
29007 self.write("(");
29008 self.generate_expression(&e.this)?;
29009 self.write(", '");
29010 self.write(&fmt);
29011 self.write("')");
29012 }
29013 Some(DialectType::DuckDB) => {
29014 let fmt = Self::snowflake_format_to_strftime(&e.format);
29016 self.write_keyword("STRPTIME");
29017 self.write("(");
29018 self.generate_expression(&e.this)?;
29019 self.write(", '");
29020 self.write(&fmt);
29021 self.write("')");
29022 }
29023 Some(DialectType::Snowflake) => {
29024 self.write_keyword("TO_TIMESTAMP");
29026 self.write("(");
29027 self.generate_expression(&e.this)?;
29028 self.write(", '");
29029 self.write(&e.format);
29030 self.write("')");
29031 }
29032 _ => {
29033 self.write_keyword("STR_TO_TIME");
29035 self.write("(");
29036 self.generate_expression(&e.this)?;
29037 self.write(", '");
29038 self.write(&e.format);
29039 self.write("'");
29040 self.write(")");
29041 }
29042 }
29043 Ok(())
29044 }
29045
29046 fn snowflake_format_to_strftime(format: &str) -> String {
29048 let mut result = String::new();
29049 let chars: Vec<char> = format.chars().collect();
29050 let mut i = 0;
29051 while i < chars.len() {
29052 let remaining = &format[i..];
29053 if remaining.starts_with("yyyy") {
29054 result.push_str("%Y");
29055 i += 4;
29056 } else if remaining.starts_with("yy") {
29057 result.push_str("%y");
29058 i += 2;
29059 } else if remaining.starts_with("mmmm") {
29060 result.push_str("%B"); i += 4;
29062 } else if remaining.starts_with("mon") {
29063 result.push_str("%b"); i += 3;
29065 } else if remaining.starts_with("mm") {
29066 result.push_str("%m");
29067 i += 2;
29068 } else if remaining.starts_with("DD") {
29069 result.push_str("%d");
29070 i += 2;
29071 } else if remaining.starts_with("dy") {
29072 result.push_str("%a"); i += 2;
29074 } else if remaining.starts_with("hh24") {
29075 result.push_str("%H");
29076 i += 4;
29077 } else if remaining.starts_with("hh12") {
29078 result.push_str("%I");
29079 i += 4;
29080 } else if remaining.starts_with("hh") {
29081 result.push_str("%H");
29082 i += 2;
29083 } else if remaining.starts_with("mi") {
29084 result.push_str("%M");
29085 i += 2;
29086 } else if remaining.starts_with("ss") {
29087 result.push_str("%S");
29088 i += 2;
29089 } else if remaining.starts_with("ff") {
29090 result.push_str("%f");
29092 i += 2;
29093 while i < chars.len() && chars[i].is_ascii_digit() {
29095 i += 1;
29096 }
29097 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
29098 result.push_str("%p");
29099 i += 2;
29100 } else if remaining.starts_with("tz") {
29101 result.push_str("%Z");
29102 i += 2;
29103 } else {
29104 result.push(chars[i]);
29105 i += 1;
29106 }
29107 }
29108 result
29109 }
29110
29111 fn snowflake_format_to_spark(format: &str) -> String {
29113 let mut result = String::new();
29114 let chars: Vec<char> = format.chars().collect();
29115 let mut i = 0;
29116 while i < chars.len() {
29117 let remaining = &format[i..];
29118 if remaining.starts_with("yyyy") {
29119 result.push_str("yyyy");
29120 i += 4;
29121 } else if remaining.starts_with("yy") {
29122 result.push_str("yy");
29123 i += 2;
29124 } else if remaining.starts_with("mmmm") {
29125 result.push_str("MMMM"); i += 4;
29127 } else if remaining.starts_with("mon") {
29128 result.push_str("MMM"); i += 3;
29130 } else if remaining.starts_with("mm") {
29131 result.push_str("MM");
29132 i += 2;
29133 } else if remaining.starts_with("DD") {
29134 result.push_str("dd");
29135 i += 2;
29136 } else if remaining.starts_with("dy") {
29137 result.push_str("EEE"); i += 2;
29139 } else if remaining.starts_with("hh24") {
29140 result.push_str("HH");
29141 i += 4;
29142 } else if remaining.starts_with("hh12") {
29143 result.push_str("hh");
29144 i += 4;
29145 } else if remaining.starts_with("hh") {
29146 result.push_str("HH");
29147 i += 2;
29148 } else if remaining.starts_with("mi") {
29149 result.push_str("mm");
29150 i += 2;
29151 } else if remaining.starts_with("ss") {
29152 result.push_str("ss");
29153 i += 2;
29154 } else if remaining.starts_with("ff") {
29155 result.push_str("SSS"); i += 2;
29157 while i < chars.len() && chars[i].is_ascii_digit() {
29159 i += 1;
29160 }
29161 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
29162 result.push_str("a");
29163 i += 2;
29164 } else if remaining.starts_with("tz") {
29165 result.push_str("z");
29166 i += 2;
29167 } else {
29168 result.push(chars[i]);
29169 i += 1;
29170 }
29171 }
29172 result
29173 }
29174
29175 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
29176 self.write_keyword("STR_TO_UNIX");
29178 self.write("(");
29179 if let Some(this) = &e.this {
29180 self.generate_expression(this)?;
29181 }
29182 if let Some(format) = &e.format {
29183 self.write(", '");
29184 self.write(format);
29185 self.write("'");
29186 }
29187 self.write(")");
29188 Ok(())
29189 }
29190
29191 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
29192 self.write_keyword("STRING_TO_ARRAY");
29194 self.write("(");
29195 self.generate_expression(&e.this)?;
29196 if let Some(expression) = &e.expression {
29197 self.write(", ");
29198 self.generate_expression(expression)?;
29199 }
29200 if let Some(null_val) = &e.null {
29201 self.write(", ");
29202 self.generate_expression(null_val)?;
29203 }
29204 self.write(")");
29205 Ok(())
29206 }
29207
29208 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
29209 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
29210 self.write_keyword("OBJECT_CONSTRUCT");
29212 self.write("(");
29213 for (i, (name, expr)) in e.fields.iter().enumerate() {
29214 if i > 0 {
29215 self.write(", ");
29216 }
29217 if let Some(name) = name {
29218 self.write("'");
29219 self.write(name);
29220 self.write("'");
29221 self.write(", ");
29222 } else {
29223 self.write("'_");
29224 self.write(&i.to_string());
29225 self.write("'");
29226 self.write(", ");
29227 }
29228 self.generate_expression(expr)?;
29229 }
29230 self.write(")");
29231 } else if self.config.struct_curly_brace_notation {
29232 self.write("{");
29234 for (i, (name, expr)) in e.fields.iter().enumerate() {
29235 if i > 0 {
29236 self.write(", ");
29237 }
29238 if let Some(name) = name {
29239 self.write("'");
29241 self.write(name);
29242 self.write("'");
29243 self.write(": ");
29244 } else {
29245 self.write("'_");
29247 self.write(&i.to_string());
29248 self.write("'");
29249 self.write(": ");
29250 }
29251 self.generate_expression(expr)?;
29252 }
29253 self.write("}");
29254 } else {
29255 let value_as_name = matches!(
29259 self.config.dialect,
29260 Some(DialectType::BigQuery)
29261 | Some(DialectType::Spark)
29262
29263 | Some(DialectType::Databricks)
29264 | Some(DialectType::Hive)
29265 );
29266 self.write_keyword("STRUCT");
29267 self.write("(");
29268 for (i, (name, expr)) in e.fields.iter().enumerate() {
29269 if i > 0 {
29270 self.write(", ");
29271 }
29272 if let Some(name) = name {
29273 if value_as_name {
29274 self.generate_expression(expr)?;
29276 self.write_space();
29277 self.write_keyword("AS");
29278 self.write_space();
29279 let needs_quoting = name.contains(' ') || name.contains('-');
29281 if needs_quoting {
29282 if matches!(self.config.dialect, Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)) {
29283 self.write("`");
29284 self.write(name);
29285 self.write("`");
29286 } else {
29287 self.write(name);
29288 }
29289 } else {
29290 self.write(name);
29291 }
29292 } else {
29293 self.write(name);
29295 self.write_space();
29296 self.write_keyword("AS");
29297 self.write_space();
29298 self.generate_expression(expr)?;
29299 }
29300 } else {
29301 self.generate_expression(expr)?;
29302 }
29303 }
29304 self.write(")");
29305 }
29306 Ok(())
29307 }
29308
29309 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
29310 self.write_keyword("STUFF");
29312 self.write("(");
29313 self.generate_expression(&e.this)?;
29314 if let Some(start) = &e.start {
29315 self.write(", ");
29316 self.generate_expression(start)?;
29317 }
29318 if let Some(length) = e.length {
29319 self.write(", ");
29320 self.write(&length.to_string());
29321 }
29322 self.write(", ");
29323 self.generate_expression(&e.expression)?;
29324 self.write(")");
29325 Ok(())
29326 }
29327
29328 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
29329 self.write_keyword("SUBSTRING_INDEX");
29331 self.write("(");
29332 self.generate_expression(&e.this)?;
29333 if let Some(delimiter) = &e.delimiter {
29334 self.write(", ");
29335 self.generate_expression(delimiter)?;
29336 }
29337 if let Some(count) = &e.count {
29338 self.write(", ");
29339 self.generate_expression(count)?;
29340 }
29341 self.write(")");
29342 Ok(())
29343 }
29344
29345 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
29346 self.write_keyword("SUMMARIZE");
29348 if e.table.is_some() {
29349 self.write_space();
29350 self.write_keyword("TABLE");
29351 }
29352 self.write_space();
29353 self.generate_expression(&e.this)?;
29354 Ok(())
29355 }
29356
29357 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
29358 self.write_keyword("SYSTIMESTAMP");
29360 Ok(())
29361 }
29362
29363 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
29364 if let Some(this) = &e.this {
29366 self.generate_expression(this)?;
29367 }
29368 if !e.columns.is_empty() {
29369 self.write("(");
29370 for (i, col) in e.columns.iter().enumerate() {
29371 if i > 0 {
29372 self.write(", ");
29373 }
29374 self.generate_expression(col)?;
29375 }
29376 self.write(")");
29377 }
29378 Ok(())
29379 }
29380
29381 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
29382 self.write_keyword("TABLE");
29384 self.write("(");
29385 self.generate_expression(&e.this)?;
29386 self.write(")");
29387 if let Some(alias) = &e.alias {
29388 self.write_space();
29389 self.write_keyword("AS");
29390 self.write_space();
29391 self.write(alias);
29392 }
29393 Ok(())
29394 }
29395
29396 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
29397 self.write_keyword("ROWS FROM");
29399 self.write(" (");
29400 for (i, expr) in e.expressions.iter().enumerate() {
29401 if i > 0 {
29402 self.write(", ");
29403 }
29404 match expr {
29408 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
29409 self.generate_expression(&tuple.expressions[0])?;
29411 self.write_space();
29412 self.write_keyword("AS");
29413 self.write_space();
29414 self.generate_expression(&tuple.expressions[1])?;
29415 }
29416 _ => {
29417 self.generate_expression(expr)?;
29418 }
29419 }
29420 }
29421 self.write(")");
29422 if e.ordinality {
29423 self.write_space();
29424 self.write_keyword("WITH ORDINALITY");
29425 }
29426 if let Some(alias) = &e.alias {
29427 self.write_space();
29428 self.write_keyword("AS");
29429 self.write_space();
29430 self.generate_expression(alias)?;
29431 }
29432 Ok(())
29433 }
29434
29435 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
29436 use crate::dialects::DialectType;
29437
29438 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
29440 if self.config.alias_post_tablesample {
29442 if let Expression::Subquery(ref s) = **this {
29444 if let Some(ref alias) = s.alias {
29445 let mut subquery_no_alias = (**s).clone();
29447 subquery_no_alias.alias = None;
29448 subquery_no_alias.column_aliases = Vec::new();
29449 self.generate_expression(&Expression::Subquery(Box::new(subquery_no_alias)))?;
29450 self.write_space();
29451 self.write_keyword("TABLESAMPLE");
29452 self.generate_sample_body(sample)?;
29453 if let Some(ref seed) = sample.seed {
29454 self.write_space();
29455 let use_seed = sample.use_seed_keyword
29456 && !matches!(self.config.dialect, Some(crate::dialects::DialectType::Databricks) | Some(crate::dialects::DialectType::Spark));
29457 if use_seed { self.write_keyword("SEED"); } else { self.write_keyword("REPEATABLE"); }
29458 self.write(" (");
29459 self.generate_expression(seed)?;
29460 self.write(")");
29461 }
29462 self.write_space();
29463 self.write_keyword("AS");
29464 self.write_space();
29465 self.generate_identifier(alias)?;
29466 return Ok(());
29467 }
29468 } else if let Expression::Alias(ref a) = **this {
29469 self.generate_expression(&a.this)?;
29471 self.write_space();
29472 self.write_keyword("TABLESAMPLE");
29473 self.generate_sample_body(sample)?;
29474 if let Some(ref seed) = sample.seed {
29475 self.write_space();
29476 let use_seed = sample.use_seed_keyword
29477 && !matches!(self.config.dialect, Some(crate::dialects::DialectType::Databricks) | Some(crate::dialects::DialectType::Spark));
29478 if use_seed { self.write_keyword("SEED"); } else { self.write_keyword("REPEATABLE"); }
29479 self.write(" (");
29480 self.generate_expression(seed)?;
29481 self.write(")");
29482 }
29483 self.write_space();
29485 self.write_keyword("AS");
29486 self.write_space();
29487 self.generate_identifier(&a.alias)?;
29488 return Ok(());
29489 }
29490 }
29491 self.generate_expression(this)?;
29493 self.write_space();
29494 self.write_keyword("TABLESAMPLE");
29495 self.generate_sample_body(sample)?;
29496 if let Some(ref seed) = sample.seed {
29498 self.write_space();
29499 let use_seed = sample.use_seed_keyword
29501 && !matches!(self.config.dialect, Some(crate::dialects::DialectType::Databricks) | Some(crate::dialects::DialectType::Spark));
29502 if use_seed {
29503 self.write_keyword("SEED");
29504 } else {
29505 self.write_keyword("REPEATABLE");
29506 }
29507 self.write(" (");
29508 self.generate_expression(seed)?;
29509 self.write(")");
29510 }
29511 return Ok(());
29512 }
29513
29514 self.write_keyword("TABLESAMPLE");
29516 if let Some(method) = &e.method {
29517 self.write_space();
29518 self.write_keyword(method);
29519 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
29520 self.write_space();
29522 self.write_keyword("BERNOULLI");
29523 }
29524 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
29525 self.write_space();
29526 self.write_keyword("BUCKET");
29527 self.write_space();
29528 self.generate_expression(numerator)?;
29529 self.write_space();
29530 self.write_keyword("OUT OF");
29531 self.write_space();
29532 self.generate_expression(denominator)?;
29533 if let Some(field) = &e.bucket_field {
29534 self.write_space();
29535 self.write_keyword("ON");
29536 self.write_space();
29537 self.generate_expression(field)?;
29538 }
29539 } else if !e.expressions.is_empty() {
29540 self.write(" (");
29541 for (i, expr) in e.expressions.iter().enumerate() {
29542 if i > 0 {
29543 self.write(", ");
29544 }
29545 self.generate_expression(expr)?;
29546 }
29547 self.write(")");
29548 } else if let Some(percent) = &e.percent {
29549 self.write(" (");
29550 self.generate_expression(percent)?;
29551 self.write_space();
29552 self.write_keyword("PERCENT");
29553 self.write(")");
29554 }
29555 Ok(())
29556 }
29557
29558 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
29559 if let Some(prefix) = &e.prefix {
29561 self.generate_expression(prefix)?;
29562 }
29563 if let Some(this) = &e.this {
29564 self.generate_expression(this)?;
29565 }
29566 if let Some(postfix) = &e.postfix {
29567 self.generate_expression(postfix)?;
29568 }
29569 Ok(())
29570 }
29571
29572 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
29573 self.write_keyword("TAG");
29575 self.write(" (");
29576 for (i, expr) in e.expressions.iter().enumerate() {
29577 if i > 0 {
29578 self.write(", ");
29579 }
29580 self.generate_expression(expr)?;
29581 }
29582 self.write(")");
29583 Ok(())
29584 }
29585
29586 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
29587 if let Some(this) = &e.this {
29589 self.generate_expression(this)?;
29590 self.write_space();
29591 }
29592 self.write_keyword("TEMPORARY");
29593 Ok(())
29594 }
29595
29596 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
29599 self.write_keyword("TIME");
29601 self.write("(");
29602 self.generate_expression(&e.this)?;
29603 self.write(")");
29604 Ok(())
29605 }
29606
29607 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
29608 self.write_keyword("TIME_ADD");
29610 self.write("(");
29611 self.generate_expression(&e.this)?;
29612 self.write(", ");
29613 self.generate_expression(&e.expression)?;
29614 if let Some(unit) = &e.unit {
29615 self.write(", ");
29616 self.write_keyword(unit);
29617 }
29618 self.write(")");
29619 Ok(())
29620 }
29621
29622 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
29623 self.write_keyword("TIME_DIFF");
29625 self.write("(");
29626 self.generate_expression(&e.this)?;
29627 self.write(", ");
29628 self.generate_expression(&e.expression)?;
29629 if let Some(unit) = &e.unit {
29630 self.write(", ");
29631 self.write_keyword(unit);
29632 }
29633 self.write(")");
29634 Ok(())
29635 }
29636
29637 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
29638 self.write_keyword("TIME_FROM_PARTS");
29640 self.write("(");
29641 let mut first = true;
29642 if let Some(hour) = &e.hour {
29643 self.generate_expression(hour)?;
29644 first = false;
29645 }
29646 if let Some(minute) = &e.min {
29647 if !first { self.write(", "); }
29648 self.generate_expression(minute)?;
29649 first = false;
29650 }
29651 if let Some(second) = &e.sec {
29652 if !first { self.write(", "); }
29653 self.generate_expression(second)?;
29654 first = false;
29655 }
29656 if let Some(ns) = &e.nano {
29657 if !first { self.write(", "); }
29658 self.generate_expression(ns)?;
29659 }
29660 self.write(")");
29661 Ok(())
29662 }
29663
29664 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
29665 self.write_keyword("TIME_SLICE");
29667 self.write("(");
29668 self.generate_expression(&e.this)?;
29669 self.write(", ");
29670 self.generate_expression(&e.expression)?;
29671 self.write(", ");
29672 self.write_keyword(&e.unit);
29673 self.write(")");
29674 Ok(())
29675 }
29676
29677 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
29678 self.write_keyword("TIME_STR_TO_TIME");
29680 self.write("(");
29681 self.generate_expression(&e.this)?;
29682 self.write(")");
29683 Ok(())
29684 }
29685
29686 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
29687 self.write_keyword("TIME_SUB");
29689 self.write("(");
29690 self.generate_expression(&e.this)?;
29691 self.write(", ");
29692 self.generate_expression(&e.expression)?;
29693 if let Some(unit) = &e.unit {
29694 self.write(", ");
29695 self.write_keyword(unit);
29696 }
29697 self.write(")");
29698 Ok(())
29699 }
29700
29701 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
29702 if self.config.dialect == Some(DialectType::Exasol) {
29704 self.write_keyword("TO_CHAR");
29705 self.write("(");
29706 self.generate_expression(&e.this)?;
29707 self.write(", '");
29708 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
29709 self.write("'");
29710 self.write(")");
29711 return Ok(());
29712 }
29713
29714 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) {
29716 self.write_keyword("TO_CHAR");
29717 self.write("(");
29718 self.generate_expression(&e.this)?;
29719 self.write(", '");
29720 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
29721 self.write("'");
29722 self.write(")");
29723 return Ok(());
29724 }
29725
29726 self.write_keyword("TIME_TO_STR");
29728 self.write("(");
29729 self.generate_expression(&e.this)?;
29730 self.write(", '");
29731 self.write(&e.format);
29732 self.write("'");
29733 self.write(")");
29734 Ok(())
29735 }
29736
29737 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
29738 self.write_keyword("TIME_TRUNC");
29740 self.write("(");
29741 self.generate_expression(&e.this)?;
29742 self.write(", ");
29743 self.write_keyword(&e.unit);
29744 self.write(")");
29745 Ok(())
29746 }
29747
29748 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
29749 if let Some(unit) = &e.unit {
29751 self.write_keyword(unit);
29752 }
29753 Ok(())
29754 }
29755
29756 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
29760 use crate::dialects::DialectType;
29761 use crate::expressions::Literal;
29762
29763 match self.config.dialect {
29764 Some(DialectType::Exasol) => {
29766 self.write_keyword("TO_TIMESTAMP");
29767 self.write("(");
29768 if let Some(this) = &e.this {
29770 match this.as_ref() {
29771 Expression::Literal(Literal::String(s)) => {
29772 self.write("'");
29773 self.write(s);
29774 self.write("'");
29775 }
29776 _ => {
29777 self.generate_expression(this)?;
29778 }
29779 }
29780 }
29781 self.write(")");
29782 }
29783 _ => {
29785 self.write_keyword("TIMESTAMP");
29786 self.write("(");
29787 if let Some(this) = &e.this {
29788 self.generate_expression(this)?;
29789 }
29790 if let Some(zone) = &e.zone {
29791 self.write(", ");
29792 self.generate_expression(zone)?;
29793 }
29794 self.write(")");
29795 }
29796 }
29797 Ok(())
29798 }
29799
29800 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
29801 self.write_keyword("TIMESTAMP_ADD");
29803 self.write("(");
29804 self.generate_expression(&e.this)?;
29805 self.write(", ");
29806 self.generate_expression(&e.expression)?;
29807 if let Some(unit) = &e.unit {
29808 self.write(", ");
29809 self.write_keyword(unit);
29810 }
29811 self.write(")");
29812 Ok(())
29813 }
29814
29815 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
29816 self.write_keyword("TIMESTAMP_DIFF");
29818 self.write("(");
29819 self.generate_expression(&e.this)?;
29820 self.write(", ");
29821 self.generate_expression(&e.expression)?;
29822 if let Some(unit) = &e.unit {
29823 self.write(", ");
29824 self.write_keyword(unit);
29825 }
29826 self.write(")");
29827 Ok(())
29828 }
29829
29830 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
29831 self.write_keyword("TIMESTAMP_FROM_PARTS");
29833 self.write("(");
29834 if let Some(this) = &e.this {
29835 self.generate_expression(this)?;
29836 }
29837 if let Some(expression) = &e.expression {
29838 self.write(", ");
29839 self.generate_expression(expression)?;
29840 }
29841 if let Some(zone) = &e.zone {
29842 self.write(", ");
29843 self.generate_expression(zone)?;
29844 }
29845 if let Some(milli) = &e.milli {
29846 self.write(", ");
29847 self.generate_expression(milli)?;
29848 }
29849 self.write(")");
29850 Ok(())
29851 }
29852
29853 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
29854 self.write_keyword("TIMESTAMP_SUB");
29856 self.write("(");
29857 self.generate_expression(&e.this)?;
29858 self.write(", ");
29859 self.write_keyword("INTERVAL");
29860 self.write_space();
29861 self.generate_expression(&e.expression)?;
29862 if let Some(unit) = &e.unit {
29863 self.write_space();
29864 self.write_keyword(unit);
29865 }
29866 self.write(")");
29867 Ok(())
29868 }
29869
29870 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
29871 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
29873 self.write("(");
29874 if let Some(zone) = &e.zone {
29875 self.generate_expression(zone)?;
29876 }
29877 self.write(")");
29878 Ok(())
29879 }
29880
29881 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
29882 self.write_keyword("TO_BINARY");
29884 self.write("(");
29885 self.generate_expression(&e.this)?;
29886 if let Some(format) = &e.format {
29887 self.write(", '");
29888 self.write(format);
29889 self.write("'");
29890 }
29891 self.write(")");
29892 Ok(())
29893 }
29894
29895 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
29896 self.write_keyword("TO_BOOLEAN");
29898 self.write("(");
29899 self.generate_expression(&e.this)?;
29900 self.write(")");
29901 Ok(())
29902 }
29903
29904 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
29905 self.write_keyword("TO_CHAR");
29907 self.write("(");
29908 self.generate_expression(&e.this)?;
29909 if let Some(format) = &e.format {
29910 self.write(", '");
29911 self.write(format);
29912 self.write("'");
29913 }
29914 if let Some(nlsparam) = &e.nlsparam {
29915 self.write(", ");
29916 self.generate_expression(nlsparam)?;
29917 }
29918 self.write(")");
29919 Ok(())
29920 }
29921
29922 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
29923 self.write_keyword("TO_DECFLOAT");
29925 self.write("(");
29926 self.generate_expression(&e.this)?;
29927 if let Some(format) = &e.format {
29928 self.write(", '");
29929 self.write(format);
29930 self.write("'");
29931 }
29932 self.write(")");
29933 Ok(())
29934 }
29935
29936 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
29937 self.write_keyword("TO_DOUBLE");
29939 self.write("(");
29940 self.generate_expression(&e.this)?;
29941 if let Some(format) = &e.format {
29942 self.write(", '");
29943 self.write(format);
29944 self.write("'");
29945 }
29946 self.write(")");
29947 Ok(())
29948 }
29949
29950 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
29951 self.write_keyword("TO_FILE");
29953 self.write("(");
29954 self.generate_expression(&e.this)?;
29955 if let Some(path) = &e.path {
29956 self.write(", ");
29957 self.generate_expression(path)?;
29958 }
29959 self.write(")");
29960 Ok(())
29961 }
29962
29963 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
29964 let is_safe = e.safe.is_some();
29967 if is_safe {
29968 self.write_keyword("TRY_TO_NUMBER");
29969 } else {
29970 self.write_keyword("TO_NUMBER");
29971 }
29972 self.write("(");
29973 self.generate_expression(&e.this)?;
29974 if let Some(format) = &e.format {
29975 self.write(", ");
29976 self.generate_expression(format)?;
29977 }
29978 if let Some(nlsparam) = &e.nlsparam {
29979 self.write(", ");
29980 self.generate_expression(nlsparam)?;
29981 }
29982 if let Some(precision) = &e.precision {
29983 self.write(", ");
29984 self.generate_expression(precision)?;
29985 }
29986 if let Some(scale) = &e.scale {
29987 self.write(", ");
29988 self.generate_expression(scale)?;
29989 }
29990 self.write(")");
29991 Ok(())
29992 }
29993
29994 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
29995 self.write_keyword("TO_TABLE");
29997 self.write_space();
29998 self.generate_expression(&e.this)?;
29999 Ok(())
30000 }
30001
30002 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
30003 let mark_text = e.mark.as_ref().map(|m| {
30005 match m.as_ref() {
30006 Expression::Identifier(id) => id.name.clone(),
30007 Expression::Literal(Literal::String(s)) => s.clone(),
30008 _ => String::new(),
30009 }
30010 });
30011
30012 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
30013 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
30014 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
30015 matches!(m.as_ref(), Expression::Literal(Literal::String(_)))
30016 });
30017
30018 if is_start {
30019 self.write_keyword("START TRANSACTION");
30021 if let Some(modes) = &e.modes {
30022 self.write_space();
30023 self.generate_expression(modes)?;
30024 }
30025 } else {
30026 self.write_keyword("BEGIN");
30028
30029 if has_transaction_keyword || has_with_mark {
30031 self.write_space();
30032 self.write_keyword("TRANSACTION");
30033 }
30034
30035 if let Some(this) = &e.this {
30037 self.write_space();
30038 self.generate_expression(this)?;
30039 }
30040
30041 if has_with_mark {
30043 self.write_space();
30044 self.write_keyword("WITH MARK");
30045 if let Some(Expression::Literal(Literal::String(desc))) = e.mark.as_deref() {
30046 if !desc.is_empty() {
30047 self.write_space();
30048 self.write(&format!("'{}'", desc));
30049 }
30050 }
30051 }
30052
30053 if let Some(modes) = &e.modes {
30055 self.write_space();
30056 self.generate_expression(modes)?;
30057 }
30058 }
30059 Ok(())
30060 }
30061
30062 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
30063 self.write_keyword("TRANSFORM");
30065 self.write("(");
30066 self.generate_expression(&e.this)?;
30067 self.write(", ");
30068 self.generate_expression(&e.expression)?;
30069 self.write(")");
30070 Ok(())
30071 }
30072
30073 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
30074 self.write_keyword("TRANSFORM");
30076 self.write("(");
30077 if self.config.pretty && !e.expressions.is_empty() {
30078 self.indent_level += 1;
30079 for (i, expr) in e.expressions.iter().enumerate() {
30080 if i > 0 {
30081 self.write(",");
30082 }
30083 self.write_newline();
30084 self.write_indent();
30085 self.generate_expression(expr)?;
30086 }
30087 self.indent_level -= 1;
30088 self.write_newline();
30089 self.write(")");
30090 } else {
30091 for (i, expr) in e.expressions.iter().enumerate() {
30092 if i > 0 {
30093 self.write(", ");
30094 }
30095 self.generate_expression(expr)?;
30096 }
30097 self.write(")");
30098 }
30099 Ok(())
30100 }
30101
30102 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
30103 use crate::dialects::DialectType;
30104 if let Some(this) = &e.this {
30106 self.generate_expression(this)?;
30107 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
30108 self.write_space();
30109 }
30110 }
30111 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
30112 self.write_keyword("TRANSIENT");
30113 }
30114 Ok(())
30115 }
30116
30117 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
30118 self.write_keyword("TRANSLATE");
30120 self.write("(");
30121 self.generate_expression(&e.this)?;
30122 if let Some(from) = &e.from_ {
30123 self.write(", ");
30124 self.generate_expression(from)?;
30125 }
30126 if let Some(to) = &e.to {
30127 self.write(", ");
30128 self.generate_expression(to)?;
30129 }
30130 self.write(")");
30131 Ok(())
30132 }
30133
30134 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
30135 self.write_keyword("TRANSLATE");
30137 self.write("(");
30138 self.generate_expression(&e.this)?;
30139 self.write_space();
30140 self.write_keyword("USING");
30141 self.write_space();
30142 self.generate_expression(&e.expression)?;
30143 if e.with_error.is_some() {
30144 self.write_space();
30145 self.write_keyword("WITH ERROR");
30146 }
30147 self.write(")");
30148 Ok(())
30149 }
30150
30151 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
30152 self.write_keyword("TRUNCATE TABLE");
30154 self.write_space();
30155 for (i, expr) in e.expressions.iter().enumerate() {
30156 if i > 0 {
30157 self.write(", ");
30158 }
30159 self.generate_expression(expr)?;
30160 }
30161 Ok(())
30162 }
30163
30164 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
30165 self.write_keyword("TRY_BASE64_DECODE_BINARY");
30167 self.write("(");
30168 self.generate_expression(&e.this)?;
30169 if let Some(alphabet) = &e.alphabet {
30170 self.write(", ");
30171 self.generate_expression(alphabet)?;
30172 }
30173 self.write(")");
30174 Ok(())
30175 }
30176
30177 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
30178 self.write_keyword("TRY_BASE64_DECODE_STRING");
30180 self.write("(");
30181 self.generate_expression(&e.this)?;
30182 if let Some(alphabet) = &e.alphabet {
30183 self.write(", ");
30184 self.generate_expression(alphabet)?;
30185 }
30186 self.write(")");
30187 Ok(())
30188 }
30189
30190 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
30191 self.write_keyword("TRY_TO_DECFLOAT");
30193 self.write("(");
30194 self.generate_expression(&e.this)?;
30195 if let Some(format) = &e.format {
30196 self.write(", '");
30197 self.write(format);
30198 self.write("'");
30199 }
30200 self.write(")");
30201 Ok(())
30202 }
30203
30204 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
30205 self.write_keyword("TS_OR_DS_ADD");
30207 self.write("(");
30208 self.generate_expression(&e.this)?;
30209 self.write(", ");
30210 self.generate_expression(&e.expression)?;
30211 if let Some(unit) = &e.unit {
30212 self.write(", ");
30213 self.write_keyword(unit);
30214 }
30215 if let Some(return_type) = &e.return_type {
30216 self.write(", ");
30217 self.generate_expression(return_type)?;
30218 }
30219 self.write(")");
30220 Ok(())
30221 }
30222
30223 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
30224 self.write_keyword("TS_OR_DS_DIFF");
30226 self.write("(");
30227 self.generate_expression(&e.this)?;
30228 self.write(", ");
30229 self.generate_expression(&e.expression)?;
30230 if let Some(unit) = &e.unit {
30231 self.write(", ");
30232 self.write_keyword(unit);
30233 }
30234 self.write(")");
30235 Ok(())
30236 }
30237
30238 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
30239 self.write_keyword("TS_OR_DS_TO_DATE");
30241 self.write("(");
30242 self.generate_expression(&e.this)?;
30243 if let Some(format) = &e.format {
30244 self.write(", '");
30245 self.write(format);
30246 self.write("'");
30247 }
30248 self.write(")");
30249 Ok(())
30250 }
30251
30252 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
30253 self.write_keyword("TS_OR_DS_TO_TIME");
30255 self.write("(");
30256 self.generate_expression(&e.this)?;
30257 if let Some(format) = &e.format {
30258 self.write(", '");
30259 self.write(format);
30260 self.write("'");
30261 }
30262 self.write(")");
30263 Ok(())
30264 }
30265
30266 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
30267 self.write_keyword("UNHEX");
30269 self.write("(");
30270 self.generate_expression(&e.this)?;
30271 if let Some(expression) = &e.expression {
30272 self.write(", ");
30273 self.generate_expression(expression)?;
30274 }
30275 self.write(")");
30276 Ok(())
30277 }
30278
30279 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
30280 self.write("U&");
30282 self.generate_expression(&e.this)?;
30283 if let Some(escape) = &e.escape {
30284 self.write_space();
30285 self.write_keyword("UESCAPE");
30286 self.write_space();
30287 self.generate_expression(escape)?;
30288 }
30289 Ok(())
30290 }
30291
30292 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
30293 self.write_keyword("UNIFORM");
30295 self.write("(");
30296 self.generate_expression(&e.this)?;
30297 self.write(", ");
30298 self.generate_expression(&e.expression)?;
30299 if let Some(gen) = &e.gen {
30300 self.write(", ");
30301 self.generate_expression(gen)?;
30302 }
30303 if let Some(seed) = &e.seed {
30304 self.write(", ");
30305 self.generate_expression(seed)?;
30306 }
30307 self.write(")");
30308 Ok(())
30309 }
30310
30311 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
30312 self.write_keyword("UNIQUE");
30314 if e.nulls.is_some() {
30316 self.write(" NULLS NOT DISTINCT");
30317 }
30318 if let Some(this) = &e.this {
30319 self.write_space();
30320 self.generate_expression(this)?;
30321 }
30322 if let Some(index_type) = &e.index_type {
30323 self.write(" USING ");
30324 self.generate_expression(index_type)?;
30325 }
30326 if let Some(on_conflict) = &e.on_conflict {
30327 self.write_space();
30328 self.generate_expression(on_conflict)?;
30329 }
30330 for opt in &e.options {
30331 self.write_space();
30332 self.generate_expression(opt)?;
30333 }
30334 Ok(())
30335 }
30336
30337 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
30338 self.write_keyword("UNIQUE KEY");
30340 self.write(" (");
30341 for (i, expr) in e.expressions.iter().enumerate() {
30342 if i > 0 {
30343 self.write(", ");
30344 }
30345 self.generate_expression(expr)?;
30346 }
30347 self.write(")");
30348 Ok(())
30349 }
30350
30351 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
30352 self.write_keyword("ROLLUP");
30354 self.write(" (");
30355 for (i, index) in e.expressions.iter().enumerate() {
30356 if i > 0 {
30357 self.write(", ");
30358 }
30359 self.generate_identifier(&index.name)?;
30360 self.write("(");
30361 for (j, col) in index.expressions.iter().enumerate() {
30362 if j > 0 {
30363 self.write(", ");
30364 }
30365 self.generate_identifier(col)?;
30366 }
30367 self.write(")");
30368 }
30369 self.write(")");
30370 Ok(())
30371 }
30372
30373 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
30374 self.write_keyword("UNIX_TO_STR");
30376 self.write("(");
30377 self.generate_expression(&e.this)?;
30378 if let Some(format) = &e.format {
30379 self.write(", '");
30380 self.write(format);
30381 self.write("'");
30382 }
30383 self.write(")");
30384 Ok(())
30385 }
30386
30387 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
30388 use crate::dialects::DialectType;
30389 let scale = e.scale.unwrap_or(0); match self.config.dialect {
30392 Some(DialectType::Snowflake) => {
30393 self.write_keyword("TO_TIMESTAMP");
30395 self.write("(");
30396 self.generate_expression(&e.this)?;
30397 if let Some(s) = e.scale {
30398 if s > 0 {
30399 self.write(", ");
30400 self.write(&s.to_string());
30401 }
30402 }
30403 self.write(")");
30404 }
30405 Some(DialectType::BigQuery) => {
30406 match scale {
30409 0 => {
30410 self.write_keyword("TIMESTAMP_SECONDS");
30411 self.write("(");
30412 self.generate_expression(&e.this)?;
30413 self.write(")");
30414 }
30415 3 => {
30416 self.write_keyword("TIMESTAMP_MILLIS");
30417 self.write("(");
30418 self.generate_expression(&e.this)?;
30419 self.write(")");
30420 }
30421 6 => {
30422 self.write_keyword("TIMESTAMP_MICROS");
30423 self.write("(");
30424 self.generate_expression(&e.this)?;
30425 self.write(")");
30426 }
30427 _ => {
30428 self.write_keyword("TIMESTAMP_SECONDS");
30430 self.write("(CAST(");
30431 self.generate_expression(&e.this)?;
30432 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
30433 }
30434 }
30435 }
30436 Some(DialectType::Spark) => {
30437 match scale {
30442 0 => {
30443 self.write_keyword("CAST");
30444 self.write("(");
30445 self.write_keyword("FROM_UNIXTIME");
30446 self.write("(");
30447 self.generate_expression(&e.this)?;
30448 self.write(") ");
30449 self.write_keyword("AS TIMESTAMP");
30450 self.write(")");
30451 }
30452 3 => {
30453 self.write_keyword("TIMESTAMP_MILLIS");
30454 self.write("(");
30455 self.generate_expression(&e.this)?;
30456 self.write(")");
30457 }
30458 6 => {
30459 self.write_keyword("TIMESTAMP_MICROS");
30460 self.write("(");
30461 self.generate_expression(&e.this)?;
30462 self.write(")");
30463 }
30464 _ => {
30465 self.write_keyword("TIMESTAMP_SECONDS");
30466 self.write("(");
30467 self.generate_expression(&e.this)?;
30468 self.write(&format!(" / POWER(10, {}))", scale));
30469 }
30470 }
30471 }
30472 Some(DialectType::Databricks) => {
30473 match scale {
30477 0 => {
30478 self.write_keyword("CAST");
30479 self.write("(");
30480 self.write_keyword("FROM_UNIXTIME");
30481 self.write("(");
30482 self.generate_expression(&e.this)?;
30483 self.write(") ");
30484 self.write_keyword("AS TIMESTAMP");
30485 self.write(")");
30486 }
30487 3 => {
30488 self.write_keyword("TIMESTAMP_MILLIS");
30489 self.write("(");
30490 self.generate_expression(&e.this)?;
30491 self.write(")");
30492 }
30493 6 => {
30494 self.write_keyword("TIMESTAMP_MICROS");
30495 self.write("(");
30496 self.generate_expression(&e.this)?;
30497 self.write(")");
30498 }
30499 _ => {
30500 self.write_keyword("TIMESTAMP_SECONDS");
30501 self.write("(");
30502 self.generate_expression(&e.this)?;
30503 self.write(&format!(" / POWER(10, {}))", scale));
30504 }
30505 }
30506 }
30507 Some(DialectType::Presto) | Some(DialectType::Trino) => {
30508 if scale == 0 {
30511 self.write_keyword("FROM_UNIXTIME");
30512 self.write("(");
30513 self.generate_expression(&e.this)?;
30514 self.write(")");
30515 } else {
30516 self.write_keyword("FROM_UNIXTIME");
30517 self.write("(CAST(");
30518 self.generate_expression(&e.this)?;
30519 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
30520 }
30521 }
30522 Some(DialectType::DuckDB) => {
30523 match scale {
30527 0 => {
30528 self.write_keyword("TO_TIMESTAMP");
30529 self.write("(");
30530 self.generate_expression(&e.this)?;
30531 self.write(")");
30532 }
30533 3 => {
30534 self.write_keyword("EPOCH_MS");
30535 self.write("(");
30536 self.generate_expression(&e.this)?;
30537 self.write(")");
30538 }
30539 6 => {
30540 self.write_keyword("MAKE_TIMESTAMP");
30541 self.write("(");
30542 self.generate_expression(&e.this)?;
30543 self.write(")");
30544 }
30545 _ => {
30546 self.write_keyword("TO_TIMESTAMP");
30547 self.write("(");
30548 self.generate_expression(&e.this)?;
30549 self.write(&format!(" / POWER(10, {}))", scale));
30550 self.write_keyword(" AT TIME ZONE");
30551 self.write(" 'UTC'");
30552 }
30553 }
30554 }
30555 Some(DialectType::Redshift) => {
30556 self.write("(TIMESTAMP 'epoch' + ");
30559 if scale == 0 {
30560 self.generate_expression(&e.this)?;
30561 } else {
30562 self.write("(");
30563 self.generate_expression(&e.this)?;
30564 self.write(&format!(" / POWER(10, {}))", scale));
30565 }
30566 self.write(" * INTERVAL '1 SECOND')");
30567 }
30568 _ => {
30569 self.write_keyword("TO_TIMESTAMP");
30571 self.write("(");
30572 self.generate_expression(&e.this)?;
30573 if let Some(s) = e.scale {
30574 self.write(", ");
30575 self.write(&s.to_string());
30576 }
30577 self.write(")");
30578 }
30579 }
30580 Ok(())
30581 }
30582
30583 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
30584 if !matches!(&*e.this, Expression::Null(_)) {
30586 self.write_keyword("NAME");
30587 self.write_space();
30588 self.generate_expression(&e.this)?;
30589 }
30590 if !e.expressions.is_empty() {
30591 self.write_space();
30592 self.write_keyword("VALUE");
30593 self.write_space();
30594 for (i, expr) in e.expressions.iter().enumerate() {
30595 if i > 0 {
30596 self.write(", ");
30597 }
30598 self.generate_expression(expr)?;
30599 }
30600 }
30601 Ok(())
30602 }
30603
30604 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
30605 if e.wrapped.is_some() {
30607 self.write("(");
30608 }
30609 self.generate_expression(&e.this)?;
30610 if e.wrapped.is_some() {
30611 self.write(")");
30612 }
30613 self.write("(");
30614 for (i, expr) in e.expressions.iter().enumerate() {
30615 if i > 0 {
30616 self.write(", ");
30617 }
30618 self.generate_expression(expr)?;
30619 }
30620 self.write(")");
30621 Ok(())
30622 }
30623
30624 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
30625 self.write_keyword("USING TEMPLATE");
30627 self.write_space();
30628 self.generate_expression(&e.this)?;
30629 Ok(())
30630 }
30631
30632 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
30633 self.write_keyword("UTC_TIME");
30635 Ok(())
30636 }
30637
30638 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
30639 self.write_keyword("UTC_TIMESTAMP");
30641 Ok(())
30642 }
30643
30644 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
30645 use crate::dialects::DialectType;
30646 let func_name = match self.config.dialect {
30648 Some(DialectType::Snowflake) => "UUID_STRING",
30649 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
30650 Some(DialectType::BigQuery) => "GENERATE_UUID",
30651 _ => {
30652 if let Some(name) = &e.name {
30653 name.as_str()
30654 } else {
30655 "UUID"
30656 }
30657 }
30658 };
30659 self.write_keyword(func_name);
30660 self.write("(");
30661 if let Some(this) = &e.this {
30662 self.generate_expression(this)?;
30663 }
30664 self.write(")");
30665 Ok(())
30666 }
30667
30668 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
30669 self.write_keyword("MAP");
30671 self.write("(");
30672 let mut first = true;
30673 for (k, v) in e.keys.iter().zip(e.values.iter()) {
30674 if !first {
30675 self.write(", ");
30676 }
30677 self.generate_expression(k)?;
30678 self.write(", ");
30679 self.generate_expression(v)?;
30680 first = false;
30681 }
30682 self.write(")");
30683 Ok(())
30684 }
30685
30686 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
30687 self.write_keyword("VECTOR_SEARCH");
30689 self.write("(");
30690 self.generate_expression(&e.this)?;
30691 if let Some(col) = &e.column_to_search {
30692 self.write(", ");
30693 self.generate_expression(col)?;
30694 }
30695 if let Some(query_table) = &e.query_table {
30696 self.write(", ");
30697 self.generate_expression(query_table)?;
30698 }
30699 if let Some(query_col) = &e.query_column_to_search {
30700 self.write(", ");
30701 self.generate_expression(query_col)?;
30702 }
30703 if let Some(top_k) = &e.top_k {
30704 self.write(", ");
30705 self.generate_expression(top_k)?;
30706 }
30707 if let Some(dist_type) = &e.distance_type {
30708 self.write(", ");
30709 self.generate_expression(dist_type)?;
30710 }
30711 self.write(")");
30712 Ok(())
30713 }
30714
30715 fn generate_version(&mut self, e: &Version) -> Result<()> {
30716 use crate::dialects::DialectType;
30722 let skip_for = matches!(self.config.dialect, Some(DialectType::Hive) | Some(DialectType::Spark));
30723 if !skip_for {
30724 self.write_keyword("FOR");
30725 self.write_space();
30726 }
30727 match e.this.as_ref() {
30729 Expression::Identifier(ident) => {
30730 self.write_keyword(&ident.name);
30731 }
30732 _ => {
30733 self.generate_expression(&e.this)?;
30734 }
30735 }
30736 self.write_space();
30737 self.write_keyword(&e.kind);
30738 if let Some(expression) = &e.expression {
30739 self.write_space();
30740 self.generate_expression(expression)?;
30741 }
30742 Ok(())
30743 }
30744
30745 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
30746 self.generate_expression(&e.this)?;
30748 Ok(())
30749 }
30750
30751 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
30752 if e.this.is_some() {
30754 self.write_keyword("NOT VOLATILE");
30755 } else {
30756 self.write_keyword("VOLATILE");
30757 }
30758 Ok(())
30759 }
30760
30761 fn generate_watermark_column_constraint(&mut self, e: &WatermarkColumnConstraint) -> Result<()> {
30762 self.write_keyword("WATERMARK FOR");
30764 self.write_space();
30765 self.generate_expression(&e.this)?;
30766 self.write_space();
30767 self.write_keyword("AS");
30768 self.write_space();
30769 self.generate_expression(&e.expression)?;
30770 Ok(())
30771 }
30772
30773 fn generate_week(&mut self, e: &Week) -> Result<()> {
30774 self.write_keyword("WEEK");
30776 self.write("(");
30777 self.generate_expression(&e.this)?;
30778 if let Some(mode) = &e.mode {
30779 self.write(", ");
30780 self.generate_expression(mode)?;
30781 }
30782 self.write(")");
30783 Ok(())
30784 }
30785
30786 fn generate_when(&mut self, e: &When) -> Result<()> {
30787 self.write_keyword("WHEN");
30791 self.write_space();
30792
30793 if let Some(matched) = &e.matched {
30795 match matched.as_ref() {
30797 Expression::Boolean(b) if b.value => {
30798 self.write_keyword("MATCHED");
30799 }
30800 _ => {
30801 self.write_keyword("NOT MATCHED");
30802 }
30803 }
30804 } else {
30805 self.write_keyword("NOT MATCHED");
30806 }
30807
30808 if self.config.matched_by_source {
30813 if let Some(source) = &e.source {
30814 if let Expression::Boolean(b) = source.as_ref() {
30815 if b.value {
30816 self.write_space();
30818 self.write_keyword("BY SOURCE");
30819 }
30820 } else {
30822 self.write_space();
30824 self.write_keyword("BY SOURCE");
30825 }
30826 }
30827 }
30828
30829 if let Some(condition) = &e.condition {
30831 self.write_space();
30832 self.write_keyword("AND");
30833 self.write_space();
30834 self.generate_expression(condition)?;
30835 }
30836
30837 self.write_space();
30838 self.write_keyword("THEN");
30839 self.write_space();
30840
30841 self.generate_merge_action(&e.then)?;
30844
30845 Ok(())
30846 }
30847
30848 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
30849 match action {
30850 Expression::Tuple(tuple) => {
30851 let elements = &tuple.expressions;
30852 if elements.is_empty() {
30853 return self.generate_expression(action);
30854 }
30855 match &elements[0] {
30857 Expression::Var(v) if v.this == "INSERT" => {
30858 self.write_keyword("INSERT");
30859 let mut values_idx = 1;
30860 if elements.len() > 1 {
30862 if let Expression::Tuple(cols) = &elements[1] {
30863 if elements.len() > 2 {
30865 self.write(" (");
30867 for (i, col) in cols.expressions.iter().enumerate() {
30868 if i > 0 { self.write(", "); }
30869 self.generate_expression(col)?;
30870 }
30871 self.write(")");
30872 values_idx = 2;
30873 } else {
30874 values_idx = 1;
30876 }
30877 }
30878 }
30879 if values_idx < elements.len() {
30881 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
30883 if !is_row {
30884 self.write_space();
30885 self.write_keyword("VALUES");
30886 }
30887 self.write(" ");
30888 if let Expression::Tuple(vals) = &elements[values_idx] {
30889 self.write("(");
30890 for (i, val) in vals.expressions.iter().enumerate() {
30891 if i > 0 { self.write(", "); }
30892 self.generate_expression(val)?;
30893 }
30894 self.write(")");
30895 } else {
30896 self.generate_expression(&elements[values_idx])?;
30897 }
30898 }
30899 }
30900 Expression::Var(v) if v.this == "UPDATE" => {
30901 self.write_keyword("UPDATE");
30902 if elements.len() > 1 {
30903 self.write_space();
30904 self.write_keyword("SET");
30905 if self.config.pretty {
30907 self.write_newline();
30908 self.indent_level += 1;
30909 self.write_indent();
30910 } else {
30911 self.write_space();
30912 }
30913 if let Expression::Tuple(assignments) = &elements[1] {
30914 for (i, assignment) in assignments.expressions.iter().enumerate() {
30915 if i > 0 { self.write(", "); }
30916 if !self.merge_strip_qualifiers.is_empty() {
30918 self.generate_merge_set_assignment(assignment)?;
30919 } else {
30920 self.generate_expression(assignment)?;
30921 }
30922 }
30923 } else {
30924 self.generate_expression(&elements[1])?;
30925 }
30926 if self.config.pretty {
30927 self.indent_level -= 1;
30928 }
30929 }
30930 }
30931 _ => {
30932 self.generate_expression(action)?;
30934 }
30935 }
30936 }
30937 Expression::Var(v) if v.this == "INSERT" || v.this == "UPDATE" || v.this == "DELETE" || v.this == "DO NOTHING" => {
30938 self.write_keyword(&v.this);
30939 }
30940 _ => {
30941 self.generate_expression(action)?;
30942 }
30943 }
30944 Ok(())
30945 }
30946
30947 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
30949 match assignment {
30950 Expression::Eq(eq) => {
30951 let stripped_left = self.strip_merge_qualifier(&eq.left);
30953 self.generate_expression(&stripped_left)?;
30954 self.write(" = ");
30955 self.generate_expression(&eq.right)?;
30956 Ok(())
30957 }
30958 other => self.generate_expression(other),
30959 }
30960 }
30961
30962 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
30964 match expr {
30965 Expression::Column(col) => {
30966 if let Some(ref table_ident) = col.table {
30967 if self.merge_strip_qualifiers.iter().any(|n| n.eq_ignore_ascii_case(&table_ident.name)) {
30968 let mut col = col.clone();
30970 col.table = None;
30971 return Expression::Column(col);
30972 }
30973 }
30974 expr.clone()
30975 }
30976 Expression::Dot(dot) => {
30977 if let Expression::Identifier(id) = &dot.this {
30979 if self.merge_strip_qualifiers.iter().any(|n| n.eq_ignore_ascii_case(&id.name)) {
30980 return Expression::Identifier(dot.field.clone());
30981 }
30982 }
30983 expr.clone()
30984 }
30985 _ => expr.clone(),
30986 }
30987 }
30988
30989 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
30990 for (i, expr) in e.expressions.iter().enumerate() {
30992 if i > 0 {
30993 if self.config.pretty {
30995 self.write_newline();
30996 self.write_indent();
30997 } else {
30998 self.write_space();
30999 }
31000 }
31001 self.generate_expression(expr)?;
31002 }
31003 Ok(())
31004 }
31005
31006 fn generate_where(&mut self, e: &Where) -> Result<()> {
31007 self.write_keyword("WHERE");
31009 self.write_space();
31010 self.generate_expression(&e.this)?;
31011 Ok(())
31012 }
31013
31014 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
31015 self.write_keyword("WIDTH_BUCKET");
31017 self.write("(");
31018 self.generate_expression(&e.this)?;
31019 if let Some(min_value) = &e.min_value {
31020 self.write(", ");
31021 self.generate_expression(min_value)?;
31022 }
31023 if let Some(max_value) = &e.max_value {
31024 self.write(", ");
31025 self.generate_expression(max_value)?;
31026 }
31027 if let Some(num_buckets) = &e.num_buckets {
31028 self.write(", ");
31029 self.generate_expression(num_buckets)?;
31030 }
31031 self.write(")");
31032 Ok(())
31033 }
31034
31035 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
31036 self.generate_window_spec(e)
31038 }
31039
31040 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
31041 let mut has_content = false;
31043
31044 if !e.partition_by.is_empty() {
31046 self.write_keyword("PARTITION BY");
31047 self.write_space();
31048 for (i, expr) in e.partition_by.iter().enumerate() {
31049 if i > 0 {
31050 self.write(", ");
31051 }
31052 self.generate_expression(expr)?;
31053 }
31054 has_content = true;
31055 }
31056
31057 if !e.order_by.is_empty() {
31059 if has_content {
31060 self.write_space();
31061 }
31062 self.write_keyword("ORDER BY");
31063 self.write_space();
31064 for (i, ordered) in e.order_by.iter().enumerate() {
31065 if i > 0 {
31066 self.write(", ");
31067 }
31068 self.generate_expression(&ordered.this)?;
31069 if ordered.desc {
31070 self.write_space();
31071 self.write_keyword("DESC");
31072 } else if ordered.explicit_asc {
31073 self.write_space();
31074 self.write_keyword("ASC");
31075 }
31076 if let Some(nulls_first) = ordered.nulls_first {
31077 self.write_space();
31078 self.write_keyword("NULLS");
31079 self.write_space();
31080 if nulls_first {
31081 self.write_keyword("FIRST");
31082 } else {
31083 self.write_keyword("LAST");
31084 }
31085 }
31086 }
31087 has_content = true;
31088 }
31089
31090 if let Some(frame) = &e.frame {
31092 if has_content {
31093 self.write_space();
31094 }
31095 self.generate_window_frame(frame)?;
31096 }
31097
31098 Ok(())
31099 }
31100
31101 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
31102 self.write_keyword("WITH");
31104 self.write_space();
31105 if e.no.is_some() {
31106 self.write_keyword("NO");
31107 self.write_space();
31108 }
31109 self.write_keyword("DATA");
31110
31111 if let Some(statistics) = &e.statistics {
31113 self.write_space();
31114 self.write_keyword("AND");
31115 self.write_space();
31116 match statistics.as_ref() {
31118 Expression::Boolean(b) if !b.value => {
31119 self.write_keyword("NO");
31120 self.write_space();
31121 }
31122 _ => {}
31123 }
31124 self.write_keyword("STATISTICS");
31125 }
31126 Ok(())
31127 }
31128
31129 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
31130 self.write_keyword("WITH FILL");
31132
31133 if let Some(from_) = &e.from_ {
31134 self.write_space();
31135 self.write_keyword("FROM");
31136 self.write_space();
31137 self.generate_expression(from_)?;
31138 }
31139
31140 if let Some(to) = &e.to {
31141 self.write_space();
31142 self.write_keyword("TO");
31143 self.write_space();
31144 self.generate_expression(to)?;
31145 }
31146
31147 if let Some(step) = &e.step {
31148 self.write_space();
31149 self.write_keyword("STEP");
31150 self.write_space();
31151 self.generate_expression(step)?;
31152 }
31153
31154 if let Some(interpolate) = &e.interpolate {
31155 self.write_space();
31156 self.write_keyword("INTERPOLATE");
31157 self.write(" (");
31158 self.generate_interpolate_item(interpolate)?;
31160 self.write(")");
31161 }
31162
31163 Ok(())
31164 }
31165
31166 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
31168 match expr {
31169 Expression::Alias(alias) => {
31170 self.generate_identifier(&alias.alias)?;
31172 self.write_space();
31173 self.write_keyword("AS");
31174 self.write_space();
31175 self.generate_expression(&alias.this)?;
31176 }
31177 Expression::Tuple(tuple) => {
31178 for (i, item) in tuple.expressions.iter().enumerate() {
31179 if i > 0 { self.write(", "); }
31180 self.generate_interpolate_item(item)?;
31181 }
31182 }
31183 other => {
31184 self.generate_expression(other)?;
31185 }
31186 }
31187 Ok(())
31188 }
31189
31190 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
31191 self.write_keyword("WITH JOURNAL TABLE");
31193 self.write("=");
31194 self.generate_expression(&e.this)?;
31195 Ok(())
31196 }
31197
31198 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
31199 self.generate_expression(&e.this)?;
31201 self.write_space();
31202 self.write_keyword("WITH");
31203 self.write_space();
31204 self.write_keyword(&e.op);
31205 Ok(())
31206 }
31207
31208 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
31209 self.write_keyword("WITH");
31211 self.write_space();
31212 for (i, expr) in e.expressions.iter().enumerate() {
31213 if i > 0 {
31214 self.write(", ");
31215 }
31216 self.generate_expression(expr)?;
31217 }
31218 Ok(())
31219 }
31220
31221 fn generate_with_schema_binding_property(&mut self, e: &WithSchemaBindingProperty) -> Result<()> {
31222 self.write_keyword("WITH");
31224 self.write_space();
31225 self.generate_expression(&e.this)?;
31226 Ok(())
31227 }
31228
31229 fn generate_with_system_versioning_property(&mut self, e: &WithSystemVersioningProperty) -> Result<()> {
31230 let mut parts = Vec::new();
31236
31237 if let Some(this) = &e.this {
31238 let mut s = String::from("HISTORY_TABLE=");
31240 let mut gen = Generator::new();
31241 gen.generate_expression(this)?;
31242 s.push_str(&gen.output);
31243 parts.push(s);
31244 }
31245
31246 if let Some(data_consistency) = &e.data_consistency {
31247 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
31248 let mut gen = Generator::new();
31249 gen.generate_expression(data_consistency)?;
31250 s.push_str(&gen.output);
31251 parts.push(s);
31252 }
31253
31254 if let Some(retention_period) = &e.retention_period {
31255 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
31256 let mut gen = Generator::new();
31257 gen.generate_expression(retention_period)?;
31258 s.push_str(&gen.output);
31259 parts.push(s);
31260 }
31261
31262 self.write_keyword("SYSTEM_VERSIONING");
31263 self.write("=");
31264
31265 if !parts.is_empty() {
31266 self.write_keyword("ON");
31267 self.write("(");
31268 self.write(&parts.join(", "));
31269 self.write(")");
31270 } else if e.on.is_some() {
31271 self.write_keyword("ON");
31272 } else {
31273 self.write_keyword("OFF");
31274 }
31275
31276 if e.with_.is_some() {
31278 let inner = self.output.clone();
31279 self.output.clear();
31280 self.write("WITH(");
31281 self.write(&inner);
31282 self.write(")");
31283 }
31284
31285 Ok(())
31286 }
31287
31288 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
31289 self.write_keyword("WITH");
31291 self.write(" (");
31292 for (i, expr) in e.expressions.iter().enumerate() {
31293 if i > 0 {
31294 self.write(", ");
31295 }
31296 self.generate_expression(expr)?;
31297 }
31298 self.write(")");
31299 Ok(())
31300 }
31301
31302 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
31303 self.write_keyword("XMLELEMENT");
31306 self.write("(");
31307
31308 if e.evalname.is_some() {
31309 self.write_keyword("EVALNAME");
31310 } else {
31311 self.write_keyword("NAME");
31312 }
31313 self.write_space();
31314 self.generate_expression(&e.this)?;
31315
31316 for expr in &e.expressions {
31317 self.write(", ");
31318 self.generate_expression(expr)?;
31319 }
31320 self.write(")");
31321 Ok(())
31322 }
31323
31324 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
31325 self.write_keyword("XMLGET");
31327 self.write("(");
31328 self.generate_expression(&e.this)?;
31329 self.write(", ");
31330 self.generate_expression(&e.expression)?;
31331 if let Some(instance) = &e.instance {
31332 self.write(", ");
31333 self.generate_expression(instance)?;
31334 }
31335 self.write(")");
31336 Ok(())
31337 }
31338
31339 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
31340 self.generate_expression(&e.this)?;
31342 if let Some(expression) = &e.expression {
31343 self.write("(");
31344 self.generate_expression(expression)?;
31345 self.write(")");
31346 }
31347 Ok(())
31348 }
31349
31350 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
31351 self.write_keyword("XMLTABLE");
31353 self.write("(");
31354
31355 if self.config.pretty {
31356 self.indent_level += 1;
31357 self.write_newline();
31358 self.write_indent();
31359 self.generate_expression(&e.this)?;
31360
31361 if let Some(passing) = &e.passing {
31362 self.write_newline();
31363 self.write_indent();
31364 self.write_keyword("PASSING");
31365 if let Expression::Tuple(tuple) = passing.as_ref() {
31366 for expr in &tuple.expressions {
31367 self.write_newline();
31368 self.indent_level += 1;
31369 self.write_indent();
31370 self.generate_expression(expr)?;
31371 self.indent_level -= 1;
31372 }
31373 } else {
31374 self.write_newline();
31375 self.indent_level += 1;
31376 self.write_indent();
31377 self.generate_expression(passing)?;
31378 self.indent_level -= 1;
31379 }
31380 }
31381
31382 if e.by_ref.is_some() {
31383 self.write_newline();
31384 self.write_indent();
31385 self.write_keyword("RETURNING SEQUENCE BY REF");
31386 }
31387
31388 if !e.columns.is_empty() {
31389 self.write_newline();
31390 self.write_indent();
31391 self.write_keyword("COLUMNS");
31392 for (i, col) in e.columns.iter().enumerate() {
31393 self.write_newline();
31394 self.indent_level += 1;
31395 self.write_indent();
31396 self.generate_expression(col)?;
31397 self.indent_level -= 1;
31398 if i < e.columns.len() - 1 {
31399 self.write(",");
31400 }
31401 }
31402 }
31403
31404 self.indent_level -= 1;
31405 self.write_newline();
31406 self.write_indent();
31407 self.write(")");
31408 return Ok(());
31409 }
31410
31411 if let Some(namespaces) = &e.namespaces {
31413 self.write_keyword("XMLNAMESPACES");
31414 self.write("(");
31415 if let Expression::Tuple(tuple) = namespaces.as_ref() {
31417 for (i, expr) in tuple.expressions.iter().enumerate() {
31418 if i > 0 {
31419 self.write(", ");
31420 }
31421 if !matches!(expr, Expression::Alias(_)) {
31424 self.write_keyword("DEFAULT");
31425 self.write_space();
31426 }
31427 self.generate_expression(expr)?;
31428 }
31429 } else {
31430 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
31432 self.write_keyword("DEFAULT");
31433 self.write_space();
31434 }
31435 self.generate_expression(namespaces)?;
31436 }
31437 self.write("), ");
31438 }
31439
31440 self.generate_expression(&e.this)?;
31442
31443 if let Some(passing) = &e.passing {
31445 self.write_space();
31446 self.write_keyword("PASSING");
31447 self.write_space();
31448 if let Expression::Tuple(tuple) = passing.as_ref() {
31450 for (i, expr) in tuple.expressions.iter().enumerate() {
31451 if i > 0 {
31452 self.write(", ");
31453 }
31454 self.generate_expression(expr)?;
31455 }
31456 } else {
31457 self.generate_expression(passing)?;
31458 }
31459 }
31460
31461 if e.by_ref.is_some() {
31463 self.write_space();
31464 self.write_keyword("RETURNING SEQUENCE BY REF");
31465 }
31466
31467 if !e.columns.is_empty() {
31469 self.write_space();
31470 self.write_keyword("COLUMNS");
31471 self.write_space();
31472 for (i, col) in e.columns.iter().enumerate() {
31473 if i > 0 {
31474 self.write(", ");
31475 }
31476 self.generate_expression(col)?;
31477 }
31478 }
31479
31480 self.write(")");
31481 Ok(())
31482 }
31483
31484 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
31485 if let Some(this) = &e.this {
31488 self.generate_expression(this)?;
31489 if let Some(expression) = &e.expression {
31490 self.write_space();
31491 self.write_keyword("XOR");
31492 self.write_space();
31493 self.generate_expression(expression)?;
31494 }
31495 }
31496
31497 for (i, expr) in e.expressions.iter().enumerate() {
31499 if i > 0 || e.this.is_some() {
31500 self.write_space();
31501 self.write_keyword("XOR");
31502 self.write_space();
31503 }
31504 self.generate_expression(expr)?;
31505 }
31506 Ok(())
31507 }
31508
31509 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
31510 self.write_keyword("ZIPF");
31512 self.write("(");
31513 self.generate_expression(&e.this)?;
31514 if let Some(elementcount) = &e.elementcount {
31515 self.write(", ");
31516 self.generate_expression(elementcount)?;
31517 }
31518 if let Some(gen) = &e.gen {
31519 self.write(", ");
31520 self.generate_expression(gen)?;
31521 }
31522 self.write(")");
31523 Ok(())
31524 }
31525}
31526
31527impl Default for Generator {
31528 fn default() -> Self {
31529 Self::new()
31530 }
31531}
31532
31533#[cfg(test)]
31534mod tests {
31535 use super::*;
31536 use crate::parser::Parser;
31537
31538 fn roundtrip(sql: &str) -> String {
31539 let ast = Parser::parse_sql(sql).unwrap();
31540 Generator::sql(&ast[0]).unwrap()
31541 }
31542
31543 #[test]
31544 fn test_simple_select() {
31545 let result = roundtrip("SELECT 1");
31546 assert_eq!(result, "SELECT 1");
31547 }
31548
31549 #[test]
31550 fn test_select_from() {
31551 let result = roundtrip("SELECT a, b FROM t");
31552 assert_eq!(result, "SELECT a, b FROM t");
31553 }
31554
31555 #[test]
31556 fn test_select_where() {
31557 let result = roundtrip("SELECT * FROM t WHERE x = 1");
31558 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
31559 }
31560
31561 #[test]
31562 fn test_select_join() {
31563 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
31564 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
31565 }
31566
31567 #[test]
31568 fn test_insert() {
31569 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
31570 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
31571 }
31572
31573 #[test]
31574 fn test_pretty_print() {
31575 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
31576 let result = Generator::pretty_sql(&ast[0]).unwrap();
31577 assert!(result.contains('\n'));
31578 }
31579
31580 #[test]
31581 fn test_window_function() {
31582 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
31583 assert_eq!(result, "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
31584 }
31585
31586 #[test]
31587 fn test_window_function_with_frame() {
31588 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
31589 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
31590 }
31591
31592 #[test]
31593 fn test_aggregate_with_filter() {
31594 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
31595 assert_eq!(result, "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders");
31596 }
31597
31598 #[test]
31599 fn test_subscript() {
31600 let result = roundtrip("SELECT arr[0]");
31601 assert_eq!(result, "SELECT arr[0]");
31602 }
31603
31604 #[test]
31606 fn test_create_table() {
31607 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
31608 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
31609 }
31610
31611 #[test]
31612 fn test_create_table_with_constraints() {
31613 let result = roundtrip("CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)");
31614 assert_eq!(result, "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)");
31615 }
31616
31617 #[test]
31618 fn test_create_table_if_not_exists() {
31619 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
31620 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
31621 }
31622
31623 #[test]
31624 fn test_drop_table() {
31625 let result = roundtrip("DROP TABLE users");
31626 assert_eq!(result, "DROP TABLE users");
31627 }
31628
31629 #[test]
31630 fn test_drop_table_if_exists_cascade() {
31631 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
31632 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
31633 }
31634
31635 #[test]
31636 fn test_alter_table_add_column() {
31637 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
31638 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
31639 }
31640
31641 #[test]
31642 fn test_alter_table_drop_column() {
31643 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
31644 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
31645 }
31646
31647 #[test]
31648 fn test_create_index() {
31649 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
31650 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
31651 }
31652
31653 #[test]
31654 fn test_create_unique_index() {
31655 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
31656 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
31657 }
31658
31659 #[test]
31660 fn test_drop_index() {
31661 let result = roundtrip("DROP INDEX idx_name");
31662 assert_eq!(result, "DROP INDEX idx_name");
31663 }
31664
31665 #[test]
31666 fn test_create_view() {
31667 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
31668 assert_eq!(result, "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
31669 }
31670
31671 #[test]
31672 fn test_drop_view() {
31673 let result = roundtrip("DROP VIEW active_users");
31674 assert_eq!(result, "DROP VIEW active_users");
31675 }
31676
31677 #[test]
31678 fn test_truncate() {
31679 let result = roundtrip("TRUNCATE TABLE users");
31680 assert_eq!(result, "TRUNCATE TABLE users");
31681 }
31682
31683 #[test]
31684 fn test_string_literal_escaping_default() {
31685 let result = roundtrip("SELECT 'hello'");
31687 assert_eq!(result, "SELECT 'hello'");
31688
31689 let result = roundtrip("SELECT 'it''s a test'");
31691 assert_eq!(result, "SELECT 'it''s a test'");
31692 }
31693
31694 #[test]
31695 fn test_string_literal_escaping_mysql() {
31696 use crate::dialects::DialectType;
31697
31698 let config = GeneratorConfig {
31699 dialect: Some(DialectType::MySQL),
31700 ..Default::default()
31701 };
31702
31703 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
31704 let mut gen = Generator::with_config(config.clone());
31705 let result = gen.generate(&ast[0]).unwrap();
31706 assert_eq!(result, "SELECT 'hello'");
31707
31708 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
31710 let mut gen = Generator::with_config(config.clone());
31711 let result = gen.generate(&ast[0]).unwrap();
31712 assert_eq!(result, "SELECT 'it''s'");
31713 }
31714
31715 #[test]
31716 fn test_string_literal_escaping_postgres() {
31717 use crate::dialects::DialectType;
31718
31719 let config = GeneratorConfig {
31720 dialect: Some(DialectType::PostgreSQL),
31721 ..Default::default()
31722 };
31723
31724 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
31725 let mut gen = Generator::with_config(config.clone());
31726 let result = gen.generate(&ast[0]).unwrap();
31727 assert_eq!(result, "SELECT 'hello'");
31728
31729 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
31731 let mut gen = Generator::with_config(config.clone());
31732 let result = gen.generate(&ast[0]).unwrap();
31733 assert_eq!(result, "SELECT 'it''s'");
31734 }
31735
31736 #[test]
31737 fn test_string_literal_escaping_bigquery() {
31738 use crate::dialects::DialectType;
31739
31740 let config = GeneratorConfig {
31741 dialect: Some(DialectType::BigQuery),
31742 ..Default::default()
31743 };
31744
31745 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
31746 let mut gen = Generator::with_config(config.clone());
31747 let result = gen.generate(&ast[0]).unwrap();
31748 assert_eq!(result, "SELECT 'hello'");
31749
31750 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
31752 let mut gen = Generator::with_config(config.clone());
31753 let result = gen.generate(&ast[0]).unwrap();
31754 assert_eq!(result, "SELECT 'it\\'s'");
31755 }
31756
31757}