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::Nullable { inner } => {
19348 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
19350 self.write("Nullable(");
19351 self.generate_data_type(inner)?;
19352 self.write(")");
19353 } else {
19354 match inner.as_ref() {
19356 DataType::Custom { name } if name.to_uppercase() == "DATETIME" => {
19357 self.generate_data_type(&DataType::Timestamp { precision: None, timezone: false })?;
19358 }
19359 _ => {
19360 self.generate_data_type(inner)?;
19361 }
19362 }
19363 }
19364 }
19365 DataType::Custom { name } => {
19366 let name_upper = name.to_uppercase();
19368 match self.config.dialect {
19369 Some(DialectType::ClickHouse) => {
19370 let (base_upper, suffix) = if let Some(idx) = name.find('(') {
19371 (name_upper[..idx].to_string(), &name[idx..])
19372 } else {
19373 (name_upper.clone(), "")
19374 };
19375 let mapped = match base_upper.as_str() {
19376 "DATETIME" | "TIMESTAMPTZ" | "TIMESTAMP" | "TIMESTAMPNTZ" | "SMALLDATETIME" | "DATETIME2" => "DateTime",
19377 "DATETIME64" => "DateTime64",
19378 "DATE32" => "Date32",
19379 "INT" => "Int32",
19380 "MEDIUMINT" => "Int32",
19381 "INT8" => "Int8",
19382 "INT16" => "Int16",
19383 "INT32" => "Int32",
19384 "INT64" => "Int64",
19385 "INT128" => "Int128",
19386 "INT256" => "Int256",
19387 "UINT8" => "UInt8",
19388 "UINT16" => "UInt16",
19389 "UINT32" => "UInt32",
19390 "UINT64" => "UInt64",
19391 "UINT128" => "UInt128",
19392 "UINT256" => "UInt256",
19393 "FLOAT32" => "Float32",
19394 "FLOAT64" => "Float64",
19395 "DECIMAL32" => "Decimal32",
19396 "DECIMAL64" => "Decimal64",
19397 "DECIMAL128" => "Decimal128",
19398 "DECIMAL256" => "Decimal256",
19399 "ENUM" => "Enum",
19400 "ENUM8" => "Enum8",
19401 "ENUM16" => "Enum16",
19402 "FIXEDSTRING" => "FixedString",
19403 "NESTED" => "Nested",
19404 "LOWCARDINALITY" => "LowCardinality",
19405 "NULLABLE" => "Nullable",
19406 "IPV4" => "IPv4",
19407 "IPV6" => "IPv6",
19408 "POINT" => "Point",
19409 "RING" => "Ring",
19410 "LINESTRING" => "LineString",
19411 "MULTILINESTRING" => "MultiLineString",
19412 "POLYGON" => "Polygon",
19413 "MULTIPOLYGON" => "MultiPolygon",
19414 "AGGREGATEFUNCTION" => "AggregateFunction",
19415 "SIMPLEAGGREGATEFUNCTION" => "SimpleAggregateFunction",
19416 "DYNAMIC" => "Dynamic",
19417 _ => "",
19418 };
19419 if mapped.is_empty() {
19420 self.write(name);
19421 } else {
19422 self.write(mapped);
19423 self.write(suffix);
19424 }
19425 }
19426 Some(DialectType::MySQL) if name_upper == "TIMESTAMPTZ" || name_upper == "TIMESTAMPLTZ" => {
19427 self.write_keyword("TIMESTAMP");
19429 }
19430 Some(DialectType::TSQL) if name_upper == "VARIANT" => {
19431 self.write_keyword("SQL_VARIANT");
19432 }
19433 Some(DialectType::DuckDB) if name_upper == "DECFLOAT" => {
19434 self.write_keyword("DECIMAL(38, 5)");
19435 }
19436 Some(DialectType::Exasol) => {
19437 match name_upper.as_str() {
19439 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => self.write_keyword("VARCHAR"),
19441 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => self.write_keyword("VARCHAR"),
19443 "MEDIUMINT" => self.write_keyword("INT"),
19445 "DECIMAL32" | "DECIMAL64" | "DECIMAL128" | "DECIMAL256" => self.write_keyword("DECIMAL"),
19447 "DATETIME" => self.write_keyword("TIMESTAMP"),
19449 "TIMESTAMPLTZ" => self.write_keyword("TIMESTAMP WITH LOCAL TIME ZONE"),
19450 _ => self.write(name),
19451 }
19452 }
19453 Some(DialectType::Dremio) => {
19454 match name_upper.as_str() {
19456 "TIMESTAMPNTZ" | "DATETIME" => self.write_keyword("TIMESTAMP"),
19457 "ARRAY" => self.write_keyword("LIST"),
19458 "NCHAR" => self.write_keyword("VARCHAR"),
19459 _ => self.write(name),
19460 }
19461 }
19462 _ => {
19464 let (base_upper, _args_str) = if let Some(idx) = name_upper.find('(') {
19466 (name_upper[..idx].to_string(), Some(&name[idx..]))
19467 } else {
19468 (name_upper.clone(), None)
19469 };
19470
19471 match base_upper.as_str() {
19472 "INT64" if !matches!(self.config.dialect, Some(DialectType::BigQuery)) => {
19473 self.write_keyword("BIGINT");
19474 }
19475 "FLOAT64" if !matches!(self.config.dialect, Some(DialectType::BigQuery)) => {
19476 self.write_keyword("DOUBLE");
19477 }
19478 "BOOL" if !matches!(self.config.dialect, Some(DialectType::BigQuery)) => {
19479 self.write_keyword("BOOLEAN");
19480 }
19481 "BYTES" if matches!(self.config.dialect, Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)) => {
19482 self.write_keyword("BINARY");
19483 }
19484 "BYTES" if !matches!(self.config.dialect, Some(DialectType::BigQuery)) => {
19485 self.write_keyword("VARBINARY");
19486 }
19487 "DATETIME2" | "SMALLDATETIME" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) => {
19489 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) {
19491 self.write_keyword("TIMESTAMP");
19492 if let Some(args) = _args_str {
19493 self.write(args);
19494 }
19495 } else {
19496 self.write_keyword("TIMESTAMP");
19497 }
19498 }
19499 "DATETIMEOFFSET" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) => {
19501 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) {
19502 self.write_keyword("TIMESTAMPTZ");
19503 if let Some(args) = _args_str {
19504 self.write(args);
19505 }
19506 } else {
19507 self.write_keyword("TIMESTAMPTZ");
19508 }
19509 }
19510 "UNIQUEIDENTIFIER" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) => {
19512 match self.config.dialect {
19513 Some(DialectType::Spark) | Some(DialectType::Databricks)
19514 | Some(DialectType::Hive) => self.write_keyword("STRING"),
19515 _ => self.write_keyword("UUID"),
19516 }
19517 }
19518 "BIT" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)
19520 | Some(DialectType::PostgreSQL) | Some(DialectType::MySQL) | Some(DialectType::DuckDB)) => {
19521 self.write_keyword("BOOLEAN");
19522 }
19523 "NVARCHAR" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) => {
19525 match self.config.dialect {
19526 Some(DialectType::SQLite) => {
19527 self.write_keyword("TEXT");
19528 if let Some(args) = _args_str {
19529 self.write(args);
19530 }
19531 }
19532 Some(DialectType::Spark) | Some(DialectType::Databricks)
19533 | Some(DialectType::Hive) => {
19534 if _args_str.is_some() {
19535 self.write_keyword("VARCHAR");
19536 self.write(_args_str.unwrap());
19537 } else {
19538 self.write_keyword("VARCHAR(30)");
19539 }
19540 }
19541 _ => {
19542 self.write_keyword("VARCHAR");
19543 if let Some(args) = _args_str {
19544 self.write(args);
19545 }
19546 }
19547 }
19548 }
19549 "NCHAR" if !matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) => {
19551 match self.config.dialect {
19552 Some(DialectType::Spark) | Some(DialectType::Databricks)
19553 | Some(DialectType::Hive) => {
19554 if _args_str.is_some() {
19555 self.write_keyword("CHAR");
19556 self.write(_args_str.unwrap());
19557 } else {
19558 self.write_keyword("CHAR(30)");
19559 }
19560 }
19561 _ => {
19562 self.write_keyword("CHAR");
19563 if let Some(args) = _args_str {
19564 self.write(args);
19565 }
19566 }
19567 }
19568 }
19569 "LONGTEXT" | "MEDIUMTEXT" | "TINYTEXT" => {
19572 match self.config.dialect {
19573 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
19574 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => self.write_keyword("TEXT"),
19575 Some(DialectType::BigQuery) => self.write_keyword("STRING"),
19576 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => self.write_keyword("VARCHAR"),
19577 Some(DialectType::Snowflake) | Some(DialectType::Redshift) | Some(DialectType::Dremio) => self.write_keyword("VARCHAR"),
19578 _ => self.write_keyword("TEXT"),
19579 }
19580 }
19581 "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => {
19584 match self.config.dialect {
19585 Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::TiDB) => self.write_keyword(&base_upper),
19586 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => self.write_keyword("BLOB"),
19587 Some(DialectType::DuckDB) => self.write_keyword("VARBINARY"),
19588 Some(DialectType::BigQuery) => self.write_keyword("BYTES"),
19589 Some(DialectType::Presto) | Some(DialectType::Trino) | Some(DialectType::Athena) => self.write_keyword("VARBINARY"),
19590 Some(DialectType::Snowflake) | Some(DialectType::Redshift) | Some(DialectType::Dremio) => self.write_keyword("VARBINARY"),
19591 _ => self.write_keyword("BLOB"),
19592 }
19593 }
19594 "LONGVARCHAR" => {
19596 match self.config.dialect {
19597 Some(DialectType::SQLite) => self.write_keyword("TEXT"),
19598 _ => self.write_keyword("VARCHAR"),
19599 }
19600 }
19601 _ => self.write(name),
19602 }
19603 }
19604 }
19605 }
19606 DataType::Geometry { subtype, srid } => {
19607 match self.config.dialect {
19609 Some(DialectType::MySQL) => {
19610 if let Some(sub) = subtype {
19612 self.write_keyword(sub);
19613 if let Some(s) = srid {
19614 self.write(" SRID ");
19615 self.write(&s.to_string());
19616 }
19617 } else {
19618 self.write_keyword("GEOMETRY");
19619 }
19620 }
19621 Some(DialectType::BigQuery) => {
19622 self.write_keyword("GEOGRAPHY");
19624 }
19625 Some(DialectType::Teradata) => {
19626 self.write_keyword("ST_GEOMETRY");
19628 if subtype.is_some() || srid.is_some() {
19629 self.write("(");
19630 if let Some(sub) = subtype {
19631 self.write_keyword(sub);
19632 }
19633 if let Some(s) = srid {
19634 if subtype.is_some() {
19635 self.write(", ");
19636 }
19637 self.write(&s.to_string());
19638 }
19639 self.write(")");
19640 }
19641 }
19642 _ => {
19643 self.write_keyword("GEOMETRY");
19645 if subtype.is_some() || srid.is_some() {
19646 self.write("(");
19647 if let Some(sub) = subtype {
19648 self.write_keyword(sub);
19649 }
19650 if let Some(s) = srid {
19651 if subtype.is_some() {
19652 self.write(", ");
19653 }
19654 self.write(&s.to_string());
19655 }
19656 self.write(")");
19657 }
19658 }
19659 }
19660 }
19661 DataType::Geography { subtype, srid } => {
19662 match self.config.dialect {
19664 Some(DialectType::MySQL) => {
19665 if let Some(sub) = subtype {
19667 self.write_keyword(sub);
19668 } else {
19669 self.write_keyword("GEOMETRY");
19670 }
19671 let effective_srid = srid.unwrap_or(4326);
19673 self.write(" SRID ");
19674 self.write(&effective_srid.to_string());
19675 }
19676 Some(DialectType::BigQuery) => {
19677 self.write_keyword("GEOGRAPHY");
19679 }
19680 Some(DialectType::Snowflake) => {
19681 self.write_keyword("GEOGRAPHY");
19683 }
19684 _ => {
19685 self.write_keyword("GEOGRAPHY");
19687 if subtype.is_some() || srid.is_some() {
19688 self.write("(");
19689 if let Some(sub) = subtype {
19690 self.write_keyword(sub);
19691 }
19692 if let Some(s) = srid {
19693 if subtype.is_some() {
19694 self.write(", ");
19695 }
19696 self.write(&s.to_string());
19697 }
19698 self.write(")");
19699 }
19700 }
19701 }
19702 }
19703 DataType::CharacterSet { name } => {
19704 self.write_keyword("CHAR CHARACTER SET ");
19706 self.write(name);
19707 }
19708 _ => self.write("UNKNOWN"),
19709 }
19710 Ok(())
19711 }
19712
19713 fn write(&mut self, s: &str) {
19716 self.output.push_str(s);
19717 }
19718
19719 fn write_space(&mut self) {
19720 self.output.push(' ');
19721 }
19722
19723 fn write_keyword(&mut self, keyword: &str) {
19724 if self.config.uppercase_keywords {
19725 self.output.push_str(keyword);
19726 } else {
19727 self.output.push_str(&keyword.to_lowercase());
19728 }
19729 }
19730
19731 fn convert_strptime_to_exasol_format(format: &str) -> String {
19735 let mut result = String::new();
19736 let chars: Vec<char> = format.chars().collect();
19737 let mut i = 0;
19738 while i < chars.len() {
19739 if chars[i] == '%' && i + 1 < chars.len() {
19740 let spec = chars[i + 1];
19741 let exasol_spec = match spec {
19742 'Y' => "YYYY",
19743 'y' => "YY",
19744 'm' => "MM",
19745 'd' => "DD",
19746 'H' => "HH",
19747 'M' => "MI",
19748 'S' => "SS",
19749 'a' => "DY", 'A' => "DAY", 'b' => "MON", 'B' => "MONTH", 'I' => "H12", 'u' => "ID", 'V' => "IW", 'G' => "IYYY", 'W' => "UW", 'U' => "UW", 'z' => "Z", _ => {
19761 result.push('%');
19763 result.push(spec);
19764 i += 2;
19765 continue;
19766 }
19767 };
19768 result.push_str(exasol_spec);
19769 i += 2;
19770 } else {
19771 result.push(chars[i]);
19772 i += 1;
19773 }
19774 }
19775 result
19776 }
19777
19778 fn convert_strptime_to_postgres_format(format: &str) -> String {
19782 let mut result = String::new();
19783 let chars: Vec<char> = format.chars().collect();
19784 let mut i = 0;
19785 while i < chars.len() {
19786 if chars[i] == '%' && i + 1 < chars.len() {
19787 let spec = chars[i + 1];
19788 let pg_spec = match spec {
19789 'Y' => "YYYY",
19790 'y' => "YY",
19791 'm' => "MM",
19792 'd' => "DD",
19793 'H' => "HH24",
19794 'I' => "HH12",
19795 'M' => "MI",
19796 'S' => "SS",
19797 'f' => "US", 'u' => "D", 'j' => "DDD", 'z' => "OF", 'Z' => "TZ", 'A' => "TMDay", 'a' => "TMDy", 'b' => "TMMon", 'B' => "TMMonth", 'U' => "WW", _ => {
19808 result.push('%');
19810 result.push(spec);
19811 i += 2;
19812 continue;
19813 }
19814 };
19815 result.push_str(pg_spec);
19816 i += 2;
19817 } else {
19818 result.push(chars[i]);
19819 i += 1;
19820 }
19821 }
19822 result
19823 }
19824
19825 fn write_limit_expr(&mut self, expr: &Expression) -> Result<()> {
19827 if self.config.limit_only_literals {
19828 if let Some(value) = Self::try_evaluate_constant(expr) {
19829 self.write(&value.to_string());
19830 return Ok(());
19831 }
19832 }
19833 self.generate_expression(expr)
19834 }
19835
19836 fn write_formatted_comment(&mut self, comment: &str) {
19840 let content = if comment.starts_with("/*") && comment.ends_with("*/") {
19843 comment[2..comment.len() - 2].trim()
19845 } else if comment.starts_with("--") {
19846 comment[2..].trim()
19848 } else {
19849 comment.trim()
19851 };
19852 self.output.push_str("/* ");
19853 self.output.push_str(content);
19854 self.output.push_str(" */");
19855 }
19856
19857 fn escape_block_for_single_quote(&self, block: &str) -> String {
19860 let escape_backslash = matches!(
19861 self.config.dialect,
19862 Some(crate::dialects::DialectType::Snowflake)
19863 );
19864 let mut escaped = String::with_capacity(block.len() + 4);
19865 for ch in block.chars() {
19866 if ch == '\'' {
19867 escaped.push('\\');
19868 escaped.push('\'');
19869 } else if escape_backslash && ch == '\\' {
19870 escaped.push('\\');
19871 escaped.push('\\');
19872 } else {
19873 escaped.push(ch);
19874 }
19875 }
19876 escaped
19877 }
19878
19879 fn write_newline(&mut self) {
19880 self.output.push('\n');
19881 }
19882
19883 fn write_indent(&mut self) {
19884 for _ in 0..self.indent_level {
19885 self.output.push_str(&self.config.indent);
19886 }
19887 }
19888
19889 fn too_wide(&self, args: &[String]) -> bool {
19895 args.iter().map(|s| s.len()).sum::<usize>() > self.config.max_text_width
19896 }
19897
19898 fn write_clause_condition(&mut self, keyword: &str, condition: &Expression) -> Result<()> {
19901 if self.config.pretty {
19902 self.write_newline();
19903 self.write_indent();
19904 self.write_keyword(keyword);
19905 self.write_newline();
19906 self.indent_level += 1;
19907 self.write_indent();
19908 self.generate_expression(condition)?;
19909 self.indent_level -= 1;
19910 } else {
19911 self.write_space();
19912 self.write_keyword(keyword);
19913 self.write_space();
19914 self.generate_expression(condition)?;
19915 }
19916 Ok(())
19917 }
19918
19919 fn write_clause_expressions(&mut self, keyword: &str, exprs: &[Expression]) -> Result<()> {
19922 if exprs.is_empty() {
19923 return Ok(());
19924 }
19925
19926 if self.config.pretty {
19927 self.write_newline();
19928 self.write_indent();
19929 self.write_keyword(keyword);
19930 self.write_newline();
19931 self.indent_level += 1;
19932 for (i, expr) in exprs.iter().enumerate() {
19933 if i > 0 {
19934 self.write(",");
19935 self.write_newline();
19936 }
19937 self.write_indent();
19938 self.generate_expression(expr)?;
19939 }
19940 self.indent_level -= 1;
19941 } else {
19942 self.write_space();
19943 self.write_keyword(keyword);
19944 self.write_space();
19945 for (i, expr) in exprs.iter().enumerate() {
19946 if i > 0 {
19947 self.write(", ");
19948 }
19949 self.generate_expression(expr)?;
19950 }
19951 }
19952 Ok(())
19953 }
19954
19955 fn write_order_clause(&mut self, keyword: &str, orderings: &[Ordered]) -> Result<()> {
19957 if orderings.is_empty() {
19958 return Ok(());
19959 }
19960
19961 if self.config.pretty {
19962 self.write_newline();
19963 self.write_indent();
19964 self.write_keyword(keyword);
19965 self.write_newline();
19966 self.indent_level += 1;
19967 for (i, ordered) in orderings.iter().enumerate() {
19968 if i > 0 {
19969 self.write(",");
19970 self.write_newline();
19971 }
19972 self.write_indent();
19973 self.generate_ordered(ordered)?;
19974 }
19975 self.indent_level -= 1;
19976 } else {
19977 self.write_space();
19978 self.write_keyword(keyword);
19979 self.write_space();
19980 for (i, ordered) in orderings.iter().enumerate() {
19981 if i > 0 {
19982 self.write(", ");
19983 }
19984 self.generate_ordered(ordered)?;
19985 }
19986 }
19987 Ok(())
19988 }
19989
19990 fn write_window_clause(&mut self, windows: &[NamedWindow]) -> Result<()> {
19992 if windows.is_empty() {
19993 return Ok(());
19994 }
19995
19996 if self.config.pretty {
19997 self.write_newline();
19998 self.write_indent();
19999 self.write_keyword("WINDOW");
20000 self.write_newline();
20001 self.indent_level += 1;
20002 for (i, named_window) in windows.iter().enumerate() {
20003 if i > 0 {
20004 self.write(",");
20005 self.write_newline();
20006 }
20007 self.write_indent();
20008 self.generate_identifier(&named_window.name)?;
20009 self.write_space();
20010 self.write_keyword("AS");
20011 self.write(" (");
20012 self.generate_over(&named_window.spec)?;
20013 self.write(")");
20014 }
20015 self.indent_level -= 1;
20016 } else {
20017 self.write_space();
20018 self.write_keyword("WINDOW");
20019 self.write_space();
20020 for (i, named_window) in windows.iter().enumerate() {
20021 if i > 0 {
20022 self.write(", ");
20023 }
20024 self.generate_identifier(&named_window.name)?;
20025 self.write_space();
20026 self.write_keyword("AS");
20027 self.write(" (");
20028 self.generate_over(&named_window.spec)?;
20029 self.write(")");
20030 }
20031 }
20032 Ok(())
20033 }
20034
20035 fn generate_ai_agg(&mut self, e: &AIAgg) -> Result<()> {
20037 self.write_keyword("AI_AGG");
20039 self.write("(");
20040 self.generate_expression(&e.this)?;
20041 self.write(", ");
20042 self.generate_expression(&e.expression)?;
20043 self.write(")");
20044 Ok(())
20045 }
20046
20047 fn generate_ai_classify(&mut self, e: &AIClassify) -> Result<()> {
20048 self.write_keyword("AI_CLASSIFY");
20050 self.write("(");
20051 self.generate_expression(&e.this)?;
20052 if let Some(categories) = &e.categories {
20053 self.write(", ");
20054 self.generate_expression(categories)?;
20055 }
20056 if let Some(config) = &e.config {
20057 self.write(", ");
20058 self.generate_expression(config)?;
20059 }
20060 self.write(")");
20061 Ok(())
20062 }
20063
20064 fn generate_add_partition(&mut self, e: &AddPartition) -> Result<()> {
20065 self.write_keyword("ADD");
20067 self.write_space();
20068 if e.exists {
20069 self.write_keyword("IF NOT EXISTS");
20070 self.write_space();
20071 }
20072 self.generate_expression(&e.this)?;
20073 if let Some(location) = &e.location {
20074 self.write_space();
20075 self.generate_expression(location)?;
20076 }
20077 Ok(())
20078 }
20079
20080 fn generate_algorithm_property(&mut self, e: &AlgorithmProperty) -> Result<()> {
20081 self.write_keyword("ALGORITHM");
20083 self.write("=");
20084 self.generate_expression(&e.this)?;
20085 Ok(())
20086 }
20087
20088 fn generate_aliases(&mut self, e: &Aliases) -> Result<()> {
20089 self.generate_expression(&e.this)?;
20091 self.write_space();
20092 self.write_keyword("AS");
20093 self.write(" (");
20094 for (i, expr) in e.expressions.iter().enumerate() {
20095 if i > 0 {
20096 self.write(", ");
20097 }
20098 self.generate_expression(expr)?;
20099 }
20100 self.write(")");
20101 Ok(())
20102 }
20103
20104 fn generate_allowed_values_property(&mut self, e: &AllowedValuesProperty) -> Result<()> {
20105 self.write_keyword("ALLOWED_VALUES");
20107 self.write_space();
20108 for (i, expr) in e.expressions.iter().enumerate() {
20109 if i > 0 {
20110 self.write(", ");
20111 }
20112 self.generate_expression(expr)?;
20113 }
20114 Ok(())
20115 }
20116
20117 fn generate_alter_column(&mut self, e: &AlterColumn) -> Result<()> {
20118 self.write_keyword("ALTER COLUMN");
20120 self.write_space();
20121 self.generate_expression(&e.this)?;
20122
20123 if let Some(dtype) = &e.dtype {
20124 self.write_space();
20125 self.write_keyword("SET DATA TYPE");
20126 self.write_space();
20127 self.generate_expression(dtype)?;
20128 if let Some(collate) = &e.collate {
20129 self.write_space();
20130 self.write_keyword("COLLATE");
20131 self.write_space();
20132 self.generate_expression(collate)?;
20133 }
20134 if let Some(using) = &e.using {
20135 self.write_space();
20136 self.write_keyword("USING");
20137 self.write_space();
20138 self.generate_expression(using)?;
20139 }
20140 } else if let Some(default) = &e.default {
20141 self.write_space();
20142 self.write_keyword("SET DEFAULT");
20143 self.write_space();
20144 self.generate_expression(default)?;
20145 } else if let Some(comment) = &e.comment {
20146 self.write_space();
20147 self.write_keyword("COMMENT");
20148 self.write_space();
20149 self.generate_expression(comment)?;
20150 } else if let Some(drop) = &e.drop {
20151 self.write_space();
20152 self.write_keyword("DROP");
20153 self.write_space();
20154 self.generate_expression(drop)?;
20155 } else if let Some(visible) = &e.visible {
20156 self.write_space();
20157 self.generate_expression(visible)?;
20158 } else if let Some(rename_to) = &e.rename_to {
20159 self.write_space();
20160 self.write_keyword("RENAME TO");
20161 self.write_space();
20162 self.generate_expression(rename_to)?;
20163 } else if let Some(allow_null) = &e.allow_null {
20164 self.write_space();
20165 self.generate_expression(allow_null)?;
20166 }
20167 Ok(())
20168 }
20169
20170 fn generate_alter_session(&mut self, e: &AlterSession) -> Result<()> {
20171 self.write_keyword("ALTER SESSION");
20173 self.write_space();
20174 if e.unset.is_some() {
20175 self.write_keyword("UNSET");
20176 } else {
20177 self.write_keyword("SET");
20178 }
20179 self.write_space();
20180 for (i, expr) in e.expressions.iter().enumerate() {
20181 if i > 0 {
20182 self.write(", ");
20183 }
20184 self.generate_expression(expr)?;
20185 }
20186 Ok(())
20187 }
20188
20189 fn generate_alter_set(&mut self, e: &AlterSet) -> Result<()> {
20190 self.write_keyword("SET");
20192
20193 if let Some(opt) = &e.option {
20195 self.write_space();
20196 self.generate_expression(opt)?;
20197 }
20198
20199 if !e.expressions.is_empty() {
20202 let is_properties = e.expressions.iter().any(|expr| matches!(expr, Expression::Eq(_)));
20204 if is_properties && e.option.is_none() {
20205 self.write_space();
20206 self.write_keyword("PROPERTIES");
20207 }
20208 self.write_space();
20209 for (i, expr) in e.expressions.iter().enumerate() {
20210 if i > 0 {
20211 self.write(", ");
20212 }
20213 self.generate_expression(expr)?;
20214 }
20215 }
20216
20217 if let Some(file_format) = &e.file_format {
20219 self.write(" ");
20220 self.write_keyword("STAGE_FILE_FORMAT");
20221 self.write(" = (");
20222 self.generate_space_separated_properties(file_format)?;
20223 self.write(")");
20224 }
20225
20226 if let Some(copy_options) = &e.copy_options {
20228 self.write(" ");
20229 self.write_keyword("STAGE_COPY_OPTIONS");
20230 self.write(" = (");
20231 self.generate_space_separated_properties(copy_options)?;
20232 self.write(")");
20233 }
20234
20235 if let Some(tag) = &e.tag {
20237 self.write(" ");
20238 self.write_keyword("TAG");
20239 self.write(" ");
20240 self.generate_expression(tag)?;
20241 }
20242
20243 Ok(())
20244 }
20245
20246 fn generate_space_separated_properties(&mut self, expr: &Expression) -> Result<()> {
20248 match expr {
20249 Expression::Tuple(t) => {
20250 for (i, prop) in t.expressions.iter().enumerate() {
20251 if i > 0 {
20252 self.write(" ");
20253 }
20254 self.generate_expression(prop)?;
20255 }
20256 }
20257 _ => {
20258 self.generate_expression(expr)?;
20259 }
20260 }
20261 Ok(())
20262 }
20263
20264 fn generate_alter_sort_key(&mut self, e: &AlterSortKey) -> Result<()> {
20265 self.write_keyword("ALTER");
20267 if e.compound.is_some() {
20268 self.write_space();
20269 self.write_keyword("COMPOUND");
20270 }
20271 self.write_space();
20272 self.write_keyword("SORTKEY");
20273 self.write_space();
20274 if let Some(this) = &e.this {
20275 self.generate_expression(this)?;
20276 } else if !e.expressions.is_empty() {
20277 self.write("(");
20278 for (i, expr) in e.expressions.iter().enumerate() {
20279 if i > 0 {
20280 self.write(", ");
20281 }
20282 self.generate_expression(expr)?;
20283 }
20284 self.write(")");
20285 }
20286 Ok(())
20287 }
20288
20289 fn generate_analyze(&mut self, e: &Analyze) -> Result<()> {
20290 self.write_keyword("ANALYZE");
20292 if !e.options.is_empty() {
20293 self.write_space();
20294 for (i, opt) in e.options.iter().enumerate() {
20295 if i > 0 {
20296 self.write_space();
20297 }
20298 if let Expression::Identifier(id) = opt {
20300 self.write_keyword(&id.name);
20301 } else {
20302 self.generate_expression(opt)?;
20303 }
20304 }
20305 }
20306 if let Some(kind) = &e.kind {
20307 self.write_space();
20308 self.write_keyword(kind);
20309 }
20310 if let Some(this) = &e.this {
20311 self.write_space();
20312 self.generate_expression(this)?;
20313 }
20314 if !e.columns.is_empty() {
20316 self.write("(");
20317 for (i, col) in e.columns.iter().enumerate() {
20318 if i > 0 {
20319 self.write(", ");
20320 }
20321 self.write(col);
20322 }
20323 self.write(")");
20324 }
20325 if let Some(partition) = &e.partition {
20326 self.write_space();
20327 self.generate_expression(partition)?;
20328 }
20329 if let Some(mode) = &e.mode {
20330 self.write_space();
20331 self.generate_expression(mode)?;
20332 }
20333 if let Some(expression) = &e.expression {
20334 self.write_space();
20335 self.generate_expression(expression)?;
20336 }
20337 if !e.properties.is_empty() {
20338 self.write_space();
20339 self.write_keyword(self.config.with_properties_prefix);
20340 self.write(" (");
20341 for (i, prop) in e.properties.iter().enumerate() {
20342 if i > 0 {
20343 self.write(", ");
20344 }
20345 self.generate_expression(prop)?;
20346 }
20347 self.write(")");
20348 }
20349 Ok(())
20350 }
20351
20352 fn generate_analyze_delete(&mut self, e: &AnalyzeDelete) -> Result<()> {
20353 self.write_keyword("DELETE");
20355 if let Some(kind) = &e.kind {
20356 self.write_space();
20357 self.write_keyword(kind);
20358 }
20359 self.write_space();
20360 self.write_keyword("STATISTICS");
20361 Ok(())
20362 }
20363
20364 fn generate_analyze_histogram(&mut self, e: &AnalyzeHistogram) -> Result<()> {
20365 if let Expression::Identifier(id) = e.this.as_ref() {
20368 self.write_keyword(&id.name);
20369 } else {
20370 self.generate_expression(&e.this)?;
20371 }
20372 self.write_space();
20373 self.write_keyword("HISTOGRAM ON");
20374 self.write_space();
20375 for (i, expr) in e.expressions.iter().enumerate() {
20376 if i > 0 {
20377 self.write(", ");
20378 }
20379 self.generate_expression(expr)?;
20380 }
20381 if let Some(expression) = &e.expression {
20382 self.write_space();
20383 self.generate_expression(expression)?;
20384 }
20385 if let Some(update_options) = &e.update_options {
20386 self.write_space();
20387 self.generate_expression(update_options)?;
20388 self.write_space();
20389 self.write_keyword("UPDATE");
20390 }
20391 Ok(())
20392 }
20393
20394 fn generate_analyze_list_chained_rows(&mut self, e: &AnalyzeListChainedRows) -> Result<()> {
20395 self.write_keyword("LIST CHAINED ROWS");
20397 if let Some(expression) = &e.expression {
20398 self.write_space();
20399 self.write_keyword("INTO");
20400 self.write_space();
20401 self.generate_expression(expression)?;
20402 }
20403 Ok(())
20404 }
20405
20406 fn generate_analyze_sample(&mut self, e: &AnalyzeSample) -> Result<()> {
20407 self.write_keyword("SAMPLE");
20409 self.write_space();
20410 if let Some(sample) = &e.sample {
20411 self.generate_expression(sample)?;
20412 self.write_space();
20413 }
20414 self.write_keyword(&e.kind);
20415 Ok(())
20416 }
20417
20418 fn generate_analyze_statistics(&mut self, e: &AnalyzeStatistics) -> Result<()> {
20419 self.write_keyword(&e.kind);
20421 if let Some(option) = &e.option {
20422 self.write_space();
20423 self.generate_expression(option)?;
20424 }
20425 self.write_space();
20426 self.write_keyword("STATISTICS");
20427 if let Some(this) = &e.this {
20428 self.write_space();
20429 self.generate_expression(this)?;
20430 }
20431 if !e.expressions.is_empty() {
20432 self.write_space();
20433 for (i, expr) in e.expressions.iter().enumerate() {
20434 if i > 0 {
20435 self.write(", ");
20436 }
20437 self.generate_expression(expr)?;
20438 }
20439 }
20440 Ok(())
20441 }
20442
20443 fn generate_analyze_validate(&mut self, e: &AnalyzeValidate) -> Result<()> {
20444 self.write_keyword("VALIDATE");
20446 self.write_space();
20447 self.write_keyword(&e.kind);
20448 if let Some(this) = &e.this {
20449 self.write_space();
20450 if let Expression::Identifier(id) = this.as_ref() {
20452 self.write_keyword(&id.name);
20453 } else {
20454 self.generate_expression(this)?;
20455 }
20456 }
20457 if let Some(expression) = &e.expression {
20458 self.write_space();
20459 self.write_keyword("INTO");
20460 self.write_space();
20461 self.generate_expression(expression)?;
20462 }
20463 Ok(())
20464 }
20465
20466 fn generate_analyze_with(&mut self, e: &AnalyzeWith) -> Result<()> {
20467 self.write_keyword("WITH");
20469 self.write_space();
20470 for (i, expr) in e.expressions.iter().enumerate() {
20471 if i > 0 {
20472 self.write(", ");
20473 }
20474 self.generate_expression(expr)?;
20475 }
20476 Ok(())
20477 }
20478
20479 fn generate_anonymous(&mut self, e: &Anonymous) -> Result<()> {
20480 self.generate_expression(&e.this)?;
20483 self.write("(");
20484 for (i, arg) in e.expressions.iter().enumerate() {
20485 if i > 0 {
20486 self.write(", ");
20487 }
20488 self.generate_expression(arg)?;
20489 }
20490 self.write(")");
20491 Ok(())
20492 }
20493
20494 fn generate_anonymous_agg_func(&mut self, e: &AnonymousAggFunc) -> Result<()> {
20495 self.generate_expression(&e.this)?;
20497 self.write("(");
20498 for (i, arg) in e.expressions.iter().enumerate() {
20499 if i > 0 {
20500 self.write(", ");
20501 }
20502 self.generate_expression(arg)?;
20503 }
20504 self.write(")");
20505 Ok(())
20506 }
20507
20508 fn generate_apply(&mut self, e: &Apply) -> Result<()> {
20509 self.generate_expression(&e.this)?;
20511 self.write_space();
20512 self.write_keyword("APPLY");
20513 self.write("(");
20514 self.generate_expression(&e.expression)?;
20515 self.write(")");
20516 Ok(())
20517 }
20518
20519 fn generate_approx_percentile_estimate(&mut self, e: &ApproxPercentileEstimate) -> Result<()> {
20520 self.write_keyword("APPROX_PERCENTILE_ESTIMATE");
20522 self.write("(");
20523 self.generate_expression(&e.this)?;
20524 if let Some(percentile) = &e.percentile {
20525 self.write(", ");
20526 self.generate_expression(percentile)?;
20527 }
20528 self.write(")");
20529 Ok(())
20530 }
20531
20532 fn generate_approx_quantile(&mut self, e: &ApproxQuantile) -> Result<()> {
20533 self.write_keyword("APPROX_QUANTILE");
20535 self.write("(");
20536 self.generate_expression(&e.this)?;
20537 if let Some(quantile) = &e.quantile {
20538 self.write(", ");
20539 self.generate_expression(quantile)?;
20540 }
20541 if let Some(accuracy) = &e.accuracy {
20542 self.write(", ");
20543 self.generate_expression(accuracy)?;
20544 }
20545 if let Some(weight) = &e.weight {
20546 self.write(", ");
20547 self.generate_expression(weight)?;
20548 }
20549 self.write(")");
20550 Ok(())
20551 }
20552
20553 fn generate_approx_quantiles(&mut self, e: &ApproxQuantiles) -> Result<()> {
20554 self.write_keyword("APPROX_QUANTILES");
20556 self.write("(");
20557 self.generate_expression(&e.this)?;
20558 if let Some(expression) = &e.expression {
20559 self.write(", ");
20560 self.generate_expression(expression)?;
20561 }
20562 self.write(")");
20563 Ok(())
20564 }
20565
20566 fn generate_approx_top_k(&mut self, e: &ApproxTopK) -> Result<()> {
20567 self.write_keyword("APPROX_TOP_K");
20569 self.write("(");
20570 self.generate_expression(&e.this)?;
20571 if let Some(expression) = &e.expression {
20572 self.write(", ");
20573 self.generate_expression(expression)?;
20574 }
20575 if let Some(counters) = &e.counters {
20576 self.write(", ");
20577 self.generate_expression(counters)?;
20578 }
20579 self.write(")");
20580 Ok(())
20581 }
20582
20583 fn generate_approx_top_k_accumulate(&mut self, e: &ApproxTopKAccumulate) -> Result<()> {
20584 self.write_keyword("APPROX_TOP_K_ACCUMULATE");
20586 self.write("(");
20587 self.generate_expression(&e.this)?;
20588 if let Some(expression) = &e.expression {
20589 self.write(", ");
20590 self.generate_expression(expression)?;
20591 }
20592 self.write(")");
20593 Ok(())
20594 }
20595
20596 fn generate_approx_top_k_combine(&mut self, e: &ApproxTopKCombine) -> Result<()> {
20597 self.write_keyword("APPROX_TOP_K_COMBINE");
20599 self.write("(");
20600 self.generate_expression(&e.this)?;
20601 if let Some(expression) = &e.expression {
20602 self.write(", ");
20603 self.generate_expression(expression)?;
20604 }
20605 self.write(")");
20606 Ok(())
20607 }
20608
20609 fn generate_approx_top_k_estimate(&mut self, e: &ApproxTopKEstimate) -> Result<()> {
20610 self.write_keyword("APPROX_TOP_K_ESTIMATE");
20612 self.write("(");
20613 self.generate_expression(&e.this)?;
20614 if let Some(expression) = &e.expression {
20615 self.write(", ");
20616 self.generate_expression(expression)?;
20617 }
20618 self.write(")");
20619 Ok(())
20620 }
20621
20622 fn generate_approx_top_sum(&mut self, e: &ApproxTopSum) -> Result<()> {
20623 self.write_keyword("APPROX_TOP_SUM");
20625 self.write("(");
20626 self.generate_expression(&e.this)?;
20627 self.write(", ");
20628 self.generate_expression(&e.expression)?;
20629 if let Some(count) = &e.count {
20630 self.write(", ");
20631 self.generate_expression(count)?;
20632 }
20633 self.write(")");
20634 Ok(())
20635 }
20636
20637 fn generate_arg_max(&mut self, e: &ArgMax) -> Result<()> {
20638 self.write_keyword("ARG_MAX");
20640 self.write("(");
20641 self.generate_expression(&e.this)?;
20642 self.write(", ");
20643 self.generate_expression(&e.expression)?;
20644 if let Some(count) = &e.count {
20645 self.write(", ");
20646 self.generate_expression(count)?;
20647 }
20648 self.write(")");
20649 Ok(())
20650 }
20651
20652 fn generate_arg_min(&mut self, e: &ArgMin) -> Result<()> {
20653 self.write_keyword("ARG_MIN");
20655 self.write("(");
20656 self.generate_expression(&e.this)?;
20657 self.write(", ");
20658 self.generate_expression(&e.expression)?;
20659 if let Some(count) = &e.count {
20660 self.write(", ");
20661 self.generate_expression(count)?;
20662 }
20663 self.write(")");
20664 Ok(())
20665 }
20666
20667 fn generate_array_all(&mut self, e: &ArrayAll) -> Result<()> {
20668 self.write_keyword("ARRAY_ALL");
20670 self.write("(");
20671 self.generate_expression(&e.this)?;
20672 self.write(", ");
20673 self.generate_expression(&e.expression)?;
20674 self.write(")");
20675 Ok(())
20676 }
20677
20678 fn generate_array_any(&mut self, e: &ArrayAny) -> Result<()> {
20679 self.write_keyword("ARRAY_ANY");
20681 self.write("(");
20682 self.generate_expression(&e.this)?;
20683 self.write(", ");
20684 self.generate_expression(&e.expression)?;
20685 self.write(")");
20686 Ok(())
20687 }
20688
20689 fn generate_array_construct_compact(&mut self, e: &ArrayConstructCompact) -> Result<()> {
20690 self.write_keyword("ARRAY_CONSTRUCT_COMPACT");
20692 self.write("(");
20693 for (i, expr) in e.expressions.iter().enumerate() {
20694 if i > 0 {
20695 self.write(", ");
20696 }
20697 self.generate_expression(expr)?;
20698 }
20699 self.write(")");
20700 Ok(())
20701 }
20702
20703 fn generate_array_sum(&mut self, e: &ArraySum) -> Result<()> {
20704 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
20706 self.write("arraySum");
20707 } else {
20708 self.write_keyword("ARRAY_SUM");
20709 }
20710 self.write("(");
20711 self.generate_expression(&e.this)?;
20712 if let Some(expression) = &e.expression {
20713 self.write(", ");
20714 self.generate_expression(expression)?;
20715 }
20716 self.write(")");
20717 Ok(())
20718 }
20719
20720 fn generate_at_index(&mut self, e: &AtIndex) -> Result<()> {
20721 self.generate_expression(&e.this)?;
20723 self.write_space();
20724 self.write_keyword("AT");
20725 self.write_space();
20726 self.generate_expression(&e.expression)?;
20727 Ok(())
20728 }
20729
20730 fn generate_attach(&mut self, e: &Attach) -> Result<()> {
20731 self.write_keyword("ATTACH");
20733 if e.exists {
20734 self.write_space();
20735 self.write_keyword("IF NOT EXISTS");
20736 }
20737 self.write_space();
20738 self.generate_expression(&e.this)?;
20739 if !e.expressions.is_empty() {
20740 self.write(" (");
20741 for (i, expr) in e.expressions.iter().enumerate() {
20742 if i > 0 {
20743 self.write(", ");
20744 }
20745 self.generate_expression(expr)?;
20746 }
20747 self.write(")");
20748 }
20749 Ok(())
20750 }
20751
20752 fn generate_attach_option(&mut self, e: &AttachOption) -> Result<()> {
20753 self.generate_expression(&e.this)?;
20756 if let Some(expression) = &e.expression {
20757 self.write_space();
20758 self.generate_expression(expression)?;
20759 }
20760 Ok(())
20761 }
20762
20763 fn generate_auto_increment_keyword(&mut self, col: &crate::expressions::ColumnDef) -> Result<()> {
20767 use crate::dialects::DialectType;
20768 if matches!(self.config.dialect, Some(DialectType::Redshift)) {
20769 self.write_keyword("IDENTITY");
20770 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
20771 self.write("(");
20772 if let Some(ref start) = col.auto_increment_start {
20773 self.generate_expression(start)?;
20774 } else {
20775 self.write("0");
20776 }
20777 self.write(", ");
20778 if let Some(ref inc) = col.auto_increment_increment {
20779 self.generate_expression(inc)?;
20780 } else {
20781 self.write("1");
20782 }
20783 self.write(")");
20784 }
20785 } else if matches!(self.config.dialect, Some(DialectType::Snowflake) | Some(DialectType::SQLite)) {
20786 self.write_keyword("AUTOINCREMENT");
20787 if let Some(ref start) = col.auto_increment_start {
20788 self.write_space();
20789 self.write_keyword("START");
20790 self.write_space();
20791 self.generate_expression(start)?;
20792 }
20793 if let Some(ref inc) = col.auto_increment_increment {
20794 self.write_space();
20795 self.write_keyword("INCREMENT");
20796 self.write_space();
20797 self.generate_expression(inc)?;
20798 }
20799 if let Some(order) = col.auto_increment_order {
20800 self.write_space();
20801 if order {
20802 self.write_keyword("ORDER");
20803 } else {
20804 self.write_keyword("NOORDER");
20805 }
20806 }
20807 } else if matches!(self.config.dialect, Some(DialectType::PostgreSQL)) {
20808 self.write_keyword("GENERATED BY DEFAULT AS IDENTITY");
20809 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
20810 self.write(" (");
20811 let mut first = true;
20812 if let Some(ref start) = col.auto_increment_start {
20813 self.write_keyword("START WITH");
20814 self.write_space();
20815 self.generate_expression(start)?;
20816 first = false;
20817 }
20818 if let Some(ref inc) = col.auto_increment_increment {
20819 if !first { self.write_space(); }
20820 self.write_keyword("INCREMENT BY");
20821 self.write_space();
20822 self.generate_expression(inc)?;
20823 }
20824 self.write(")");
20825 }
20826 } else if matches!(self.config.dialect, Some(DialectType::Databricks)) {
20827 self.write_keyword("GENERATED ALWAYS AS IDENTITY");
20828 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
20829 self.write(" (");
20830 let mut first = true;
20831 if let Some(ref start) = col.auto_increment_start {
20832 self.write_keyword("START WITH");
20833 self.write_space();
20834 self.generate_expression(start)?;
20835 first = false;
20836 }
20837 if let Some(ref inc) = col.auto_increment_increment {
20838 if !first { self.write_space(); }
20839 self.write_keyword("INCREMENT BY");
20840 self.write_space();
20841 self.generate_expression(inc)?;
20842 }
20843 self.write(")");
20844 }
20845 } else if matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) {
20846 self.write_keyword("IDENTITY");
20847 if col.auto_increment_start.is_some() || col.auto_increment_increment.is_some() {
20848 self.write("(");
20849 if let Some(ref start) = col.auto_increment_start {
20850 self.generate_expression(start)?;
20851 } else {
20852 self.write("0");
20853 }
20854 self.write(", ");
20855 if let Some(ref inc) = col.auto_increment_increment {
20856 self.generate_expression(inc)?;
20857 } else {
20858 self.write("1");
20859 }
20860 self.write(")");
20861 }
20862 } else {
20863 self.write_keyword("AUTO_INCREMENT");
20864 if let Some(ref start) = col.auto_increment_start {
20865 self.write_space();
20866 self.write_keyword("START");
20867 self.write_space();
20868 self.generate_expression(start)?;
20869 }
20870 if let Some(ref inc) = col.auto_increment_increment {
20871 self.write_space();
20872 self.write_keyword("INCREMENT");
20873 self.write_space();
20874 self.generate_expression(inc)?;
20875 }
20876 if let Some(order) = col.auto_increment_order {
20877 self.write_space();
20878 if order {
20879 self.write_keyword("ORDER");
20880 } else {
20881 self.write_keyword("NOORDER");
20882 }
20883 }
20884 }
20885 Ok(())
20886 }
20887
20888 fn generate_auto_increment_property(&mut self, e: &AutoIncrementProperty) -> Result<()> {
20889 self.write_keyword("AUTO_INCREMENT");
20891 self.write("=");
20892 self.generate_expression(&e.this)?;
20893 Ok(())
20894 }
20895
20896 fn generate_auto_refresh_property(&mut self, e: &AutoRefreshProperty) -> Result<()> {
20897 self.write_keyword("AUTO_REFRESH");
20899 self.write("=");
20900 self.generate_expression(&e.this)?;
20901 Ok(())
20902 }
20903
20904 fn generate_backup_property(&mut self, e: &BackupProperty) -> Result<()> {
20905 self.write_keyword("BACKUP");
20907 self.write_space();
20908 self.generate_expression(&e.this)?;
20909 Ok(())
20910 }
20911
20912 fn generate_base64_decode_binary(&mut self, e: &Base64DecodeBinary) -> Result<()> {
20913 self.write_keyword("BASE64_DECODE_BINARY");
20915 self.write("(");
20916 self.generate_expression(&e.this)?;
20917 if let Some(alphabet) = &e.alphabet {
20918 self.write(", ");
20919 self.generate_expression(alphabet)?;
20920 }
20921 self.write(")");
20922 Ok(())
20923 }
20924
20925 fn generate_base64_decode_string(&mut self, e: &Base64DecodeString) -> Result<()> {
20926 self.write_keyword("BASE64_DECODE_STRING");
20928 self.write("(");
20929 self.generate_expression(&e.this)?;
20930 if let Some(alphabet) = &e.alphabet {
20931 self.write(", ");
20932 self.generate_expression(alphabet)?;
20933 }
20934 self.write(")");
20935 Ok(())
20936 }
20937
20938 fn generate_base64_encode(&mut self, e: &Base64Encode) -> Result<()> {
20939 self.write_keyword("BASE64_ENCODE");
20941 self.write("(");
20942 self.generate_expression(&e.this)?;
20943 if let Some(max_line_length) = &e.max_line_length {
20944 self.write(", ");
20945 self.generate_expression(max_line_length)?;
20946 }
20947 if let Some(alphabet) = &e.alphabet {
20948 self.write(", ");
20949 self.generate_expression(alphabet)?;
20950 }
20951 self.write(")");
20952 Ok(())
20953 }
20954
20955 fn generate_block_compression_property(&mut self, e: &BlockCompressionProperty) -> Result<()> {
20956 self.write_keyword("BLOCKCOMPRESSION");
20958 self.write("=");
20959 if let Some(autotemp) = &e.autotemp {
20960 self.write_keyword("AUTOTEMP");
20961 self.write("(");
20962 self.generate_expression(autotemp)?;
20963 self.write(")");
20964 }
20965 if let Some(always) = &e.always {
20966 self.generate_expression(always)?;
20967 }
20968 if let Some(default) = &e.default {
20969 self.generate_expression(default)?;
20970 }
20971 if let Some(manual) = &e.manual {
20972 self.generate_expression(manual)?;
20973 }
20974 if let Some(never) = &e.never {
20975 self.generate_expression(never)?;
20976 }
20977 Ok(())
20978 }
20979
20980 fn generate_booland(&mut self, e: &Booland) -> Result<()> {
20981 self.write("((");
20983 self.generate_expression(&e.this)?;
20984 self.write(") ");
20985 self.write_keyword("AND");
20986 self.write(" (");
20987 self.generate_expression(&e.expression)?;
20988 self.write("))");
20989 Ok(())
20990 }
20991
20992 fn generate_boolor(&mut self, e: &Boolor) -> Result<()> {
20993 self.write("((");
20995 self.generate_expression(&e.this)?;
20996 self.write(") ");
20997 self.write_keyword("OR");
20998 self.write(" (");
20999 self.generate_expression(&e.expression)?;
21000 self.write("))");
21001 Ok(())
21002 }
21003
21004 fn generate_build_property(&mut self, e: &BuildProperty) -> Result<()> {
21005 self.write_keyword("BUILD");
21007 self.write_space();
21008 self.generate_expression(&e.this)?;
21009 Ok(())
21010 }
21011
21012 fn generate_byte_string(&mut self, e: &ByteString) -> Result<()> {
21013 self.generate_expression(&e.this)?;
21015 Ok(())
21016 }
21017
21018 fn generate_case_specific_column_constraint(&mut self, e: &CaseSpecificColumnConstraint) -> Result<()> {
21019 if e.not_.is_some() {
21021 self.write_keyword("NOT");
21022 self.write_space();
21023 }
21024 self.write_keyword("CASESPECIFIC");
21025 Ok(())
21026 }
21027
21028 fn generate_cast_to_str_type(&mut self, e: &CastToStrType) -> Result<()> {
21029 self.write_keyword("CAST");
21031 self.write("(");
21032 self.generate_expression(&e.this)?;
21033 if self.config.dialect == Some(DialectType::ClickHouse) {
21034 self.write(", ");
21036 } else {
21037 self.write_space();
21038 self.write_keyword("AS");
21039 self.write_space();
21040 }
21041 if let Some(to) = &e.to {
21042 self.generate_expression(to)?;
21043 }
21044 self.write(")");
21045 Ok(())
21046 }
21047
21048 fn generate_changes(&mut self, e: &Changes) -> Result<()> {
21049 self.write_keyword("CHANGES");
21052 self.write(" (");
21053 if let Some(information) = &e.information {
21054 self.write_keyword("INFORMATION");
21055 self.write(" => ");
21056 self.generate_expression(information)?;
21057 }
21058 self.write(")");
21059 if let Some(at_before) = &e.at_before {
21061 self.write(" ");
21062 self.generate_expression(at_before)?;
21063 }
21064 if let Some(end) = &e.end {
21065 self.write(" ");
21066 self.generate_expression(end)?;
21067 }
21068 Ok(())
21069 }
21070
21071 fn generate_character_set_column_constraint(&mut self, e: &CharacterSetColumnConstraint) -> Result<()> {
21072 self.write_keyword("CHARACTER SET");
21074 self.write_space();
21075 self.generate_expression(&e.this)?;
21076 Ok(())
21077 }
21078
21079 fn generate_character_set_property(&mut self, e: &CharacterSetProperty) -> Result<()> {
21080 if e.default.is_some() {
21082 self.write_keyword("DEFAULT");
21083 self.write_space();
21084 }
21085 self.write_keyword("CHARACTER SET");
21086 self.write("=");
21087 self.generate_expression(&e.this)?;
21088 Ok(())
21089 }
21090
21091 fn generate_check_column_constraint(&mut self, e: &CheckColumnConstraint) -> Result<()> {
21092 self.write_keyword("CHECK");
21094 self.write(" (");
21095 self.generate_expression(&e.this)?;
21096 self.write(")");
21097 if e.enforced.is_some() {
21098 self.write_space();
21099 self.write_keyword("ENFORCED");
21100 }
21101 Ok(())
21102 }
21103
21104 fn generate_check_json(&mut self, e: &CheckJson) -> Result<()> {
21105 self.write_keyword("CHECK_JSON");
21107 self.write("(");
21108 self.generate_expression(&e.this)?;
21109 self.write(")");
21110 Ok(())
21111 }
21112
21113 fn generate_check_xml(&mut self, e: &CheckXml) -> Result<()> {
21114 self.write_keyword("CHECK_XML");
21116 self.write("(");
21117 self.generate_expression(&e.this)?;
21118 self.write(")");
21119 Ok(())
21120 }
21121
21122 fn generate_checksum_property(&mut self, e: &ChecksumProperty) -> Result<()> {
21123 self.write_keyword("CHECKSUM");
21125 self.write("=");
21126 if e.on.is_some() {
21127 self.write_keyword("ON");
21128 } else if e.default.is_some() {
21129 self.write_keyword("DEFAULT");
21130 } else {
21131 self.write_keyword("OFF");
21132 }
21133 Ok(())
21134 }
21135
21136 fn generate_clone(&mut self, e: &Clone) -> Result<()> {
21137 if e.shallow.is_some() {
21139 self.write_keyword("SHALLOW");
21140 self.write_space();
21141 }
21142 if e.copy.is_some() {
21143 self.write_keyword("COPY");
21144 } else {
21145 self.write_keyword("CLONE");
21146 }
21147 self.write_space();
21148 self.generate_expression(&e.this)?;
21149 Ok(())
21150 }
21151
21152 fn generate_cluster_by(&mut self, e: &ClusterBy) -> Result<()> {
21153 self.write_keyword("CLUSTER BY");
21155 self.write(" (");
21156 for (i, ord) in e.expressions.iter().enumerate() {
21157 if i > 0 {
21158 self.write(", ");
21159 }
21160 self.generate_ordered(ord)?;
21161 }
21162 self.write(")");
21163 Ok(())
21164 }
21165
21166 fn generate_clustered_by_property(&mut self, e: &ClusteredByProperty) -> Result<()> {
21167 self.write_keyword("CLUSTERED BY");
21169 self.write(" (");
21170 for (i, expr) in e.expressions.iter().enumerate() {
21171 if i > 0 {
21172 self.write(", ");
21173 }
21174 self.generate_expression(expr)?;
21175 }
21176 self.write(")");
21177 if let Some(sorted_by) = &e.sorted_by {
21178 self.write_space();
21179 self.write_keyword("SORTED BY");
21180 self.write(" (");
21181 if let Expression::Tuple(t) = sorted_by.as_ref() {
21183 for (i, expr) in t.expressions.iter().enumerate() {
21184 if i > 0 {
21185 self.write(", ");
21186 }
21187 self.generate_expression(expr)?;
21188 }
21189 } else {
21190 self.generate_expression(sorted_by)?;
21191 }
21192 self.write(")");
21193 }
21194 if let Some(buckets) = &e.buckets {
21195 self.write_space();
21196 self.write_keyword("INTO");
21197 self.write_space();
21198 self.generate_expression(buckets)?;
21199 self.write_space();
21200 self.write_keyword("BUCKETS");
21201 }
21202 Ok(())
21203 }
21204
21205 fn generate_collate_property(&mut self, e: &CollateProperty) -> Result<()> {
21206 if e.default.is_some() {
21210 self.write_keyword("DEFAULT");
21211 self.write_space();
21212 }
21213 self.write_keyword("COLLATE");
21214 match self.config.dialect {
21216 Some(DialectType::BigQuery) => self.write_space(),
21217 _ => self.write("="),
21218 }
21219 self.generate_expression(&e.this)?;
21220 Ok(())
21221 }
21222
21223 fn generate_column_constraint(&mut self, e: &ColumnConstraint) -> Result<()> {
21224 match e {
21226 ColumnConstraint::NotNull => {
21227 self.write_keyword("NOT NULL");
21228 }
21229 ColumnConstraint::Null => {
21230 self.write_keyword("NULL");
21231 }
21232 ColumnConstraint::Unique => {
21233 self.write_keyword("UNIQUE");
21234 }
21235 ColumnConstraint::PrimaryKey => {
21236 self.write_keyword("PRIMARY KEY");
21237 }
21238 ColumnConstraint::Default(expr) => {
21239 self.write_keyword("DEFAULT");
21240 self.write_space();
21241 self.generate_expression(expr)?;
21242 }
21243 ColumnConstraint::Check(expr) => {
21244 self.write_keyword("CHECK");
21245 self.write(" (");
21246 self.generate_expression(expr)?;
21247 self.write(")");
21248 }
21249 ColumnConstraint::References(fk_ref) => {
21250 if fk_ref.has_foreign_key_keywords {
21251 self.write_keyword("FOREIGN KEY");
21252 self.write_space();
21253 }
21254 self.write_keyword("REFERENCES");
21255 self.write_space();
21256 self.generate_table(&fk_ref.table)?;
21257 if !fk_ref.columns.is_empty() {
21258 self.write(" (");
21259 for (i, col) in fk_ref.columns.iter().enumerate() {
21260 if i > 0 {
21261 self.write(", ");
21262 }
21263 self.generate_identifier(col)?;
21264 }
21265 self.write(")");
21266 }
21267 }
21268 ColumnConstraint::GeneratedAsIdentity(gen) => {
21269 self.write_keyword("GENERATED");
21270 self.write_space();
21271 if gen.always {
21272 self.write_keyword("ALWAYS");
21273 } else {
21274 self.write_keyword("BY DEFAULT");
21275 if gen.on_null {
21276 self.write_space();
21277 self.write_keyword("ON NULL");
21278 }
21279 }
21280 self.write_space();
21281 self.write_keyword("AS IDENTITY");
21282 }
21283 ColumnConstraint::Collate(collation) => {
21284 self.write_keyword("COLLATE");
21285 self.write_space();
21286 self.generate_identifier(collation)?;
21287 }
21288 ColumnConstraint::Comment(comment) => {
21289 self.write_keyword("COMMENT");
21290 self.write(" '");
21291 self.write(comment);
21292 self.write("'");
21293 }
21294 ColumnConstraint::ComputedColumn(cc) => {
21295 self.generate_computed_column_inline(cc)?;
21296 }
21297 ColumnConstraint::GeneratedAsRow(gar) => {
21298 self.generate_generated_as_row_inline(gar)?;
21299 }
21300 ColumnConstraint::Tags(tags) => {
21301 self.write_keyword("TAG");
21302 self.write(" (");
21303 for (i, expr) in tags.expressions.iter().enumerate() {
21304 if i > 0 {
21305 self.write(", ");
21306 }
21307 self.generate_expression(expr)?;
21308 }
21309 self.write(")");
21310 }
21311 ColumnConstraint::Path(path_expr) => {
21312 self.write_keyword("PATH");
21313 self.write_space();
21314 self.generate_expression(path_expr)?;
21315 }
21316 }
21317 Ok(())
21318 }
21319
21320 fn generate_column_position(&mut self, e: &ColumnPosition) -> Result<()> {
21321 match e {
21323 ColumnPosition::First => {
21324 self.write_keyword("FIRST");
21325 }
21326 ColumnPosition::After(ident) => {
21327 self.write_keyword("AFTER");
21328 self.write_space();
21329 self.generate_identifier(ident)?;
21330 }
21331 }
21332 Ok(())
21333 }
21334
21335 fn generate_column_prefix(&mut self, e: &ColumnPrefix) -> Result<()> {
21336 self.generate_expression(&e.this)?;
21338 self.write("(");
21339 self.generate_expression(&e.expression)?;
21340 self.write(")");
21341 Ok(())
21342 }
21343
21344 fn generate_columns(&mut self, e: &Columns) -> Result<()> {
21345 if let Some(ref unpack) = e.unpack {
21348 if let Expression::Boolean(b) = unpack.as_ref() {
21349 if b.value {
21350 self.write("*");
21351 }
21352 }
21353 }
21354 self.write_keyword("COLUMNS");
21355 self.write("(");
21356 self.generate_expression(&e.this)?;
21357 self.write(")");
21358 Ok(())
21359 }
21360
21361 fn generate_combined_agg_func(&mut self, e: &CombinedAggFunc) -> Result<()> {
21362 self.generate_expression(&e.this)?;
21364 self.write("(");
21365 for (i, expr) in e.expressions.iter().enumerate() {
21366 if i > 0 {
21367 self.write(", ");
21368 }
21369 self.generate_expression(expr)?;
21370 }
21371 self.write(")");
21372 Ok(())
21373 }
21374
21375 fn generate_combined_parameterized_agg(&mut self, e: &CombinedParameterizedAgg) -> Result<()> {
21376 self.generate_expression(&e.this)?;
21378 self.write("(");
21379 for (i, param) in e.params.iter().enumerate() {
21380 if i > 0 {
21381 self.write(", ");
21382 }
21383 self.generate_expression(param)?;
21384 }
21385 self.write(")(");
21386 for (i, expr) in e.expressions.iter().enumerate() {
21387 if i > 0 {
21388 self.write(", ");
21389 }
21390 self.generate_expression(expr)?;
21391 }
21392 self.write(")");
21393 Ok(())
21394 }
21395
21396 fn generate_commit(&mut self, e: &Commit) -> Result<()> {
21397 self.write_keyword("COMMIT");
21399
21400 if e.this.is_none() && matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) {
21402 self.write_space();
21403 self.write_keyword("TRANSACTION");
21404 }
21405
21406 if let Some(this) = &e.this {
21408 let is_transaction_marker = matches!(
21410 this.as_ref(),
21411 Expression::Identifier(id) if id.name == "TRANSACTION"
21412 );
21413
21414 self.write_space();
21415 self.write_keyword("TRANSACTION");
21416
21417 if !is_transaction_marker {
21419 self.write_space();
21420 self.generate_expression(this)?;
21421 }
21422 }
21423
21424 if let Some(durability) = &e.durability {
21426 self.write_space();
21427 self.write_keyword("WITH");
21428 self.write(" (");
21429 self.write_keyword("DELAYED_DURABILITY");
21430 self.write(" = ");
21431 if let Expression::Boolean(BooleanLiteral { value: true }) = durability.as_ref() {
21432 self.write_keyword("ON");
21433 } else {
21434 self.write_keyword("OFF");
21435 }
21436 self.write(")");
21437 }
21438
21439 if let Some(chain) = &e.chain {
21441 self.write_space();
21442 if let Expression::Boolean(BooleanLiteral { value: false }) = chain.as_ref() {
21443 self.write_keyword("AND NO CHAIN");
21444 } else {
21445 self.write_keyword("AND CHAIN");
21446 }
21447 }
21448 Ok(())
21449 }
21450
21451 fn generate_comprehension(&mut self, e: &Comprehension) -> Result<()> {
21452 self.write("[");
21454 self.generate_expression(&e.this)?;
21455 self.write_space();
21456 self.write_keyword("FOR");
21457 self.write_space();
21458 self.generate_expression(&e.expression)?;
21459 if let Some(pos) = &e.position {
21461 self.write(", ");
21462 self.generate_expression(pos)?;
21463 }
21464 if let Some(iterator) = &e.iterator {
21465 self.write_space();
21466 self.write_keyword("IN");
21467 self.write_space();
21468 self.generate_expression(iterator)?;
21469 }
21470 if let Some(condition) = &e.condition {
21471 self.write_space();
21472 self.write_keyword("IF");
21473 self.write_space();
21474 self.generate_expression(condition)?;
21475 }
21476 self.write("]");
21477 Ok(())
21478 }
21479
21480 fn generate_compress(&mut self, e: &Compress) -> Result<()> {
21481 self.write_keyword("COMPRESS");
21483 self.write("(");
21484 self.generate_expression(&e.this)?;
21485 if let Some(method) = &e.method {
21486 self.write(", '");
21487 self.write(method);
21488 self.write("'");
21489 }
21490 self.write(")");
21491 Ok(())
21492 }
21493
21494 fn generate_compress_column_constraint(&mut self, e: &CompressColumnConstraint) -> Result<()> {
21495 self.write_keyword("COMPRESS");
21497 if let Some(this) = &e.this {
21498 self.write_space();
21499 self.generate_expression(this)?;
21500 }
21501 Ok(())
21502 }
21503
21504 fn generate_computed_column_constraint(&mut self, e: &ComputedColumnConstraint) -> Result<()> {
21505 self.write_keyword("AS");
21507 self.write_space();
21508 self.generate_expression(&e.this)?;
21509 if e.not_null.is_some() {
21510 self.write_space();
21511 self.write_keyword("PERSISTED NOT NULL");
21512 } else if e.persisted.is_some() {
21513 self.write_space();
21514 self.write_keyword("PERSISTED");
21515 }
21516 Ok(())
21517 }
21518
21519 fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> {
21523 let computed_expr = if matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) {
21524 match &*cc.expression {
21525 Expression::Year(y)
21526 if !matches!(&y.this, Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
21527 {
21528 let wrapped = Expression::Cast(Box::new(Cast {
21529 this: y.this.clone(),
21530 to: DataType::Date,
21531 trailing_comments: Vec::new(),
21532 double_colon_syntax: false,
21533 format: None,
21534 default: None,
21535 }));
21536 Expression::Year(Box::new(UnaryFunc::new(wrapped)))
21537 }
21538 Expression::Function(f)
21539 if f.name.eq_ignore_ascii_case("YEAR")
21540 && f.args.len() == 1
21541 && !matches!(&f.args[0], Expression::Cast(c) if matches!(c.to, DataType::Date)) =>
21542 {
21543 let wrapped = Expression::Cast(Box::new(Cast {
21544 this: f.args[0].clone(),
21545 to: DataType::Date,
21546 trailing_comments: Vec::new(),
21547 double_colon_syntax: false,
21548 format: None,
21549 default: None,
21550 }));
21551 Expression::Function(Box::new(Function::new("YEAR".to_string(), vec![wrapped])))
21552 }
21553 _ => *cc.expression.clone(),
21554 }
21555 } else {
21556 *cc.expression.clone()
21557 };
21558
21559 match cc.persistence_kind.as_deref() {
21560 Some("STORED") | Some("VIRTUAL") => {
21561 self.write_keyword("GENERATED ALWAYS AS");
21563 self.write(" (");
21564 self.generate_expression(&computed_expr)?;
21565 self.write(")");
21566 self.write_space();
21567 if cc.persisted {
21568 self.write_keyword("STORED");
21569 } else {
21570 self.write_keyword("VIRTUAL");
21571 }
21572 }
21573 Some("PERSISTED") => {
21574 self.write_keyword("AS");
21576 self.write(" (");
21577 self.generate_expression(&computed_expr)?;
21578 self.write(")");
21579 self.write_space();
21580 self.write_keyword("PERSISTED");
21581 if let Some(ref dt) = cc.data_type {
21583 self.write_space();
21584 self.generate_data_type(dt)?;
21585 }
21586 if cc.not_null {
21587 self.write_space();
21588 self.write_keyword("NOT NULL");
21589 }
21590 }
21591 _ => {
21592 if matches!(
21595 self.config.dialect,
21596 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)
21597 ) {
21598 self.write_keyword("GENERATED ALWAYS AS");
21599 self.write(" (");
21600 self.generate_expression(&computed_expr)?;
21601 self.write(")");
21602 } else if matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) {
21603 self.write_keyword("AS");
21604 let omit_parens = matches!(computed_expr, Expression::Year(_))
21605 || matches!(&computed_expr, Expression::Function(f) if f.name.eq_ignore_ascii_case("YEAR"));
21606 if omit_parens {
21607 self.write_space();
21608 self.generate_expression(&computed_expr)?;
21609 } else {
21610 self.write(" (");
21611 self.generate_expression(&computed_expr)?;
21612 self.write(")");
21613 }
21614 } else {
21615 self.write_keyword("AS");
21616 self.write(" (");
21617 self.generate_expression(&computed_expr)?;
21618 self.write(")");
21619 }
21620 }
21621 }
21622 Ok(())
21623 }
21624
21625 fn generate_generated_as_row_inline(&mut self, gar: &GeneratedAsRow) -> Result<()> {
21628 self.write_keyword("GENERATED ALWAYS AS ROW ");
21629 if gar.start {
21630 self.write_keyword("START");
21631 } else {
21632 self.write_keyword("END");
21633 }
21634 if gar.hidden {
21635 self.write_space();
21636 self.write_keyword("HIDDEN");
21637 }
21638 Ok(())
21639 }
21640
21641 fn generate_system_versioning_content(&mut self, e: &WithSystemVersioningProperty) -> Result<()> {
21643 let mut parts = Vec::new();
21644
21645 if let Some(this) = &e.this {
21646 let mut s = String::from("HISTORY_TABLE=");
21647 let mut gen = Generator::new();
21648 gen.config = self.config.clone();
21649 gen.generate_expression(this)?;
21650 s.push_str(&gen.output);
21651 parts.push(s);
21652 }
21653
21654 if let Some(data_consistency) = &e.data_consistency {
21655 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
21656 let mut gen = Generator::new();
21657 gen.config = self.config.clone();
21658 gen.generate_expression(data_consistency)?;
21659 s.push_str(&gen.output);
21660 parts.push(s);
21661 }
21662
21663 if let Some(retention_period) = &e.retention_period {
21664 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
21665 let mut gen = Generator::new();
21666 gen.config = self.config.clone();
21667 gen.generate_expression(retention_period)?;
21668 s.push_str(&gen.output);
21669 parts.push(s);
21670 }
21671
21672 self.write_keyword("SYSTEM_VERSIONING");
21673 self.write("=");
21674
21675 if !parts.is_empty() {
21676 self.write_keyword("ON");
21677 self.write("(");
21678 self.write(&parts.join(", "));
21679 self.write(")");
21680 } else if e.on.is_some() {
21681 self.write_keyword("ON");
21682 } else {
21683 self.write_keyword("OFF");
21684 }
21685
21686 Ok(())
21687 }
21688
21689 fn generate_conditional_insert(&mut self, e: &ConditionalInsert) -> Result<()> {
21690 if e.else_.is_some() {
21693 self.write_keyword("ELSE");
21694 self.write_space();
21695 } else if let Some(expression) = &e.expression {
21696 self.write_keyword("WHEN");
21697 self.write_space();
21698 self.generate_expression(expression)?;
21699 self.write_space();
21700 self.write_keyword("THEN");
21701 self.write_space();
21702 }
21703
21704 if let Expression::Insert(insert) = e.this.as_ref() {
21707 self.write_keyword("INTO");
21708 self.write_space();
21709 self.generate_table(&insert.table)?;
21710
21711 if !insert.columns.is_empty() {
21713 self.write(" (");
21714 for (i, col) in insert.columns.iter().enumerate() {
21715 if i > 0 {
21716 self.write(", ");
21717 }
21718 self.generate_identifier(col)?;
21719 }
21720 self.write(")");
21721 }
21722
21723 if !insert.values.is_empty() {
21725 self.write_space();
21726 self.write_keyword("VALUES");
21727 for (row_idx, row) in insert.values.iter().enumerate() {
21728 if row_idx > 0 {
21729 self.write(", ");
21730 }
21731 self.write(" (");
21732 for (i, val) in row.iter().enumerate() {
21733 if i > 0 {
21734 self.write(", ");
21735 }
21736 self.generate_expression(val)?;
21737 }
21738 self.write(")");
21739 }
21740 }
21741 } else {
21742 self.generate_expression(&e.this)?;
21744 }
21745 Ok(())
21746 }
21747
21748 fn generate_constraint(&mut self, e: &Constraint) -> Result<()> {
21749 self.write_keyword("CONSTRAINT");
21751 self.write_space();
21752 self.generate_expression(&e.this)?;
21753 if !e.expressions.is_empty() {
21754 self.write_space();
21755 for (i, expr) in e.expressions.iter().enumerate() {
21756 if i > 0 {
21757 self.write_space();
21758 }
21759 self.generate_expression(expr)?;
21760 }
21761 }
21762 Ok(())
21763 }
21764
21765 fn generate_convert_timezone(&mut self, e: &ConvertTimezone) -> Result<()> {
21766 self.write_keyword("CONVERT_TIMEZONE");
21768 self.write("(");
21769 let mut first = true;
21770 if let Some(source_tz) = &e.source_tz {
21771 self.generate_expression(source_tz)?;
21772 first = false;
21773 }
21774 if let Some(target_tz) = &e.target_tz {
21775 if !first {
21776 self.write(", ");
21777 }
21778 self.generate_expression(target_tz)?;
21779 first = false;
21780 }
21781 if let Some(timestamp) = &e.timestamp {
21782 if !first {
21783 self.write(", ");
21784 }
21785 self.generate_expression(timestamp)?;
21786 }
21787 self.write(")");
21788 Ok(())
21789 }
21790
21791 fn generate_convert_to_charset(&mut self, e: &ConvertToCharset) -> Result<()> {
21792 self.write_keyword("CONVERT");
21794 self.write("(");
21795 self.generate_expression(&e.this)?;
21796 if let Some(dest) = &e.dest {
21797 self.write_space();
21798 self.write_keyword("USING");
21799 self.write_space();
21800 self.generate_expression(dest)?;
21801 }
21802 self.write(")");
21803 Ok(())
21804 }
21805
21806 fn generate_copy(&mut self, e: &CopyStmt) -> Result<()> {
21807 self.write_keyword("COPY");
21808 if e.is_into {
21809 self.write_space();
21810 self.write_keyword("INTO");
21811 }
21812 self.write_space();
21813
21814 if let Expression::Literal(Literal::String(s)) = &e.this {
21816 if s.starts_with('@') {
21817 self.write(s);
21818 } else {
21819 self.generate_expression(&e.this)?;
21820 }
21821 } else {
21822 self.generate_expression(&e.this)?;
21823 }
21824
21825 if e.kind {
21827 if self.config.pretty {
21829 self.write_newline();
21830 } else {
21831 self.write_space();
21832 }
21833 self.write_keyword("FROM");
21834 self.write_space();
21835 } else if !e.files.is_empty() {
21836 if self.config.pretty {
21838 self.write_newline();
21839 } else {
21840 self.write_space();
21841 }
21842 self.write_keyword("TO");
21843 self.write_space();
21844 }
21845
21846 for (i, file) in e.files.iter().enumerate() {
21848 if i > 0 {
21849 self.write_space();
21850 }
21851 if let Expression::Literal(Literal::String(s)) = file {
21853 if s.starts_with('@') {
21854 self.write(s);
21855 } else {
21856 self.generate_expression(file)?;
21857 }
21858 } else if let Expression::Identifier(id) = file {
21859 if id.quoted {
21861 self.write("`");
21862 self.write(&id.name);
21863 self.write("`");
21864 } else {
21865 self.generate_expression(file)?;
21866 }
21867 } else {
21868 self.generate_expression(file)?;
21869 }
21870 }
21871
21872 if !e.with_wrapped {
21874 if let Some(ref creds) = e.credentials {
21875 if let Some(ref storage) = creds.storage {
21876 if self.config.pretty { self.write_newline(); } else { self.write_space(); }
21877 self.write_keyword("STORAGE_INTEGRATION");
21878 self.write(" = ");
21879 self.write(storage);
21880 }
21881 if creds.credentials.is_empty() {
21882 if self.config.pretty { self.write_newline(); } else { self.write_space(); }
21884 self.write_keyword("CREDENTIALS");
21885 self.write(" = ()");
21886 } else {
21887 if self.config.pretty { self.write_newline(); } else { self.write_space(); }
21888 self.write_keyword("CREDENTIALS");
21889 if creds.credentials.len() == 1 && creds.credentials[0].0.is_empty() {
21892 self.write(" '");
21894 self.write(&creds.credentials[0].1);
21895 self.write("'");
21896 } else {
21897 self.write(" = (");
21899 for (i, (k, v)) in creds.credentials.iter().enumerate() {
21900 if i > 0 {
21901 self.write_space();
21902 }
21903 self.write(k);
21904 self.write("='");
21905 self.write(v);
21906 self.write("'");
21907 }
21908 self.write(")");
21909 }
21910 }
21911 if let Some(ref encryption) = creds.encryption {
21912 self.write_space();
21913 self.write_keyword("ENCRYPTION");
21914 self.write(" = ");
21915 self.write(encryption);
21916 }
21917 }
21918 }
21919
21920 if !e.params.is_empty() {
21922 if e.with_wrapped {
21923 self.write_space();
21925 self.write_keyword("WITH");
21926 self.write(" (");
21927 for (i, param) in e.params.iter().enumerate() {
21928 if i > 0 {
21929 self.write(", ");
21930 }
21931 self.generate_copy_param_with_format(param)?;
21932 }
21933 self.write(")");
21934 } else {
21935 for param in &e.params {
21939 if self.config.pretty { self.write_newline(); } else { self.write_space(); }
21940 self.write(¶m.name);
21942 if let Some(ref value) = param.value {
21943 if param.eq {
21945 self.write(" = ");
21946 } else {
21947 self.write(" ");
21948 }
21949 if !param.values.is_empty() {
21950 self.write("(");
21951 for (i, v) in param.values.iter().enumerate() {
21952 if i > 0 {
21953 self.write_space();
21954 }
21955 self.generate_copy_nested_param(v)?;
21956 }
21957 self.write(")");
21958 } else {
21959 self.generate_copy_param_value(value)?;
21961 }
21962 } else if !param.values.is_empty() {
21963 if param.eq {
21965 self.write(" = (");
21966 } else {
21967 self.write(" (");
21968 }
21969 let is_key_value_pairs = param.values.first().map_or(false, |v| matches!(v, Expression::Eq(_)));
21974 let sep = if is_key_value_pairs && param.eq { " " } else { ", " };
21975 for (i, v) in param.values.iter().enumerate() {
21976 if i > 0 {
21977 self.write(sep);
21978 }
21979 self.generate_copy_nested_param(v)?;
21980 }
21981 self.write(")");
21982 }
21983 }
21984 }
21985 }
21986
21987 Ok(())
21988 }
21989
21990 fn generate_copy_param_with_format(&mut self, param: &CopyParameter) -> Result<()> {
21993 self.write_keyword(¶m.name);
21994 if !param.values.is_empty() {
21995 self.write(" = (");
21997 for (i, v) in param.values.iter().enumerate() {
21998 if i > 0 {
21999 self.write(", ");
22000 }
22001 self.generate_copy_nested_param(v)?;
22002 }
22003 self.write(")");
22004 } else if let Some(ref value) = param.value {
22005 if param.eq {
22006 self.write(" = ");
22007 } else {
22008 self.write(" ");
22009 }
22010 self.generate_expression(value)?;
22011 }
22012 Ok(())
22013 }
22014
22015 fn generate_copy_nested_param(&mut self, expr: &Expression) -> Result<()> {
22017 match expr {
22018 Expression::Eq(eq) => {
22019 match &eq.left {
22021 Expression::Column(c) => self.write(&c.name.name),
22022 _ => self.generate_expression(&eq.left)?,
22023 }
22024 self.write("=");
22025 match &eq.right {
22027 Expression::Literal(Literal::String(s)) => {
22028 self.write("'");
22029 self.write(s);
22030 self.write("'");
22031 }
22032 Expression::Tuple(t) => {
22033 self.write("(");
22035 if self.config.pretty {
22036 self.write_newline();
22037 self.indent_level += 1;
22038 for (i, item) in t.expressions.iter().enumerate() {
22039 if i > 0 {
22040 self.write(", ");
22041 }
22042 self.write_indent();
22043 self.generate_expression(item)?;
22044 }
22045 self.write_newline();
22046 self.indent_level -= 1;
22047 } else {
22048 for (i, item) in t.expressions.iter().enumerate() {
22049 if i > 0 {
22050 self.write(", ");
22051 }
22052 self.generate_expression(item)?;
22053 }
22054 }
22055 self.write(")");
22056 }
22057 _ => self.generate_expression(&eq.right)?,
22058 }
22059 Ok(())
22060 }
22061 Expression::Column(c) => {
22062 self.write(&c.name.name);
22064 Ok(())
22065 }
22066 _ => self.generate_expression(expr),
22067 }
22068 }
22069
22070 fn generate_copy_param_value(&mut self, expr: &Expression) -> Result<()> {
22073 match expr {
22074 Expression::Column(c) => {
22075 if c.name.quoted {
22077 self.write("\"");
22078 self.write(&c.name.name);
22079 self.write("\"");
22080 } else {
22081 self.write(&c.name.name);
22082 }
22083 Ok(())
22084 }
22085 Expression::Identifier(id) => {
22086 if id.quoted {
22088 self.write("\"");
22089 self.write(&id.name);
22090 self.write("\"");
22091 } else {
22092 self.write(&id.name);
22093 }
22094 Ok(())
22095 }
22096 Expression::Literal(Literal::String(s)) => {
22097 self.write("'");
22099 self.write(s);
22100 self.write("'");
22101 Ok(())
22102 }
22103 _ => self.generate_expression(expr),
22104 }
22105 }
22106
22107 fn generate_copy_parameter(&mut self, e: &CopyParameter) -> Result<()> {
22108 self.write_keyword(&e.name);
22109 if let Some(ref value) = e.value {
22110 if e.eq {
22111 self.write(" = ");
22112 } else {
22113 self.write(" ");
22114 }
22115 self.generate_expression(value)?;
22116 }
22117 if !e.values.is_empty() {
22118 if e.eq {
22119 self.write(" = ");
22120 } else {
22121 self.write(" ");
22122 }
22123 self.write("(");
22124 for (i, v) in e.values.iter().enumerate() {
22125 if i > 0 {
22126 self.write(", ");
22127 }
22128 self.generate_expression(v)?;
22129 }
22130 self.write(")");
22131 }
22132 Ok(())
22133 }
22134
22135 fn generate_corr(&mut self, e: &Corr) -> Result<()> {
22136 self.write_keyword("CORR");
22138 self.write("(");
22139 self.generate_expression(&e.this)?;
22140 self.write(", ");
22141 self.generate_expression(&e.expression)?;
22142 self.write(")");
22143 Ok(())
22144 }
22145
22146 fn generate_cosine_distance(&mut self, e: &CosineDistance) -> Result<()> {
22147 self.write_keyword("COSINE_DISTANCE");
22149 self.write("(");
22150 self.generate_expression(&e.this)?;
22151 self.write(", ");
22152 self.generate_expression(&e.expression)?;
22153 self.write(")");
22154 Ok(())
22155 }
22156
22157 fn generate_covar_pop(&mut self, e: &CovarPop) -> Result<()> {
22158 self.write_keyword("COVAR_POP");
22160 self.write("(");
22161 self.generate_expression(&e.this)?;
22162 self.write(", ");
22163 self.generate_expression(&e.expression)?;
22164 self.write(")");
22165 Ok(())
22166 }
22167
22168 fn generate_covar_samp(&mut self, e: &CovarSamp) -> Result<()> {
22169 self.write_keyword("COVAR_SAMP");
22171 self.write("(");
22172 self.generate_expression(&e.this)?;
22173 self.write(", ");
22174 self.generate_expression(&e.expression)?;
22175 self.write(")");
22176 Ok(())
22177 }
22178
22179 fn generate_credentials(&mut self, e: &Credentials) -> Result<()> {
22180 self.write_keyword("CREDENTIALS");
22182 self.write(" (");
22183 for (i, (key, value)) in e.credentials.iter().enumerate() {
22184 if i > 0 {
22185 self.write(", ");
22186 }
22187 self.write(key);
22188 self.write("='");
22189 self.write(value);
22190 self.write("'");
22191 }
22192 self.write(")");
22193 Ok(())
22194 }
22195
22196 fn generate_credentials_property(&mut self, e: &CredentialsProperty) -> Result<()> {
22197 self.write_keyword("CREDENTIALS");
22199 self.write("=(");
22200 for (i, expr) in e.expressions.iter().enumerate() {
22201 if i > 0 {
22202 self.write(", ");
22203 }
22204 self.generate_expression(expr)?;
22205 }
22206 self.write(")");
22207 Ok(())
22208 }
22209
22210 fn generate_cte(&mut self, e: &Cte) -> Result<()> {
22211 use crate::dialects::DialectType;
22212
22213 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) && !e.alias_first {
22216 self.generate_expression(&e.this)?;
22217 self.write_space();
22218 self.write_keyword("AS");
22219 self.write_space();
22220 self.generate_identifier(&e.alias)?;
22221 return Ok(());
22222 }
22223 self.write(&e.alias.name);
22224
22225 let skip_cte_columns = matches!(self.config.dialect, Some(DialectType::BigQuery));
22227
22228 if !e.columns.is_empty() && !skip_cte_columns {
22229 self.write("(");
22230 for (i, col) in e.columns.iter().enumerate() {
22231 if i > 0 {
22232 self.write(", ");
22233 }
22234 self.write(&col.name);
22235 }
22236 self.write(")");
22237 }
22238 if !e.key_expressions.is_empty() {
22240 self.write_space();
22241 self.write_keyword("USING KEY");
22242 self.write(" (");
22243 for (i, key) in e.key_expressions.iter().enumerate() {
22244 if i > 0 {
22245 self.write(", ");
22246 }
22247 self.write(&key.name);
22248 }
22249 self.write(")");
22250 }
22251 self.write_space();
22252 self.write_keyword("AS");
22253 self.write_space();
22254 if let Some(materialized) = e.materialized {
22255 if materialized {
22256 self.write_keyword("MATERIALIZED");
22257 } else {
22258 self.write_keyword("NOT MATERIALIZED");
22259 }
22260 self.write_space();
22261 }
22262 self.write("(");
22263 self.generate_expression(&e.this)?;
22264 self.write(")");
22265 Ok(())
22266 }
22267
22268 fn generate_cube(&mut self, e: &Cube) -> Result<()> {
22269 if e.expressions.is_empty() {
22271 self.write_keyword("WITH CUBE");
22272 } else {
22273 self.write_keyword("CUBE");
22274 self.write("(");
22275 for (i, expr) in e.expressions.iter().enumerate() {
22276 if i > 0 {
22277 self.write(", ");
22278 }
22279 self.generate_expression(expr)?;
22280 }
22281 self.write(")");
22282 }
22283 Ok(())
22284 }
22285
22286 fn generate_current_datetime(&mut self, e: &CurrentDatetime) -> Result<()> {
22287 self.write_keyword("CURRENT_DATETIME");
22289 if let Some(this) = &e.this {
22290 self.write("(");
22291 self.generate_expression(this)?;
22292 self.write(")");
22293 }
22294 Ok(())
22295 }
22296
22297 fn generate_current_schema(&mut self, _e: &CurrentSchema) -> Result<()> {
22298 self.write_keyword("CURRENT_SCHEMA");
22300 Ok(())
22301 }
22302
22303 fn generate_current_schemas(&mut self, e: &CurrentSchemas) -> Result<()> {
22304 self.write_keyword("CURRENT_SCHEMAS");
22306 self.write("(");
22307 if let Some(this) = &e.this {
22308 self.generate_expression(this)?;
22309 }
22310 self.write(")");
22311 Ok(())
22312 }
22313
22314 fn generate_current_user(&mut self, e: &CurrentUser) -> Result<()> {
22315 self.write_keyword("CURRENT_USER");
22317 let needs_parens = e.this.is_some() || matches!(
22319 self.config.dialect,
22320 Some(DialectType::Snowflake) | Some(DialectType::Spark)
22321 | Some(DialectType::Hive) | Some(DialectType::DuckDB) | Some(DialectType::BigQuery)
22322 | Some(DialectType::MySQL) | Some(DialectType::Databricks)
22323 );
22324 if needs_parens {
22325 self.write("()");
22326 }
22327 Ok(())
22328 }
22329
22330 fn generate_d_pipe(&mut self, e: &DPipe) -> Result<()> {
22331 if self.config.dialect == Some(DialectType::Solr) {
22333 self.generate_expression(&e.this)?;
22334 self.write(" ");
22335 self.write_keyword("OR");
22336 self.write(" ");
22337 self.generate_expression(&e.expression)?;
22338 } else {
22339 self.generate_expression(&e.this)?;
22341 self.write(" || ");
22342 self.generate_expression(&e.expression)?;
22343 }
22344 Ok(())
22345 }
22346
22347 fn generate_data_blocksize_property(&mut self, e: &DataBlocksizeProperty) -> Result<()> {
22348 self.write_keyword("DATABLOCKSIZE");
22350 self.write("=");
22351 if let Some(size) = e.size {
22352 self.write(&size.to_string());
22353 if let Some(units) = &e.units {
22354 self.write_space();
22355 self.generate_expression(units)?;
22356 }
22357 } else if e.minimum.is_some() {
22358 self.write_keyword("MINIMUM");
22359 } else if e.maximum.is_some() {
22360 self.write_keyword("MAXIMUM");
22361 } else if e.default.is_some() {
22362 self.write_keyword("DEFAULT");
22363 }
22364 Ok(())
22365 }
22366
22367 fn generate_data_deletion_property(&mut self, e: &DataDeletionProperty) -> Result<()> {
22368 self.write_keyword("DATA_DELETION");
22370 self.write("=");
22371
22372 let is_on = matches!(&*e.on, Expression::Boolean(BooleanLiteral { value: true }));
22373 let has_options = e.filter_column.is_some() || e.retention_period.is_some();
22374
22375 if is_on {
22376 self.write_keyword("ON");
22377 if has_options {
22378 self.write("(");
22379 let mut first = true;
22380 if let Some(filter_column) = &e.filter_column {
22381 self.write_keyword("FILTER_COLUMN");
22382 self.write("=");
22383 self.generate_expression(filter_column)?;
22384 first = false;
22385 }
22386 if let Some(retention_period) = &e.retention_period {
22387 if !first {
22388 self.write(", ");
22389 }
22390 self.write_keyword("RETENTION_PERIOD");
22391 self.write("=");
22392 self.generate_expression(retention_period)?;
22393 }
22394 self.write(")");
22395 }
22396 } else {
22397 self.write_keyword("OFF");
22398 }
22399 Ok(())
22400 }
22401
22402 fn generate_date_func(&mut self, e: &UnaryFunc) -> Result<()> {
22406 use crate::dialects::DialectType;
22407 use crate::expressions::Literal;
22408
22409 match self.config.dialect {
22410 Some(DialectType::Exasol) => {
22412 self.write_keyword("TO_DATE");
22413 self.write("(");
22414 match &e.this {
22416 Expression::Literal(Literal::String(s)) => {
22417 self.write("'");
22418 self.write(s);
22419 self.write("'");
22420 }
22421 _ => {
22422 self.generate_expression(&e.this)?;
22423 }
22424 }
22425 self.write(")");
22426 }
22427 _ => {
22429 self.write_keyword("DATE");
22430 self.write("(");
22431 self.generate_expression(&e.this)?;
22432 self.write(")");
22433 }
22434 }
22435 Ok(())
22436 }
22437
22438 fn generate_date_bin(&mut self, e: &DateBin) -> Result<()> {
22439 self.write_keyword("DATE_BIN");
22441 self.write("(");
22442 self.generate_expression(&e.this)?;
22443 self.write(", ");
22444 self.generate_expression(&e.expression)?;
22445 if let Some(origin) = &e.origin {
22446 self.write(", ");
22447 self.generate_expression(origin)?;
22448 }
22449 self.write(")");
22450 Ok(())
22451 }
22452
22453 fn generate_date_format_column_constraint(&mut self, e: &DateFormatColumnConstraint) -> Result<()> {
22454 self.write_keyword("FORMAT");
22456 self.write_space();
22457 self.generate_expression(&e.this)?;
22458 Ok(())
22459 }
22460
22461 fn generate_date_from_parts(&mut self, e: &DateFromParts) -> Result<()> {
22462 self.write_keyword("DATE_FROM_PARTS");
22464 self.write("(");
22465 let mut first = true;
22466 if let Some(year) = &e.year {
22467 self.generate_expression(year)?;
22468 first = false;
22469 }
22470 if let Some(month) = &e.month {
22471 if !first {
22472 self.write(", ");
22473 }
22474 self.generate_expression(month)?;
22475 first = false;
22476 }
22477 if let Some(day) = &e.day {
22478 if !first {
22479 self.write(", ");
22480 }
22481 self.generate_expression(day)?;
22482 }
22483 self.write(")");
22484 Ok(())
22485 }
22486
22487 fn generate_datetime(&mut self, e: &Datetime) -> Result<()> {
22488 self.write_keyword("DATETIME");
22490 self.write("(");
22491 self.generate_expression(&e.this)?;
22492 if let Some(expr) = &e.expression {
22493 self.write(", ");
22494 self.generate_expression(expr)?;
22495 }
22496 self.write(")");
22497 Ok(())
22498 }
22499
22500 fn generate_datetime_add(&mut self, e: &DatetimeAdd) -> Result<()> {
22501 self.write_keyword("DATETIME_ADD");
22503 self.write("(");
22504 self.generate_expression(&e.this)?;
22505 self.write(", ");
22506 self.generate_expression(&e.expression)?;
22507 if let Some(unit) = &e.unit {
22508 self.write(", ");
22509 self.write_keyword(unit);
22510 }
22511 self.write(")");
22512 Ok(())
22513 }
22514
22515 fn generate_datetime_diff(&mut self, e: &DatetimeDiff) -> Result<()> {
22516 self.write_keyword("DATETIME_DIFF");
22518 self.write("(");
22519 self.generate_expression(&e.this)?;
22520 self.write(", ");
22521 self.generate_expression(&e.expression)?;
22522 if let Some(unit) = &e.unit {
22523 self.write(", ");
22524 self.write_keyword(unit);
22525 }
22526 self.write(")");
22527 Ok(())
22528 }
22529
22530 fn generate_datetime_sub(&mut self, e: &DatetimeSub) -> Result<()> {
22531 self.write_keyword("DATETIME_SUB");
22533 self.write("(");
22534 self.generate_expression(&e.this)?;
22535 self.write(", ");
22536 self.generate_expression(&e.expression)?;
22537 if let Some(unit) = &e.unit {
22538 self.write(", ");
22539 self.write_keyword(unit);
22540 }
22541 self.write(")");
22542 Ok(())
22543 }
22544
22545 fn generate_datetime_trunc(&mut self, e: &DatetimeTrunc) -> Result<()> {
22546 self.write_keyword("DATETIME_TRUNC");
22548 self.write("(");
22549 self.generate_expression(&e.this)?;
22550 self.write(", ");
22551 self.write_keyword(&e.unit);
22552 if let Some(zone) = &e.zone {
22553 self.write(", ");
22554 self.generate_expression(zone)?;
22555 }
22556 self.write(")");
22557 Ok(())
22558 }
22559
22560 fn generate_dayname(&mut self, e: &Dayname) -> Result<()> {
22561 self.write_keyword("DAYNAME");
22563 self.write("(");
22564 self.generate_expression(&e.this)?;
22565 self.write(")");
22566 Ok(())
22567 }
22568
22569 fn generate_declare(&mut self, e: &Declare) -> Result<()> {
22570 self.write_keyword("DECLARE");
22572 self.write_space();
22573 for (i, expr) in e.expressions.iter().enumerate() {
22574 if i > 0 {
22575 self.write(", ");
22576 }
22577 self.generate_expression(expr)?;
22578 }
22579 Ok(())
22580 }
22581
22582 fn generate_declare_item(&mut self, e: &DeclareItem) -> Result<()> {
22583 use crate::dialects::DialectType;
22584
22585 self.generate_expression(&e.this)?;
22587 for name in &e.additional_names {
22589 self.write(", ");
22590 self.generate_expression(name)?;
22591 }
22592 if let Some(kind) = &e.kind {
22593 self.write_space();
22594 match self.config.dialect {
22598 Some(DialectType::BigQuery) => {
22599 self.write(kind);
22600 }
22601 Some(DialectType::TSQL) => {
22602 let is_complex_table = kind.starts_with("TABLE") &&
22606 (kind.contains("CLUSTERED") || kind.contains("INDEX"));
22607
22608 if is_complex_table {
22609 self.write(kind);
22611 } else {
22612 if !kind.starts_with("CURSOR") {
22614 self.write_keyword("AS");
22615 self.write_space();
22616 }
22617 if kind == "INT" {
22619 self.write("INTEGER");
22620 } else if kind.starts_with("TABLE") {
22621 let normalized = kind
22623 .replace(" INT ", " INTEGER ")
22624 .replace(" INT,", " INTEGER,")
22625 .replace(" INT)", " INTEGER)")
22626 .replace("(INT ", "(INTEGER ");
22627 self.write(&normalized);
22628 } else {
22629 self.write(kind);
22630 }
22631 }
22632 }
22633 _ => {
22634 if e.has_as {
22635 self.write_keyword("AS");
22636 self.write_space();
22637 }
22638 self.write(kind);
22639 }
22640 }
22641 }
22642 if let Some(default) = &e.default {
22643 match self.config.dialect {
22645 Some(DialectType::BigQuery) => {
22646 self.write_space();
22647 self.write_keyword("DEFAULT");
22648 self.write_space();
22649 }
22650 _ => {
22651 self.write(" = ");
22652 }
22653 }
22654 self.generate_expression(default)?;
22655 }
22656 Ok(())
22657 }
22658
22659 fn generate_decode_case(&mut self, e: &DecodeCase) -> Result<()> {
22660 self.write_keyword("DECODE");
22662 self.write("(");
22663 for (i, expr) in e.expressions.iter().enumerate() {
22664 if i > 0 {
22665 self.write(", ");
22666 }
22667 self.generate_expression(expr)?;
22668 }
22669 self.write(")");
22670 Ok(())
22671 }
22672
22673 fn generate_decompress_binary(&mut self, e: &DecompressBinary) -> Result<()> {
22674 self.write_keyword("DECOMPRESS");
22676 self.write("(");
22677 self.generate_expression(&e.this)?;
22678 self.write(", '");
22679 self.write(&e.method);
22680 self.write("')");
22681 Ok(())
22682 }
22683
22684 fn generate_decompress_string(&mut self, e: &DecompressString) -> Result<()> {
22685 self.write_keyword("DECOMPRESS");
22687 self.write("(");
22688 self.generate_expression(&e.this)?;
22689 self.write(", '");
22690 self.write(&e.method);
22691 self.write("')");
22692 Ok(())
22693 }
22694
22695 fn generate_decrypt(&mut self, e: &Decrypt) -> Result<()> {
22696 self.write_keyword("DECRYPT");
22698 self.write("(");
22699 self.generate_expression(&e.this)?;
22700 if let Some(passphrase) = &e.passphrase {
22701 self.write(", ");
22702 self.generate_expression(passphrase)?;
22703 }
22704 if let Some(aad) = &e.aad {
22705 self.write(", ");
22706 self.generate_expression(aad)?;
22707 }
22708 if let Some(method) = &e.encryption_method {
22709 self.write(", ");
22710 self.generate_expression(method)?;
22711 }
22712 self.write(")");
22713 Ok(())
22714 }
22715
22716 fn generate_decrypt_raw(&mut self, e: &DecryptRaw) -> Result<()> {
22717 self.write_keyword("DECRYPT_RAW");
22719 self.write("(");
22720 self.generate_expression(&e.this)?;
22721 if let Some(key) = &e.key {
22722 self.write(", ");
22723 self.generate_expression(key)?;
22724 }
22725 if let Some(iv) = &e.iv {
22726 self.write(", ");
22727 self.generate_expression(iv)?;
22728 }
22729 if let Some(aad) = &e.aad {
22730 self.write(", ");
22731 self.generate_expression(aad)?;
22732 }
22733 if let Some(method) = &e.encryption_method {
22734 self.write(", ");
22735 self.generate_expression(method)?;
22736 }
22737 self.write(")");
22738 Ok(())
22739 }
22740
22741 fn generate_definer_property(&mut self, e: &DefinerProperty) -> Result<()> {
22742 self.write_keyword("DEFINER");
22744 self.write(" = ");
22745 self.generate_expression(&e.this)?;
22746 Ok(())
22747 }
22748
22749 fn generate_detach(&mut self, e: &Detach) -> Result<()> {
22750 self.write_keyword("DETACH");
22752 if e.exists {
22753 self.write_keyword(" DATABASE IF EXISTS");
22754 }
22755 self.write_space();
22756 self.generate_expression(&e.this)?;
22757 Ok(())
22758 }
22759
22760 fn generate_dict_property(&mut self, e: &DictProperty) -> Result<()> {
22761 let property_name = match e.this.as_ref() {
22762 Expression::Identifier(id) => id.name.as_str(),
22763 Expression::Var(v) => v.this.as_str(),
22764 _ => "DICTIONARY",
22765 };
22766 self.write_keyword(property_name);
22767 self.write("(");
22768 self.write(&e.kind);
22769 if let Some(settings) = &e.settings {
22770 self.write("(");
22771 if let Expression::Tuple(t) = settings.as_ref() {
22772 if self.config.pretty && !t.expressions.is_empty() {
22773 self.write_newline();
22774 self.indent_level += 1;
22775 for (i, pair) in t.expressions.iter().enumerate() {
22776 if i > 0 {
22777 self.write(",");
22778 self.write_newline();
22779 }
22780 self.write_indent();
22781 if let Expression::Tuple(pair_tuple) = pair {
22782 if let Some(k) = pair_tuple.expressions.first() {
22783 self.generate_expression(k)?;
22784 }
22785 if let Some(v) = pair_tuple.expressions.get(1) {
22786 self.write(" ");
22787 self.generate_expression(v)?;
22788 }
22789 } else {
22790 self.generate_expression(pair)?;
22791 }
22792 }
22793 self.indent_level -= 1;
22794 self.write_newline();
22795 self.write_indent();
22796 } else {
22797 for (i, pair) in t.expressions.iter().enumerate() {
22798 if i > 0 {
22799 self.write(", ");
22800 }
22801 if let Expression::Tuple(pair_tuple) = pair {
22802 if let Some(k) = pair_tuple.expressions.first() {
22803 self.generate_expression(k)?;
22804 }
22805 if let Some(v) = pair_tuple.expressions.get(1) {
22806 self.write(" ");
22807 self.generate_expression(v)?;
22808 }
22809 } else {
22810 self.generate_expression(pair)?;
22811 }
22812 }
22813 }
22814 } else {
22815 self.generate_expression(settings)?;
22816 }
22817 self.write(")");
22818 } else if property_name.eq_ignore_ascii_case("LAYOUT") {
22819 self.write("()");
22820 }
22821 self.write(")");
22822 Ok(())
22823 }
22824
22825 fn generate_dict_range(&mut self, e: &DictRange) -> Result<()> {
22826 let property_name = match e.this.as_ref() {
22827 Expression::Identifier(id) => id.name.as_str(),
22828 Expression::Var(v) => v.this.as_str(),
22829 _ => "RANGE",
22830 };
22831 self.write_keyword(property_name);
22832 self.write("(");
22833 if let Some(min) = &e.min {
22834 self.write_keyword("MIN");
22835 self.write_space();
22836 self.generate_expression(min)?;
22837 }
22838 if let Some(max) = &e.max {
22839 self.write_space();
22840 self.write_keyword("MAX");
22841 self.write_space();
22842 self.generate_expression(max)?;
22843 }
22844 self.write(")");
22845 Ok(())
22846 }
22847
22848 fn generate_directory(&mut self, e: &Directory) -> Result<()> {
22849 if e.local.is_some() {
22851 self.write_keyword("LOCAL ");
22852 }
22853 self.write_keyword("DIRECTORY");
22854 self.write_space();
22855 self.generate_expression(&e.this)?;
22856 if let Some(row_format) = &e.row_format {
22857 self.write_space();
22858 self.generate_expression(row_format)?;
22859 }
22860 Ok(())
22861 }
22862
22863 fn generate_dist_key_property(&mut self, e: &DistKeyProperty) -> Result<()> {
22864 self.write_keyword("DISTKEY");
22866 self.write("(");
22867 self.generate_expression(&e.this)?;
22868 self.write(")");
22869 Ok(())
22870 }
22871
22872 fn generate_dist_style_property(&mut self, e: &DistStyleProperty) -> Result<()> {
22873 self.write_keyword("DISTSTYLE");
22875 self.write_space();
22876 self.generate_expression(&e.this)?;
22877 Ok(())
22878 }
22879
22880 fn generate_distribute_by(&mut self, e: &DistributeBy) -> Result<()> {
22881 self.write_keyword("DISTRIBUTE BY");
22883 self.write_space();
22884 for (i, expr) in e.expressions.iter().enumerate() {
22885 if i > 0 {
22886 self.write(", ");
22887 }
22888 self.generate_expression(expr)?;
22889 }
22890 Ok(())
22891 }
22892
22893 fn generate_distributed_by_property(&mut self, e: &DistributedByProperty) -> Result<()> {
22894 self.write_keyword("DISTRIBUTED BY");
22896 self.write_space();
22897 self.write(&e.kind);
22898 if !e.expressions.is_empty() {
22899 self.write(" (");
22900 for (i, expr) in e.expressions.iter().enumerate() {
22901 if i > 0 {
22902 self.write(", ");
22903 }
22904 self.generate_expression(expr)?;
22905 }
22906 self.write(")");
22907 }
22908 if let Some(buckets) = &e.buckets {
22909 self.write_space();
22910 self.write_keyword("BUCKETS");
22911 self.write_space();
22912 self.generate_expression(buckets)?;
22913 }
22914 if let Some(order) = &e.order {
22915 self.write_space();
22916 self.generate_expression(order)?;
22917 }
22918 Ok(())
22919 }
22920
22921 fn generate_dot_product(&mut self, e: &DotProduct) -> Result<()> {
22922 self.write_keyword("DOT_PRODUCT");
22924 self.write("(");
22925 self.generate_expression(&e.this)?;
22926 self.write(", ");
22927 self.generate_expression(&e.expression)?;
22928 self.write(")");
22929 Ok(())
22930 }
22931
22932 fn generate_drop_partition(&mut self, e: &DropPartition) -> Result<()> {
22933 self.write_keyword("DROP");
22935 if e.exists {
22936 self.write_keyword(" IF EXISTS ");
22937 } else {
22938 self.write_space();
22939 }
22940 for (i, expr) in e.expressions.iter().enumerate() {
22941 if i > 0 {
22942 self.write(", ");
22943 }
22944 self.generate_expression(expr)?;
22945 }
22946 Ok(())
22947 }
22948
22949 fn generate_duplicate_key_property(&mut self, e: &DuplicateKeyProperty) -> Result<()> {
22950 self.write_keyword("DUPLICATE KEY");
22952 self.write(" (");
22953 for (i, expr) in e.expressions.iter().enumerate() {
22954 if i > 0 {
22955 self.write(", ");
22956 }
22957 self.generate_expression(expr)?;
22958 }
22959 self.write(")");
22960 Ok(())
22961 }
22962
22963 fn generate_elt(&mut self, e: &Elt) -> Result<()> {
22964 self.write_keyword("ELT");
22966 self.write("(");
22967 self.generate_expression(&e.this)?;
22968 for expr in &e.expressions {
22969 self.write(", ");
22970 self.generate_expression(expr)?;
22971 }
22972 self.write(")");
22973 Ok(())
22974 }
22975
22976 fn generate_encode(&mut self, e: &Encode) -> Result<()> {
22977 self.write_keyword("ENCODE");
22979 self.write("(");
22980 self.generate_expression(&e.this)?;
22981 if let Some(charset) = &e.charset {
22982 self.write(", ");
22983 self.generate_expression(charset)?;
22984 }
22985 self.write(")");
22986 Ok(())
22987 }
22988
22989 fn generate_encode_property(&mut self, e: &EncodeProperty) -> Result<()> {
22990 if e.key.is_some() {
22992 self.write_keyword("KEY ");
22993 }
22994 self.write_keyword("ENCODE");
22995 self.write_space();
22996 self.generate_expression(&e.this)?;
22997 if !e.properties.is_empty() {
22998 self.write(" (");
22999 for (i, prop) in e.properties.iter().enumerate() {
23000 if i > 0 {
23001 self.write(", ");
23002 }
23003 self.generate_expression(prop)?;
23004 }
23005 self.write(")");
23006 }
23007 Ok(())
23008 }
23009
23010 fn generate_encrypt(&mut self, e: &Encrypt) -> Result<()> {
23011 self.write_keyword("ENCRYPT");
23013 self.write("(");
23014 self.generate_expression(&e.this)?;
23015 if let Some(passphrase) = &e.passphrase {
23016 self.write(", ");
23017 self.generate_expression(passphrase)?;
23018 }
23019 if let Some(aad) = &e.aad {
23020 self.write(", ");
23021 self.generate_expression(aad)?;
23022 }
23023 if let Some(method) = &e.encryption_method {
23024 self.write(", ");
23025 self.generate_expression(method)?;
23026 }
23027 self.write(")");
23028 Ok(())
23029 }
23030
23031 fn generate_encrypt_raw(&mut self, e: &EncryptRaw) -> Result<()> {
23032 self.write_keyword("ENCRYPT_RAW");
23034 self.write("(");
23035 self.generate_expression(&e.this)?;
23036 if let Some(key) = &e.key {
23037 self.write(", ");
23038 self.generate_expression(key)?;
23039 }
23040 if let Some(iv) = &e.iv {
23041 self.write(", ");
23042 self.generate_expression(iv)?;
23043 }
23044 if let Some(aad) = &e.aad {
23045 self.write(", ");
23046 self.generate_expression(aad)?;
23047 }
23048 if let Some(method) = &e.encryption_method {
23049 self.write(", ");
23050 self.generate_expression(method)?;
23051 }
23052 self.write(")");
23053 Ok(())
23054 }
23055
23056 fn generate_engine_property(&mut self, e: &EngineProperty) -> Result<()> {
23057 self.write_keyword("ENGINE");
23059 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
23060 self.write("=");
23061 } else {
23062 self.write(" = ");
23063 }
23064 self.generate_expression(&e.this)?;
23065 Ok(())
23066 }
23067
23068 fn generate_enviroment_property(&mut self, e: &EnviromentProperty) -> Result<()> {
23069 self.write_keyword("ENVIRONMENT");
23071 self.write(" (");
23072 for (i, expr) in e.expressions.iter().enumerate() {
23073 if i > 0 {
23074 self.write(", ");
23075 }
23076 self.generate_expression(expr)?;
23077 }
23078 self.write(")");
23079 Ok(())
23080 }
23081
23082 fn generate_ephemeral_column_constraint(&mut self, e: &EphemeralColumnConstraint) -> Result<()> {
23083 self.write_keyword("EPHEMERAL");
23085 if let Some(this) = &e.this {
23086 self.write_space();
23087 self.generate_expression(this)?;
23088 }
23089 Ok(())
23090 }
23091
23092 fn generate_equal_null(&mut self, e: &EqualNull) -> Result<()> {
23093 self.write_keyword("EQUAL_NULL");
23095 self.write("(");
23096 self.generate_expression(&e.this)?;
23097 self.write(", ");
23098 self.generate_expression(&e.expression)?;
23099 self.write(")");
23100 Ok(())
23101 }
23102
23103 fn generate_euclidean_distance(&mut self, e: &EuclideanDistance) -> Result<()> {
23104 use crate::dialects::DialectType;
23105
23106 match self.config.dialect {
23108 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
23109 self.generate_expression(&e.this)?;
23110 self.write(" <-> ");
23111 self.generate_expression(&e.expression)?;
23112 }
23113 _ => {
23114 self.write_keyword("EUCLIDEAN_DISTANCE");
23116 self.write("(");
23117 self.generate_expression(&e.this)?;
23118 self.write(", ");
23119 self.generate_expression(&e.expression)?;
23120 self.write(")");
23121 }
23122 }
23123 Ok(())
23124 }
23125
23126 fn generate_execute_as_property(&mut self, e: &ExecuteAsProperty) -> Result<()> {
23127 self.write_keyword("EXECUTE AS");
23129 self.write_space();
23130 self.generate_expression(&e.this)?;
23131 Ok(())
23132 }
23133
23134 fn generate_export(&mut self, e: &Export) -> Result<()> {
23135 self.write_keyword("EXPORT DATA");
23137 if let Some(connection) = &e.connection {
23138 self.write_space();
23139 self.write_keyword("WITH CONNECTION");
23140 self.write_space();
23141 self.generate_expression(connection)?;
23142 }
23143 if !e.options.is_empty() {
23144 self.write_space();
23145 self.generate_options_clause(&e.options)?;
23146 }
23147 self.write_space();
23148 self.write_keyword("AS");
23149 self.write_space();
23150 self.generate_expression(&e.this)?;
23151 Ok(())
23152 }
23153
23154 fn generate_external_property(&mut self, e: &ExternalProperty) -> Result<()> {
23155 self.write_keyword("EXTERNAL");
23157 if let Some(this) = &e.this {
23158 self.write_space();
23159 self.generate_expression(this)?;
23160 }
23161 Ok(())
23162 }
23163
23164 fn generate_fallback_property(&mut self, e: &FallbackProperty) -> Result<()> {
23165 if e.no.is_some() {
23167 self.write_keyword("NO ");
23168 }
23169 self.write_keyword("FALLBACK");
23170 if e.protection.is_some() {
23171 self.write_keyword(" PROTECTION");
23172 }
23173 Ok(())
23174 }
23175
23176 fn generate_farm_fingerprint(&mut self, e: &FarmFingerprint) -> Result<()> {
23177 self.write_keyword("FARM_FINGERPRINT");
23179 self.write("(");
23180 for (i, expr) in e.expressions.iter().enumerate() {
23181 if i > 0 {
23182 self.write(", ");
23183 }
23184 self.generate_expression(expr)?;
23185 }
23186 self.write(")");
23187 Ok(())
23188 }
23189
23190 fn generate_features_at_time(&mut self, e: &FeaturesAtTime) -> Result<()> {
23191 self.write_keyword("FEATURES_AT_TIME");
23193 self.write("(");
23194 self.generate_expression(&e.this)?;
23195 if let Some(time) = &e.time {
23196 self.write(", ");
23197 self.generate_expression(time)?;
23198 }
23199 if let Some(num_rows) = &e.num_rows {
23200 self.write(", ");
23201 self.generate_expression(num_rows)?;
23202 }
23203 if let Some(ignore_nulls) = &e.ignore_feature_nulls {
23204 self.write(", ");
23205 self.generate_expression(ignore_nulls)?;
23206 }
23207 self.write(")");
23208 Ok(())
23209 }
23210
23211 fn generate_fetch(&mut self, e: &Fetch) -> Result<()> {
23212 let use_limit = !e.percent && !e.with_ties && e.count.is_some() && matches!(
23214 self.config.dialect,
23215 Some(DialectType::Spark) | Some(DialectType::Hive)
23216 | Some(DialectType::DuckDB) | Some(DialectType::SQLite) | Some(DialectType::MySQL)
23217 | Some(DialectType::BigQuery) | Some(DialectType::Databricks) | Some(DialectType::StarRocks)
23218 | Some(DialectType::Doris) | Some(DialectType::Athena) | Some(DialectType::ClickHouse)
23219 );
23220
23221 if use_limit {
23222 self.write_keyword("LIMIT");
23223 self.write_space();
23224 self.generate_expression(e.count.as_ref().unwrap())?;
23225 return Ok(());
23226 }
23227
23228 self.write_keyword("FETCH");
23230 if !e.direction.is_empty() {
23231 self.write_space();
23232 self.write_keyword(&e.direction);
23233 }
23234 if let Some(count) = &e.count {
23235 self.write_space();
23236 self.generate_expression(count)?;
23237 }
23238 if e.percent {
23240 self.write_keyword(" PERCENT");
23241 }
23242 if e.rows {
23243 self.write_keyword(" ROWS");
23244 }
23245 if e.with_ties {
23246 self.write_keyword(" WITH TIES");
23247 } else if e.rows {
23248 self.write_keyword(" ONLY");
23249 } else {
23250 self.write_keyword(" ROWS ONLY");
23251 }
23252 Ok(())
23253 }
23254
23255 fn generate_file_format_property(&mut self, e: &FileFormatProperty) -> Result<()> {
23256 if e.hive_format.is_some() {
23260 self.write_keyword("STORED AS");
23262 self.write_space();
23263 if let Some(this) = &e.this {
23264 if let Expression::Identifier(id) = this.as_ref() {
23266 self.write_keyword(&id.name.to_uppercase());
23267 } else {
23268 self.generate_expression(this)?;
23269 }
23270 }
23271 } else if matches!(self.config.dialect, Some(DialectType::Hive)) {
23272 self.write_keyword("STORED AS");
23274 self.write_space();
23275 if let Some(this) = &e.this {
23276 if let Expression::Identifier(id) = this.as_ref() {
23277 self.write_keyword(&id.name.to_uppercase());
23278 } else {
23279 self.generate_expression(this)?;
23280 }
23281 }
23282 } else if matches!(self.config.dialect, Some(DialectType::Spark) | Some(DialectType::Databricks)) {
23283 self.write_keyword("USING");
23285 self.write_space();
23286 if let Some(this) = &e.this {
23287 self.generate_expression(this)?;
23288 }
23289 } else {
23290 self.write_keyword("FILE_FORMAT");
23292 self.write(" = ");
23293 if let Some(this) = &e.this {
23294 self.generate_expression(this)?;
23295 } else if !e.expressions.is_empty() {
23296 self.write("(");
23297 for (i, expr) in e.expressions.iter().enumerate() {
23298 if i > 0 {
23299 self.write(", ");
23300 }
23301 self.generate_expression(expr)?;
23302 }
23303 self.write(")");
23304 }
23305 }
23306 Ok(())
23307 }
23308
23309 fn generate_filter(&mut self, e: &Filter) -> Result<()> {
23310 self.generate_expression(&e.this)?;
23312 self.write_space();
23313 self.write_keyword("FILTER");
23314 self.write("(");
23315 self.write_keyword("WHERE");
23316 self.write_space();
23317 self.generate_expression(&e.expression)?;
23318 self.write(")");
23319 Ok(())
23320 }
23321
23322 fn generate_float64(&mut self, e: &Float64) -> Result<()> {
23323 self.write_keyword("FLOAT64");
23325 self.write("(");
23326 self.generate_expression(&e.this)?;
23327 if let Some(expr) = &e.expression {
23328 self.write(", ");
23329 self.generate_expression(expr)?;
23330 }
23331 self.write(")");
23332 Ok(())
23333 }
23334
23335 fn generate_for_in(&mut self, e: &ForIn) -> Result<()> {
23336 self.write_keyword("FOR");
23338 self.write_space();
23339 self.generate_expression(&e.this)?;
23340 self.write_space();
23341 self.write_keyword("DO");
23342 self.write_space();
23343 self.generate_expression(&e.expression)?;
23344 Ok(())
23345 }
23346
23347 fn generate_foreign_key(&mut self, e: &ForeignKey) -> Result<()> {
23348 self.write_keyword("FOREIGN KEY");
23350 if !e.expressions.is_empty() {
23351 self.write(" (");
23352 for (i, expr) in e.expressions.iter().enumerate() {
23353 if i > 0 {
23354 self.write(", ");
23355 }
23356 self.generate_expression(expr)?;
23357 }
23358 self.write(")");
23359 }
23360 if let Some(reference) = &e.reference {
23361 self.write_space();
23362 self.generate_expression(reference)?;
23363 }
23364 if let Some(delete) = &e.delete {
23365 self.write_space();
23366 self.write_keyword("ON DELETE");
23367 self.write_space();
23368 self.generate_expression(delete)?;
23369 }
23370 if let Some(update) = &e.update {
23371 self.write_space();
23372 self.write_keyword("ON UPDATE");
23373 self.write_space();
23374 self.generate_expression(update)?;
23375 }
23376 if !e.options.is_empty() {
23377 self.write_space();
23378 for (i, opt) in e.options.iter().enumerate() {
23379 if i > 0 {
23380 self.write_space();
23381 }
23382 self.generate_expression(opt)?;
23383 }
23384 }
23385 Ok(())
23386 }
23387
23388 fn generate_format(&mut self, e: &Format) -> Result<()> {
23389 self.write_keyword("FORMAT");
23391 self.write("(");
23392 self.generate_expression(&e.this)?;
23393 for expr in &e.expressions {
23394 self.write(", ");
23395 self.generate_expression(expr)?;
23396 }
23397 self.write(")");
23398 Ok(())
23399 }
23400
23401 fn generate_format_phrase(&mut self, e: &FormatPhrase) -> Result<()> {
23402 self.generate_expression(&e.this)?;
23404 self.write(" (");
23405 self.write_keyword("FORMAT");
23406 self.write(" '");
23407 self.write(&e.format);
23408 self.write("')");
23409 Ok(())
23410 }
23411
23412 fn generate_freespace_property(&mut self, e: &FreespaceProperty) -> Result<()> {
23413 self.write_keyword("FREESPACE");
23415 self.write("=");
23416 self.generate_expression(&e.this)?;
23417 if e.percent.is_some() {
23418 self.write_keyword(" PERCENT");
23419 }
23420 Ok(())
23421 }
23422
23423 fn generate_from(&mut self, e: &From) -> Result<()> {
23424 self.write_keyword("FROM");
23426 self.write_space();
23427
23428 use crate::dialects::DialectType;
23431 let has_tablesample = e.expressions.iter().any(|expr| matches!(expr, Expression::TableSample(_)));
23432 let use_cross_join = !has_tablesample && matches!(
23433 self.config.dialect,
23434 Some(DialectType::BigQuery)
23435 | Some(DialectType::Hive)
23436 | Some(DialectType::Spark)
23437 | Some(DialectType::Databricks)
23438 | Some(DialectType::SQLite)
23439 | Some(DialectType::ClickHouse)
23440 );
23441
23442 let wrap_values_in_parens = matches!(
23444 self.config.dialect,
23445 Some(DialectType::Snowflake)
23446 );
23447
23448 for (i, expr) in e.expressions.iter().enumerate() {
23449 if i > 0 {
23450 if use_cross_join {
23451 self.write(" CROSS JOIN ");
23452 } else {
23453 self.write(", ");
23454 }
23455 }
23456 if wrap_values_in_parens && matches!(expr, Expression::Values(_)) {
23457 self.write("(");
23458 self.generate_expression(expr)?;
23459 self.write(")");
23460 } else {
23461 self.generate_expression(expr)?;
23462 }
23463 }
23464 Ok(())
23465 }
23466
23467 fn generate_from_base(&mut self, e: &FromBase) -> Result<()> {
23468 self.write_keyword("FROM_BASE");
23470 self.write("(");
23471 self.generate_expression(&e.this)?;
23472 self.write(", ");
23473 self.generate_expression(&e.expression)?;
23474 self.write(")");
23475 Ok(())
23476 }
23477
23478 fn generate_from_time_zone(&mut self, e: &FromTimeZone) -> Result<()> {
23479 self.generate_expression(&e.this)?;
23481 if let Some(zone) = &e.zone {
23482 self.write_space();
23483 self.write_keyword("AT TIME ZONE");
23484 self.write_space();
23485 self.generate_expression(zone)?;
23486 self.write_space();
23487 self.write_keyword("AT TIME ZONE");
23488 self.write(" 'UTC'");
23489 }
23490 Ok(())
23491 }
23492
23493 fn generate_gap_fill(&mut self, e: &GapFill) -> Result<()> {
23494 self.write_keyword("GAP_FILL");
23496 self.write("(");
23497 self.generate_expression(&e.this)?;
23498 if let Some(ts_column) = &e.ts_column {
23499 self.write(", ");
23500 self.generate_expression(ts_column)?;
23501 }
23502 if let Some(bucket_width) = &e.bucket_width {
23503 self.write(", ");
23504 self.generate_expression(bucket_width)?;
23505 }
23506 if let Some(partitioning_columns) = &e.partitioning_columns {
23507 self.write(", ");
23508 self.generate_expression(partitioning_columns)?;
23509 }
23510 if let Some(value_columns) = &e.value_columns {
23511 self.write(", ");
23512 self.generate_expression(value_columns)?;
23513 }
23514 self.write(")");
23515 Ok(())
23516 }
23517
23518 fn generate_generate_date_array(&mut self, e: &GenerateDateArray) -> Result<()> {
23519 self.write_keyword("GENERATE_DATE_ARRAY");
23521 self.write("(");
23522 let mut first = true;
23523 if let Some(start) = &e.start {
23524 self.generate_expression(start)?;
23525 first = false;
23526 }
23527 if let Some(end) = &e.end {
23528 if !first {
23529 self.write(", ");
23530 }
23531 self.generate_expression(end)?;
23532 first = false;
23533 }
23534 if let Some(step) = &e.step {
23535 if !first {
23536 self.write(", ");
23537 }
23538 self.generate_expression(step)?;
23539 }
23540 self.write(")");
23541 Ok(())
23542 }
23543
23544 fn generate_generate_embedding(&mut self, e: &GenerateEmbedding) -> Result<()> {
23545 self.write_keyword("ML.GENERATE_EMBEDDING");
23547 self.write("(");
23548 self.generate_expression(&e.this)?;
23549 self.write(", ");
23550 self.generate_expression(&e.expression)?;
23551 if let Some(params) = &e.params_struct {
23552 self.write(", ");
23553 self.generate_expression(params)?;
23554 }
23555 self.write(")");
23556 Ok(())
23557 }
23558
23559 fn generate_generate_series(&mut self, e: &GenerateSeries) -> Result<()> {
23560 self.write_keyword("GENERATE_SERIES");
23562 self.write("(");
23563 let mut first = true;
23564 if let Some(start) = &e.start {
23565 self.generate_expression(start)?;
23566 first = false;
23567 }
23568 if let Some(end) = &e.end {
23569 if !first {
23570 self.write(", ");
23571 }
23572 self.generate_expression(end)?;
23573 first = false;
23574 }
23575 if let Some(step) = &e.step {
23576 if !first {
23577 self.write(", ");
23578 }
23579 self.generate_expression(step)?;
23580 }
23581 self.write(")");
23582 Ok(())
23583 }
23584
23585 fn generate_generate_timestamp_array(&mut self, e: &GenerateTimestampArray) -> Result<()> {
23586 self.write_keyword("GENERATE_TIMESTAMP_ARRAY");
23588 self.write("(");
23589 let mut first = true;
23590 if let Some(start) = &e.start {
23591 self.generate_expression(start)?;
23592 first = false;
23593 }
23594 if let Some(end) = &e.end {
23595 if !first {
23596 self.write(", ");
23597 }
23598 self.generate_expression(end)?;
23599 first = false;
23600 }
23601 if let Some(step) = &e.step {
23602 if !first {
23603 self.write(", ");
23604 }
23605 self.generate_expression(step)?;
23606 }
23607 self.write(")");
23608 Ok(())
23609 }
23610
23611 fn generate_generated_as_identity_column_constraint(&mut self, e: &GeneratedAsIdentityColumnConstraint) -> Result<()> {
23612 use crate::dialects::DialectType;
23613
23614 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
23616 self.write_keyword("AUTOINCREMENT");
23617 if let Some(start) = &e.start {
23618 self.write_keyword(" START ");
23619 self.generate_expression(start)?;
23620 }
23621 if let Some(increment) = &e.increment {
23622 self.write_keyword(" INCREMENT ");
23623 self.generate_expression(increment)?;
23624 }
23625 return Ok(());
23626 }
23627
23628 self.write_keyword("GENERATED");
23630 if let Some(this) = &e.this {
23631 if let Expression::Boolean(b) = this.as_ref() {
23633 if b.value {
23634 self.write_keyword(" ALWAYS");
23635 } else {
23636 self.write_keyword(" BY DEFAULT");
23637 if e.on_null.is_some() {
23638 self.write_keyword(" ON NULL");
23639 }
23640 }
23641 } else {
23642 self.write_keyword(" ALWAYS");
23643 }
23644 }
23645 self.write_keyword(" AS IDENTITY");
23646 let has_options = e.start.is_some() || e.increment.is_some() || e.minvalue.is_some() || e.maxvalue.is_some();
23648 if has_options {
23649 self.write(" (");
23650 let mut first = true;
23651 if let Some(start) = &e.start {
23652 self.write_keyword("START WITH ");
23653 self.generate_expression(start)?;
23654 first = false;
23655 }
23656 if let Some(increment) = &e.increment {
23657 if !first { self.write(" "); }
23658 self.write_keyword("INCREMENT BY ");
23659 self.generate_expression(increment)?;
23660 first = false;
23661 }
23662 if let Some(minvalue) = &e.minvalue {
23663 if !first { self.write(" "); }
23664 self.write_keyword("MINVALUE ");
23665 self.generate_expression(minvalue)?;
23666 first = false;
23667 }
23668 if let Some(maxvalue) = &e.maxvalue {
23669 if !first { self.write(" "); }
23670 self.write_keyword("MAXVALUE ");
23671 self.generate_expression(maxvalue)?;
23672 }
23673 self.write(")");
23674 }
23675 Ok(())
23676 }
23677
23678 fn generate_generated_as_row_column_constraint(&mut self, e: &GeneratedAsRowColumnConstraint) -> Result<()> {
23679 self.write_keyword("GENERATED ALWAYS AS ROW ");
23681 if e.start.is_some() {
23682 self.write_keyword("START");
23683 } else {
23684 self.write_keyword("END");
23685 }
23686 if e.hidden.is_some() {
23687 self.write_keyword(" HIDDEN");
23688 }
23689 Ok(())
23690 }
23691
23692 fn generate_get(&mut self, e: &Get) -> Result<()> {
23693 self.write_keyword("GET");
23695 self.write_space();
23696 self.generate_expression(&e.this)?;
23697 if let Some(target) = &e.target {
23698 self.write_space();
23699 self.generate_expression(target)?;
23700 }
23701 for prop in &e.properties {
23702 self.write_space();
23703 self.generate_expression(prop)?;
23704 }
23705 Ok(())
23706 }
23707
23708 fn generate_get_extract(&mut self, e: &GetExtract) -> Result<()> {
23709 self.generate_expression(&e.this)?;
23711 self.write("[");
23712 self.generate_expression(&e.expression)?;
23713 self.write("]");
23714 Ok(())
23715 }
23716
23717 fn generate_getbit(&mut self, e: &Getbit) -> Result<()> {
23718 self.write_keyword("GETBIT");
23720 self.write("(");
23721 self.generate_expression(&e.this)?;
23722 self.write(", ");
23723 self.generate_expression(&e.expression)?;
23724 self.write(")");
23725 Ok(())
23726 }
23727
23728 fn generate_grant_principal(&mut self, e: &GrantPrincipal) -> Result<()> {
23729 if e.is_role {
23731 self.write_keyword("ROLE");
23732 self.write_space();
23733 } else if e.is_group {
23734 self.write_keyword("GROUP");
23735 self.write_space();
23736 }
23737 self.write(&e.name.name);
23738 Ok(())
23739 }
23740
23741 fn generate_grant_privilege(&mut self, e: &GrantPrivilege) -> Result<()> {
23742 self.generate_expression(&e.this)?;
23744 if !e.expressions.is_empty() {
23745 self.write("(");
23746 for (i, expr) in e.expressions.iter().enumerate() {
23747 if i > 0 {
23748 self.write(", ");
23749 }
23750 self.generate_expression(expr)?;
23751 }
23752 self.write(")");
23753 }
23754 Ok(())
23755 }
23756
23757 fn generate_group(&mut self, e: &Group) -> Result<()> {
23758 self.write_keyword("GROUP BY");
23760 match e.all {
23762 Some(true) => {
23763 self.write_space();
23764 self.write_keyword("ALL");
23765 }
23766 Some(false) => {
23767 self.write_space();
23768 self.write_keyword("DISTINCT");
23769 }
23770 None => {}
23771 }
23772 if !e.expressions.is_empty() {
23773 self.write_space();
23774 for (i, expr) in e.expressions.iter().enumerate() {
23775 if i > 0 {
23776 self.write(", ");
23777 }
23778 self.generate_expression(expr)?;
23779 }
23780 }
23781 if let Some(cube) = &e.cube {
23783 if !e.expressions.is_empty() {
23784 self.write(", ");
23785 } else {
23786 self.write_space();
23787 }
23788 self.generate_expression(cube)?;
23789 }
23790 if let Some(rollup) = &e.rollup {
23791 if !e.expressions.is_empty() || e.cube.is_some() {
23792 self.write(", ");
23793 } else {
23794 self.write_space();
23795 }
23796 self.generate_expression(rollup)?;
23797 }
23798 if let Some(grouping_sets) = &e.grouping_sets {
23799 if !e.expressions.is_empty() || e.cube.is_some() || e.rollup.is_some() {
23800 self.write(", ");
23801 } else {
23802 self.write_space();
23803 }
23804 self.generate_expression(grouping_sets)?;
23805 }
23806 if let Some(totals) = &e.totals {
23807 self.write_space();
23808 self.write_keyword("WITH TOTALS");
23809 self.generate_expression(totals)?;
23810 }
23811 Ok(())
23812 }
23813
23814 fn generate_group_by(&mut self, e: &GroupBy) -> Result<()> {
23815 self.write_keyword("GROUP BY");
23817 match e.all {
23819 Some(true) => {
23820 self.write_space();
23821 self.write_keyword("ALL");
23822 }
23823 Some(false) => {
23824 self.write_space();
23825 self.write_keyword("DISTINCT");
23826 }
23827 None => {}
23828 }
23829
23830 let mut trailing_cube = false;
23833 let mut trailing_rollup = false;
23834 let mut regular_expressions: Vec<&Expression> = Vec::new();
23835
23836 for expr in &e.expressions {
23837 match expr {
23838 Expression::Cube(c) if c.expressions.is_empty() => {
23839 trailing_cube = true;
23840 }
23841 Expression::Rollup(r) if r.expressions.is_empty() => {
23842 trailing_rollup = true;
23843 }
23844 _ => {
23845 regular_expressions.push(expr);
23846 }
23847 }
23848 }
23849
23850 if self.config.pretty {
23852 self.write_newline();
23853 self.indent_level += 1;
23854 for (i, expr) in regular_expressions.iter().enumerate() {
23855 if i > 0 {
23856 self.write(",");
23857 self.write_newline();
23858 }
23859 self.write_indent();
23860 self.generate_expression(expr)?;
23861 }
23862 self.indent_level -= 1;
23863 } else {
23864 self.write_space();
23865 for (i, expr) in regular_expressions.iter().enumerate() {
23866 if i > 0 {
23867 self.write(", ");
23868 }
23869 self.generate_expression(expr)?;
23870 }
23871 }
23872
23873 if trailing_cube {
23875 self.write_space();
23876 self.write_keyword("WITH CUBE");
23877 } else if trailing_rollup {
23878 self.write_space();
23879 self.write_keyword("WITH ROLLUP");
23880 }
23881
23882 if e.totals {
23884 self.write_space();
23885 self.write_keyword("WITH TOTALS");
23886 }
23887
23888 Ok(())
23889 }
23890
23891 fn generate_grouping(&mut self, e: &Grouping) -> Result<()> {
23892 self.write_keyword("GROUPING");
23894 self.write("(");
23895 for (i, expr) in e.expressions.iter().enumerate() {
23896 if i > 0 {
23897 self.write(", ");
23898 }
23899 self.generate_expression(expr)?;
23900 }
23901 self.write(")");
23902 Ok(())
23903 }
23904
23905 fn generate_grouping_id(&mut self, e: &GroupingId) -> Result<()> {
23906 self.write_keyword("GROUPING_ID");
23908 self.write("(");
23909 for (i, expr) in e.expressions.iter().enumerate() {
23910 if i > 0 {
23911 self.write(", ");
23912 }
23913 self.generate_expression(expr)?;
23914 }
23915 self.write(")");
23916 Ok(())
23917 }
23918
23919 fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> {
23920 self.write_keyword("GROUPING SETS");
23922 self.write(" (");
23923 for (i, expr) in e.expressions.iter().enumerate() {
23924 if i > 0 {
23925 self.write(", ");
23926 }
23927 self.generate_expression(expr)?;
23928 }
23929 self.write(")");
23930 Ok(())
23931 }
23932
23933 fn generate_hash_agg(&mut self, e: &HashAgg) -> Result<()> {
23934 self.write_keyword("HASH_AGG");
23936 self.write("(");
23937 self.generate_expression(&e.this)?;
23938 for expr in &e.expressions {
23939 self.write(", ");
23940 self.generate_expression(expr)?;
23941 }
23942 self.write(")");
23943 Ok(())
23944 }
23945
23946 fn generate_having(&mut self, e: &Having) -> Result<()> {
23947 self.write_keyword("HAVING");
23949 self.write_space();
23950 self.generate_expression(&e.this)?;
23951 Ok(())
23952 }
23953
23954 fn generate_having_max(&mut self, e: &HavingMax) -> Result<()> {
23955 self.generate_expression(&e.this)?;
23957 self.write_space();
23958 self.write_keyword("HAVING");
23959 self.write_space();
23960 if e.max.is_some() {
23961 self.write_keyword("MAX");
23962 } else {
23963 self.write_keyword("MIN");
23964 }
23965 self.write_space();
23966 self.generate_expression(&e.expression)?;
23967 Ok(())
23968 }
23969
23970 fn generate_heredoc(&mut self, e: &Heredoc) -> Result<()> {
23971 use crate::dialects::DialectType;
23972 if matches!(self.config.dialect, Some(DialectType::DuckDB)) {
23974 if let Expression::Literal(Literal::String(ref s)) = *e.this {
23976 return self.generate_string_literal(s);
23977 }
23978 }
23979 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) {
23981 self.write("$");
23982 if let Some(tag) = &e.tag {
23983 self.generate_expression(tag)?;
23984 }
23985 self.write("$");
23986 self.generate_expression(&e.this)?;
23987 self.write("$");
23988 if let Some(tag) = &e.tag {
23989 self.generate_expression(tag)?;
23990 }
23991 self.write("$");
23992 return Ok(());
23993 }
23994 self.write("$");
23996 if let Some(tag) = &e.tag {
23997 self.generate_expression(tag)?;
23998 }
23999 self.write("$");
24000 self.generate_expression(&e.this)?;
24001 self.write("$");
24002 if let Some(tag) = &e.tag {
24003 self.generate_expression(tag)?;
24004 }
24005 self.write("$");
24006 Ok(())
24007 }
24008
24009 fn generate_hex_encode(&mut self, e: &HexEncode) -> Result<()> {
24010 self.write_keyword("HEX_ENCODE");
24012 self.write("(");
24013 self.generate_expression(&e.this)?;
24014 self.write(")");
24015 Ok(())
24016 }
24017
24018 fn generate_historical_data(&mut self, e: &HistoricalData) -> Result<()> {
24019 match e.this.as_ref() {
24022 Expression::Identifier(id) => self.write(&id.name),
24023 other => self.generate_expression(other)?,
24024 }
24025 self.write(" (");
24026 self.write(&e.kind);
24027 self.write(" => ");
24028 self.generate_expression(&e.expression)?;
24029 self.write(")");
24030 Ok(())
24031 }
24032
24033 fn generate_hll(&mut self, e: &Hll) -> Result<()> {
24034 self.write_keyword("HLL");
24036 self.write("(");
24037 self.generate_expression(&e.this)?;
24038 for expr in &e.expressions {
24039 self.write(", ");
24040 self.generate_expression(expr)?;
24041 }
24042 self.write(")");
24043 Ok(())
24044 }
24045
24046 fn generate_in_out_column_constraint(&mut self, e: &InOutColumnConstraint) -> Result<()> {
24047 if e.input_.is_some() && e.output.is_some() {
24049 self.write_keyword("IN OUT");
24050 } else if e.input_.is_some() {
24051 self.write_keyword("IN");
24052 } else if e.output.is_some() {
24053 self.write_keyword("OUT");
24054 }
24055 Ok(())
24056 }
24057
24058 fn generate_include_property(&mut self, e: &IncludeProperty) -> Result<()> {
24059 self.write_keyword("INCLUDE");
24061 self.write_space();
24062 self.generate_expression(&e.this)?;
24063 if let Some(column_def) = &e.column_def {
24064 self.write_space();
24065 self.generate_expression(column_def)?;
24066 }
24067 if let Some(alias) = &e.alias {
24068 self.write_space();
24069 self.write_keyword("AS");
24070 self.write_space();
24071 self.write(alias);
24072 }
24073 Ok(())
24074 }
24075
24076 fn generate_index(&mut self, e: &Index) -> Result<()> {
24077 if e.unique {
24079 self.write_keyword("UNIQUE");
24080 self.write_space();
24081 }
24082 if e.primary.is_some() {
24083 self.write_keyword("PRIMARY");
24084 self.write_space();
24085 }
24086 if e.amp.is_some() {
24087 self.write_keyword("AMP");
24088 self.write_space();
24089 }
24090 if e.table.is_none() {
24091 self.write_keyword("INDEX");
24092 self.write_space();
24093 }
24094 if let Some(name) = &e.this {
24095 self.generate_expression(name)?;
24096 self.write_space();
24097 }
24098 if let Some(table) = &e.table {
24099 self.write_keyword("ON");
24100 self.write_space();
24101 self.generate_expression(table)?;
24102 }
24103 if !e.params.is_empty() {
24104 self.write("(");
24105 for (i, param) in e.params.iter().enumerate() {
24106 if i > 0 {
24107 self.write(", ");
24108 }
24109 self.generate_expression(param)?;
24110 }
24111 self.write(")");
24112 }
24113 Ok(())
24114 }
24115
24116 fn generate_index_column_constraint(&mut self, e: &IndexColumnConstraint) -> Result<()> {
24117 if let Some(kind) = &e.kind {
24119 self.write(kind);
24120 self.write_space();
24121 }
24122 self.write_keyword("INDEX");
24123 if let Some(this) = &e.this {
24124 self.write_space();
24125 self.generate_expression(this)?;
24126 }
24127 if let Some(index_type) = &e.index_type {
24128 self.write_space();
24129 self.write_keyword("USING");
24130 self.write_space();
24131 self.generate_expression(index_type)?;
24132 }
24133 if !e.expressions.is_empty() {
24134 self.write(" (");
24135 for (i, expr) in e.expressions.iter().enumerate() {
24136 if i > 0 {
24137 self.write(", ");
24138 }
24139 self.generate_expression(expr)?;
24140 }
24141 self.write(")");
24142 }
24143 for opt in &e.options {
24144 self.write_space();
24145 self.generate_expression(opt)?;
24146 }
24147 Ok(())
24148 }
24149
24150 fn generate_index_constraint_option(&mut self, e: &IndexConstraintOption) -> Result<()> {
24151 if let Some(key_block_size) = &e.key_block_size {
24153 self.write_keyword("KEY_BLOCK_SIZE");
24154 self.write(" = ");
24155 self.generate_expression(key_block_size)?;
24156 } else if let Some(using) = &e.using {
24157 self.write_keyword("USING");
24158 self.write_space();
24159 self.generate_expression(using)?;
24160 } else if let Some(parser) = &e.parser {
24161 self.write_keyword("WITH PARSER");
24162 self.write_space();
24163 self.generate_expression(parser)?;
24164 } else if let Some(comment) = &e.comment {
24165 self.write_keyword("COMMENT");
24166 self.write_space();
24167 self.generate_expression(comment)?;
24168 } else if let Some(visible) = &e.visible {
24169 self.generate_expression(visible)?;
24170 } else if let Some(engine_attr) = &e.engine_attr {
24171 self.write_keyword("ENGINE_ATTRIBUTE");
24172 self.write(" = ");
24173 self.generate_expression(engine_attr)?;
24174 } else if let Some(secondary_engine_attr) = &e.secondary_engine_attr {
24175 self.write_keyword("SECONDARY_ENGINE_ATTRIBUTE");
24176 self.write(" = ");
24177 self.generate_expression(secondary_engine_attr)?;
24178 }
24179 Ok(())
24180 }
24181
24182 fn generate_index_parameters(&mut self, e: &IndexParameters) -> Result<()> {
24183 if let Some(using) = &e.using {
24185 self.write_keyword("USING");
24186 self.write_space();
24187 self.generate_expression(using)?;
24188 }
24189 if !e.columns.is_empty() {
24190 self.write("(");
24191 for (i, col) in e.columns.iter().enumerate() {
24192 if i > 0 {
24193 self.write(", ");
24194 }
24195 self.generate_expression(col)?;
24196 }
24197 self.write(")");
24198 }
24199 if let Some(partition_by) = &e.partition_by {
24200 self.write_space();
24201 self.write_keyword("PARTITION BY");
24202 self.write_space();
24203 self.generate_expression(partition_by)?;
24204 }
24205 if let Some(where_) = &e.where_ {
24206 self.write_space();
24207 self.generate_expression(where_)?;
24208 }
24209 if let Some(include) = &e.include {
24210 self.write_space();
24211 self.write_keyword("INCLUDE");
24212 self.write(" (");
24213 self.generate_expression(include)?;
24214 self.write(")");
24215 }
24216 if let Some(with_storage) = &e.with_storage {
24217 self.write_space();
24218 self.write_keyword("WITH");
24219 self.write(" (");
24220 self.generate_expression(with_storage)?;
24221 self.write(")");
24222 }
24223 if let Some(tablespace) = &e.tablespace {
24224 self.write_space();
24225 self.write_keyword("USING INDEX TABLESPACE");
24226 self.write_space();
24227 self.generate_expression(tablespace)?;
24228 }
24229 Ok(())
24230 }
24231
24232 fn generate_index_table_hint(&mut self, e: &IndexTableHint) -> Result<()> {
24233 if let Expression::Identifier(id) = &*e.this {
24237 self.write_keyword(&id.name);
24238 } else {
24239 self.generate_expression(&e.this)?;
24240 }
24241 self.write_space();
24242 self.write_keyword("INDEX");
24243 if let Some(target) = &e.target {
24244 self.write_space();
24245 self.write_keyword("FOR");
24246 self.write_space();
24247 if let Expression::Identifier(id) = &**target {
24248 self.write_keyword(&id.name);
24249 } else {
24250 self.generate_expression(target)?;
24251 }
24252 }
24253 self.write(" (");
24255 for (i, expr) in e.expressions.iter().enumerate() {
24256 if i > 0 {
24257 self.write(", ");
24258 }
24259 self.generate_expression(expr)?;
24260 }
24261 self.write(")");
24262 Ok(())
24263 }
24264
24265 fn generate_inherits_property(&mut self, e: &InheritsProperty) -> Result<()> {
24266 self.write_keyword("INHERITS");
24268 self.write(" (");
24269 for (i, expr) in e.expressions.iter().enumerate() {
24270 if i > 0 {
24271 self.write(", ");
24272 }
24273 self.generate_expression(expr)?;
24274 }
24275 self.write(")");
24276 Ok(())
24277 }
24278
24279 fn generate_input_model_property(&mut self, e: &InputModelProperty) -> Result<()> {
24280 self.write_keyword("INPUT");
24282 self.write("(");
24283 self.generate_expression(&e.this)?;
24284 self.write(")");
24285 Ok(())
24286 }
24287
24288 fn generate_input_output_format(&mut self, e: &InputOutputFormat) -> Result<()> {
24289 if let Some(input_format) = &e.input_format {
24291 self.write_keyword("INPUTFORMAT");
24292 self.write_space();
24293 self.generate_expression(input_format)?;
24294 }
24295 if let Some(output_format) = &e.output_format {
24296 if e.input_format.is_some() {
24297 self.write(" ");
24298 }
24299 self.write_keyword("OUTPUTFORMAT");
24300 self.write_space();
24301 self.generate_expression(output_format)?;
24302 }
24303 Ok(())
24304 }
24305
24306 fn generate_install(&mut self, e: &Install) -> Result<()> {
24307 if e.force.is_some() {
24309 self.write_keyword("FORCE");
24310 self.write_space();
24311 }
24312 self.write_keyword("INSTALL");
24313 self.write_space();
24314 self.generate_expression(&e.this)?;
24315 if let Some(from) = &e.from_ {
24316 self.write_space();
24317 self.write_keyword("FROM");
24318 self.write_space();
24319 self.generate_expression(from)?;
24320 }
24321 Ok(())
24322 }
24323
24324 fn generate_interval_op(&mut self, e: &IntervalOp) -> Result<()> {
24325 self.write_keyword("INTERVAL");
24327 self.write_space();
24328 self.generate_expression(&e.expression)?;
24330 if let Some(unit) = &e.unit {
24331 self.write_space();
24332 self.write(unit);
24333 }
24334 Ok(())
24335 }
24336
24337 fn generate_interval_span(&mut self, e: &IntervalSpan) -> Result<()> {
24338 self.write(&format!("{:?}", e.this).to_uppercase());
24340 self.write_space();
24341 self.write_keyword("TO");
24342 self.write_space();
24343 self.write(&format!("{:?}", e.expression).to_uppercase());
24344 Ok(())
24345 }
24346
24347 fn generate_into_clause(&mut self, e: &IntoClause) -> Result<()> {
24348 self.write_keyword("INTO");
24350 if e.temporary {
24351 self.write_keyword(" TEMPORARY");
24352 }
24353 if e.unlogged.is_some() {
24354 self.write_keyword(" UNLOGGED");
24355 }
24356 if let Some(this) = &e.this {
24357 self.write_space();
24358 self.generate_expression(this)?;
24359 }
24360 if !e.expressions.is_empty() {
24361 self.write(" (");
24362 for (i, expr) in e.expressions.iter().enumerate() {
24363 if i > 0 {
24364 self.write(", ");
24365 }
24366 self.generate_expression(expr)?;
24367 }
24368 self.write(")");
24369 }
24370 Ok(())
24371 }
24372
24373 fn generate_introducer(&mut self, e: &Introducer) -> Result<()> {
24374 self.generate_expression(&e.this)?;
24376 self.write_space();
24377 self.generate_expression(&e.expression)?;
24378 Ok(())
24379 }
24380
24381 fn generate_isolated_loading_property(&mut self, e: &IsolatedLoadingProperty) -> Result<()> {
24382 self.write_keyword("WITH");
24384 if e.no.is_some() {
24385 self.write_keyword(" NO");
24386 }
24387 if e.concurrent.is_some() {
24388 self.write_keyword(" CONCURRENT");
24389 }
24390 self.write_keyword(" ISOLATED LOADING");
24391 if let Some(target) = &e.target {
24392 self.write_space();
24393 self.generate_expression(target)?;
24394 }
24395 Ok(())
24396 }
24397
24398 fn generate_json(&mut self, e: &JSON) -> Result<()> {
24399 self.write_keyword("JSON");
24401 if let Some(this) = &e.this {
24402 self.write_space();
24403 self.generate_expression(this)?;
24404 }
24405 if let Some(with_) = &e.with_ {
24406 if let Expression::Boolean(b) = with_.as_ref() {
24408 if b.value {
24409 self.write_keyword(" WITH");
24410 } else {
24411 self.write_keyword(" WITHOUT");
24412 }
24413 }
24414 }
24415 if e.unique {
24416 self.write_keyword(" UNIQUE KEYS");
24417 }
24418 Ok(())
24419 }
24420
24421 fn generate_json_array(&mut self, e: &JSONArray) -> Result<()> {
24422 self.write_keyword("JSON_ARRAY");
24424 self.write("(");
24425 for (i, expr) in e.expressions.iter().enumerate() {
24426 if i > 0 {
24427 self.write(", ");
24428 }
24429 self.generate_expression(expr)?;
24430 }
24431 if let Some(null_handling) = &e.null_handling {
24432 self.write_space();
24433 self.generate_expression(null_handling)?;
24434 }
24435 if let Some(return_type) = &e.return_type {
24436 self.write_space();
24437 self.write_keyword("RETURNING");
24438 self.write_space();
24439 self.generate_expression(return_type)?;
24440 }
24441 if e.strict.is_some() {
24442 self.write_space();
24443 self.write_keyword("STRICT");
24444 }
24445 self.write(")");
24446 Ok(())
24447 }
24448
24449 fn generate_json_array_agg_struct(&mut self, e: &JSONArrayAgg) -> Result<()> {
24450 self.write_keyword("JSON_ARRAYAGG");
24452 self.write("(");
24453 self.generate_expression(&e.this)?;
24454 if let Some(order) = &e.order {
24455 self.write_space();
24456 if let Expression::OrderBy(ob) = order.as_ref() {
24458 self.write_keyword("ORDER BY");
24459 self.write_space();
24460 for (i, ord) in ob.expressions.iter().enumerate() {
24461 if i > 0 {
24462 self.write(", ");
24463 }
24464 self.generate_ordered(ord)?;
24465 }
24466 } else {
24467 self.generate_expression(order)?;
24469 }
24470 }
24471 if let Some(null_handling) = &e.null_handling {
24472 self.write_space();
24473 self.generate_expression(null_handling)?;
24474 }
24475 if let Some(return_type) = &e.return_type {
24476 self.write_space();
24477 self.write_keyword("RETURNING");
24478 self.write_space();
24479 self.generate_expression(return_type)?;
24480 }
24481 if e.strict.is_some() {
24482 self.write_space();
24483 self.write_keyword("STRICT");
24484 }
24485 self.write(")");
24486 Ok(())
24487 }
24488
24489 fn generate_json_object_agg_struct(&mut self, e: &JSONObjectAgg) -> Result<()> {
24490 self.write_keyword("JSON_OBJECTAGG");
24492 self.write("(");
24493 for (i, expr) in e.expressions.iter().enumerate() {
24494 if i > 0 {
24495 self.write(", ");
24496 }
24497 self.generate_expression(expr)?;
24498 }
24499 if let Some(null_handling) = &e.null_handling {
24500 self.write_space();
24501 self.generate_expression(null_handling)?;
24502 }
24503 if let Some(unique_keys) = &e.unique_keys {
24504 self.write_space();
24505 if let Expression::Boolean(b) = unique_keys.as_ref() {
24506 if b.value {
24507 self.write_keyword("WITH UNIQUE KEYS");
24508 } else {
24509 self.write_keyword("WITHOUT UNIQUE KEYS");
24510 }
24511 }
24512 }
24513 if let Some(return_type) = &e.return_type {
24514 self.write_space();
24515 self.write_keyword("RETURNING");
24516 self.write_space();
24517 self.generate_expression(return_type)?;
24518 }
24519 self.write(")");
24520 Ok(())
24521 }
24522
24523 fn generate_json_array_append(&mut self, e: &JSONArrayAppend) -> Result<()> {
24524 self.write_keyword("JSON_ARRAY_APPEND");
24526 self.write("(");
24527 self.generate_expression(&e.this)?;
24528 for expr in &e.expressions {
24529 self.write(", ");
24530 self.generate_expression(expr)?;
24531 }
24532 self.write(")");
24533 Ok(())
24534 }
24535
24536 fn generate_json_array_contains(&mut self, e: &JSONArrayContains) -> Result<()> {
24537 self.write_keyword("JSON_ARRAY_CONTAINS");
24539 self.write("(");
24540 self.generate_expression(&e.this)?;
24541 self.write(", ");
24542 self.generate_expression(&e.expression)?;
24543 self.write(")");
24544 Ok(())
24545 }
24546
24547 fn generate_json_array_insert(&mut self, e: &JSONArrayInsert) -> Result<()> {
24548 self.write_keyword("JSON_ARRAY_INSERT");
24550 self.write("(");
24551 self.generate_expression(&e.this)?;
24552 for expr in &e.expressions {
24553 self.write(", ");
24554 self.generate_expression(expr)?;
24555 }
24556 self.write(")");
24557 Ok(())
24558 }
24559
24560 fn generate_jsonb_exists(&mut self, e: &JSONBExists) -> Result<()> {
24561 self.write_keyword("JSONB_EXISTS");
24563 self.write("(");
24564 self.generate_expression(&e.this)?;
24565 if let Some(path) = &e.path {
24566 self.write(", ");
24567 self.generate_expression(path)?;
24568 }
24569 self.write(")");
24570 Ok(())
24571 }
24572
24573 fn generate_jsonb_extract_scalar(&mut self, e: &JSONBExtractScalar) -> Result<()> {
24574 self.write_keyword("JSONB_EXTRACT_SCALAR");
24576 self.write("(");
24577 self.generate_expression(&e.this)?;
24578 self.write(", ");
24579 self.generate_expression(&e.expression)?;
24580 self.write(")");
24581 Ok(())
24582 }
24583
24584 fn generate_jsonb_object_agg(&mut self, e: &JSONBObjectAgg) -> Result<()> {
24585 self.write_keyword("JSONB_OBJECT_AGG");
24587 self.write("(");
24588 self.generate_expression(&e.this)?;
24589 self.write(", ");
24590 self.generate_expression(&e.expression)?;
24591 self.write(")");
24592 Ok(())
24593 }
24594
24595 fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> {
24596 if let Some(nested_schema) = &e.nested_schema {
24598 self.write_keyword("NESTED");
24599 if let Some(path) = &e.path {
24600 self.write_space();
24601 self.write_keyword("PATH");
24602 self.write_space();
24603 self.generate_expression(path)?;
24604 }
24605 self.write_space();
24606 self.generate_expression(nested_schema)?;
24607 } else {
24608 if let Some(this) = &e.this {
24609 self.generate_expression(this)?;
24610 }
24611 if let Some(kind) = &e.kind {
24612 self.write_space();
24613 self.write(kind);
24614 }
24615 if let Some(path) = &e.path {
24616 self.write_space();
24617 self.write_keyword("PATH");
24618 self.write_space();
24619 self.generate_expression(path)?;
24620 }
24621 if e.ordinality.is_some() {
24622 self.write_keyword(" FOR ORDINALITY");
24623 }
24624 }
24625 Ok(())
24626 }
24627
24628 fn generate_json_exists(&mut self, e: &JSONExists) -> Result<()> {
24629 self.write_keyword("JSON_EXISTS");
24631 self.write("(");
24632 self.generate_expression(&e.this)?;
24633 if let Some(path) = &e.path {
24634 self.write(", ");
24635 self.generate_expression(path)?;
24636 }
24637 if let Some(passing) = &e.passing {
24638 self.write_space();
24639 self.write_keyword("PASSING");
24640 self.write_space();
24641 self.generate_expression(passing)?;
24642 }
24643 if let Some(on_condition) = &e.on_condition {
24644 self.write_space();
24645 self.generate_expression(on_condition)?;
24646 }
24647 self.write(")");
24648 Ok(())
24649 }
24650
24651 fn generate_json_cast(&mut self, e: &JSONCast) -> Result<()> {
24652 self.generate_expression(&e.this)?;
24653 self.write(".:");
24654 self.generate_data_type(&e.to)?;
24655 Ok(())
24656 }
24657
24658 fn generate_json_extract_array(&mut self, e: &JSONExtractArray) -> Result<()> {
24659 self.write_keyword("JSON_EXTRACT_ARRAY");
24661 self.write("(");
24662 self.generate_expression(&e.this)?;
24663 if let Some(expr) = &e.expression {
24664 self.write(", ");
24665 self.generate_expression(expr)?;
24666 }
24667 self.write(")");
24668 Ok(())
24669 }
24670
24671 fn generate_json_extract_quote(&mut self, e: &JSONExtractQuote) -> Result<()> {
24672 if let Some(option) = &e.option {
24674 self.generate_expression(option)?;
24675 self.write_space();
24676 }
24677 self.write_keyword("QUOTES");
24678 if e.scalar.is_some() {
24679 self.write_keyword(" SCALAR_ONLY");
24680 }
24681 Ok(())
24682 }
24683
24684 fn generate_json_extract_scalar(&mut self, e: &JSONExtractScalar) -> Result<()> {
24685 self.write_keyword("JSON_EXTRACT_SCALAR");
24687 self.write("(");
24688 self.generate_expression(&e.this)?;
24689 self.write(", ");
24690 self.generate_expression(&e.expression)?;
24691 self.write(")");
24692 Ok(())
24693 }
24694
24695 fn generate_json_extract_path(&mut self, e: &JSONExtract) -> Result<()> {
24696 if e.variant_extract.is_some() {
24700 use crate::dialects::DialectType;
24701 if matches!(self.config.dialect, Some(DialectType::Databricks)) {
24702 self.generate_expression(&e.this)?;
24704 self.write(":");
24705 match e.expression.as_ref() {
24708 Expression::Literal(Literal::String(s)) => {
24709 self.write(s);
24710 }
24711 _ => {
24712 self.generate_expression(&e.expression)?;
24714 }
24715 }
24716 } else {
24717 self.write_keyword("GET_PATH");
24719 self.write("(");
24720 self.generate_expression(&e.this)?;
24721 self.write(", ");
24722 self.generate_expression(&e.expression)?;
24723 self.write(")");
24724 }
24725 } else {
24726 self.write_keyword("JSON_EXTRACT");
24727 self.write("(");
24728 self.generate_expression(&e.this)?;
24729 self.write(", ");
24730 self.generate_expression(&e.expression)?;
24731 for expr in &e.expressions {
24732 self.write(", ");
24733 self.generate_expression(expr)?;
24734 }
24735 self.write(")");
24736 }
24737 Ok(())
24738 }
24739
24740 fn generate_json_format(&mut self, e: &JSONFormat) -> Result<()> {
24741 if let Some(this) = &e.this {
24744 self.generate_expression(this)?;
24745 self.write_space();
24746 }
24747 self.write_keyword("FORMAT JSON");
24748 Ok(())
24749 }
24750
24751 fn generate_json_key_value(&mut self, e: &JSONKeyValue) -> Result<()> {
24752 self.generate_expression(&e.this)?;
24754 self.write(": ");
24755 self.generate_expression(&e.expression)?;
24756 Ok(())
24757 }
24758
24759 fn generate_json_keys(&mut self, e: &JSONKeys) -> Result<()> {
24760 self.write_keyword("JSON_KEYS");
24762 self.write("(");
24763 self.generate_expression(&e.this)?;
24764 if let Some(expr) = &e.expression {
24765 self.write(", ");
24766 self.generate_expression(expr)?;
24767 }
24768 for expr in &e.expressions {
24769 self.write(", ");
24770 self.generate_expression(expr)?;
24771 }
24772 self.write(")");
24773 Ok(())
24774 }
24775
24776 fn generate_json_keys_at_depth(&mut self, e: &JSONKeysAtDepth) -> Result<()> {
24777 self.write_keyword("JSON_KEYS");
24779 self.write("(");
24780 self.generate_expression(&e.this)?;
24781 if let Some(expr) = &e.expression {
24782 self.write(", ");
24783 self.generate_expression(expr)?;
24784 }
24785 self.write(")");
24786 Ok(())
24787 }
24788
24789 fn generate_json_path_expr(&mut self, e: &JSONPath) -> Result<()> {
24790 let mut path_str = String::new();
24793 for expr in &e.expressions {
24794 match expr {
24795 Expression::JSONPathRoot(_) => {
24796 path_str.push('$');
24797 }
24798 Expression::JSONPathKey(k) => {
24799 if let Expression::Literal(crate::expressions::Literal::String(s)) = k.this.as_ref() {
24801 path_str.push('.');
24802 let needs_quoting = s.chars().any(|c| !c.is_alphanumeric() && c != '_');
24804 if needs_quoting {
24805 path_str.push('"');
24806 path_str.push_str(s);
24807 path_str.push('"');
24808 } else {
24809 path_str.push_str(s);
24810 }
24811 }
24812 }
24813 Expression::JSONPathSubscript(s) => {
24814 if let Expression::Literal(crate::expressions::Literal::Number(n)) = s.this.as_ref() {
24816 path_str.push('[');
24817 path_str.push_str(n);
24818 path_str.push(']');
24819 }
24820 }
24821 _ => {
24822 let mut temp_gen = Self::with_config(self.config.clone());
24824 temp_gen.generate_expression(expr)?;
24825 path_str.push_str(&temp_gen.output);
24826 }
24827 }
24828 }
24829 self.write("'");
24831 self.write(&path_str);
24832 self.write("'");
24833 Ok(())
24834 }
24835
24836 fn generate_json_path_filter(&mut self, e: &JSONPathFilter) -> Result<()> {
24837 self.write("?(");
24839 self.generate_expression(&e.this)?;
24840 self.write(")");
24841 Ok(())
24842 }
24843
24844 fn generate_json_path_key(&mut self, e: &JSONPathKey) -> Result<()> {
24845 self.write(".");
24847 self.generate_expression(&e.this)?;
24848 Ok(())
24849 }
24850
24851 fn generate_json_path_recursive(&mut self, e: &JSONPathRecursive) -> Result<()> {
24852 self.write("..");
24854 if let Some(this) = &e.this {
24855 self.generate_expression(this)?;
24856 }
24857 Ok(())
24858 }
24859
24860 fn generate_json_path_root(&mut self) -> Result<()> {
24861 self.write("$");
24863 Ok(())
24864 }
24865
24866 fn generate_json_path_script(&mut self, e: &JSONPathScript) -> Result<()> {
24867 self.write("(");
24869 self.generate_expression(&e.this)?;
24870 self.write(")");
24871 Ok(())
24872 }
24873
24874 fn generate_json_path_selector(&mut self, e: &JSONPathSelector) -> Result<()> {
24875 self.generate_expression(&e.this)?;
24877 Ok(())
24878 }
24879
24880 fn generate_json_path_slice(&mut self, e: &JSONPathSlice) -> Result<()> {
24881 self.write("[");
24883 if let Some(start) = &e.start {
24884 self.generate_expression(start)?;
24885 }
24886 self.write(":");
24887 if let Some(end) = &e.end {
24888 self.generate_expression(end)?;
24889 }
24890 if let Some(step) = &e.step {
24891 self.write(":");
24892 self.generate_expression(step)?;
24893 }
24894 self.write("]");
24895 Ok(())
24896 }
24897
24898 fn generate_json_path_subscript(&mut self, e: &JSONPathSubscript) -> Result<()> {
24899 self.write("[");
24901 self.generate_expression(&e.this)?;
24902 self.write("]");
24903 Ok(())
24904 }
24905
24906 fn generate_json_path_union(&mut self, e: &JSONPathUnion) -> Result<()> {
24907 self.write("[");
24909 for (i, expr) in e.expressions.iter().enumerate() {
24910 if i > 0 {
24911 self.write(", ");
24912 }
24913 self.generate_expression(expr)?;
24914 }
24915 self.write("]");
24916 Ok(())
24917 }
24918
24919 fn generate_json_remove(&mut self, e: &JSONRemove) -> Result<()> {
24920 self.write_keyword("JSON_REMOVE");
24922 self.write("(");
24923 self.generate_expression(&e.this)?;
24924 for expr in &e.expressions {
24925 self.write(", ");
24926 self.generate_expression(expr)?;
24927 }
24928 self.write(")");
24929 Ok(())
24930 }
24931
24932 fn generate_json_schema(&mut self, e: &JSONSchema) -> Result<()> {
24933 self.write_keyword("COLUMNS");
24936 self.write("(");
24937
24938 if self.config.pretty && !e.expressions.is_empty() {
24939 let mut expr_strings: Vec<String> = Vec::with_capacity(e.expressions.len());
24941 for expr in &e.expressions {
24942 let mut temp_gen = Generator::with_config(self.config.clone());
24943 temp_gen.generate_expression(expr)?;
24944 expr_strings.push(temp_gen.output);
24945 }
24946
24947 if self.too_wide(&expr_strings) {
24949 self.write_newline();
24951 self.indent_level += 1;
24952 for (i, expr_str) in expr_strings.iter().enumerate() {
24953 if i > 0 {
24954 self.write(",");
24955 self.write_newline();
24956 }
24957 self.write_indent();
24958 self.write(expr_str);
24959 }
24960 self.write_newline();
24961 self.indent_level -= 1;
24962 self.write_indent();
24963 } else {
24964 for (i, expr_str) in expr_strings.iter().enumerate() {
24966 if i > 0 {
24967 self.write(", ");
24968 }
24969 self.write(expr_str);
24970 }
24971 }
24972 } else {
24973 for (i, expr) in e.expressions.iter().enumerate() {
24975 if i > 0 {
24976 self.write(", ");
24977 }
24978 self.generate_expression(expr)?;
24979 }
24980 }
24981 self.write(")");
24982 Ok(())
24983 }
24984
24985 fn generate_json_set(&mut self, e: &JSONSet) -> Result<()> {
24986 self.write_keyword("JSON_SET");
24988 self.write("(");
24989 self.generate_expression(&e.this)?;
24990 for expr in &e.expressions {
24991 self.write(", ");
24992 self.generate_expression(expr)?;
24993 }
24994 self.write(")");
24995 Ok(())
24996 }
24997
24998 fn generate_json_strip_nulls(&mut self, e: &JSONStripNulls) -> Result<()> {
24999 self.write_keyword("JSON_STRIP_NULLS");
25001 self.write("(");
25002 self.generate_expression(&e.this)?;
25003 if let Some(expr) = &e.expression {
25004 self.write(", ");
25005 self.generate_expression(expr)?;
25006 }
25007 self.write(")");
25008 Ok(())
25009 }
25010
25011 fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> {
25012 self.write_keyword("JSON_TABLE");
25014 self.write("(");
25015 self.generate_expression(&e.this)?;
25016 if let Some(path) = &e.path {
25017 self.write(", ");
25018 self.generate_expression(path)?;
25019 }
25020 if let Some(error_handling) = &e.error_handling {
25021 self.write_space();
25022 self.generate_expression(error_handling)?;
25023 }
25024 if let Some(empty_handling) = &e.empty_handling {
25025 self.write_space();
25026 self.generate_expression(empty_handling)?;
25027 }
25028 if let Some(schema) = &e.schema {
25029 self.write_space();
25030 self.generate_expression(schema)?;
25031 }
25032 self.write(")");
25033 Ok(())
25034 }
25035
25036 fn generate_json_type(&mut self, e: &JSONType) -> Result<()> {
25037 self.write_keyword("JSON_TYPE");
25039 self.write("(");
25040 self.generate_expression(&e.this)?;
25041 self.write(")");
25042 Ok(())
25043 }
25044
25045 fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> {
25046 self.write_keyword("JSON_VALUE");
25048 self.write("(");
25049 self.generate_expression(&e.this)?;
25050 if let Some(path) = &e.path {
25051 self.write(", ");
25052 self.generate_expression(path)?;
25053 }
25054 if let Some(returning) = &e.returning {
25055 self.write_space();
25056 self.write_keyword("RETURNING");
25057 self.write_space();
25058 self.generate_expression(returning)?;
25059 }
25060 if let Some(on_condition) = &e.on_condition {
25061 self.write_space();
25062 self.generate_expression(on_condition)?;
25063 }
25064 self.write(")");
25065 Ok(())
25066 }
25067
25068 fn generate_json_value_array(&mut self, e: &JSONValueArray) -> Result<()> {
25069 self.write_keyword("JSON_VALUE_ARRAY");
25071 self.write("(");
25072 self.generate_expression(&e.this)?;
25073 self.write(")");
25074 Ok(())
25075 }
25076
25077 fn generate_jarowinkler_similarity(&mut self, e: &JarowinklerSimilarity) -> Result<()> {
25078 self.write_keyword("JAROWINKLER_SIMILARITY");
25080 self.write("(");
25081 self.generate_expression(&e.this)?;
25082 self.write(", ");
25083 self.generate_expression(&e.expression)?;
25084 self.write(")");
25085 Ok(())
25086 }
25087
25088 fn generate_join_hint(&mut self, e: &JoinHint) -> Result<()> {
25089 self.generate_expression(&e.this)?;
25091 self.write("(");
25092 for (i, expr) in e.expressions.iter().enumerate() {
25093 if i > 0 {
25094 self.write(", ");
25095 }
25096 self.generate_expression(expr)?;
25097 }
25098 self.write(")");
25099 Ok(())
25100 }
25101
25102 fn generate_journal_property(&mut self, e: &JournalProperty) -> Result<()> {
25103 if e.no.is_some() {
25105 self.write_keyword("NO ");
25106 }
25107 if let Some(local) = &e.local {
25108 self.generate_expression(local)?;
25109 self.write_space();
25110 }
25111 if e.dual.is_some() {
25112 self.write_keyword("DUAL ");
25113 }
25114 if e.before.is_some() {
25115 self.write_keyword("BEFORE ");
25116 }
25117 if e.after.is_some() {
25118 self.write_keyword("AFTER ");
25119 }
25120 self.write_keyword("JOURNAL");
25121 Ok(())
25122 }
25123
25124 fn generate_language_property(&mut self, e: &LanguageProperty) -> Result<()> {
25125 self.write_keyword("LANGUAGE");
25127 self.write_space();
25128 self.generate_expression(&e.this)?;
25129 Ok(())
25130 }
25131
25132 fn generate_lateral(&mut self, e: &Lateral) -> Result<()> {
25133 if e.view.is_some() {
25135 self.write_keyword("LATERAL VIEW");
25137 if e.outer.is_some() {
25138 self.write_space();
25139 self.write_keyword("OUTER");
25140 }
25141 self.write_space();
25142 self.generate_expression(&e.this)?;
25143 if let Some(alias) = &e.alias {
25144 self.write_space();
25145 self.write(alias);
25146 }
25147 } else {
25148 self.write_keyword("LATERAL");
25150 self.write_space();
25151 self.generate_expression(&e.this)?;
25152 if e.ordinality.is_some() {
25153 self.write_space();
25154 self.write_keyword("WITH ORDINALITY");
25155 }
25156 if let Some(alias) = &e.alias {
25157 self.write_space();
25158 self.write_keyword("AS");
25159 self.write_space();
25160 self.write(alias);
25161 if !e.column_aliases.is_empty() {
25162 self.write("(");
25163 for (i, col) in e.column_aliases.iter().enumerate() {
25164 if i > 0 {
25165 self.write(", ");
25166 }
25167 self.write(col);
25168 }
25169 self.write(")");
25170 }
25171 }
25172 }
25173 Ok(())
25174 }
25175
25176 fn generate_like_property(&mut self, e: &LikeProperty) -> Result<()> {
25177 self.write_keyword("LIKE");
25179 self.write_space();
25180 self.generate_expression(&e.this)?;
25181 for expr in &e.expressions {
25182 self.write_space();
25183 self.generate_expression(expr)?;
25184 }
25185 Ok(())
25186 }
25187
25188 fn generate_limit(&mut self, e: &Limit) -> Result<()> {
25189 self.write_keyword("LIMIT");
25190 self.write_space();
25191 self.write_limit_expr(&e.this)?;
25192 if e.percent {
25193 self.write_space();
25194 self.write_keyword("PERCENT");
25195 }
25196 Ok(())
25197 }
25198
25199 fn generate_limit_options(&mut self, e: &LimitOptions) -> Result<()> {
25200 if e.percent.is_some() {
25202 self.write_keyword(" PERCENT");
25203 }
25204 if e.rows.is_some() {
25205 self.write_keyword(" ROWS");
25206 }
25207 if e.with_ties.is_some() {
25208 self.write_keyword(" WITH TIES");
25209 } else if e.rows.is_some() {
25210 self.write_keyword(" ONLY");
25211 }
25212 Ok(())
25213 }
25214
25215 fn generate_list(&mut self, e: &List) -> Result<()> {
25216 use crate::dialects::DialectType;
25217 let is_materialize = matches!(self.config.dialect, Some(DialectType::Materialize));
25218
25219 if e.expressions.len() == 1 {
25221 if let Expression::Select(_) = &e.expressions[0] {
25222 self.write_keyword("LIST");
25223 self.write("(");
25224 self.generate_expression(&e.expressions[0])?;
25225 self.write(")");
25226 return Ok(());
25227 }
25228 }
25229
25230 if is_materialize {
25232 self.write_keyword("LIST");
25233 self.write("[");
25234 for (i, expr) in e.expressions.iter().enumerate() {
25235 if i > 0 {
25236 self.write(", ");
25237 }
25238 self.generate_expression(expr)?;
25239 }
25240 self.write("]");
25241 } else {
25242 self.write_keyword("LIST");
25244 self.write("(");
25245 for (i, expr) in e.expressions.iter().enumerate() {
25246 if i > 0 {
25247 self.write(", ");
25248 }
25249 self.generate_expression(expr)?;
25250 }
25251 self.write(")");
25252 }
25253 Ok(())
25254 }
25255
25256 fn generate_tomap(&mut self, e: &ToMap) -> Result<()> {
25257 if let Expression::Select(_) = &*e.this {
25259 self.write_keyword("MAP");
25260 self.write("(");
25261 self.generate_expression(&e.this)?;
25262 self.write(")");
25263 return Ok(());
25264 }
25265
25266 let is_duckdb = matches!(self.config.dialect, Some(DialectType::DuckDB));
25267
25268 self.write_keyword("MAP");
25270 if is_duckdb {
25271 self.write(" {");
25272 } else {
25273 self.write("[");
25274 }
25275 if let Expression::Struct(s) = &*e.this {
25276 for (i, (_, expr)) in s.fields.iter().enumerate() {
25277 if i > 0 {
25278 self.write(", ");
25279 }
25280 if let Expression::PropertyEQ(op) = expr {
25281 self.generate_expression(&op.left)?;
25282 if is_duckdb {
25283 self.write(": ");
25284 } else {
25285 self.write(" => ");
25286 }
25287 self.generate_expression(&op.right)?;
25288 } else {
25289 self.generate_expression(expr)?;
25290 }
25291 }
25292 }
25293 if is_duckdb {
25294 self.write("}");
25295 } else {
25296 self.write("]");
25297 }
25298 Ok(())
25299 }
25300
25301 fn generate_localtime(&mut self, e: &Localtime) -> Result<()> {
25302 self.write_keyword("LOCALTIME");
25304 if let Some(precision) = &e.this {
25305 self.write("(");
25306 self.generate_expression(precision)?;
25307 self.write(")");
25308 }
25309 Ok(())
25310 }
25311
25312 fn generate_localtimestamp(&mut self, e: &Localtimestamp) -> Result<()> {
25313 self.write_keyword("LOCALTIMESTAMP");
25315 if let Some(precision) = &e.this {
25316 self.write("(");
25317 self.generate_expression(precision)?;
25318 self.write(")");
25319 }
25320 Ok(())
25321 }
25322
25323 fn generate_location_property(&mut self, e: &LocationProperty) -> Result<()> {
25324 self.write_keyword("LOCATION");
25326 self.write_space();
25327 self.generate_expression(&e.this)?;
25328 Ok(())
25329 }
25330
25331 fn generate_lock(&mut self, e: &Lock) -> Result<()> {
25332 if e.update.is_some() {
25334 if e.key.is_some() {
25335 self.write_keyword("FOR NO KEY UPDATE");
25336 } else {
25337 self.write_keyword("FOR UPDATE");
25338 }
25339 } else {
25340 if e.key.is_some() {
25341 self.write_keyword("FOR KEY SHARE");
25342 } else {
25343 self.write_keyword("FOR SHARE");
25344 }
25345 }
25346 if !e.expressions.is_empty() {
25347 self.write_keyword(" OF ");
25348 for (i, expr) in e.expressions.iter().enumerate() {
25349 if i > 0 {
25350 self.write(", ");
25351 }
25352 self.generate_expression(expr)?;
25353 }
25354 }
25355 if let Some(wait) = &e.wait {
25360 match wait.as_ref() {
25361 Expression::Boolean(b) => {
25362 if b.value {
25363 self.write_keyword(" NOWAIT");
25364 } else {
25365 self.write_keyword(" SKIP LOCKED");
25366 }
25367 }
25368 _ => {
25369 self.write_keyword(" WAIT ");
25371 self.generate_expression(wait)?;
25372 }
25373 }
25374 }
25375 Ok(())
25376 }
25377
25378 fn generate_lock_property(&mut self, e: &LockProperty) -> Result<()> {
25379 self.write_keyword("LOCK");
25381 self.write_space();
25382 self.generate_expression(&e.this)?;
25383 Ok(())
25384 }
25385
25386 fn generate_locking_property(&mut self, e: &LockingProperty) -> Result<()> {
25387 self.write_keyword("LOCKING");
25389 self.write_space();
25390 self.write(&e.kind);
25391 if let Some(this) = &e.this {
25392 self.write_space();
25393 self.generate_expression(this)?;
25394 }
25395 if let Some(for_or_in) = &e.for_or_in {
25396 self.write_space();
25397 self.generate_expression(for_or_in)?;
25398 }
25399 if let Some(lock_type) = &e.lock_type {
25400 self.write_space();
25401 self.generate_expression(lock_type)?;
25402 }
25403 if e.override_.is_some() {
25404 self.write_keyword(" OVERRIDE");
25405 }
25406 Ok(())
25407 }
25408
25409 fn generate_locking_statement(&mut self, e: &LockingStatement) -> Result<()> {
25410 self.generate_expression(&e.this)?;
25412 self.write_space();
25413 self.generate_expression(&e.expression)?;
25414 Ok(())
25415 }
25416
25417 fn generate_log_property(&mut self, e: &LogProperty) -> Result<()> {
25418 if e.no.is_some() {
25420 self.write_keyword("NO ");
25421 }
25422 self.write_keyword("LOG");
25423 Ok(())
25424 }
25425
25426 fn generate_md5_digest(&mut self, e: &MD5Digest) -> Result<()> {
25427 self.write_keyword("MD5");
25429 self.write("(");
25430 self.generate_expression(&e.this)?;
25431 for expr in &e.expressions {
25432 self.write(", ");
25433 self.generate_expression(expr)?;
25434 }
25435 self.write(")");
25436 Ok(())
25437 }
25438
25439 fn generate_ml_forecast(&mut self, e: &MLForecast) -> Result<()> {
25440 self.write_keyword("ML.FORECAST");
25442 self.write("(");
25443 self.generate_expression(&e.this)?;
25444 if let Some(expression) = &e.expression {
25445 self.write(", ");
25446 self.generate_expression(expression)?;
25447 }
25448 if let Some(params) = &e.params_struct {
25449 self.write(", ");
25450 self.generate_expression(params)?;
25451 }
25452 self.write(")");
25453 Ok(())
25454 }
25455
25456 fn generate_ml_translate(&mut self, e: &MLTranslate) -> Result<()> {
25457 self.write_keyword("ML.TRANSLATE");
25459 self.write("(");
25460 self.generate_expression(&e.this)?;
25461 self.write(", ");
25462 self.generate_expression(&e.expression)?;
25463 if let Some(params) = &e.params_struct {
25464 self.write(", ");
25465 self.generate_expression(params)?;
25466 }
25467 self.write(")");
25468 Ok(())
25469 }
25470
25471 fn generate_make_interval(&mut self, e: &MakeInterval) -> Result<()> {
25472 self.write_keyword("MAKE_INTERVAL");
25474 self.write("(");
25475 let mut first = true;
25476 if let Some(year) = &e.year {
25477 self.write("years => ");
25478 self.generate_expression(year)?;
25479 first = false;
25480 }
25481 if let Some(month) = &e.month {
25482 if !first { self.write(", "); }
25483 self.write("months => ");
25484 self.generate_expression(month)?;
25485 first = false;
25486 }
25487 if let Some(week) = &e.week {
25488 if !first { self.write(", "); }
25489 self.write("weeks => ");
25490 self.generate_expression(week)?;
25491 first = false;
25492 }
25493 if let Some(day) = &e.day {
25494 if !first { self.write(", "); }
25495 self.write("days => ");
25496 self.generate_expression(day)?;
25497 first = false;
25498 }
25499 if let Some(hour) = &e.hour {
25500 if !first { self.write(", "); }
25501 self.write("hours => ");
25502 self.generate_expression(hour)?;
25503 first = false;
25504 }
25505 if let Some(minute) = &e.minute {
25506 if !first { self.write(", "); }
25507 self.write("mins => ");
25508 self.generate_expression(minute)?;
25509 first = false;
25510 }
25511 if let Some(second) = &e.second {
25512 if !first { self.write(", "); }
25513 self.write("secs => ");
25514 self.generate_expression(second)?;
25515 }
25516 self.write(")");
25517 Ok(())
25518 }
25519
25520 fn generate_manhattan_distance(&mut self, e: &ManhattanDistance) -> Result<()> {
25521 self.write_keyword("MANHATTAN_DISTANCE");
25523 self.write("(");
25524 self.generate_expression(&e.this)?;
25525 self.write(", ");
25526 self.generate_expression(&e.expression)?;
25527 self.write(")");
25528 Ok(())
25529 }
25530
25531 fn generate_map(&mut self, e: &Map) -> Result<()> {
25532 self.write_keyword("MAP");
25534 self.write("(");
25535 for (i, (key, value)) in e.keys.iter().zip(e.values.iter()).enumerate() {
25536 if i > 0 {
25537 self.write(", ");
25538 }
25539 self.generate_expression(key)?;
25540 self.write(", ");
25541 self.generate_expression(value)?;
25542 }
25543 self.write(")");
25544 Ok(())
25545 }
25546
25547 fn generate_map_cat(&mut self, e: &MapCat) -> Result<()> {
25548 self.write_keyword("MAP_CAT");
25550 self.write("(");
25551 self.generate_expression(&e.this)?;
25552 self.write(", ");
25553 self.generate_expression(&e.expression)?;
25554 self.write(")");
25555 Ok(())
25556 }
25557
25558 fn generate_map_delete(&mut self, e: &MapDelete) -> Result<()> {
25559 self.write_keyword("MAP_DELETE");
25561 self.write("(");
25562 self.generate_expression(&e.this)?;
25563 for expr in &e.expressions {
25564 self.write(", ");
25565 self.generate_expression(expr)?;
25566 }
25567 self.write(")");
25568 Ok(())
25569 }
25570
25571 fn generate_map_insert(&mut self, e: &MapInsert) -> Result<()> {
25572 self.write_keyword("MAP_INSERT");
25574 self.write("(");
25575 self.generate_expression(&e.this)?;
25576 if let Some(key) = &e.key {
25577 self.write(", ");
25578 self.generate_expression(key)?;
25579 }
25580 if let Some(value) = &e.value {
25581 self.write(", ");
25582 self.generate_expression(value)?;
25583 }
25584 if let Some(update_flag) = &e.update_flag {
25585 self.write(", ");
25586 self.generate_expression(update_flag)?;
25587 }
25588 self.write(")");
25589 Ok(())
25590 }
25591
25592 fn generate_map_pick(&mut self, e: &MapPick) -> Result<()> {
25593 self.write_keyword("MAP_PICK");
25595 self.write("(");
25596 self.generate_expression(&e.this)?;
25597 for expr in &e.expressions {
25598 self.write(", ");
25599 self.generate_expression(expr)?;
25600 }
25601 self.write(")");
25602 Ok(())
25603 }
25604
25605 fn generate_masking_policy_column_constraint(&mut self, e: &MaskingPolicyColumnConstraint) -> Result<()> {
25606 self.write_keyword("MASKING POLICY");
25608 self.write_space();
25609 self.generate_expression(&e.this)?;
25610 if !e.expressions.is_empty() {
25611 self.write_keyword(" USING");
25612 self.write(" (");
25613 for (i, expr) in e.expressions.iter().enumerate() {
25614 if i > 0 {
25615 self.write(", ");
25616 }
25617 self.generate_expression(expr)?;
25618 }
25619 self.write(")");
25620 }
25621 Ok(())
25622 }
25623
25624 fn generate_match_against(&mut self, e: &MatchAgainst) -> Result<()> {
25625 if matches!(
25626 self.config.dialect,
25627 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)
25628 ) {
25629 if e.expressions.len() > 1 {
25630 self.write("(");
25631 }
25632 for (i, expr) in e.expressions.iter().enumerate() {
25633 if i > 0 {
25634 self.write_keyword(" OR ");
25635 }
25636 self.generate_expression(expr)?;
25637 self.write_space();
25638 self.write("@@");
25639 self.write_space();
25640 self.generate_expression(&e.this)?;
25641 }
25642 if e.expressions.len() > 1 {
25643 self.write(")");
25644 }
25645 return Ok(());
25646 }
25647
25648 self.write_keyword("MATCH");
25650 self.write("(");
25651 for (i, expr) in e.expressions.iter().enumerate() {
25652 if i > 0 {
25653 self.write(", ");
25654 }
25655 self.generate_expression(expr)?;
25656 }
25657 self.write(")");
25658 self.write_keyword(" AGAINST");
25659 self.write("(");
25660 self.generate_expression(&e.this)?;
25661 if let Some(modifier) = &e.modifier {
25662 self.write_space();
25663 self.generate_expression(modifier)?;
25664 }
25665 self.write(")");
25666 Ok(())
25667 }
25668
25669 fn generate_match_recognize_measure(&mut self, e: &MatchRecognizeMeasure) -> Result<()> {
25670 if let Some(window_frame) = &e.window_frame {
25672 self.write(&format!("{:?}", window_frame).to_uppercase());
25673 self.write_space();
25674 }
25675 self.generate_expression(&e.this)?;
25676 Ok(())
25677 }
25678
25679 fn generate_materialized_property(&mut self, e: &MaterializedProperty) -> Result<()> {
25680 self.write_keyword("MATERIALIZED");
25682 if let Some(this) = &e.this {
25683 self.write_space();
25684 self.generate_expression(this)?;
25685 }
25686 Ok(())
25687 }
25688
25689 fn generate_merge(&mut self, e: &Merge) -> Result<()> {
25690 if let Some(with_) = &e.with_ {
25693 self.generate_expression(with_)?;
25694 self.write_space();
25695 }
25696 self.write_keyword("MERGE INTO");
25697 self.write_space();
25698 self.generate_expression(&e.this)?;
25699
25700 if self.config.pretty {
25702 self.write_newline();
25703 self.write_indent();
25704 } else {
25705 self.write_space();
25706 }
25707 self.write_keyword("USING");
25708 self.write_space();
25709 self.generate_expression(&e.using)?;
25710
25711 if let Some(on) = &e.on {
25713 if self.config.pretty {
25714 self.write_newline();
25715 self.write_indent();
25716 } else {
25717 self.write_space();
25718 }
25719 self.write_keyword("ON");
25720 self.write_space();
25721 self.generate_expression(on)?;
25722 }
25723 if let Some(using_cond) = &e.using_cond {
25725 self.write_space();
25726 self.write_keyword("USING");
25727 self.write_space();
25728 self.write("(");
25729 if let Expression::Tuple(tuple) = using_cond.as_ref() {
25731 for (i, col) in tuple.expressions.iter().enumerate() {
25732 if i > 0 {
25733 self.write(", ");
25734 }
25735 self.generate_expression(col)?;
25736 }
25737 } else {
25738 self.generate_expression(using_cond)?;
25739 }
25740 self.write(")");
25741 }
25742 let saved_merge_strip = std::mem::take(&mut self.merge_strip_qualifiers);
25744 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)) {
25745 let mut names = Vec::new();
25746 match e.this.as_ref() {
25747 Expression::Alias(a) => {
25748 if let Expression::Table(t) = &a.this {
25750 names.push(t.name.name.clone());
25751 } else if let Expression::Identifier(id) = &a.this {
25752 names.push(id.name.clone());
25753 }
25754 names.push(a.alias.name.clone());
25755 }
25756 Expression::Table(t) => {
25757 names.push(t.name.name.clone());
25758 }
25759 Expression::Identifier(id) => {
25760 names.push(id.name.clone());
25761 }
25762 _ => {}
25763 }
25764 self.merge_strip_qualifiers = names;
25765 }
25766
25767 if let Some(whens) = &e.whens {
25769 if self.config.pretty {
25770 self.write_newline();
25771 self.write_indent();
25772 } else {
25773 self.write_space();
25774 }
25775 self.generate_expression(whens)?;
25776 }
25777
25778 self.merge_strip_qualifiers = saved_merge_strip;
25780
25781 if let Some(returning) = &e.returning {
25783 if self.config.pretty {
25784 self.write_newline();
25785 self.write_indent();
25786 } else {
25787 self.write_space();
25788 }
25789 self.generate_expression(returning)?;
25790 }
25791 Ok(())
25792 }
25793
25794 fn generate_merge_block_ratio_property(&mut self, e: &MergeBlockRatioProperty) -> Result<()> {
25795 if e.no.is_some() {
25797 self.write_keyword("NO MERGEBLOCKRATIO");
25798 } else if e.default.is_some() {
25799 self.write_keyword("DEFAULT MERGEBLOCKRATIO");
25800 } else {
25801 self.write_keyword("MERGEBLOCKRATIO");
25802 self.write("=");
25803 if let Some(this) = &e.this {
25804 self.generate_expression(this)?;
25805 }
25806 if e.percent.is_some() {
25807 self.write_keyword(" PERCENT");
25808 }
25809 }
25810 Ok(())
25811 }
25812
25813 fn generate_merge_tree_ttl(&mut self, e: &MergeTreeTTL) -> Result<()> {
25814 self.write_keyword("TTL");
25816 let pretty_clickhouse = self.config.pretty
25817 && matches!(self.config.dialect, Some(crate::dialects::DialectType::ClickHouse));
25818
25819 if pretty_clickhouse {
25820 self.write_newline();
25821 self.indent_level += 1;
25822 for (i, expr) in e.expressions.iter().enumerate() {
25823 if i > 0 {
25824 self.write(",");
25825 self.write_newline();
25826 }
25827 self.write_indent();
25828 self.generate_expression(expr)?;
25829 }
25830 self.indent_level -= 1;
25831 } else {
25832 self.write_space();
25833 for (i, expr) in e.expressions.iter().enumerate() {
25834 if i > 0 {
25835 self.write(", ");
25836 }
25837 self.generate_expression(expr)?;
25838 }
25839 }
25840
25841 if let Some(where_) = &e.where_ {
25842 if pretty_clickhouse {
25843 self.write_newline();
25844 if let Expression::Where(w) = where_.as_ref() {
25845 self.write_indent();
25846 self.write_keyword("WHERE");
25847 self.write_newline();
25848 self.indent_level += 1;
25849 self.write_indent();
25850 self.generate_expression(&w.this)?;
25851 self.indent_level -= 1;
25852 } else {
25853 self.write_indent();
25854 self.generate_expression(where_)?;
25855 }
25856 } else {
25857 self.write_space();
25858 self.generate_expression(where_)?;
25859 }
25860 }
25861 if let Some(group) = &e.group {
25862 if pretty_clickhouse {
25863 self.write_newline();
25864 if let Expression::Group(g) = group.as_ref() {
25865 self.write_indent();
25866 self.write_keyword("GROUP BY");
25867 self.write_newline();
25868 self.indent_level += 1;
25869 for (i, expr) in g.expressions.iter().enumerate() {
25870 if i > 0 {
25871 self.write(",");
25872 self.write_newline();
25873 }
25874 self.write_indent();
25875 self.generate_expression(expr)?;
25876 }
25877 self.indent_level -= 1;
25878 } else {
25879 self.write_indent();
25880 self.generate_expression(group)?;
25881 }
25882 } else {
25883 self.write_space();
25884 self.generate_expression(group)?;
25885 }
25886 }
25887 if let Some(aggregates) = &e.aggregates {
25888 if pretty_clickhouse {
25889 self.write_newline();
25890 self.write_indent();
25891 self.write_keyword("SET");
25892 self.write_newline();
25893 self.indent_level += 1;
25894 if let Expression::Tuple(t) = aggregates.as_ref() {
25895 for (i, agg) in t.expressions.iter().enumerate() {
25896 if i > 0 {
25897 self.write(",");
25898 self.write_newline();
25899 }
25900 self.write_indent();
25901 self.generate_expression(agg)?;
25902 }
25903 } else {
25904 self.write_indent();
25905 self.generate_expression(aggregates)?;
25906 }
25907 self.indent_level -= 1;
25908 } else {
25909 self.write_space();
25910 self.write_keyword("SET");
25911 self.write_space();
25912 self.generate_expression(aggregates)?;
25913 }
25914 }
25915 Ok(())
25916 }
25917
25918 fn generate_merge_tree_ttl_action(&mut self, e: &MergeTreeTTLAction) -> Result<()> {
25919 self.generate_expression(&e.this)?;
25921 if e.delete.is_some() {
25922 self.write_keyword(" DELETE");
25923 }
25924 if let Some(recompress) = &e.recompress {
25925 self.write_keyword(" RECOMPRESS ");
25926 self.generate_expression(recompress)?;
25927 }
25928 if let Some(to_disk) = &e.to_disk {
25929 self.write_keyword(" TO DISK ");
25930 self.generate_expression(to_disk)?;
25931 }
25932 if let Some(to_volume) = &e.to_volume {
25933 self.write_keyword(" TO VOLUME ");
25934 self.generate_expression(to_volume)?;
25935 }
25936 Ok(())
25937 }
25938
25939 fn generate_minhash(&mut self, e: &Minhash) -> Result<()> {
25940 self.write_keyword("MINHASH");
25942 self.write("(");
25943 self.generate_expression(&e.this)?;
25944 for expr in &e.expressions {
25945 self.write(", ");
25946 self.generate_expression(expr)?;
25947 }
25948 self.write(")");
25949 Ok(())
25950 }
25951
25952 fn generate_model_attribute(&mut self, e: &ModelAttribute) -> Result<()> {
25953 self.generate_expression(&e.this)?;
25955 self.write("!");
25956 self.generate_expression(&e.expression)?;
25957 Ok(())
25958 }
25959
25960 fn generate_monthname(&mut self, e: &Monthname) -> Result<()> {
25961 self.write_keyword("MONTHNAME");
25963 self.write("(");
25964 self.generate_expression(&e.this)?;
25965 self.write(")");
25966 Ok(())
25967 }
25968
25969 fn generate_multitable_inserts(&mut self, e: &MultitableInserts) -> Result<()> {
25970 for comment in &e.leading_comments {
25972 self.write_formatted_comment(comment);
25973 self.write_space();
25974 }
25975 self.write_keyword("INSERT");
25977 self.write_space();
25978 self.write(&e.kind);
25979 for expr in &e.expressions {
25980 self.write_space();
25981 self.generate_expression(expr)?;
25982 }
25983 if let Some(source) = &e.source {
25984 self.write_space();
25985 self.generate_expression(source)?;
25986 }
25987 Ok(())
25988 }
25989
25990 fn generate_next_value_for(&mut self, e: &NextValueFor) -> Result<()> {
25991 self.write_keyword("NEXT VALUE FOR");
25993 self.write_space();
25994 self.generate_expression(&e.this)?;
25995 if let Some(order) = &e.order {
25996 self.write_space();
25997 self.write_keyword("OVER");
25998 self.write(" (");
25999 self.generate_expression(order)?;
26000 self.write(")");
26001 }
26002 Ok(())
26003 }
26004
26005 fn generate_normal(&mut self, e: &Normal) -> Result<()> {
26006 self.write_keyword("NORMAL");
26008 self.write("(");
26009 self.generate_expression(&e.this)?;
26010 if let Some(stddev) = &e.stddev {
26011 self.write(", ");
26012 self.generate_expression(stddev)?;
26013 }
26014 if let Some(gen) = &e.gen {
26015 self.write(", ");
26016 self.generate_expression(gen)?;
26017 }
26018 self.write(")");
26019 Ok(())
26020 }
26021
26022 fn generate_normalize(&mut self, e: &Normalize) -> Result<()> {
26023 if e.is_casefold.is_some() {
26025 self.write_keyword("NORMALIZE_AND_CASEFOLD");
26026 } else {
26027 self.write_keyword("NORMALIZE");
26028 }
26029 self.write("(");
26030 self.generate_expression(&e.this)?;
26031 if let Some(form) = &e.form {
26032 self.write(", ");
26033 self.generate_expression(form)?;
26034 }
26035 self.write(")");
26036 Ok(())
26037 }
26038
26039 fn generate_not_null_column_constraint(&mut self, e: &NotNullColumnConstraint) -> Result<()> {
26040 if e.allow_null.is_none() {
26042 self.write_keyword("NOT ");
26043 }
26044 self.write_keyword("NULL");
26045 Ok(())
26046 }
26047
26048 fn generate_nullif(&mut self, e: &Nullif) -> Result<()> {
26049 self.write_keyword("NULLIF");
26051 self.write("(");
26052 self.generate_expression(&e.this)?;
26053 self.write(", ");
26054 self.generate_expression(&e.expression)?;
26055 self.write(")");
26056 Ok(())
26057 }
26058
26059 fn generate_number_to_str(&mut self, e: &NumberToStr) -> Result<()> {
26060 self.write_keyword("FORMAT");
26062 self.write("(");
26063 self.generate_expression(&e.this)?;
26064 self.write(", '");
26065 self.write(&e.format);
26066 self.write("'");
26067 if let Some(culture) = &e.culture {
26068 self.write(", ");
26069 self.generate_expression(culture)?;
26070 }
26071 self.write(")");
26072 Ok(())
26073 }
26074
26075 fn generate_object_agg(&mut self, e: &ObjectAgg) -> Result<()> {
26076 self.write_keyword("OBJECT_AGG");
26078 self.write("(");
26079 self.generate_expression(&e.this)?;
26080 self.write(", ");
26081 self.generate_expression(&e.expression)?;
26082 self.write(")");
26083 Ok(())
26084 }
26085
26086 fn generate_object_identifier(&mut self, e: &ObjectIdentifier) -> Result<()> {
26087 self.generate_expression(&e.this)?;
26089 Ok(())
26090 }
26091
26092 fn generate_object_insert(&mut self, e: &ObjectInsert) -> Result<()> {
26093 self.write_keyword("OBJECT_INSERT");
26095 self.write("(");
26096 self.generate_expression(&e.this)?;
26097 if let Some(key) = &e.key {
26098 self.write(", ");
26099 self.generate_expression(key)?;
26100 }
26101 if let Some(value) = &e.value {
26102 self.write(", ");
26103 self.generate_expression(value)?;
26104 }
26105 if let Some(update_flag) = &e.update_flag {
26106 self.write(", ");
26107 self.generate_expression(update_flag)?;
26108 }
26109 self.write(")");
26110 Ok(())
26111 }
26112
26113 fn generate_offset(&mut self, e: &Offset) -> Result<()> {
26114 self.write_keyword("OFFSET");
26116 self.write_space();
26117 self.generate_expression(&e.this)?;
26118 if e.rows == Some(true) && matches!(self.config.dialect, Some(crate::dialects::DialectType::TSQL) | Some(crate::dialects::DialectType::Oracle)) {
26120 self.write_space();
26121 self.write_keyword("ROWS");
26122 }
26123 Ok(())
26124 }
26125
26126 fn generate_qualify(&mut self, e: &Qualify) -> Result<()> {
26127 self.write_keyword("QUALIFY");
26129 self.write_space();
26130 self.generate_expression(&e.this)?;
26131 Ok(())
26132 }
26133
26134 fn generate_on_cluster(&mut self, e: &OnCluster) -> Result<()> {
26135 self.write_keyword("ON CLUSTER");
26137 self.write_space();
26138 self.generate_expression(&e.this)?;
26139 Ok(())
26140 }
26141
26142 fn generate_on_commit_property(&mut self, e: &OnCommitProperty) -> Result<()> {
26143 self.write_keyword("ON COMMIT");
26145 if e.delete.is_some() {
26146 self.write_keyword(" DELETE ROWS");
26147 } else {
26148 self.write_keyword(" PRESERVE ROWS");
26149 }
26150 Ok(())
26151 }
26152
26153 fn generate_on_condition(&mut self, e: &OnCondition) -> Result<()> {
26154 if let Some(empty) = &e.empty {
26156 self.generate_expression(empty)?;
26157 self.write_keyword(" ON EMPTY");
26158 }
26159 if let Some(error) = &e.error {
26160 if e.empty.is_some() {
26161 self.write_space();
26162 }
26163 self.generate_expression(error)?;
26164 self.write_keyword(" ON ERROR");
26165 }
26166 if let Some(null) = &e.null {
26167 if e.empty.is_some() || e.error.is_some() {
26168 self.write_space();
26169 }
26170 self.generate_expression(null)?;
26171 self.write_keyword(" ON NULL");
26172 }
26173 Ok(())
26174 }
26175
26176 fn generate_on_conflict(&mut self, e: &OnConflict) -> Result<()> {
26177 if matches!(self.config.dialect, Some(DialectType::Materialize)) {
26179 return Ok(());
26180 }
26181 if e.duplicate.is_some() {
26183 self.write_keyword("ON DUPLICATE KEY UPDATE");
26185 for (i, expr) in e.expressions.iter().enumerate() {
26186 if i > 0 {
26187 self.write(",");
26188 }
26189 self.write_space();
26190 self.generate_expression(expr)?;
26191 }
26192 return Ok(());
26193 } else {
26194 self.write_keyword("ON CONFLICT");
26195 }
26196 if let Some(constraint) = &e.constraint {
26197 self.write_keyword(" ON CONSTRAINT ");
26198 self.generate_expression(constraint)?;
26199 }
26200 if let Some(conflict_keys) = &e.conflict_keys {
26201 if let Expression::Tuple(t) = conflict_keys.as_ref() {
26203 self.write("(");
26204 for (i, expr) in t.expressions.iter().enumerate() {
26205 if i > 0 {
26206 self.write(", ");
26207 }
26208 self.generate_expression(expr)?;
26209 }
26210 self.write(")");
26211 } else {
26212 self.write("(");
26213 self.generate_expression(conflict_keys)?;
26214 self.write(")");
26215 }
26216 }
26217 if let Some(index_predicate) = &e.index_predicate {
26218 self.write_keyword(" WHERE ");
26219 self.generate_expression(index_predicate)?;
26220 }
26221 if let Some(action) = &e.action {
26222 if let Expression::Identifier(id) = action.as_ref() {
26224 if id.name == "NOTHING" || id.name.to_uppercase() == "NOTHING" {
26225 self.write_keyword(" DO NOTHING");
26226 } else {
26227 self.write_keyword(" DO ");
26228 self.generate_expression(action)?;
26229 }
26230 } else if let Expression::Tuple(t) = action.as_ref() {
26231 self.write_keyword(" DO UPDATE SET ");
26233 for (i, expr) in t.expressions.iter().enumerate() {
26234 if i > 0 {
26235 self.write(", ");
26236 }
26237 self.generate_expression(expr)?;
26238 }
26239 } else {
26240 self.write_keyword(" DO ");
26241 self.generate_expression(action)?;
26242 }
26243 }
26244 if let Some(where_) = &e.where_ {
26246 self.write_keyword(" WHERE ");
26247 self.generate_expression(where_)?;
26248 }
26249 Ok(())
26250 }
26251
26252 fn generate_on_property(&mut self, e: &OnProperty) -> Result<()> {
26253 self.write_keyword("ON");
26255 self.write_space();
26256 self.generate_expression(&e.this)?;
26257 Ok(())
26258 }
26259
26260 fn generate_opclass(&mut self, e: &Opclass) -> Result<()> {
26261 self.generate_expression(&e.this)?;
26263 self.write_space();
26264 self.generate_expression(&e.expression)?;
26265 Ok(())
26266 }
26267
26268 fn generate_open_json(&mut self, e: &OpenJSON) -> Result<()> {
26269 self.write_keyword("OPENJSON");
26271 self.write("(");
26272 self.generate_expression(&e.this)?;
26273 if let Some(path) = &e.path {
26274 self.write(", ");
26275 self.generate_expression(path)?;
26276 }
26277 self.write(")");
26278 if !e.expressions.is_empty() {
26279 self.write_keyword(" WITH");
26280 if self.config.pretty {
26281 self.write(" (\n");
26282 self.indent_level += 2;
26283 for (i, expr) in e.expressions.iter().enumerate() {
26284 if i > 0 {
26285 self.write(",\n");
26286 }
26287 self.write_indent();
26288 self.generate_expression(expr)?;
26289 }
26290 self.write("\n");
26291 self.indent_level -= 2;
26292 self.write(")");
26293 } else {
26294 self.write(" (");
26295 for (i, expr) in e.expressions.iter().enumerate() {
26296 if i > 0 {
26297 self.write(", ");
26298 }
26299 self.generate_expression(expr)?;
26300 }
26301 self.write(")");
26302 }
26303 }
26304 Ok(())
26305 }
26306
26307 fn generate_open_json_column_def(&mut self, e: &OpenJSONColumnDef) -> Result<()> {
26308 self.generate_expression(&e.this)?;
26310 self.write_space();
26311 if let Some(ref dt) = e.data_type {
26313 self.generate_data_type(dt)?;
26314 } else if !e.kind.is_empty() {
26315 self.write(&e.kind);
26316 }
26317 if let Some(path) = &e.path {
26318 self.write_space();
26319 self.generate_expression(path)?;
26320 }
26321 if e.as_json.is_some() {
26322 self.write_keyword(" AS JSON");
26323 }
26324 Ok(())
26325 }
26326
26327 fn generate_operator(&mut self, e: &Operator) -> Result<()> {
26328 self.generate_expression(&e.this)?;
26330 self.write_space();
26331 if let Some(op) = &e.operator {
26332 self.write_keyword("OPERATOR");
26333 self.write("(");
26334 self.generate_expression(op)?;
26335 self.write(")");
26336 }
26337 self.write_space();
26338 self.generate_expression(&e.expression)?;
26339 Ok(())
26340 }
26341
26342 fn generate_order_by(&mut self, e: &OrderBy) -> Result<()> {
26343 self.write_keyword("ORDER BY");
26345 let pretty_clickhouse_single_paren = self.config.pretty
26346 && matches!(self.config.dialect, Some(DialectType::ClickHouse))
26347 && e.expressions.len() == 1
26348 && matches!(e.expressions[0].this, Expression::Paren(ref p) if !matches!(p.this, Expression::Tuple(_)));
26349 let clickhouse_single_tuple = matches!(self.config.dialect, Some(DialectType::ClickHouse))
26350 && e.expressions.len() == 1
26351 && matches!(e.expressions[0].this, Expression::Tuple(_))
26352 && !e.expressions[0].desc
26353 && e.expressions[0].nulls_first.is_none();
26354
26355 if pretty_clickhouse_single_paren {
26356 self.write_space();
26357 if let Expression::Paren(p) = &e.expressions[0].this {
26358 self.write("(");
26359 self.write_newline();
26360 self.indent_level += 1;
26361 self.write_indent();
26362 self.generate_expression(&p.this)?;
26363 self.indent_level -= 1;
26364 self.write_newline();
26365 self.write(")");
26366 }
26367 return Ok(());
26368 }
26369
26370 if clickhouse_single_tuple {
26371 self.write_space();
26372 if let Expression::Tuple(t) = &e.expressions[0].this {
26373 self.write("(");
26374 for (i, expr) in t.expressions.iter().enumerate() {
26375 if i > 0 {
26376 self.write(", ");
26377 }
26378 self.generate_expression(expr)?;
26379 }
26380 self.write(")");
26381 }
26382 return Ok(());
26383 }
26384
26385 self.write_space();
26386 for (i, ordered) in e.expressions.iter().enumerate() {
26387 if i > 0 {
26388 self.write(", ");
26389 }
26390 self.generate_expression(&ordered.this)?;
26391 if ordered.desc {
26392 self.write_space();
26393 self.write_keyword("DESC");
26394 } else if ordered.explicit_asc {
26395 self.write_space();
26396 self.write_keyword("ASC");
26397 }
26398 if let Some(nulls_first) = ordered.nulls_first {
26399 let skip_nulls_last = !nulls_first
26401 && matches!(self.config.dialect, Some(DialectType::Dremio));
26402 if !skip_nulls_last {
26403 self.write_space();
26404 self.write_keyword("NULLS");
26405 self.write_space();
26406 if nulls_first {
26407 self.write_keyword("FIRST");
26408 } else {
26409 self.write_keyword("LAST");
26410 }
26411 }
26412 }
26413 }
26414 Ok(())
26415 }
26416
26417 fn generate_output_model_property(&mut self, e: &OutputModelProperty) -> Result<()> {
26418 self.write_keyword("OUTPUT");
26420 self.write("(");
26421 if self.config.pretty {
26422 self.indent_level += 1;
26423 self.write_newline();
26424 self.write_indent();
26425 self.generate_expression(&e.this)?;
26426 self.indent_level -= 1;
26427 self.write_newline();
26428 } else {
26429 self.generate_expression(&e.this)?;
26430 }
26431 self.write(")");
26432 Ok(())
26433 }
26434
26435 fn generate_overflow_truncate_behavior(&mut self, e: &OverflowTruncateBehavior) -> Result<()> {
26436 self.write_keyword("TRUNCATE");
26438 if let Some(this) = &e.this {
26439 self.write_space();
26440 self.generate_expression(this)?;
26441 }
26442 if e.with_count.is_some() {
26443 self.write_keyword(" WITH COUNT");
26444 } else {
26445 self.write_keyword(" WITHOUT COUNT");
26446 }
26447 Ok(())
26448 }
26449
26450 fn generate_parameterized_agg(&mut self, e: &ParameterizedAgg) -> Result<()> {
26451 self.generate_expression(&e.this)?;
26453 self.write("(");
26454 for (i, expr) in e.expressions.iter().enumerate() {
26455 if i > 0 {
26456 self.write(", ");
26457 }
26458 self.generate_expression(expr)?;
26459 }
26460 self.write(")(");
26461 for (i, param) in e.params.iter().enumerate() {
26462 if i > 0 {
26463 self.write(", ");
26464 }
26465 self.generate_expression(param)?;
26466 }
26467 self.write(")");
26468 Ok(())
26469 }
26470
26471 fn generate_parse_datetime(&mut self, e: &ParseDatetime) -> Result<()> {
26472 self.write_keyword("PARSE_DATETIME");
26474 self.write("(");
26475 if let Some(format) = &e.format {
26476 self.write("'");
26477 self.write(format);
26478 self.write("', ");
26479 }
26480 self.generate_expression(&e.this)?;
26481 if let Some(zone) = &e.zone {
26482 self.write(", ");
26483 self.generate_expression(zone)?;
26484 }
26485 self.write(")");
26486 Ok(())
26487 }
26488
26489 fn generate_parse_ip(&mut self, e: &ParseIp) -> Result<()> {
26490 self.write_keyword("PARSE_IP");
26492 self.write("(");
26493 self.generate_expression(&e.this)?;
26494 if let Some(type_) = &e.type_ {
26495 self.write(", ");
26496 self.generate_expression(type_)?;
26497 }
26498 if let Some(permissive) = &e.permissive {
26499 self.write(", ");
26500 self.generate_expression(permissive)?;
26501 }
26502 self.write(")");
26503 Ok(())
26504 }
26505
26506 fn generate_parse_json(&mut self, e: &ParseJSON) -> Result<()> {
26507 self.write_keyword("PARSE_JSON");
26509 self.write("(");
26510 self.generate_expression(&e.this)?;
26511 if let Some(expression) = &e.expression {
26512 self.write(", ");
26513 self.generate_expression(expression)?;
26514 }
26515 self.write(")");
26516 Ok(())
26517 }
26518
26519 fn generate_parse_time(&mut self, e: &ParseTime) -> Result<()> {
26520 self.write_keyword("PARSE_TIME");
26522 self.write("(");
26523 self.write(&format!("'{}'", e.format));
26524 self.write(", ");
26525 self.generate_expression(&e.this)?;
26526 self.write(")");
26527 Ok(())
26528 }
26529
26530 fn generate_parse_url(&mut self, e: &ParseUrl) -> Result<()> {
26531 self.write_keyword("PARSE_URL");
26533 self.write("(");
26534 self.generate_expression(&e.this)?;
26535 if let Some(part) = &e.part_to_extract {
26536 self.write(", ");
26537 self.generate_expression(part)?;
26538 }
26539 if let Some(key) = &e.key {
26540 self.write(", ");
26541 self.generate_expression(key)?;
26542 }
26543 if let Some(permissive) = &e.permissive {
26544 self.write(", ");
26545 self.generate_expression(permissive)?;
26546 }
26547 self.write(")");
26548 Ok(())
26549 }
26550
26551 fn generate_partition_expr(&mut self, e: &Partition) -> Result<()> {
26552 if e.subpartition {
26554 self.write_keyword("SUBPARTITION");
26555 } else {
26556 self.write_keyword("PARTITION");
26557 }
26558 self.write("(");
26559 for (i, expr) in e.expressions.iter().enumerate() {
26560 if i > 0 {
26561 self.write(", ");
26562 }
26563 self.generate_expression(expr)?;
26564 }
26565 self.write(")");
26566 Ok(())
26567 }
26568
26569 fn generate_partition_bound_spec(&mut self, e: &PartitionBoundSpec) -> Result<()> {
26570 if let Some(this) = &e.this {
26572 if let Some(expression) = &e.expression {
26573 self.write_keyword("WITH");
26575 self.write(" (");
26576 self.write_keyword("MODULUS");
26577 self.write_space();
26578 self.generate_expression(this)?;
26579 self.write(", ");
26580 self.write_keyword("REMAINDER");
26581 self.write_space();
26582 self.generate_expression(expression)?;
26583 self.write(")");
26584 } else {
26585 self.write_keyword("IN");
26587 self.write(" (");
26588 self.generate_partition_bound_values(this)?;
26589 self.write(")");
26590 }
26591 } else if let (Some(from), Some(to)) = (&e.from_expressions, &e.to_expressions) {
26592 self.write_keyword("FROM");
26594 self.write(" (");
26595 self.generate_partition_bound_values(from)?;
26596 self.write(") ");
26597 self.write_keyword("TO");
26598 self.write(" (");
26599 self.generate_partition_bound_values(to)?;
26600 self.write(")");
26601 }
26602 Ok(())
26603 }
26604
26605 fn generate_partition_bound_values(&mut self, expr: &Expression) -> Result<()> {
26608 if let Expression::Tuple(t) = expr {
26609 for (i, e) in t.expressions.iter().enumerate() {
26610 if i > 0 {
26611 self.write(", ");
26612 }
26613 self.generate_expression(e)?;
26614 }
26615 Ok(())
26616 } else {
26617 self.generate_expression(expr)
26618 }
26619 }
26620
26621 fn generate_partition_by_list_property(&mut self, e: &PartitionByListProperty) -> Result<()> {
26622 self.write_keyword("PARTITION BY LIST");
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_partition_by_range_property(&mut self, e: &PartitionByRangeProperty) -> Result<()> {
26640 self.write_keyword("PARTITION BY RANGE");
26642 if let Some(partition_exprs) = &e.partition_expressions {
26643 self.write(" (");
26644 self.generate_doris_partition_expressions(partition_exprs)?;
26646 self.write(")");
26647 }
26648 if let Some(create_exprs) = &e.create_expressions {
26649 self.write(" (");
26650 self.generate_doris_partition_definitions(create_exprs)?;
26652 self.write(")");
26653 }
26654 Ok(())
26655 }
26656
26657 fn generate_doris_partition_expressions(&mut self, expr: &Expression) -> Result<()> {
26659 if let Expression::Tuple(t) = expr {
26660 for (i, e) in t.expressions.iter().enumerate() {
26661 if i > 0 {
26662 self.write(", ");
26663 }
26664 self.generate_expression(e)?;
26665 }
26666 } else {
26667 self.generate_expression(expr)?;
26668 }
26669 Ok(())
26670 }
26671
26672 fn generate_doris_partition_definitions(&mut self, expr: &Expression) -> Result<()> {
26674 match expr {
26675 Expression::Tuple(t) => {
26676 for (i, part) in t.expressions.iter().enumerate() {
26678 if i > 0 {
26679 self.write(", ");
26680 }
26681 if let Expression::Partition(p) = part {
26683 for (j, inner) in p.expressions.iter().enumerate() {
26684 if j > 0 {
26685 self.write(", ");
26686 }
26687 self.generate_expression(inner)?;
26688 }
26689 } else {
26690 self.generate_expression(part)?;
26691 }
26692 }
26693 }
26694 Expression::PartitionByRangePropertyDynamic(_) => {
26695 self.generate_expression(expr)?;
26697 }
26698 _ => {
26699 self.generate_expression(expr)?;
26700 }
26701 }
26702 Ok(())
26703 }
26704
26705 fn generate_partition_by_range_property_dynamic(&mut self, e: &PartitionByRangePropertyDynamic) -> Result<()> {
26706 if let Some(start) = &e.start {
26708 self.write_keyword("FROM");
26709 self.write(" (");
26710 self.generate_expression(start)?;
26711 self.write(")");
26712 }
26713 if let Some(end) = &e.end {
26714 self.write_space();
26715 self.write_keyword("TO");
26716 self.write(" (");
26717 self.generate_expression(end)?;
26718 self.write(")");
26719 }
26720 if let Some(every) = &e.every {
26721 self.write_space();
26722 self.generate_doris_interval(every)?;
26724 }
26725 Ok(())
26726 }
26727
26728 fn generate_doris_interval(&mut self, expr: &Expression) -> Result<()> {
26730 if let Expression::Interval(interval) = expr {
26731 self.write_keyword("INTERVAL");
26732 if let Some(ref value) = interval.this {
26733 self.write_space();
26734 self.generate_expression(value)?;
26736 }
26737 if let Some(ref unit_spec) = interval.unit {
26738 self.write_space();
26739 self.write_interval_unit_spec(unit_spec)?;
26740 }
26741 Ok(())
26742 } else {
26743 self.generate_expression(expr)
26744 }
26745 }
26746
26747 fn generate_partition_by_truncate(&mut self, e: &PartitionByTruncate) -> Result<()> {
26748 self.write_keyword("TRUNCATE");
26750 self.write("(");
26751 self.generate_expression(&e.expression)?;
26752 self.write(", ");
26753 self.generate_expression(&e.this)?;
26754 self.write(")");
26755 Ok(())
26756 }
26757
26758 fn generate_partition_list(&mut self, e: &PartitionList) -> Result<()> {
26759 self.write_keyword("PARTITION");
26761 self.write_space();
26762 self.generate_expression(&e.this)?;
26763 self.write_space();
26764 self.write_keyword("VALUES IN");
26765 self.write(" (");
26766 for (i, expr) in e.expressions.iter().enumerate() {
26767 if i > 0 {
26768 self.write(", ");
26769 }
26770 self.generate_expression(expr)?;
26771 }
26772 self.write(")");
26773 Ok(())
26774 }
26775
26776 fn generate_partition_range(&mut self, e: &PartitionRange) -> Result<()> {
26777 if e.expressions.is_empty() && e.expression.is_some() {
26780 self.generate_expression(&e.this)?;
26782 self.write_space();
26783 self.write_keyword("TO");
26784 self.write_space();
26785 self.generate_expression(e.expression.as_ref().unwrap())?;
26786 return Ok(());
26787 }
26788
26789 self.write_keyword("PARTITION");
26791 self.write_space();
26792 self.generate_expression(&e.this)?;
26793 self.write_space();
26794
26795 if e.expressions.len() == 1 {
26797 self.write_keyword("VALUES LESS THAN");
26799 self.write(" (");
26800 self.generate_expression(&e.expressions[0])?;
26801 self.write(")");
26802 } else if !e.expressions.is_empty() {
26803 self.write_keyword("VALUES");
26805 self.write(" [");
26806 for (i, expr) in e.expressions.iter().enumerate() {
26807 if i > 0 {
26808 self.write(", ");
26809 }
26810 if let Expression::Tuple(t) = expr {
26812 self.write("(");
26813 for (j, inner) in t.expressions.iter().enumerate() {
26814 if j > 0 {
26815 self.write(", ");
26816 }
26817 self.generate_expression(inner)?;
26818 }
26819 self.write(")");
26820 } else {
26821 self.write("(");
26822 self.generate_expression(expr)?;
26823 self.write(")");
26824 }
26825 }
26826 self.write(")");
26827 }
26828 Ok(())
26829 }
26830
26831 fn generate_partitioned_by_bucket(&mut self, e: &PartitionedByBucket) -> Result<()> {
26832 self.write_keyword("BUCKET");
26834 self.write("(");
26835 self.generate_expression(&e.this)?;
26836 self.write(", ");
26837 self.generate_expression(&e.expression)?;
26838 self.write(")");
26839 Ok(())
26840 }
26841
26842 fn generate_partitioned_by_property(&mut self, e: &PartitionedByProperty) -> Result<()> {
26843 if matches!(
26845 self.config.dialect,
26846 Some(crate::dialects::DialectType::Teradata) | Some(crate::dialects::DialectType::ClickHouse)
26847 ) {
26848 self.write_keyword("PARTITION BY");
26849 } else {
26850 self.write_keyword("PARTITIONED BY");
26851 }
26852 self.write_space();
26853 if self.config.pretty {
26855 if let Expression::Tuple(ref tuple) = *e.this {
26856 self.write("(");
26857 self.write_newline();
26858 self.indent_level += 1;
26859 for (i, expr) in tuple.expressions.iter().enumerate() {
26860 if i > 0 {
26861 self.write(",");
26862 self.write_newline();
26863 }
26864 self.write_indent();
26865 self.generate_expression(expr)?;
26866 }
26867 self.indent_level -= 1;
26868 self.write_newline();
26869 self.write(")");
26870 } else {
26871 self.generate_expression(&e.this)?;
26872 }
26873 } else {
26874 self.generate_expression(&e.this)?;
26875 }
26876 Ok(())
26877 }
26878
26879 fn generate_partitioned_of_property(&mut self, e: &PartitionedOfProperty) -> Result<()> {
26880 self.write_keyword("PARTITION OF");
26882 self.write_space();
26883 self.generate_expression(&e.this)?;
26884 if let Expression::PartitionBoundSpec(_) = e.expression.as_ref() {
26886 self.write_space();
26887 self.write_keyword("FOR VALUES");
26888 self.write_space();
26889 self.generate_expression(&e.expression)?;
26890 } else {
26891 self.write_space();
26892 self.write_keyword("DEFAULT");
26893 }
26894 Ok(())
26895 }
26896
26897 fn generate_period_for_system_time_constraint(&mut self, e: &PeriodForSystemTimeConstraint) -> Result<()> {
26898 self.write_keyword("PERIOD FOR SYSTEM_TIME");
26900 self.write(" (");
26901 self.generate_expression(&e.this)?;
26902 self.write(", ");
26903 self.generate_expression(&e.expression)?;
26904 self.write(")");
26905 Ok(())
26906 }
26907
26908 fn generate_pivot_alias(&mut self, e: &PivotAlias) -> Result<()> {
26909 self.generate_expression(&e.this)?;
26912 self.write_space();
26913 self.write_keyword("AS");
26914 self.write_space();
26915 if self.config.unpivot_aliases_are_identifiers {
26917 match &e.alias {
26918 Expression::Literal(Literal::String(s)) => {
26919 self.generate_identifier(&Identifier::new(s.clone()))?;
26921 }
26922 Expression::Literal(Literal::Number(n)) => {
26923 let mut id = Identifier::new(n.clone());
26925 id.quoted = true;
26926 self.generate_identifier(&id)?;
26927 }
26928 other => {
26929 self.generate_expression(other)?;
26930 }
26931 }
26932 } else {
26933 self.generate_expression(&e.alias)?;
26934 }
26935 Ok(())
26936 }
26937
26938 fn generate_pivot_any(&mut self, e: &PivotAny) -> Result<()> {
26939 self.write_keyword("ANY");
26941 if let Some(this) = &e.this {
26942 self.write_space();
26943 self.generate_expression(this)?;
26944 }
26945 Ok(())
26946 }
26947
26948 fn generate_predict(&mut self, e: &Predict) -> Result<()> {
26949 self.write_keyword("ML.PREDICT");
26951 self.write("(");
26952 self.write_keyword("MODEL");
26953 self.write_space();
26954 self.generate_expression(&e.this)?;
26955 self.write(", ");
26956 self.generate_expression(&e.expression)?;
26957 if let Some(params) = &e.params_struct {
26958 self.write(", ");
26959 self.generate_expression(params)?;
26960 }
26961 self.write(")");
26962 Ok(())
26963 }
26964
26965 fn generate_previous_day(&mut self, e: &PreviousDay) -> Result<()> {
26966 self.write_keyword("PREVIOUS_DAY");
26968 self.write("(");
26969 self.generate_expression(&e.this)?;
26970 self.write(", ");
26971 self.generate_expression(&e.expression)?;
26972 self.write(")");
26973 Ok(())
26974 }
26975
26976 fn generate_primary_key(&mut self, e: &PrimaryKey) -> Result<()> {
26977 self.write_keyword("PRIMARY KEY");
26979 if let Some(name) = &e.this {
26980 self.write_space();
26981 self.generate_expression(name)?;
26982 }
26983 if !e.expressions.is_empty() {
26984 self.write(" (");
26985 for (i, expr) in e.expressions.iter().enumerate() {
26986 if i > 0 {
26987 self.write(", ");
26988 }
26989 self.generate_expression(expr)?;
26990 }
26991 self.write(")");
26992 }
26993 if let Some(include) = &e.include {
26994 self.write_space();
26995 self.generate_expression(include)?;
26996 }
26997 if !e.options.is_empty() {
26998 self.write_space();
26999 for (i, opt) in e.options.iter().enumerate() {
27000 if i > 0 {
27001 self.write_space();
27002 }
27003 self.generate_expression(opt)?;
27004 }
27005 }
27006 Ok(())
27007 }
27008
27009 fn generate_primary_key_column_constraint(&mut self, _e: &PrimaryKeyColumnConstraint) -> Result<()> {
27010 self.write_keyword("PRIMARY KEY");
27012 Ok(())
27013 }
27014
27015 fn generate_path_column_constraint(&mut self, e: &PathColumnConstraint) -> Result<()> {
27016 self.write_keyword("PATH");
27018 self.write_space();
27019 self.generate_expression(&e.this)?;
27020 Ok(())
27021 }
27022
27023 fn generate_projection_def(&mut self, e: &ProjectionDef) -> Result<()> {
27024 self.write_keyword("PROJECTION");
27026 self.write_space();
27027 self.generate_expression(&e.this)?;
27028 self.write(" (");
27029 self.generate_expression(&e.expression)?;
27030 self.write(")");
27031 Ok(())
27032 }
27033
27034 fn generate_properties(&mut self, e: &Properties) -> Result<()> {
27035 for (i, prop) in e.expressions.iter().enumerate() {
27037 if i > 0 {
27038 self.write(", ");
27039 }
27040 self.generate_expression(prop)?;
27041 }
27042 Ok(())
27043 }
27044
27045 fn generate_property(&mut self, e: &Property) -> Result<()> {
27046 self.generate_expression(&e.this)?;
27048 if let Some(value) = &e.value {
27049 self.write("=");
27050 self.generate_expression(value)?;
27051 }
27052 Ok(())
27053 }
27054
27055 fn generate_options_clause(&mut self, options: &[Expression]) -> Result<()> {
27057 self.write_keyword("OPTIONS");
27058 self.write(" (");
27059 for (i, opt) in options.iter().enumerate() {
27060 if i > 0 {
27061 self.write(", ");
27062 }
27063 self.generate_option_expression(opt)?;
27064 }
27065 self.write(")");
27066 Ok(())
27067 }
27068
27069 fn generate_properties_clause(&mut self, properties: &[Expression]) -> Result<()> {
27071 self.write_keyword("PROPERTIES");
27072 self.write(" (");
27073 for (i, prop) in properties.iter().enumerate() {
27074 if i > 0 {
27075 self.write(", ");
27076 }
27077 self.generate_option_expression(prop)?;
27078 }
27079 self.write(")");
27080 Ok(())
27081 }
27082
27083 fn generate_environment_clause(&mut self, environment: &[Expression]) -> Result<()> {
27085 self.write_keyword("ENVIRONMENT");
27086 self.write(" (");
27087 for (i, env_item) in environment.iter().enumerate() {
27088 if i > 0 {
27089 self.write(", ");
27090 }
27091 self.generate_environment_expression(env_item)?;
27092 }
27093 self.write(")");
27094 Ok(())
27095 }
27096
27097 fn generate_environment_expression(&mut self, expr: &Expression) -> Result<()> {
27099 match expr {
27100 Expression::Eq(eq) => {
27101 self.generate_expression(&eq.left)?;
27103 self.write(" = ");
27104 self.generate_expression(&eq.right)?;
27105 Ok(())
27106 }
27107 _ => self.generate_expression(expr),
27108 }
27109 }
27110
27111 fn generate_tblproperties_clause(&mut self, options: &[Expression]) -> Result<()> {
27113 self.write_keyword("TBLPROPERTIES");
27114 if self.config.pretty {
27115 self.write(" (");
27116 self.write_newline();
27117 self.indent_level += 1;
27118 for (i, opt) in options.iter().enumerate() {
27119 if i > 0 {
27120 self.write(",");
27121 self.write_newline();
27122 }
27123 self.write_indent();
27124 self.generate_option_expression(opt)?;
27125 }
27126 self.indent_level -= 1;
27127 self.write_newline();
27128 self.write(")");
27129 } else {
27130 self.write(" (");
27131 for (i, opt) in options.iter().enumerate() {
27132 if i > 0 {
27133 self.write(", ");
27134 }
27135 self.generate_option_expression(opt)?;
27136 }
27137 self.write(")");
27138 }
27139 Ok(())
27140 }
27141
27142 fn generate_option_expression(&mut self, expr: &Expression) -> Result<()> {
27144 match expr {
27145 Expression::Eq(eq) => {
27146 self.generate_expression(&eq.left)?;
27148 self.write("=");
27149 self.generate_expression(&eq.right)?;
27150 Ok(())
27151 }
27152 _ => self.generate_expression(expr),
27153 }
27154 }
27155
27156 fn generate_pseudo_type(&mut self, e: &PseudoType) -> Result<()> {
27157 self.generate_expression(&e.this)?;
27159 Ok(())
27160 }
27161
27162 fn generate_put(&mut self, e: &PutStmt) -> Result<()> {
27163 self.write_keyword("PUT");
27165 self.write_space();
27166
27167 if e.source_quoted {
27169 self.write("'");
27170 self.write(&e.source);
27171 self.write("'");
27172 } else {
27173 self.write(&e.source);
27174 }
27175
27176 self.write_space();
27177
27178 if let Expression::Literal(Literal::String(s)) = &e.target {
27180 self.write(s);
27181 } else {
27182 self.generate_expression(&e.target)?;
27183 }
27184
27185 for param in &e.params {
27187 self.write_space();
27188 self.write(¶m.name);
27189 if let Some(ref value) = param.value {
27190 self.write("=");
27191 self.generate_expression(value)?;
27192 }
27193 }
27194
27195 Ok(())
27196 }
27197
27198 fn generate_quantile(&mut self, e: &Quantile) -> Result<()> {
27199 self.write_keyword("QUANTILE");
27201 self.write("(");
27202 self.generate_expression(&e.this)?;
27203 if let Some(quantile) = &e.quantile {
27204 self.write(", ");
27205 self.generate_expression(quantile)?;
27206 }
27207 self.write(")");
27208 Ok(())
27209 }
27210
27211 fn generate_query_band(&mut self, e: &QueryBand) -> Result<()> {
27212 if matches!(self.config.dialect, Some(crate::dialects::DialectType::Teradata)) {
27214 self.write_keyword("SET");
27215 self.write_space();
27216 }
27217 self.write_keyword("QUERY_BAND");
27218 self.write(" = ");
27219 self.generate_expression(&e.this)?;
27220 if e.update.is_some() {
27221 self.write_space();
27222 self.write_keyword("UPDATE");
27223 }
27224 if let Some(scope) = &e.scope {
27225 self.write_space();
27226 self.write_keyword("FOR");
27227 self.write_space();
27228 self.generate_expression(scope)?;
27229 }
27230 Ok(())
27231 }
27232
27233 fn generate_query_option(&mut self, e: &QueryOption) -> Result<()> {
27234 self.generate_expression(&e.this)?;
27236 if let Some(expression) = &e.expression {
27237 self.write(" = ");
27238 self.generate_expression(expression)?;
27239 }
27240 Ok(())
27241 }
27242
27243 fn generate_query_transform(&mut self, e: &QueryTransform) -> Result<()> {
27244 self.write_keyword("TRANSFORM");
27246 self.write("(");
27247 for (i, expr) in e.expressions.iter().enumerate() {
27248 if i > 0 {
27249 self.write(", ");
27250 }
27251 self.generate_expression(expr)?;
27252 }
27253 self.write(")");
27254 if let Some(row_format_before) = &e.row_format_before {
27255 self.write_space();
27256 self.generate_expression(row_format_before)?;
27257 }
27258 if let Some(record_writer) = &e.record_writer {
27259 self.write_space();
27260 self.write_keyword("RECORDWRITER");
27261 self.write_space();
27262 self.generate_expression(record_writer)?;
27263 }
27264 if let Some(command_script) = &e.command_script {
27265 self.write_space();
27266 self.write_keyword("USING");
27267 self.write_space();
27268 self.generate_expression(command_script)?;
27269 }
27270 if let Some(schema) = &e.schema {
27271 self.write_space();
27272 self.write_keyword("AS");
27273 self.write_space();
27274 self.generate_expression(schema)?;
27275 }
27276 if let Some(row_format_after) = &e.row_format_after {
27277 self.write_space();
27278 self.generate_expression(row_format_after)?;
27279 }
27280 if let Some(record_reader) = &e.record_reader {
27281 self.write_space();
27282 self.write_keyword("RECORDREADER");
27283 self.write_space();
27284 self.generate_expression(record_reader)?;
27285 }
27286 Ok(())
27287 }
27288
27289 fn generate_randn(&mut self, e: &Randn) -> Result<()> {
27290 self.write_keyword("RANDN");
27292 self.write("(");
27293 if let Some(this) = &e.this {
27294 self.generate_expression(this)?;
27295 }
27296 self.write(")");
27297 Ok(())
27298 }
27299
27300 fn generate_randstr(&mut self, e: &Randstr) -> Result<()> {
27301 self.write_keyword("RANDSTR");
27303 self.write("(");
27304 self.generate_expression(&e.this)?;
27305 if let Some(generator) = &e.generator {
27306 self.write(", ");
27307 self.generate_expression(generator)?;
27308 }
27309 self.write(")");
27310 Ok(())
27311 }
27312
27313 fn generate_range_bucket(&mut self, e: &RangeBucket) -> Result<()> {
27314 self.write_keyword("RANGE_BUCKET");
27316 self.write("(");
27317 self.generate_expression(&e.this)?;
27318 self.write(", ");
27319 self.generate_expression(&e.expression)?;
27320 self.write(")");
27321 Ok(())
27322 }
27323
27324 fn generate_range_n(&mut self, e: &RangeN) -> Result<()> {
27325 self.write_keyword("RANGE_N");
27327 self.write("(");
27328 self.generate_expression(&e.this)?;
27329 self.write_space();
27330 self.write_keyword("BETWEEN");
27331 self.write_space();
27332 for (i, expr) in e.expressions.iter().enumerate() {
27333 if i > 0 {
27334 self.write(", ");
27335 }
27336 self.generate_expression(expr)?;
27337 }
27338 if let Some(each) = &e.each {
27339 self.write_space();
27340 self.write_keyword("EACH");
27341 self.write_space();
27342 self.generate_expression(each)?;
27343 }
27344 self.write(")");
27345 Ok(())
27346 }
27347
27348 fn generate_read_csv(&mut self, e: &ReadCSV) -> Result<()> {
27349 self.write_keyword("READ_CSV");
27351 self.write("(");
27352 self.generate_expression(&e.this)?;
27353 for expr in &e.expressions {
27354 self.write(", ");
27355 self.generate_expression(expr)?;
27356 }
27357 self.write(")");
27358 Ok(())
27359 }
27360
27361 fn generate_read_parquet(&mut self, e: &ReadParquet) -> Result<()> {
27362 self.write_keyword("READ_PARQUET");
27364 self.write("(");
27365 for (i, expr) in e.expressions.iter().enumerate() {
27366 if i > 0 {
27367 self.write(", ");
27368 }
27369 self.generate_expression(expr)?;
27370 }
27371 self.write(")");
27372 Ok(())
27373 }
27374
27375 fn generate_recursive_with_search(&mut self, e: &RecursiveWithSearch) -> Result<()> {
27376 if e.kind == "CYCLE" {
27379 self.write_keyword("CYCLE");
27380 } else {
27381 self.write_keyword("SEARCH");
27382 self.write_space();
27383 self.write(&e.kind);
27384 self.write_space();
27385 self.write_keyword("FIRST BY");
27386 }
27387 self.write_space();
27388 self.generate_expression(&e.this)?;
27389 self.write_space();
27390 self.write_keyword("SET");
27391 self.write_space();
27392 self.generate_expression(&e.expression)?;
27393 if let Some(using) = &e.using {
27394 self.write_space();
27395 self.write_keyword("USING");
27396 self.write_space();
27397 self.generate_expression(using)?;
27398 }
27399 Ok(())
27400 }
27401
27402 fn generate_reduce(&mut self, e: &Reduce) -> Result<()> {
27403 self.write_keyword("REDUCE");
27405 self.write("(");
27406 self.generate_expression(&e.this)?;
27407 if let Some(initial) = &e.initial {
27408 self.write(", ");
27409 self.generate_expression(initial)?;
27410 }
27411 if let Some(merge) = &e.merge {
27412 self.write(", ");
27413 self.generate_expression(merge)?;
27414 }
27415 if let Some(finish) = &e.finish {
27416 self.write(", ");
27417 self.generate_expression(finish)?;
27418 }
27419 self.write(")");
27420 Ok(())
27421 }
27422
27423 fn generate_reference(&mut self, e: &Reference) -> Result<()> {
27424 self.write_keyword("REFERENCES");
27426 self.write_space();
27427 self.generate_expression(&e.this)?;
27428 if !e.expressions.is_empty() {
27429 self.write(" (");
27430 for (i, expr) in e.expressions.iter().enumerate() {
27431 if i > 0 {
27432 self.write(", ");
27433 }
27434 self.generate_expression(expr)?;
27435 }
27436 self.write(")");
27437 }
27438 for opt in &e.options {
27439 self.write_space();
27440 self.generate_expression(opt)?;
27441 }
27442 Ok(())
27443 }
27444
27445 fn generate_refresh(&mut self, e: &Refresh) -> Result<()> {
27446 self.write_keyword("REFRESH");
27448 if !e.kind.is_empty() {
27449 self.write_space();
27450 self.write_keyword(&e.kind);
27451 }
27452 self.write_space();
27453 self.generate_expression(&e.this)?;
27454 Ok(())
27455 }
27456
27457 fn generate_refresh_trigger_property(&mut self, e: &RefreshTriggerProperty) -> Result<()> {
27458 self.write_keyword("REFRESH");
27460 self.write_space();
27461 self.write_keyword(&e.method);
27462
27463 if let Some(ref kind) = e.kind {
27464 self.write_space();
27465 self.write_keyword("ON");
27466 self.write_space();
27467 self.write_keyword(kind);
27468
27469 if let Some(ref every) = e.every {
27471 self.write_space();
27472 self.write_keyword("EVERY");
27473 self.write_space();
27474 self.generate_expression(every)?;
27475 if let Some(ref unit) = e.unit {
27476 self.write_space();
27477 self.write_keyword(unit);
27478 }
27479 }
27480
27481 if let Some(ref starts) = e.starts {
27483 self.write_space();
27484 self.write_keyword("STARTS");
27485 self.write_space();
27486 self.generate_expression(starts)?;
27487 }
27488 }
27489 Ok(())
27490 }
27491
27492 fn generate_regexp_count(&mut self, e: &RegexpCount) -> Result<()> {
27493 self.write_keyword("REGEXP_COUNT");
27495 self.write("(");
27496 self.generate_expression(&e.this)?;
27497 self.write(", ");
27498 self.generate_expression(&e.expression)?;
27499 if let Some(position) = &e.position {
27500 self.write(", ");
27501 self.generate_expression(position)?;
27502 }
27503 if let Some(parameters) = &e.parameters {
27504 self.write(", ");
27505 self.generate_expression(parameters)?;
27506 }
27507 self.write(")");
27508 Ok(())
27509 }
27510
27511 fn generate_regexp_extract_all(&mut self, e: &RegexpExtractAll) -> Result<()> {
27512 self.write_keyword("REGEXP_EXTRACT_ALL");
27514 self.write("(");
27515 self.generate_expression(&e.this)?;
27516 self.write(", ");
27517 self.generate_expression(&e.expression)?;
27518 if let Some(group) = &e.group {
27519 self.write(", ");
27520 self.generate_expression(group)?;
27521 }
27522 self.write(")");
27523 Ok(())
27524 }
27525
27526 fn generate_regexp_full_match(&mut self, e: &RegexpFullMatch) -> Result<()> {
27527 self.write_keyword("REGEXP_FULL_MATCH");
27529 self.write("(");
27530 self.generate_expression(&e.this)?;
27531 self.write(", ");
27532 self.generate_expression(&e.expression)?;
27533 self.write(")");
27534 Ok(())
27535 }
27536
27537 fn generate_regexp_i_like(&mut self, e: &RegexpILike) -> Result<()> {
27538 use crate::dialects::DialectType;
27539 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) && e.flag.is_none() {
27541 self.generate_expression(&e.this)?;
27542 self.write(" ~* ");
27543 self.generate_expression(&e.expression)?;
27544 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
27545 self.write_keyword("REGEXP_LIKE");
27547 self.write("(");
27548 self.generate_expression(&e.this)?;
27549 self.write(", ");
27550 self.generate_expression(&e.expression)?;
27551 self.write(", ");
27552 if let Some(flag) = &e.flag {
27553 self.generate_expression(flag)?;
27554 } else {
27555 self.write("'i'");
27556 }
27557 self.write(")");
27558 } else {
27559 self.generate_expression(&e.this)?;
27561 self.write_space();
27562 self.write_keyword("REGEXP_ILIKE");
27563 self.write_space();
27564 self.generate_expression(&e.expression)?;
27565 if let Some(flag) = &e.flag {
27566 self.write(", ");
27567 self.generate_expression(flag)?;
27568 }
27569 }
27570 Ok(())
27571 }
27572
27573 fn generate_regexp_instr(&mut self, e: &RegexpInstr) -> Result<()> {
27574 self.write_keyword("REGEXP_INSTR");
27576 self.write("(");
27577 self.generate_expression(&e.this)?;
27578 self.write(", ");
27579 self.generate_expression(&e.expression)?;
27580 if let Some(position) = &e.position {
27581 self.write(", ");
27582 self.generate_expression(position)?;
27583 }
27584 if let Some(occurrence) = &e.occurrence {
27585 self.write(", ");
27586 self.generate_expression(occurrence)?;
27587 }
27588 if let Some(option) = &e.option {
27589 self.write(", ");
27590 self.generate_expression(option)?;
27591 }
27592 if let Some(parameters) = &e.parameters {
27593 self.write(", ");
27594 self.generate_expression(parameters)?;
27595 }
27596 if let Some(group) = &e.group {
27597 self.write(", ");
27598 self.generate_expression(group)?;
27599 }
27600 self.write(")");
27601 Ok(())
27602 }
27603
27604 fn generate_regexp_split(&mut self, e: &RegexpSplit) -> Result<()> {
27605 self.write_keyword("REGEXP_SPLIT");
27607 self.write("(");
27608 self.generate_expression(&e.this)?;
27609 self.write(", ");
27610 self.generate_expression(&e.expression)?;
27611 if let Some(limit) = &e.limit {
27612 self.write(", ");
27613 self.generate_expression(limit)?;
27614 }
27615 self.write(")");
27616 Ok(())
27617 }
27618
27619 fn generate_regr_avgx(&mut self, e: &RegrAvgx) -> Result<()> {
27620 self.write_keyword("REGR_AVGX");
27622 self.write("(");
27623 self.generate_expression(&e.this)?;
27624 self.write(", ");
27625 self.generate_expression(&e.expression)?;
27626 self.write(")");
27627 Ok(())
27628 }
27629
27630 fn generate_regr_avgy(&mut self, e: &RegrAvgy) -> Result<()> {
27631 self.write_keyword("REGR_AVGY");
27633 self.write("(");
27634 self.generate_expression(&e.this)?;
27635 self.write(", ");
27636 self.generate_expression(&e.expression)?;
27637 self.write(")");
27638 Ok(())
27639 }
27640
27641 fn generate_regr_count(&mut self, e: &RegrCount) -> Result<()> {
27642 self.write_keyword("REGR_COUNT");
27644 self.write("(");
27645 self.generate_expression(&e.this)?;
27646 self.write(", ");
27647 self.generate_expression(&e.expression)?;
27648 self.write(")");
27649 Ok(())
27650 }
27651
27652 fn generate_regr_intercept(&mut self, e: &RegrIntercept) -> Result<()> {
27653 self.write_keyword("REGR_INTERCEPT");
27655 self.write("(");
27656 self.generate_expression(&e.this)?;
27657 self.write(", ");
27658 self.generate_expression(&e.expression)?;
27659 self.write(")");
27660 Ok(())
27661 }
27662
27663 fn generate_regr_r2(&mut self, e: &RegrR2) -> Result<()> {
27664 self.write_keyword("REGR_R2");
27666 self.write("(");
27667 self.generate_expression(&e.this)?;
27668 self.write(", ");
27669 self.generate_expression(&e.expression)?;
27670 self.write(")");
27671 Ok(())
27672 }
27673
27674 fn generate_regr_slope(&mut self, e: &RegrSlope) -> Result<()> {
27675 self.write_keyword("REGR_SLOPE");
27677 self.write("(");
27678 self.generate_expression(&e.this)?;
27679 self.write(", ");
27680 self.generate_expression(&e.expression)?;
27681 self.write(")");
27682 Ok(())
27683 }
27684
27685 fn generate_regr_sxx(&mut self, e: &RegrSxx) -> Result<()> {
27686 self.write_keyword("REGR_SXX");
27688 self.write("(");
27689 self.generate_expression(&e.this)?;
27690 self.write(", ");
27691 self.generate_expression(&e.expression)?;
27692 self.write(")");
27693 Ok(())
27694 }
27695
27696 fn generate_regr_sxy(&mut self, e: &RegrSxy) -> Result<()> {
27697 self.write_keyword("REGR_SXY");
27699 self.write("(");
27700 self.generate_expression(&e.this)?;
27701 self.write(", ");
27702 self.generate_expression(&e.expression)?;
27703 self.write(")");
27704 Ok(())
27705 }
27706
27707 fn generate_regr_syy(&mut self, e: &RegrSyy) -> Result<()> {
27708 self.write_keyword("REGR_SYY");
27710 self.write("(");
27711 self.generate_expression(&e.this)?;
27712 self.write(", ");
27713 self.generate_expression(&e.expression)?;
27714 self.write(")");
27715 Ok(())
27716 }
27717
27718 fn generate_regr_valx(&mut self, e: &RegrValx) -> Result<()> {
27719 self.write_keyword("REGR_VALX");
27721 self.write("(");
27722 self.generate_expression(&e.this)?;
27723 self.write(", ");
27724 self.generate_expression(&e.expression)?;
27725 self.write(")");
27726 Ok(())
27727 }
27728
27729 fn generate_regr_valy(&mut self, e: &RegrValy) -> Result<()> {
27730 self.write_keyword("REGR_VALY");
27732 self.write("(");
27733 self.generate_expression(&e.this)?;
27734 self.write(", ");
27735 self.generate_expression(&e.expression)?;
27736 self.write(")");
27737 Ok(())
27738 }
27739
27740 fn generate_remote_with_connection_model_property(&mut self, e: &RemoteWithConnectionModelProperty) -> Result<()> {
27741 self.write_keyword("REMOTE WITH CONNECTION");
27743 self.write_space();
27744 self.generate_expression(&e.this)?;
27745 Ok(())
27746 }
27747
27748 fn generate_rename_column(&mut self, e: &RenameColumn) -> Result<()> {
27749 self.write_keyword("RENAME COLUMN");
27751 if e.exists {
27752 self.write_space();
27753 self.write_keyword("IF EXISTS");
27754 }
27755 self.write_space();
27756 self.generate_expression(&e.this)?;
27757 if let Some(to) = &e.to {
27758 self.write_space();
27759 self.write_keyword("TO");
27760 self.write_space();
27761 self.generate_expression(to)?;
27762 }
27763 Ok(())
27764 }
27765
27766 fn generate_replace_partition(&mut self, e: &ReplacePartition) -> Result<()> {
27767 self.write_keyword("REPLACE PARTITION");
27769 self.write_space();
27770 self.generate_expression(&e.expression)?;
27771 if let Some(source) = &e.source {
27772 self.write_space();
27773 self.write_keyword("FROM");
27774 self.write_space();
27775 self.generate_expression(source)?;
27776 }
27777 Ok(())
27778 }
27779
27780 fn generate_returning(&mut self, e: &Returning) -> Result<()> {
27781 let keyword = match self.config.dialect {
27784 Some(DialectType::TSQL) | Some(DialectType::Fabric) => "OUTPUT",
27785 _ => "RETURNING",
27786 };
27787 self.write_keyword(keyword);
27788 self.write_space();
27789 for (i, expr) in e.expressions.iter().enumerate() {
27790 if i > 0 {
27791 self.write(", ");
27792 }
27793 self.generate_expression(expr)?;
27794 }
27795 if let Some(into) = &e.into {
27796 self.write_space();
27797 self.write_keyword("INTO");
27798 self.write_space();
27799 self.generate_expression(into)?;
27800 }
27801 Ok(())
27802 }
27803
27804 fn generate_output_clause(&mut self, output: &OutputClause) -> Result<()> {
27805 self.write_space();
27807 self.write_keyword("OUTPUT");
27808 self.write_space();
27809 for (i, expr) in output.columns.iter().enumerate() {
27810 if i > 0 {
27811 self.write(", ");
27812 }
27813 self.generate_expression(expr)?;
27814 }
27815 if let Some(into_table) = &output.into_table {
27816 self.write_space();
27817 self.write_keyword("INTO");
27818 self.write_space();
27819 self.generate_expression(into_table)?;
27820 }
27821 Ok(())
27822 }
27823
27824 fn generate_returns_property(&mut self, e: &ReturnsProperty) -> Result<()> {
27825 self.write_keyword("RETURNS");
27827 if e.is_table.is_some() {
27828 self.write_space();
27829 self.write_keyword("TABLE");
27830 }
27831 if let Some(table) = &e.table {
27832 self.write_space();
27833 self.generate_expression(table)?;
27834 } else if let Some(this) = &e.this {
27835 self.write_space();
27836 self.generate_expression(this)?;
27837 }
27838 if e.null.is_some() {
27839 self.write_space();
27840 self.write_keyword("NULL ON NULL INPUT");
27841 }
27842 Ok(())
27843 }
27844
27845 fn generate_rollback(&mut self, e: &Rollback) -> Result<()> {
27846 self.write_keyword("ROLLBACK");
27848
27849 if e.this.is_none() && matches!(self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric)) {
27851 self.write_space();
27852 self.write_keyword("TRANSACTION");
27853 }
27854
27855 if let Some(this) = &e.this {
27857 let is_transaction_marker = matches!(
27859 this.as_ref(),
27860 Expression::Identifier(id) if id.name == "TRANSACTION"
27861 );
27862
27863 self.write_space();
27864 self.write_keyword("TRANSACTION");
27865
27866 if !is_transaction_marker {
27868 self.write_space();
27869 self.generate_expression(this)?;
27870 }
27871 }
27872
27873 if let Some(savepoint) = &e.savepoint {
27875 self.write_space();
27876 self.write_keyword("TO");
27877 self.write_space();
27878 self.generate_expression(savepoint)?;
27879 }
27880 Ok(())
27881 }
27882
27883 fn generate_rollup(&mut self, e: &Rollup) -> Result<()> {
27884 if e.expressions.is_empty() {
27886 self.write_keyword("WITH ROLLUP");
27887 } else {
27888 self.write_keyword("ROLLUP");
27889 self.write("(");
27890 for (i, expr) in e.expressions.iter().enumerate() {
27891 if i > 0 {
27892 self.write(", ");
27893 }
27894 self.generate_expression(expr)?;
27895 }
27896 self.write(")");
27897 }
27898 Ok(())
27899 }
27900
27901 fn generate_row_format_delimited_property(&mut self, e: &RowFormatDelimitedProperty) -> Result<()> {
27902 self.write_keyword("ROW FORMAT DELIMITED");
27904 if let Some(fields) = &e.fields {
27905 self.write_space();
27906 self.write_keyword("FIELDS TERMINATED BY");
27907 self.write_space();
27908 self.generate_expression(fields)?;
27909 }
27910 if let Some(escaped) = &e.escaped {
27911 self.write_space();
27912 self.write_keyword("ESCAPED BY");
27913 self.write_space();
27914 self.generate_expression(escaped)?;
27915 }
27916 if let Some(items) = &e.collection_items {
27917 self.write_space();
27918 self.write_keyword("COLLECTION ITEMS TERMINATED BY");
27919 self.write_space();
27920 self.generate_expression(items)?;
27921 }
27922 if let Some(keys) = &e.map_keys {
27923 self.write_space();
27924 self.write_keyword("MAP KEYS TERMINATED BY");
27925 self.write_space();
27926 self.generate_expression(keys)?;
27927 }
27928 if let Some(lines) = &e.lines {
27929 self.write_space();
27930 self.write_keyword("LINES TERMINATED BY");
27931 self.write_space();
27932 self.generate_expression(lines)?;
27933 }
27934 if let Some(null) = &e.null {
27935 self.write_space();
27936 self.write_keyword("NULL DEFINED AS");
27937 self.write_space();
27938 self.generate_expression(null)?;
27939 }
27940 if let Some(serde) = &e.serde {
27941 self.write_space();
27942 self.generate_expression(serde)?;
27943 }
27944 Ok(())
27945 }
27946
27947 fn generate_row_format_property(&mut self, e: &RowFormatProperty) -> Result<()> {
27948 self.write_keyword("ROW FORMAT");
27950 self.write_space();
27951 self.generate_expression(&e.this)?;
27952 Ok(())
27953 }
27954
27955 fn generate_row_format_serde_property(&mut self, e: &RowFormatSerdeProperty) -> Result<()> {
27956 self.write_keyword("ROW FORMAT SERDE");
27958 self.write_space();
27959 self.generate_expression(&e.this)?;
27960 if let Some(props) = &e.serde_properties {
27961 self.write_space();
27962 self.generate_expression(props)?;
27964 }
27965 Ok(())
27966 }
27967
27968 fn generate_sha2(&mut self, e: &SHA2) -> Result<()> {
27969 self.write_keyword("SHA2");
27971 self.write("(");
27972 self.generate_expression(&e.this)?;
27973 if let Some(length) = e.length {
27974 self.write(", ");
27975 self.write(&length.to_string());
27976 }
27977 self.write(")");
27978 Ok(())
27979 }
27980
27981 fn generate_sha2_digest(&mut self, e: &SHA2Digest) -> Result<()> {
27982 self.write_keyword("SHA2_DIGEST");
27984 self.write("(");
27985 self.generate_expression(&e.this)?;
27986 if let Some(length) = e.length {
27987 self.write(", ");
27988 self.write(&length.to_string());
27989 }
27990 self.write(")");
27991 Ok(())
27992 }
27993
27994 fn generate_safe_add(&mut self, e: &SafeAdd) -> Result<()> {
27995 let name = if matches!(self.config.dialect, Some(crate::dialects::DialectType::Spark) | Some(crate::dialects::DialectType::Databricks)) {
27996 "TRY_ADD"
27997 } else {
27998 "SAFE_ADD"
27999 };
28000 self.write_keyword(name);
28001 self.write("(");
28002 self.generate_expression(&e.this)?;
28003 self.write(", ");
28004 self.generate_expression(&e.expression)?;
28005 self.write(")");
28006 Ok(())
28007 }
28008
28009 fn generate_safe_divide(&mut self, e: &SafeDivide) -> Result<()> {
28010 self.write_keyword("SAFE_DIVIDE");
28012 self.write("(");
28013 self.generate_expression(&e.this)?;
28014 self.write(", ");
28015 self.generate_expression(&e.expression)?;
28016 self.write(")");
28017 Ok(())
28018 }
28019
28020 fn generate_safe_multiply(&mut self, e: &SafeMultiply) -> Result<()> {
28021 let name = if matches!(self.config.dialect, Some(crate::dialects::DialectType::Spark) | Some(crate::dialects::DialectType::Databricks)) {
28022 "TRY_MULTIPLY"
28023 } else {
28024 "SAFE_MULTIPLY"
28025 };
28026 self.write_keyword(name);
28027 self.write("(");
28028 self.generate_expression(&e.this)?;
28029 self.write(", ");
28030 self.generate_expression(&e.expression)?;
28031 self.write(")");
28032 Ok(())
28033 }
28034
28035 fn generate_safe_subtract(&mut self, e: &SafeSubtract) -> Result<()> {
28036 let name = if matches!(self.config.dialect, Some(crate::dialects::DialectType::Spark) | Some(crate::dialects::DialectType::Databricks)) {
28037 "TRY_SUBTRACT"
28038 } else {
28039 "SAFE_SUBTRACT"
28040 };
28041 self.write_keyword(name);
28042 self.write("(");
28043 self.generate_expression(&e.this)?;
28044 self.write(", ");
28045 self.generate_expression(&e.expression)?;
28046 self.write(")");
28047 Ok(())
28048 }
28049
28050 fn generate_sample_body(&mut self, sample: &Sample) -> Result<()> {
28053 if matches!(sample.method, SampleMethod::Bucket) {
28055 self.write(" (");
28056 self.write_keyword("BUCKET");
28057 self.write_space();
28058 if let Some(ref num) = sample.bucket_numerator {
28059 self.generate_expression(num)?;
28060 }
28061 self.write_space();
28062 self.write_keyword("OUT OF");
28063 self.write_space();
28064 if let Some(ref denom) = sample.bucket_denominator {
28065 self.generate_expression(denom)?;
28066 }
28067 if let Some(ref field) = sample.bucket_field {
28068 self.write_space();
28069 self.write_keyword("ON");
28070 self.write_space();
28071 self.generate_expression(field)?;
28072 }
28073 self.write(")");
28074 return Ok(());
28075 }
28076
28077 let is_snowflake = matches!(self.config.dialect, Some(crate::dialects::DialectType::Snowflake));
28079 let is_postgres = matches!(self.config.dialect, Some(crate::dialects::DialectType::PostgreSQL) | Some(crate::dialects::DialectType::Redshift));
28080 let is_databricks = matches!(self.config.dialect, Some(crate::dialects::DialectType::Databricks));
28082 let is_spark = matches!(self.config.dialect, Some(crate::dialects::DialectType::Spark));
28083 let suppress_method = is_databricks || is_spark || sample.suppress_method_output;
28084 let force_method = is_postgres && matches!(sample.method, SampleMethod::Bernoulli);
28086 if !suppress_method && (sample.explicit_method || is_snowflake || force_method) {
28087 self.write_space();
28088 if !sample.explicit_method && (is_snowflake || force_method) {
28089 self.write_keyword("BERNOULLI");
28091 } else {
28092 match sample.method {
28093 SampleMethod::Bernoulli => self.write_keyword("BERNOULLI"),
28094 SampleMethod::System => self.write_keyword("SYSTEM"),
28095 SampleMethod::Block => self.write_keyword("BLOCK"),
28096 SampleMethod::Row => self.write_keyword("ROW"),
28097 SampleMethod::Reservoir => self.write_keyword("RESERVOIR"),
28098 SampleMethod::Percent => self.write_keyword("SYSTEM"),
28099 SampleMethod::Bucket => {} }
28101 }
28102 }
28103
28104 let emit_size_no_parens = !self.config.tablesample_requires_parens;
28106 if emit_size_no_parens {
28107 self.write_space();
28108 match &sample.size {
28109 Expression::Tuple(tuple) => {
28110 for (i, expr) in tuple.expressions.iter().enumerate() {
28111 if i > 0 {
28112 self.write(", ");
28113 }
28114 self.generate_expression(expr)?;
28115 }
28116 }
28117 expr => self.generate_expression(expr)?,
28118 }
28119 } else {
28120 self.write(" (");
28121 self.generate_expression(&sample.size)?;
28122 }
28123
28124 let is_rows_method = matches!(sample.method, SampleMethod::Reservoir | SampleMethod::Row | SampleMethod::Bucket);
28126 let is_percent = matches!(sample.method, SampleMethod::Percent | SampleMethod::System | SampleMethod::Bernoulli | SampleMethod::Block);
28127
28128 let is_presto = matches!(self.config.dialect, Some(crate::dialects::DialectType::Presto) | Some(crate::dialects::DialectType::Trino) | Some(crate::dialects::DialectType::Athena));
28132 let should_output_unit = if is_databricks || is_spark {
28133 is_percent || is_rows_method || sample.unit_after_size
28135 } else if is_snowflake || is_postgres || is_presto {
28136 sample.unit_after_size
28137 } else {
28138 sample.unit_after_size || (sample.explicit_method && (is_rows_method || is_percent))
28139 };
28140
28141 if should_output_unit {
28142 self.write_space();
28143 if sample.is_percent {
28144 self.write_keyword("PERCENT");
28145 } else if is_rows_method && !sample.unit_after_size {
28146 self.write_keyword("ROWS");
28147 } else if sample.unit_after_size {
28148 match sample.method {
28149 SampleMethod::Percent | SampleMethod::System | SampleMethod::Bernoulli | SampleMethod::Block => {
28150 self.write_keyword("PERCENT");
28151 }
28152 SampleMethod::Row | SampleMethod::Reservoir => {
28153 self.write_keyword("ROWS");
28154 }
28155 _ => self.write_keyword("ROWS"),
28156 }
28157 } else {
28158 self.write_keyword("PERCENT");
28159 }
28160 }
28161
28162 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
28163 if let Some(ref offset) = sample.offset {
28164 self.write_space();
28165 self.write_keyword("OFFSET");
28166 self.write_space();
28167 self.generate_expression(offset)?;
28168 }
28169 }
28170 if !emit_size_no_parens {
28171 self.write(")");
28172 }
28173
28174 Ok(())
28175 }
28176
28177 fn generate_sample_property(&mut self, e: &SampleProperty) -> Result<()> {
28178 if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
28180 self.write_keyword("SAMPLE BY");
28181 } else {
28182 self.write_keyword("SAMPLE");
28183 }
28184 self.write_space();
28185 self.generate_expression(&e.this)?;
28186 Ok(())
28187 }
28188
28189 fn generate_schema(&mut self, e: &Schema) -> Result<()> {
28190 if let Some(this) = &e.this {
28192 self.generate_expression(this)?;
28193 }
28194 if !e.expressions.is_empty() {
28195 if e.this.is_some() {
28197 self.write_space();
28198 }
28199 self.write("(");
28200 for (i, expr) in e.expressions.iter().enumerate() {
28201 if i > 0 {
28202 self.write(", ");
28203 }
28204 self.generate_expression(expr)?;
28205 }
28206 self.write(")");
28207 }
28208 Ok(())
28209 }
28210
28211 fn generate_schema_comment_property(&mut self, e: &SchemaCommentProperty) -> Result<()> {
28212 self.write_keyword("COMMENT");
28214 self.write_space();
28215 self.generate_expression(&e.this)?;
28216 Ok(())
28217 }
28218
28219 fn generate_scope_resolution(&mut self, e: &ScopeResolution) -> Result<()> {
28220 if let Some(this) = &e.this {
28222 self.generate_expression(this)?;
28223 self.write("::");
28224 }
28225 self.generate_expression(&e.expression)?;
28226 Ok(())
28227 }
28228
28229 fn generate_search(&mut self, e: &Search) -> Result<()> {
28230 self.write_keyword("SEARCH");
28232 self.write("(");
28233 self.generate_expression(&e.this)?;
28234 self.write(", ");
28235 self.generate_expression(&e.expression)?;
28236 if let Some(json_scope) = &e.json_scope {
28237 self.write(", ");
28238 self.generate_expression(json_scope)?;
28239 }
28240 if let Some(analyzer) = &e.analyzer {
28241 self.write(", ");
28242 self.generate_expression(analyzer)?;
28243 }
28244 if let Some(analyzer_options) = &e.analyzer_options {
28245 self.write(", ");
28246 self.generate_expression(analyzer_options)?;
28247 }
28248 if let Some(search_mode) = &e.search_mode {
28249 self.write(", ");
28250 self.generate_expression(search_mode)?;
28251 }
28252 self.write(")");
28253 Ok(())
28254 }
28255
28256 fn generate_search_ip(&mut self, e: &SearchIp) -> Result<()> {
28257 self.write_keyword("SEARCH_IP");
28259 self.write("(");
28260 self.generate_expression(&e.this)?;
28261 self.write(", ");
28262 self.generate_expression(&e.expression)?;
28263 self.write(")");
28264 Ok(())
28265 }
28266
28267 fn generate_security_property(&mut self, e: &SecurityProperty) -> Result<()> {
28268 self.write_keyword("SECURITY");
28270 self.write_space();
28271 self.generate_expression(&e.this)?;
28272 Ok(())
28273 }
28274
28275 fn generate_semantic_view(&mut self, e: &SemanticView) -> Result<()> {
28276 self.write("SEMANTIC_VIEW(");
28278
28279 if self.config.pretty {
28280 self.write_newline();
28282 self.indent_level += 1;
28283 self.write_indent();
28284 self.generate_expression(&e.this)?;
28285
28286 if let Some(metrics) = &e.metrics {
28287 self.write_newline();
28288 self.write_indent();
28289 self.write_keyword("METRICS");
28290 self.write_space();
28291 self.generate_semantic_view_tuple(metrics)?;
28292 }
28293 if let Some(dimensions) = &e.dimensions {
28294 self.write_newline();
28295 self.write_indent();
28296 self.write_keyword("DIMENSIONS");
28297 self.write_space();
28298 self.generate_semantic_view_tuple(dimensions)?;
28299 }
28300 if let Some(facts) = &e.facts {
28301 self.write_newline();
28302 self.write_indent();
28303 self.write_keyword("FACTS");
28304 self.write_space();
28305 self.generate_semantic_view_tuple(facts)?;
28306 }
28307 if let Some(where_) = &e.where_ {
28308 self.write_newline();
28309 self.write_indent();
28310 self.write_keyword("WHERE");
28311 self.write_space();
28312 self.generate_expression(where_)?;
28313 }
28314 self.write_newline();
28315 self.indent_level -= 1;
28316 self.write_indent();
28317 } else {
28318 self.generate_expression(&e.this)?;
28320 if let Some(metrics) = &e.metrics {
28321 self.write_space();
28322 self.write_keyword("METRICS");
28323 self.write_space();
28324 self.generate_semantic_view_tuple(metrics)?;
28325 }
28326 if let Some(dimensions) = &e.dimensions {
28327 self.write_space();
28328 self.write_keyword("DIMENSIONS");
28329 self.write_space();
28330 self.generate_semantic_view_tuple(dimensions)?;
28331 }
28332 if let Some(facts) = &e.facts {
28333 self.write_space();
28334 self.write_keyword("FACTS");
28335 self.write_space();
28336 self.generate_semantic_view_tuple(facts)?;
28337 }
28338 if let Some(where_) = &e.where_ {
28339 self.write_space();
28340 self.write_keyword("WHERE");
28341 self.write_space();
28342 self.generate_expression(where_)?;
28343 }
28344 }
28345 self.write(")");
28346 Ok(())
28347 }
28348
28349 fn generate_semantic_view_tuple(&mut self, expr: &Expression) -> Result<()> {
28351 if let Expression::Tuple(t) = expr {
28352 for (i, e) in t.expressions.iter().enumerate() {
28353 if i > 0 {
28354 self.write(", ");
28355 }
28356 self.generate_expression(e)?;
28357 }
28358 } else {
28359 self.generate_expression(expr)?;
28360 }
28361 Ok(())
28362 }
28363
28364 fn generate_sequence_properties(&mut self, e: &SequenceProperties) -> Result<()> {
28365 if let Some(start) = &e.start {
28367 self.write_keyword("START WITH");
28368 self.write_space();
28369 self.generate_expression(start)?;
28370 }
28371 if let Some(increment) = &e.increment {
28372 self.write_space();
28373 self.write_keyword("INCREMENT BY");
28374 self.write_space();
28375 self.generate_expression(increment)?;
28376 }
28377 if let Some(minvalue) = &e.minvalue {
28378 self.write_space();
28379 self.write_keyword("MINVALUE");
28380 self.write_space();
28381 self.generate_expression(minvalue)?;
28382 }
28383 if let Some(maxvalue) = &e.maxvalue {
28384 self.write_space();
28385 self.write_keyword("MAXVALUE");
28386 self.write_space();
28387 self.generate_expression(maxvalue)?;
28388 }
28389 if let Some(cache) = &e.cache {
28390 self.write_space();
28391 self.write_keyword("CACHE");
28392 self.write_space();
28393 self.generate_expression(cache)?;
28394 }
28395 if let Some(owned) = &e.owned {
28396 self.write_space();
28397 self.write_keyword("OWNED BY");
28398 self.write_space();
28399 self.generate_expression(owned)?;
28400 }
28401 for opt in &e.options {
28402 self.write_space();
28403 self.generate_expression(opt)?;
28404 }
28405 Ok(())
28406 }
28407
28408 fn generate_serde_properties(&mut self, e: &SerdeProperties) -> Result<()> {
28409 if e.with_.is_some() {
28411 self.write_keyword("WITH");
28412 self.write_space();
28413 }
28414 self.write_keyword("SERDEPROPERTIES");
28415 self.write(" (");
28416 for (i, expr) in e.expressions.iter().enumerate() {
28417 if i > 0 {
28418 self.write(", ");
28419 }
28420 match expr {
28422 Expression::Eq(eq) => {
28423 self.generate_expression(&eq.left)?;
28424 self.write("=");
28425 self.generate_expression(&eq.right)?;
28426 }
28427 _ => self.generate_expression(expr)?,
28428 }
28429 }
28430 self.write(")");
28431 Ok(())
28432 }
28433
28434 fn generate_session_parameter(&mut self, e: &SessionParameter) -> Result<()> {
28435 self.write("@@");
28437 if let Some(kind) = &e.kind {
28438 self.write(kind);
28439 self.write(".");
28440 }
28441 self.generate_expression(&e.this)?;
28442 Ok(())
28443 }
28444
28445 fn generate_set(&mut self, e: &Set) -> Result<()> {
28446 if e.unset.is_some() {
28448 self.write_keyword("UNSET");
28449 } else {
28450 self.write_keyword("SET");
28451 }
28452 if e.tag.is_some() {
28453 self.write_space();
28454 self.write_keyword("TAG");
28455 }
28456 if !e.expressions.is_empty() {
28457 self.write_space();
28458 for (i, expr) in e.expressions.iter().enumerate() {
28459 if i > 0 {
28460 self.write(", ");
28461 }
28462 self.generate_expression(expr)?;
28463 }
28464 }
28465 Ok(())
28466 }
28467
28468 fn generate_set_config_property(&mut self, e: &SetConfigProperty) -> Result<()> {
28469 self.write_keyword("SET");
28471 self.write_space();
28472 self.generate_expression(&e.this)?;
28473 Ok(())
28474 }
28475
28476 fn generate_set_item(&mut self, e: &SetItem) -> Result<()> {
28477 if let Some(kind) = &e.kind {
28479 self.write_keyword(kind);
28480 self.write_space();
28481 }
28482 self.generate_expression(&e.name)?;
28483 self.write(" = ");
28484 self.generate_expression(&e.value)?;
28485 Ok(())
28486 }
28487
28488 fn generate_set_operation(&mut self, e: &SetOperation) -> Result<()> {
28489 if let Some(with_) = &e.with_ {
28491 self.generate_expression(with_)?;
28492 self.write_space();
28493 }
28494 self.generate_expression(&e.this)?;
28495 self.write_space();
28496 if let Some(kind) = &e.kind {
28498 self.write_keyword(kind);
28499 }
28500 if e.distinct {
28501 self.write_space();
28502 self.write_keyword("DISTINCT");
28503 } else {
28504 self.write_space();
28505 self.write_keyword("ALL");
28506 }
28507 if e.by_name.is_some() {
28508 self.write_space();
28509 self.write_keyword("BY NAME");
28510 }
28511 self.write_space();
28512 self.generate_expression(&e.expression)?;
28513 Ok(())
28514 }
28515
28516 fn generate_set_property(&mut self, e: &SetProperty) -> Result<()> {
28517 if e.multi.is_some() {
28519 self.write_keyword("MULTISET");
28520 } else {
28521 self.write_keyword("SET");
28522 }
28523 Ok(())
28524 }
28525
28526 fn generate_settings_property(&mut self, e: &SettingsProperty) -> Result<()> {
28527 self.write_keyword("SETTINGS");
28529 if self.config.pretty && e.expressions.len() > 1 {
28530 self.indent_level += 1;
28532 for (i, expr) in e.expressions.iter().enumerate() {
28533 if i > 0 {
28534 self.write(",");
28535 }
28536 self.write_newline();
28537 self.write_indent();
28538 self.generate_expression(expr)?;
28539 }
28540 self.indent_level -= 1;
28541 } else {
28542 self.write_space();
28543 for (i, expr) in e.expressions.iter().enumerate() {
28544 if i > 0 {
28545 self.write(", ");
28546 }
28547 self.generate_expression(expr)?;
28548 }
28549 }
28550 Ok(())
28551 }
28552
28553 fn generate_sharing_property(&mut self, e: &SharingProperty) -> Result<()> {
28554 self.write_keyword("SHARING");
28556 if let Some(this) = &e.this {
28557 self.write(" = ");
28558 self.generate_expression(this)?;
28559 }
28560 Ok(())
28561 }
28562
28563 fn generate_slice(&mut self, e: &Slice) -> Result<()> {
28564 if let Some(begin) = &e.this {
28566 self.generate_expression(begin)?;
28567 }
28568 self.write(":");
28569 if let Some(end) = &e.expression {
28570 self.generate_expression(end)?;
28571 }
28572 if let Some(step) = &e.step {
28573 self.write(":");
28574 self.generate_expression(step)?;
28575 }
28576 Ok(())
28577 }
28578
28579 fn generate_sort_array(&mut self, e: &SortArray) -> Result<()> {
28580 self.write_keyword("SORT_ARRAY");
28582 self.write("(");
28583 self.generate_expression(&e.this)?;
28584 if let Some(asc) = &e.asc {
28585 self.write(", ");
28586 self.generate_expression(asc)?;
28587 }
28588 self.write(")");
28589 Ok(())
28590 }
28591
28592 fn generate_sort_by(&mut self, e: &SortBy) -> Result<()> {
28593 self.write_keyword("SORT BY");
28595 self.write_space();
28596 for (i, expr) in e.expressions.iter().enumerate() {
28597 if i > 0 {
28598 self.write(", ");
28599 }
28600 self.generate_ordered(expr)?;
28601 }
28602 Ok(())
28603 }
28604
28605 fn generate_sort_key_property(&mut self, e: &SortKeyProperty) -> Result<()> {
28606 if e.compound.is_some() {
28608 self.write_keyword("COMPOUND");
28609 self.write_space();
28610 }
28611 self.write_keyword("SORTKEY");
28612 self.write("(");
28613 if let Expression::Tuple(t) = e.this.as_ref() {
28615 for (i, expr) in t.expressions.iter().enumerate() {
28616 if i > 0 {
28617 self.write(", ");
28618 }
28619 self.generate_expression(expr)?;
28620 }
28621 } else {
28622 self.generate_expression(&e.this)?;
28623 }
28624 self.write(")");
28625 Ok(())
28626 }
28627
28628 fn generate_split_part(&mut self, e: &SplitPart) -> Result<()> {
28629 self.write_keyword("SPLIT_PART");
28631 self.write("(");
28632 self.generate_expression(&e.this)?;
28633 if let Some(delimiter) = &e.delimiter {
28634 self.write(", ");
28635 self.generate_expression(delimiter)?;
28636 }
28637 if let Some(part_index) = &e.part_index {
28638 self.write(", ");
28639 self.generate_expression(part_index)?;
28640 }
28641 self.write(")");
28642 Ok(())
28643 }
28644
28645 fn generate_sql_read_write_property(&mut self, e: &SqlReadWriteProperty) -> Result<()> {
28646 self.generate_expression(&e.this)?;
28648 Ok(())
28649 }
28650
28651 fn generate_sql_security_property(&mut self, e: &SqlSecurityProperty) -> Result<()> {
28652 self.write_keyword("SQL SECURITY");
28654 self.write_space();
28655 self.generate_expression(&e.this)?;
28656 Ok(())
28657 }
28658
28659 fn generate_st_distance(&mut self, e: &StDistance) -> Result<()> {
28660 self.write_keyword("ST_DISTANCE");
28662 self.write("(");
28663 self.generate_expression(&e.this)?;
28664 self.write(", ");
28665 self.generate_expression(&e.expression)?;
28666 if let Some(use_spheroid) = &e.use_spheroid {
28667 self.write(", ");
28668 self.generate_expression(use_spheroid)?;
28669 }
28670 self.write(")");
28671 Ok(())
28672 }
28673
28674 fn generate_st_point(&mut self, e: &StPoint) -> Result<()> {
28675 self.write_keyword("ST_POINT");
28677 self.write("(");
28678 self.generate_expression(&e.this)?;
28679 self.write(", ");
28680 self.generate_expression(&e.expression)?;
28681 self.write(")");
28682 Ok(())
28683 }
28684
28685 fn generate_stability_property(&mut self, e: &StabilityProperty) -> Result<()> {
28686 self.generate_expression(&e.this)?;
28688 Ok(())
28689 }
28690
28691 fn generate_standard_hash(&mut self, e: &StandardHash) -> Result<()> {
28692 self.write_keyword("STANDARD_HASH");
28694 self.write("(");
28695 self.generate_expression(&e.this)?;
28696 if let Some(expression) = &e.expression {
28697 self.write(", ");
28698 self.generate_expression(expression)?;
28699 }
28700 self.write(")");
28701 Ok(())
28702 }
28703
28704 fn generate_storage_handler_property(&mut self, e: &StorageHandlerProperty) -> Result<()> {
28705 self.write_keyword("STORED BY");
28707 self.write_space();
28708 self.generate_expression(&e.this)?;
28709 Ok(())
28710 }
28711
28712 fn generate_str_position(&mut self, e: &StrPosition) -> Result<()> {
28713 use crate::dialects::DialectType;
28716 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
28717 self.write_keyword("CHARINDEX");
28719 self.write("(");
28720 if let Some(substr) = &e.substr {
28721 self.generate_expression(substr)?;
28722 self.write(", ");
28723 }
28724 self.generate_expression(&e.this)?;
28725 if let Some(position) = &e.position {
28726 self.write(", ");
28727 self.generate_expression(position)?;
28728 }
28729 self.write(")");
28730 } else if matches!(self.config.dialect, Some(DialectType::ClickHouse)) {
28731 self.write_keyword("POSITION");
28732 self.write("(");
28733 self.generate_expression(&e.this)?;
28734 if let Some(substr) = &e.substr {
28735 self.write(", ");
28736 self.generate_expression(substr)?;
28737 }
28738 if let Some(position) = &e.position {
28739 self.write(", ");
28740 self.generate_expression(position)?;
28741 }
28742 if let Some(occurrence) = &e.occurrence {
28743 self.write(", ");
28744 self.generate_expression(occurrence)?;
28745 }
28746 self.write(")");
28747 } else if matches!(self.config.dialect, Some(DialectType::SQLite) | Some(DialectType::Oracle) | Some(DialectType::BigQuery) | Some(DialectType::Teradata)) {
28748 self.write_keyword("INSTR");
28749 self.write("(");
28750 self.generate_expression(&e.this)?;
28751 if let Some(substr) = &e.substr {
28752 self.write(", ");
28753 self.generate_expression(substr)?;
28754 }
28755 if let Some(position) = &e.position {
28756 self.write(", ");
28757 self.generate_expression(position)?;
28758 } else if e.occurrence.is_some() {
28759 self.write(", 1");
28762 }
28763 if let Some(occurrence) = &e.occurrence {
28764 self.write(", ");
28765 self.generate_expression(occurrence)?;
28766 }
28767 self.write(")");
28768 } else if matches!(self.config.dialect, Some(DialectType::MySQL) | Some(DialectType::SingleStore) | Some(DialectType::Doris) | Some(DialectType::StarRocks)
28769 | Some(DialectType::Hive) | Some(DialectType::Spark) | Some(DialectType::Databricks)) {
28770 self.write_keyword("LOCATE");
28772 self.write("(");
28773 if let Some(substr) = &e.substr {
28774 self.generate_expression(substr)?;
28775 self.write(", ");
28776 }
28777 self.generate_expression(&e.this)?;
28778 if let Some(position) = &e.position {
28779 self.write(", ");
28780 self.generate_expression(position)?;
28781 }
28782 self.write(")");
28783 } else if matches!(self.config.dialect, Some(DialectType::TSQL)) {
28784 self.write_keyword("CHARINDEX");
28786 self.write("(");
28787 if let Some(substr) = &e.substr {
28788 self.generate_expression(substr)?;
28789 self.write(", ");
28790 }
28791 self.generate_expression(&e.this)?;
28792 if let Some(position) = &e.position {
28793 self.write(", ");
28794 self.generate_expression(position)?;
28795 }
28796 self.write(")");
28797 } else {
28798 self.write_keyword("STRPOS");
28799 self.write("(");
28800 self.generate_expression(&e.this)?;
28801 if let Some(substr) = &e.substr {
28802 self.write(", ");
28803 self.generate_expression(substr)?;
28804 }
28805 if let Some(position) = &e.position {
28806 self.write(", ");
28807 self.generate_expression(position)?;
28808 }
28809 if let Some(occurrence) = &e.occurrence {
28810 self.write(", ");
28811 self.generate_expression(occurrence)?;
28812 }
28813 self.write(")");
28814 }
28815 Ok(())
28816 }
28817
28818 fn generate_str_to_date(&mut self, e: &StrToDate) -> Result<()> {
28819 match self.config.dialect {
28820 Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive) => {
28821 self.write_keyword("TO_DATE");
28823 self.write("(");
28824 self.generate_expression(&e.this)?;
28825 if let Some(format) = &e.format {
28826 self.write(", '");
28827 self.write(&Self::strftime_to_java_format(format));
28828 self.write("'");
28829 }
28830 self.write(")");
28831 }
28832 Some(DialectType::DuckDB) => {
28833 self.write_keyword("CAST");
28835 self.write("(");
28836 self.write_keyword("STRPTIME");
28837 self.write("(");
28838 self.generate_expression(&e.this)?;
28839 if let Some(format) = &e.format {
28840 self.write(", '");
28841 self.write(format);
28842 self.write("'");
28843 }
28844 self.write(")");
28845 self.write_keyword(" AS ");
28846 self.write_keyword("DATE");
28847 self.write(")");
28848 }
28849 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => {
28850 self.write_keyword("TO_DATE");
28852 self.write("(");
28853 self.generate_expression(&e.this)?;
28854 if let Some(format) = &e.format {
28855 self.write(", '");
28856 self.write(&Self::strftime_to_postgres_format(format));
28857 self.write("'");
28858 }
28859 self.write(")");
28860 }
28861 Some(DialectType::BigQuery) => {
28862 self.write_keyword("PARSE_DATE");
28864 self.write("(");
28865 if let Some(format) = &e.format {
28866 self.write("'");
28867 self.write(format);
28868 self.write("'");
28869 self.write(", ");
28870 }
28871 self.generate_expression(&e.this)?;
28872 self.write(")");
28873 }
28874 Some(DialectType::Teradata) => {
28875 self.write_keyword("CAST");
28877 self.write("(");
28878 self.generate_expression(&e.this)?;
28879 self.write_keyword(" AS ");
28880 self.write_keyword("DATE");
28881 if let Some(format) = &e.format {
28882 self.write_keyword(" FORMAT ");
28883 self.write("'");
28884 self.write(&Self::strftime_to_teradata_format(format));
28885 self.write("'");
28886 }
28887 self.write(")");
28888 }
28889 _ => {
28890 self.write_keyword("STR_TO_DATE");
28892 self.write("(");
28893 self.generate_expression(&e.this)?;
28894 if let Some(format) = &e.format {
28895 self.write(", '");
28896 self.write(format);
28897 self.write("'");
28898 }
28899 self.write(")");
28900 }
28901 }
28902 Ok(())
28903 }
28904
28905 fn strftime_to_teradata_format(fmt: &str) -> String {
28907 let mut result = fmt.to_string();
28908 result = result.replace("%Y", "YYYY");
28909 result = result.replace("%y", "YY");
28910 result = result.replace("%m", "MM");
28911 result = result.replace("%B", "MMMM");
28912 result = result.replace("%b", "MMM");
28913 result = result.replace("%d", "DD");
28914 result = result.replace("%j", "DDD");
28915 result = result.replace("%H", "HH");
28916 result = result.replace("%M", "MI");
28917 result = result.replace("%S", "SS");
28918 result = result.replace("%f", "SSSSSS");
28919 result = result.replace("%A", "EEEE");
28920 result = result.replace("%a", "EEE");
28921 result
28922 }
28923
28924 fn strftime_to_java_format(fmt: &str) -> String {
28926 let mut result = fmt.to_string();
28927 result = result.replace("%Y", "yyyy");
28928 result = result.replace("%y", "yy");
28929 result = result.replace("%m", "MM");
28930 result = result.replace("%B", "MMMM");
28931 result = result.replace("%b", "MMM");
28932 result = result.replace("%d", "dd");
28933 result = result.replace("%j", "DDD");
28934 result = result.replace("%H", "HH");
28935 result = result.replace("%M", "mm");
28936 result = result.replace("%S", "ss");
28937 result = result.replace("%f", "SSSSSS");
28938 result = result.replace("%A", "EEEE");
28939 result = result.replace("%a", "EEE");
28940 result
28941 }
28942
28943 fn strftime_to_postgres_format(fmt: &str) -> String {
28945 let mut result = fmt.to_string();
28946 result = result.replace("%Y", "YYYY");
28947 result = result.replace("%y", "YY");
28948 result = result.replace("%m", "MM");
28949 result = result.replace("%B", "Month");
28950 result = result.replace("%b", "Mon");
28951 result = result.replace("%d", "DD");
28952 result = result.replace("%j", "DDD");
28953 result = result.replace("%H", "HH24");
28954 result = result.replace("%M", "MI");
28955 result = result.replace("%S", "SS");
28956 result = result.replace("%f", "US");
28957 result = result.replace("%A", "Day");
28958 result = result.replace("%a", "Dy");
28959 result
28960 }
28961
28962 fn generate_str_to_map(&mut self, e: &StrToMap) -> Result<()> {
28963 self.write_keyword("STR_TO_MAP");
28965 self.write("(");
28966 self.generate_expression(&e.this)?;
28967 let needs_defaults = matches!(
28969 self.config.dialect,
28970 Some(DialectType::Spark) | Some(DialectType::Hive) | Some(DialectType::Databricks)
28971 );
28972 if let Some(pair_delim) = &e.pair_delim {
28973 self.write(", ");
28974 self.generate_expression(pair_delim)?;
28975 } else if needs_defaults {
28976 self.write(", ','");
28977 }
28978 if let Some(key_value_delim) = &e.key_value_delim {
28979 self.write(", ");
28980 self.generate_expression(key_value_delim)?;
28981 } else if needs_defaults {
28982 self.write(", ':'");
28983 }
28984 self.write(")");
28985 Ok(())
28986 }
28987
28988 fn generate_str_to_time(&mut self, e: &StrToTime) -> Result<()> {
28989 match self.config.dialect {
28990 Some(DialectType::Exasol) => {
28991 self.write_keyword("TO_DATE");
28992 self.write("(");
28993 self.generate_expression(&e.this)?;
28994 self.write(", '");
28995 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
28996 self.write("'");
28997 self.write(")");
28998 }
28999 Some(DialectType::BigQuery) => {
29000 let fmt = Self::snowflake_format_to_strftime(&e.format);
29002 let fmt = fmt.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
29004 self.write_keyword("PARSE_TIMESTAMP");
29005 self.write("('");
29006 self.write(&fmt);
29007 self.write("', ");
29008 self.generate_expression(&e.this)?;
29009 self.write(")");
29010 }
29011 Some(DialectType::Spark) | Some(DialectType::Databricks) => {
29012 let fmt = Self::snowflake_format_to_spark(&e.format);
29014 self.write_keyword("TO_TIMESTAMP");
29015 self.write("(");
29016 self.generate_expression(&e.this)?;
29017 self.write(", '");
29018 self.write(&fmt);
29019 self.write("')");
29020 }
29021 Some(DialectType::Presto) | Some(DialectType::Trino) => {
29022 let fmt = Self::snowflake_format_to_strftime(&e.format);
29024 self.write_keyword("DATE_PARSE");
29025 self.write("(");
29026 self.generate_expression(&e.this)?;
29027 self.write(", '");
29028 self.write(&fmt);
29029 self.write("')");
29030 }
29031 Some(DialectType::DuckDB) => {
29032 let fmt = Self::snowflake_format_to_strftime(&e.format);
29034 self.write_keyword("STRPTIME");
29035 self.write("(");
29036 self.generate_expression(&e.this)?;
29037 self.write(", '");
29038 self.write(&fmt);
29039 self.write("')");
29040 }
29041 Some(DialectType::Snowflake) => {
29042 self.write_keyword("TO_TIMESTAMP");
29044 self.write("(");
29045 self.generate_expression(&e.this)?;
29046 self.write(", '");
29047 self.write(&e.format);
29048 self.write("')");
29049 }
29050 _ => {
29051 self.write_keyword("STR_TO_TIME");
29053 self.write("(");
29054 self.generate_expression(&e.this)?;
29055 self.write(", '");
29056 self.write(&e.format);
29057 self.write("'");
29058 self.write(")");
29059 }
29060 }
29061 Ok(())
29062 }
29063
29064 fn snowflake_format_to_strftime(format: &str) -> String {
29066 let mut result = String::new();
29067 let chars: Vec<char> = format.chars().collect();
29068 let mut i = 0;
29069 while i < chars.len() {
29070 let remaining = &format[i..];
29071 if remaining.starts_with("yyyy") {
29072 result.push_str("%Y");
29073 i += 4;
29074 } else if remaining.starts_with("yy") {
29075 result.push_str("%y");
29076 i += 2;
29077 } else if remaining.starts_with("mmmm") {
29078 result.push_str("%B"); i += 4;
29080 } else if remaining.starts_with("mon") {
29081 result.push_str("%b"); i += 3;
29083 } else if remaining.starts_with("mm") {
29084 result.push_str("%m");
29085 i += 2;
29086 } else if remaining.starts_with("DD") {
29087 result.push_str("%d");
29088 i += 2;
29089 } else if remaining.starts_with("dy") {
29090 result.push_str("%a"); i += 2;
29092 } else if remaining.starts_with("hh24") {
29093 result.push_str("%H");
29094 i += 4;
29095 } else if remaining.starts_with("hh12") {
29096 result.push_str("%I");
29097 i += 4;
29098 } else if remaining.starts_with("hh") {
29099 result.push_str("%H");
29100 i += 2;
29101 } else if remaining.starts_with("mi") {
29102 result.push_str("%M");
29103 i += 2;
29104 } else if remaining.starts_with("ss") {
29105 result.push_str("%S");
29106 i += 2;
29107 } else if remaining.starts_with("ff") {
29108 result.push_str("%f");
29110 i += 2;
29111 while i < chars.len() && chars[i].is_ascii_digit() {
29113 i += 1;
29114 }
29115 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
29116 result.push_str("%p");
29117 i += 2;
29118 } else if remaining.starts_with("tz") {
29119 result.push_str("%Z");
29120 i += 2;
29121 } else {
29122 result.push(chars[i]);
29123 i += 1;
29124 }
29125 }
29126 result
29127 }
29128
29129 fn snowflake_format_to_spark(format: &str) -> String {
29131 let mut result = String::new();
29132 let chars: Vec<char> = format.chars().collect();
29133 let mut i = 0;
29134 while i < chars.len() {
29135 let remaining = &format[i..];
29136 if remaining.starts_with("yyyy") {
29137 result.push_str("yyyy");
29138 i += 4;
29139 } else if remaining.starts_with("yy") {
29140 result.push_str("yy");
29141 i += 2;
29142 } else if remaining.starts_with("mmmm") {
29143 result.push_str("MMMM"); i += 4;
29145 } else if remaining.starts_with("mon") {
29146 result.push_str("MMM"); i += 3;
29148 } else if remaining.starts_with("mm") {
29149 result.push_str("MM");
29150 i += 2;
29151 } else if remaining.starts_with("DD") {
29152 result.push_str("dd");
29153 i += 2;
29154 } else if remaining.starts_with("dy") {
29155 result.push_str("EEE"); i += 2;
29157 } else if remaining.starts_with("hh24") {
29158 result.push_str("HH");
29159 i += 4;
29160 } else if remaining.starts_with("hh12") {
29161 result.push_str("hh");
29162 i += 4;
29163 } else if remaining.starts_with("hh") {
29164 result.push_str("HH");
29165 i += 2;
29166 } else if remaining.starts_with("mi") {
29167 result.push_str("mm");
29168 i += 2;
29169 } else if remaining.starts_with("ss") {
29170 result.push_str("ss");
29171 i += 2;
29172 } else if remaining.starts_with("ff") {
29173 result.push_str("SSS"); i += 2;
29175 while i < chars.len() && chars[i].is_ascii_digit() {
29177 i += 1;
29178 }
29179 } else if remaining.starts_with("am") || remaining.starts_with("pm") {
29180 result.push_str("a");
29181 i += 2;
29182 } else if remaining.starts_with("tz") {
29183 result.push_str("z");
29184 i += 2;
29185 } else {
29186 result.push(chars[i]);
29187 i += 1;
29188 }
29189 }
29190 result
29191 }
29192
29193 fn generate_str_to_unix(&mut self, e: &StrToUnix) -> Result<()> {
29194 self.write_keyword("STR_TO_UNIX");
29196 self.write("(");
29197 if let Some(this) = &e.this {
29198 self.generate_expression(this)?;
29199 }
29200 if let Some(format) = &e.format {
29201 self.write(", '");
29202 self.write(format);
29203 self.write("'");
29204 }
29205 self.write(")");
29206 Ok(())
29207 }
29208
29209 fn generate_string_to_array(&mut self, e: &StringToArray) -> Result<()> {
29210 self.write_keyword("STRING_TO_ARRAY");
29212 self.write("(");
29213 self.generate_expression(&e.this)?;
29214 if let Some(expression) = &e.expression {
29215 self.write(", ");
29216 self.generate_expression(expression)?;
29217 }
29218 if let Some(null_val) = &e.null {
29219 self.write(", ");
29220 self.generate_expression(null_val)?;
29221 }
29222 self.write(")");
29223 Ok(())
29224 }
29225
29226 fn generate_struct(&mut self, e: &Struct) -> Result<()> {
29227 if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
29228 self.write_keyword("OBJECT_CONSTRUCT");
29230 self.write("(");
29231 for (i, (name, expr)) in e.fields.iter().enumerate() {
29232 if i > 0 {
29233 self.write(", ");
29234 }
29235 if let Some(name) = name {
29236 self.write("'");
29237 self.write(name);
29238 self.write("'");
29239 self.write(", ");
29240 } else {
29241 self.write("'_");
29242 self.write(&i.to_string());
29243 self.write("'");
29244 self.write(", ");
29245 }
29246 self.generate_expression(expr)?;
29247 }
29248 self.write(")");
29249 } else if self.config.struct_curly_brace_notation {
29250 self.write("{");
29252 for (i, (name, expr)) in e.fields.iter().enumerate() {
29253 if i > 0 {
29254 self.write(", ");
29255 }
29256 if let Some(name) = name {
29257 self.write("'");
29259 self.write(name);
29260 self.write("'");
29261 self.write(": ");
29262 } else {
29263 self.write("'_");
29265 self.write(&i.to_string());
29266 self.write("'");
29267 self.write(": ");
29268 }
29269 self.generate_expression(expr)?;
29270 }
29271 self.write("}");
29272 } else {
29273 let value_as_name = matches!(
29277 self.config.dialect,
29278 Some(DialectType::BigQuery)
29279 | Some(DialectType::Spark)
29280
29281 | Some(DialectType::Databricks)
29282 | Some(DialectType::Hive)
29283 );
29284 self.write_keyword("STRUCT");
29285 self.write("(");
29286 for (i, (name, expr)) in e.fields.iter().enumerate() {
29287 if i > 0 {
29288 self.write(", ");
29289 }
29290 if let Some(name) = name {
29291 if value_as_name {
29292 self.generate_expression(expr)?;
29294 self.write_space();
29295 self.write_keyword("AS");
29296 self.write_space();
29297 let needs_quoting = name.contains(' ') || name.contains('-');
29299 if needs_quoting {
29300 if matches!(self.config.dialect, Some(DialectType::Spark) | Some(DialectType::Databricks) | Some(DialectType::Hive)) {
29301 self.write("`");
29302 self.write(name);
29303 self.write("`");
29304 } else {
29305 self.write(name);
29306 }
29307 } else {
29308 self.write(name);
29309 }
29310 } else {
29311 self.write(name);
29313 self.write_space();
29314 self.write_keyword("AS");
29315 self.write_space();
29316 self.generate_expression(expr)?;
29317 }
29318 } else {
29319 self.generate_expression(expr)?;
29320 }
29321 }
29322 self.write(")");
29323 }
29324 Ok(())
29325 }
29326
29327 fn generate_stuff(&mut self, e: &Stuff) -> Result<()> {
29328 self.write_keyword("STUFF");
29330 self.write("(");
29331 self.generate_expression(&e.this)?;
29332 if let Some(start) = &e.start {
29333 self.write(", ");
29334 self.generate_expression(start)?;
29335 }
29336 if let Some(length) = e.length {
29337 self.write(", ");
29338 self.write(&length.to_string());
29339 }
29340 self.write(", ");
29341 self.generate_expression(&e.expression)?;
29342 self.write(")");
29343 Ok(())
29344 }
29345
29346 fn generate_substring_index(&mut self, e: &SubstringIndex) -> Result<()> {
29347 self.write_keyword("SUBSTRING_INDEX");
29349 self.write("(");
29350 self.generate_expression(&e.this)?;
29351 if let Some(delimiter) = &e.delimiter {
29352 self.write(", ");
29353 self.generate_expression(delimiter)?;
29354 }
29355 if let Some(count) = &e.count {
29356 self.write(", ");
29357 self.generate_expression(count)?;
29358 }
29359 self.write(")");
29360 Ok(())
29361 }
29362
29363 fn generate_summarize(&mut self, e: &Summarize) -> Result<()> {
29364 self.write_keyword("SUMMARIZE");
29366 if e.table.is_some() {
29367 self.write_space();
29368 self.write_keyword("TABLE");
29369 }
29370 self.write_space();
29371 self.generate_expression(&e.this)?;
29372 Ok(())
29373 }
29374
29375 fn generate_systimestamp(&mut self, _e: &Systimestamp) -> Result<()> {
29376 self.write_keyword("SYSTIMESTAMP");
29378 Ok(())
29379 }
29380
29381 fn generate_table_alias(&mut self, e: &TableAlias) -> Result<()> {
29382 if let Some(this) = &e.this {
29384 self.generate_expression(this)?;
29385 }
29386 if !e.columns.is_empty() {
29387 self.write("(");
29388 for (i, col) in e.columns.iter().enumerate() {
29389 if i > 0 {
29390 self.write(", ");
29391 }
29392 self.generate_expression(col)?;
29393 }
29394 self.write(")");
29395 }
29396 Ok(())
29397 }
29398
29399 fn generate_table_from_rows(&mut self, e: &TableFromRows) -> Result<()> {
29400 self.write_keyword("TABLE");
29402 self.write("(");
29403 self.generate_expression(&e.this)?;
29404 self.write(")");
29405 if let Some(alias) = &e.alias {
29406 self.write_space();
29407 self.write_keyword("AS");
29408 self.write_space();
29409 self.write(alias);
29410 }
29411 Ok(())
29412 }
29413
29414 fn generate_rows_from(&mut self, e: &RowsFrom) -> Result<()> {
29415 self.write_keyword("ROWS FROM");
29417 self.write(" (");
29418 for (i, expr) in e.expressions.iter().enumerate() {
29419 if i > 0 {
29420 self.write(", ");
29421 }
29422 match expr {
29426 Expression::Tuple(tuple) if tuple.expressions.len() == 2 => {
29427 self.generate_expression(&tuple.expressions[0])?;
29429 self.write_space();
29430 self.write_keyword("AS");
29431 self.write_space();
29432 self.generate_expression(&tuple.expressions[1])?;
29433 }
29434 _ => {
29435 self.generate_expression(expr)?;
29436 }
29437 }
29438 }
29439 self.write(")");
29440 if e.ordinality {
29441 self.write_space();
29442 self.write_keyword("WITH ORDINALITY");
29443 }
29444 if let Some(alias) = &e.alias {
29445 self.write_space();
29446 self.write_keyword("AS");
29447 self.write_space();
29448 self.generate_expression(alias)?;
29449 }
29450 Ok(())
29451 }
29452
29453 fn generate_table_sample(&mut self, e: &TableSample) -> Result<()> {
29454 use crate::dialects::DialectType;
29455
29456 if let (Some(this), Some(sample)) = (&e.this, &e.sample) {
29458 if self.config.alias_post_tablesample {
29460 if let Expression::Subquery(ref s) = **this {
29462 if let Some(ref alias) = s.alias {
29463 let mut subquery_no_alias = (**s).clone();
29465 subquery_no_alias.alias = None;
29466 subquery_no_alias.column_aliases = Vec::new();
29467 self.generate_expression(&Expression::Subquery(Box::new(subquery_no_alias)))?;
29468 self.write_space();
29469 self.write_keyword("TABLESAMPLE");
29470 self.generate_sample_body(sample)?;
29471 if let Some(ref seed) = sample.seed {
29472 self.write_space();
29473 let use_seed = sample.use_seed_keyword
29474 && !matches!(self.config.dialect, Some(crate::dialects::DialectType::Databricks) | Some(crate::dialects::DialectType::Spark));
29475 if use_seed { self.write_keyword("SEED"); } else { self.write_keyword("REPEATABLE"); }
29476 self.write(" (");
29477 self.generate_expression(seed)?;
29478 self.write(")");
29479 }
29480 self.write_space();
29481 self.write_keyword("AS");
29482 self.write_space();
29483 self.generate_identifier(alias)?;
29484 return Ok(());
29485 }
29486 } else if let Expression::Alias(ref a) = **this {
29487 self.generate_expression(&a.this)?;
29489 self.write_space();
29490 self.write_keyword("TABLESAMPLE");
29491 self.generate_sample_body(sample)?;
29492 if let Some(ref seed) = sample.seed {
29493 self.write_space();
29494 let use_seed = sample.use_seed_keyword
29495 && !matches!(self.config.dialect, Some(crate::dialects::DialectType::Databricks) | Some(crate::dialects::DialectType::Spark));
29496 if use_seed { self.write_keyword("SEED"); } else { self.write_keyword("REPEATABLE"); }
29497 self.write(" (");
29498 self.generate_expression(seed)?;
29499 self.write(")");
29500 }
29501 self.write_space();
29503 self.write_keyword("AS");
29504 self.write_space();
29505 self.generate_identifier(&a.alias)?;
29506 return Ok(());
29507 }
29508 }
29509 self.generate_expression(this)?;
29511 self.write_space();
29512 self.write_keyword("TABLESAMPLE");
29513 self.generate_sample_body(sample)?;
29514 if let Some(ref seed) = sample.seed {
29516 self.write_space();
29517 let use_seed = sample.use_seed_keyword
29519 && !matches!(self.config.dialect, Some(crate::dialects::DialectType::Databricks) | Some(crate::dialects::DialectType::Spark));
29520 if use_seed {
29521 self.write_keyword("SEED");
29522 } else {
29523 self.write_keyword("REPEATABLE");
29524 }
29525 self.write(" (");
29526 self.generate_expression(seed)?;
29527 self.write(")");
29528 }
29529 return Ok(());
29530 }
29531
29532 self.write_keyword("TABLESAMPLE");
29534 if let Some(method) = &e.method {
29535 self.write_space();
29536 self.write_keyword(method);
29537 } else if matches!(self.config.dialect, Some(DialectType::Snowflake)) {
29538 self.write_space();
29540 self.write_keyword("BERNOULLI");
29541 }
29542 if let (Some(numerator), Some(denominator)) = (&e.bucket_numerator, &e.bucket_denominator) {
29543 self.write_space();
29544 self.write_keyword("BUCKET");
29545 self.write_space();
29546 self.generate_expression(numerator)?;
29547 self.write_space();
29548 self.write_keyword("OUT OF");
29549 self.write_space();
29550 self.generate_expression(denominator)?;
29551 if let Some(field) = &e.bucket_field {
29552 self.write_space();
29553 self.write_keyword("ON");
29554 self.write_space();
29555 self.generate_expression(field)?;
29556 }
29557 } else if !e.expressions.is_empty() {
29558 self.write(" (");
29559 for (i, expr) in e.expressions.iter().enumerate() {
29560 if i > 0 {
29561 self.write(", ");
29562 }
29563 self.generate_expression(expr)?;
29564 }
29565 self.write(")");
29566 } else if let Some(percent) = &e.percent {
29567 self.write(" (");
29568 self.generate_expression(percent)?;
29569 self.write_space();
29570 self.write_keyword("PERCENT");
29571 self.write(")");
29572 }
29573 Ok(())
29574 }
29575
29576 fn generate_tag(&mut self, e: &Tag) -> Result<()> {
29577 if let Some(prefix) = &e.prefix {
29579 self.generate_expression(prefix)?;
29580 }
29581 if let Some(this) = &e.this {
29582 self.generate_expression(this)?;
29583 }
29584 if let Some(postfix) = &e.postfix {
29585 self.generate_expression(postfix)?;
29586 }
29587 Ok(())
29588 }
29589
29590 fn generate_tags(&mut self, e: &Tags) -> Result<()> {
29591 self.write_keyword("TAG");
29593 self.write(" (");
29594 for (i, expr) in e.expressions.iter().enumerate() {
29595 if i > 0 {
29596 self.write(", ");
29597 }
29598 self.generate_expression(expr)?;
29599 }
29600 self.write(")");
29601 Ok(())
29602 }
29603
29604 fn generate_temporary_property(&mut self, e: &TemporaryProperty) -> Result<()> {
29605 if let Some(this) = &e.this {
29607 self.generate_expression(this)?;
29608 self.write_space();
29609 }
29610 self.write_keyword("TEMPORARY");
29611 Ok(())
29612 }
29613
29614 fn generate_time_func(&mut self, e: &UnaryFunc) -> Result<()> {
29617 self.write_keyword("TIME");
29619 self.write("(");
29620 self.generate_expression(&e.this)?;
29621 self.write(")");
29622 Ok(())
29623 }
29624
29625 fn generate_time_add(&mut self, e: &TimeAdd) -> Result<()> {
29626 self.write_keyword("TIME_ADD");
29628 self.write("(");
29629 self.generate_expression(&e.this)?;
29630 self.write(", ");
29631 self.generate_expression(&e.expression)?;
29632 if let Some(unit) = &e.unit {
29633 self.write(", ");
29634 self.write_keyword(unit);
29635 }
29636 self.write(")");
29637 Ok(())
29638 }
29639
29640 fn generate_time_diff(&mut self, e: &TimeDiff) -> Result<()> {
29641 self.write_keyword("TIME_DIFF");
29643 self.write("(");
29644 self.generate_expression(&e.this)?;
29645 self.write(", ");
29646 self.generate_expression(&e.expression)?;
29647 if let Some(unit) = &e.unit {
29648 self.write(", ");
29649 self.write_keyword(unit);
29650 }
29651 self.write(")");
29652 Ok(())
29653 }
29654
29655 fn generate_time_from_parts(&mut self, e: &TimeFromParts) -> Result<()> {
29656 self.write_keyword("TIME_FROM_PARTS");
29658 self.write("(");
29659 let mut first = true;
29660 if let Some(hour) = &e.hour {
29661 self.generate_expression(hour)?;
29662 first = false;
29663 }
29664 if let Some(minute) = &e.min {
29665 if !first { self.write(", "); }
29666 self.generate_expression(minute)?;
29667 first = false;
29668 }
29669 if let Some(second) = &e.sec {
29670 if !first { self.write(", "); }
29671 self.generate_expression(second)?;
29672 first = false;
29673 }
29674 if let Some(ns) = &e.nano {
29675 if !first { self.write(", "); }
29676 self.generate_expression(ns)?;
29677 }
29678 self.write(")");
29679 Ok(())
29680 }
29681
29682 fn generate_time_slice(&mut self, e: &TimeSlice) -> Result<()> {
29683 self.write_keyword("TIME_SLICE");
29685 self.write("(");
29686 self.generate_expression(&e.this)?;
29687 self.write(", ");
29688 self.generate_expression(&e.expression)?;
29689 self.write(", ");
29690 self.write_keyword(&e.unit);
29691 self.write(")");
29692 Ok(())
29693 }
29694
29695 fn generate_time_str_to_time(&mut self, e: &TimeStrToTime) -> Result<()> {
29696 self.write_keyword("TIME_STR_TO_TIME");
29698 self.write("(");
29699 self.generate_expression(&e.this)?;
29700 self.write(")");
29701 Ok(())
29702 }
29703
29704 fn generate_time_sub(&mut self, e: &TimeSub) -> Result<()> {
29705 self.write_keyword("TIME_SUB");
29707 self.write("(");
29708 self.generate_expression(&e.this)?;
29709 self.write(", ");
29710 self.generate_expression(&e.expression)?;
29711 if let Some(unit) = &e.unit {
29712 self.write(", ");
29713 self.write_keyword(unit);
29714 }
29715 self.write(")");
29716 Ok(())
29717 }
29718
29719 fn generate_time_to_str(&mut self, e: &TimeToStr) -> Result<()> {
29720 if self.config.dialect == Some(DialectType::Exasol) {
29722 self.write_keyword("TO_CHAR");
29723 self.write("(");
29724 self.generate_expression(&e.this)?;
29725 self.write(", '");
29726 self.write(&Self::convert_strptime_to_exasol_format(&e.format));
29727 self.write("'");
29728 self.write(")");
29729 return Ok(());
29730 }
29731
29732 if matches!(self.config.dialect, Some(DialectType::PostgreSQL) | Some(DialectType::Redshift)) {
29734 self.write_keyword("TO_CHAR");
29735 self.write("(");
29736 self.generate_expression(&e.this)?;
29737 self.write(", '");
29738 self.write(&Self::convert_strptime_to_postgres_format(&e.format));
29739 self.write("'");
29740 self.write(")");
29741 return Ok(());
29742 }
29743
29744 self.write_keyword("TIME_TO_STR");
29746 self.write("(");
29747 self.generate_expression(&e.this)?;
29748 self.write(", '");
29749 self.write(&e.format);
29750 self.write("'");
29751 self.write(")");
29752 Ok(())
29753 }
29754
29755 fn generate_time_trunc(&mut self, e: &TimeTrunc) -> Result<()> {
29756 self.write_keyword("TIME_TRUNC");
29758 self.write("(");
29759 self.generate_expression(&e.this)?;
29760 self.write(", ");
29761 self.write_keyword(&e.unit);
29762 self.write(")");
29763 Ok(())
29764 }
29765
29766 fn generate_time_unit(&mut self, e: &TimeUnit) -> Result<()> {
29767 if let Some(unit) = &e.unit {
29769 self.write_keyword(unit);
29770 }
29771 Ok(())
29772 }
29773
29774 fn generate_timestamp_func(&mut self, e: &TimestampFunc) -> Result<()> {
29778 use crate::dialects::DialectType;
29779 use crate::expressions::Literal;
29780
29781 match self.config.dialect {
29782 Some(DialectType::Exasol) => {
29784 self.write_keyword("TO_TIMESTAMP");
29785 self.write("(");
29786 if let Some(this) = &e.this {
29788 match this.as_ref() {
29789 Expression::Literal(Literal::String(s)) => {
29790 self.write("'");
29791 self.write(s);
29792 self.write("'");
29793 }
29794 _ => {
29795 self.generate_expression(this)?;
29796 }
29797 }
29798 }
29799 self.write(")");
29800 }
29801 _ => {
29803 self.write_keyword("TIMESTAMP");
29804 self.write("(");
29805 if let Some(this) = &e.this {
29806 self.generate_expression(this)?;
29807 }
29808 if let Some(zone) = &e.zone {
29809 self.write(", ");
29810 self.generate_expression(zone)?;
29811 }
29812 self.write(")");
29813 }
29814 }
29815 Ok(())
29816 }
29817
29818 fn generate_timestamp_add(&mut self, e: &TimestampAdd) -> Result<()> {
29819 self.write_keyword("TIMESTAMP_ADD");
29821 self.write("(");
29822 self.generate_expression(&e.this)?;
29823 self.write(", ");
29824 self.generate_expression(&e.expression)?;
29825 if let Some(unit) = &e.unit {
29826 self.write(", ");
29827 self.write_keyword(unit);
29828 }
29829 self.write(")");
29830 Ok(())
29831 }
29832
29833 fn generate_timestamp_diff(&mut self, e: &TimestampDiff) -> Result<()> {
29834 self.write_keyword("TIMESTAMP_DIFF");
29836 self.write("(");
29837 self.generate_expression(&e.this)?;
29838 self.write(", ");
29839 self.generate_expression(&e.expression)?;
29840 if let Some(unit) = &e.unit {
29841 self.write(", ");
29842 self.write_keyword(unit);
29843 }
29844 self.write(")");
29845 Ok(())
29846 }
29847
29848 fn generate_timestamp_from_parts(&mut self, e: &TimestampFromParts) -> Result<()> {
29849 self.write_keyword("TIMESTAMP_FROM_PARTS");
29851 self.write("(");
29852 if let Some(this) = &e.this {
29853 self.generate_expression(this)?;
29854 }
29855 if let Some(expression) = &e.expression {
29856 self.write(", ");
29857 self.generate_expression(expression)?;
29858 }
29859 if let Some(zone) = &e.zone {
29860 self.write(", ");
29861 self.generate_expression(zone)?;
29862 }
29863 if let Some(milli) = &e.milli {
29864 self.write(", ");
29865 self.generate_expression(milli)?;
29866 }
29867 self.write(")");
29868 Ok(())
29869 }
29870
29871 fn generate_timestamp_sub(&mut self, e: &TimestampSub) -> Result<()> {
29872 self.write_keyword("TIMESTAMP_SUB");
29874 self.write("(");
29875 self.generate_expression(&e.this)?;
29876 self.write(", ");
29877 self.write_keyword("INTERVAL");
29878 self.write_space();
29879 self.generate_expression(&e.expression)?;
29880 if let Some(unit) = &e.unit {
29881 self.write_space();
29882 self.write_keyword(unit);
29883 }
29884 self.write(")");
29885 Ok(())
29886 }
29887
29888 fn generate_timestamp_tz_from_parts(&mut self, e: &TimestampTzFromParts) -> Result<()> {
29889 self.write_keyword("TIMESTAMP_TZ_FROM_PARTS");
29891 self.write("(");
29892 if let Some(zone) = &e.zone {
29893 self.generate_expression(zone)?;
29894 }
29895 self.write(")");
29896 Ok(())
29897 }
29898
29899 fn generate_to_binary(&mut self, e: &ToBinary) -> Result<()> {
29900 self.write_keyword("TO_BINARY");
29902 self.write("(");
29903 self.generate_expression(&e.this)?;
29904 if let Some(format) = &e.format {
29905 self.write(", '");
29906 self.write(format);
29907 self.write("'");
29908 }
29909 self.write(")");
29910 Ok(())
29911 }
29912
29913 fn generate_to_boolean(&mut self, e: &ToBoolean) -> Result<()> {
29914 self.write_keyword("TO_BOOLEAN");
29916 self.write("(");
29917 self.generate_expression(&e.this)?;
29918 self.write(")");
29919 Ok(())
29920 }
29921
29922 fn generate_to_char(&mut self, e: &ToChar) -> Result<()> {
29923 self.write_keyword("TO_CHAR");
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 if let Some(nlsparam) = &e.nlsparam {
29933 self.write(", ");
29934 self.generate_expression(nlsparam)?;
29935 }
29936 self.write(")");
29937 Ok(())
29938 }
29939
29940 fn generate_to_decfloat(&mut self, e: &ToDecfloat) -> Result<()> {
29941 self.write_keyword("TO_DECFLOAT");
29943 self.write("(");
29944 self.generate_expression(&e.this)?;
29945 if let Some(format) = &e.format {
29946 self.write(", '");
29947 self.write(format);
29948 self.write("'");
29949 }
29950 self.write(")");
29951 Ok(())
29952 }
29953
29954 fn generate_to_double(&mut self, e: &ToDouble) -> Result<()> {
29955 self.write_keyword("TO_DOUBLE");
29957 self.write("(");
29958 self.generate_expression(&e.this)?;
29959 if let Some(format) = &e.format {
29960 self.write(", '");
29961 self.write(format);
29962 self.write("'");
29963 }
29964 self.write(")");
29965 Ok(())
29966 }
29967
29968 fn generate_to_file(&mut self, e: &ToFile) -> Result<()> {
29969 self.write_keyword("TO_FILE");
29971 self.write("(");
29972 self.generate_expression(&e.this)?;
29973 if let Some(path) = &e.path {
29974 self.write(", ");
29975 self.generate_expression(path)?;
29976 }
29977 self.write(")");
29978 Ok(())
29979 }
29980
29981 fn generate_to_number(&mut self, e: &ToNumber) -> Result<()> {
29982 let is_safe = e.safe.is_some();
29985 if is_safe {
29986 self.write_keyword("TRY_TO_NUMBER");
29987 } else {
29988 self.write_keyword("TO_NUMBER");
29989 }
29990 self.write("(");
29991 self.generate_expression(&e.this)?;
29992 if let Some(format) = &e.format {
29993 self.write(", ");
29994 self.generate_expression(format)?;
29995 }
29996 if let Some(nlsparam) = &e.nlsparam {
29997 self.write(", ");
29998 self.generate_expression(nlsparam)?;
29999 }
30000 if let Some(precision) = &e.precision {
30001 self.write(", ");
30002 self.generate_expression(precision)?;
30003 }
30004 if let Some(scale) = &e.scale {
30005 self.write(", ");
30006 self.generate_expression(scale)?;
30007 }
30008 self.write(")");
30009 Ok(())
30010 }
30011
30012 fn generate_to_table_property(&mut self, e: &ToTableProperty) -> Result<()> {
30013 self.write_keyword("TO_TABLE");
30015 self.write_space();
30016 self.generate_expression(&e.this)?;
30017 Ok(())
30018 }
30019
30020 fn generate_transaction(&mut self, e: &Transaction) -> Result<()> {
30021 let mark_text = e.mark.as_ref().map(|m| {
30023 match m.as_ref() {
30024 Expression::Identifier(id) => id.name.clone(),
30025 Expression::Literal(Literal::String(s)) => s.clone(),
30026 _ => String::new(),
30027 }
30028 });
30029
30030 let is_start = mark_text.as_ref().map_or(false, |s| s == "START");
30031 let has_transaction_keyword = mark_text.as_ref().map_or(false, |s| s == "TRANSACTION");
30032 let has_with_mark = e.mark.as_ref().map_or(false, |m| {
30033 matches!(m.as_ref(), Expression::Literal(Literal::String(_)))
30034 });
30035
30036 if is_start {
30037 self.write_keyword("START TRANSACTION");
30039 if let Some(modes) = &e.modes {
30040 self.write_space();
30041 self.generate_expression(modes)?;
30042 }
30043 } else {
30044 self.write_keyword("BEGIN");
30046
30047 if has_transaction_keyword || has_with_mark {
30049 self.write_space();
30050 self.write_keyword("TRANSACTION");
30051 }
30052
30053 if let Some(this) = &e.this {
30055 self.write_space();
30056 self.generate_expression(this)?;
30057 }
30058
30059 if has_with_mark {
30061 self.write_space();
30062 self.write_keyword("WITH MARK");
30063 if let Some(Expression::Literal(Literal::String(desc))) = e.mark.as_deref() {
30064 if !desc.is_empty() {
30065 self.write_space();
30066 self.write(&format!("'{}'", desc));
30067 }
30068 }
30069 }
30070
30071 if let Some(modes) = &e.modes {
30073 self.write_space();
30074 self.generate_expression(modes)?;
30075 }
30076 }
30077 Ok(())
30078 }
30079
30080 fn generate_transform(&mut self, e: &Transform) -> Result<()> {
30081 self.write_keyword("TRANSFORM");
30083 self.write("(");
30084 self.generate_expression(&e.this)?;
30085 self.write(", ");
30086 self.generate_expression(&e.expression)?;
30087 self.write(")");
30088 Ok(())
30089 }
30090
30091 fn generate_transform_model_property(&mut self, e: &TransformModelProperty) -> Result<()> {
30092 self.write_keyword("TRANSFORM");
30094 self.write("(");
30095 if self.config.pretty && !e.expressions.is_empty() {
30096 self.indent_level += 1;
30097 for (i, expr) in e.expressions.iter().enumerate() {
30098 if i > 0 {
30099 self.write(",");
30100 }
30101 self.write_newline();
30102 self.write_indent();
30103 self.generate_expression(expr)?;
30104 }
30105 self.indent_level -= 1;
30106 self.write_newline();
30107 self.write(")");
30108 } else {
30109 for (i, expr) in e.expressions.iter().enumerate() {
30110 if i > 0 {
30111 self.write(", ");
30112 }
30113 self.generate_expression(expr)?;
30114 }
30115 self.write(")");
30116 }
30117 Ok(())
30118 }
30119
30120 fn generate_transient_property(&mut self, e: &TransientProperty) -> Result<()> {
30121 use crate::dialects::DialectType;
30122 if let Some(this) = &e.this {
30124 self.generate_expression(this)?;
30125 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
30126 self.write_space();
30127 }
30128 }
30129 if matches!(self.config.dialect, Some(DialectType::Snowflake) | None) {
30130 self.write_keyword("TRANSIENT");
30131 }
30132 Ok(())
30133 }
30134
30135 fn generate_translate(&mut self, e: &Translate) -> Result<()> {
30136 self.write_keyword("TRANSLATE");
30138 self.write("(");
30139 self.generate_expression(&e.this)?;
30140 if let Some(from) = &e.from_ {
30141 self.write(", ");
30142 self.generate_expression(from)?;
30143 }
30144 if let Some(to) = &e.to {
30145 self.write(", ");
30146 self.generate_expression(to)?;
30147 }
30148 self.write(")");
30149 Ok(())
30150 }
30151
30152 fn generate_translate_characters(&mut self, e: &TranslateCharacters) -> Result<()> {
30153 self.write_keyword("TRANSLATE");
30155 self.write("(");
30156 self.generate_expression(&e.this)?;
30157 self.write_space();
30158 self.write_keyword("USING");
30159 self.write_space();
30160 self.generate_expression(&e.expression)?;
30161 if e.with_error.is_some() {
30162 self.write_space();
30163 self.write_keyword("WITH ERROR");
30164 }
30165 self.write(")");
30166 Ok(())
30167 }
30168
30169 fn generate_truncate_table(&mut self, e: &TruncateTable) -> Result<()> {
30170 self.write_keyword("TRUNCATE TABLE");
30172 self.write_space();
30173 for (i, expr) in e.expressions.iter().enumerate() {
30174 if i > 0 {
30175 self.write(", ");
30176 }
30177 self.generate_expression(expr)?;
30178 }
30179 Ok(())
30180 }
30181
30182 fn generate_try_base64_decode_binary(&mut self, e: &TryBase64DecodeBinary) -> Result<()> {
30183 self.write_keyword("TRY_BASE64_DECODE_BINARY");
30185 self.write("(");
30186 self.generate_expression(&e.this)?;
30187 if let Some(alphabet) = &e.alphabet {
30188 self.write(", ");
30189 self.generate_expression(alphabet)?;
30190 }
30191 self.write(")");
30192 Ok(())
30193 }
30194
30195 fn generate_try_base64_decode_string(&mut self, e: &TryBase64DecodeString) -> Result<()> {
30196 self.write_keyword("TRY_BASE64_DECODE_STRING");
30198 self.write("(");
30199 self.generate_expression(&e.this)?;
30200 if let Some(alphabet) = &e.alphabet {
30201 self.write(", ");
30202 self.generate_expression(alphabet)?;
30203 }
30204 self.write(")");
30205 Ok(())
30206 }
30207
30208 fn generate_try_to_decfloat(&mut self, e: &TryToDecfloat) -> Result<()> {
30209 self.write_keyword("TRY_TO_DECFLOAT");
30211 self.write("(");
30212 self.generate_expression(&e.this)?;
30213 if let Some(format) = &e.format {
30214 self.write(", '");
30215 self.write(format);
30216 self.write("'");
30217 }
30218 self.write(")");
30219 Ok(())
30220 }
30221
30222 fn generate_ts_or_ds_add(&mut self, e: &TsOrDsAdd) -> Result<()> {
30223 self.write_keyword("TS_OR_DS_ADD");
30225 self.write("(");
30226 self.generate_expression(&e.this)?;
30227 self.write(", ");
30228 self.generate_expression(&e.expression)?;
30229 if let Some(unit) = &e.unit {
30230 self.write(", ");
30231 self.write_keyword(unit);
30232 }
30233 if let Some(return_type) = &e.return_type {
30234 self.write(", ");
30235 self.generate_expression(return_type)?;
30236 }
30237 self.write(")");
30238 Ok(())
30239 }
30240
30241 fn generate_ts_or_ds_diff(&mut self, e: &TsOrDsDiff) -> Result<()> {
30242 self.write_keyword("TS_OR_DS_DIFF");
30244 self.write("(");
30245 self.generate_expression(&e.this)?;
30246 self.write(", ");
30247 self.generate_expression(&e.expression)?;
30248 if let Some(unit) = &e.unit {
30249 self.write(", ");
30250 self.write_keyword(unit);
30251 }
30252 self.write(")");
30253 Ok(())
30254 }
30255
30256 fn generate_ts_or_ds_to_date(&mut self, e: &TsOrDsToDate) -> Result<()> {
30257 self.write_keyword("TS_OR_DS_TO_DATE");
30259 self.write("(");
30260 self.generate_expression(&e.this)?;
30261 if let Some(format) = &e.format {
30262 self.write(", '");
30263 self.write(format);
30264 self.write("'");
30265 }
30266 self.write(")");
30267 Ok(())
30268 }
30269
30270 fn generate_ts_or_ds_to_time(&mut self, e: &TsOrDsToTime) -> Result<()> {
30271 self.write_keyword("TS_OR_DS_TO_TIME");
30273 self.write("(");
30274 self.generate_expression(&e.this)?;
30275 if let Some(format) = &e.format {
30276 self.write(", '");
30277 self.write(format);
30278 self.write("'");
30279 }
30280 self.write(")");
30281 Ok(())
30282 }
30283
30284 fn generate_unhex(&mut self, e: &Unhex) -> Result<()> {
30285 self.write_keyword("UNHEX");
30287 self.write("(");
30288 self.generate_expression(&e.this)?;
30289 if let Some(expression) = &e.expression {
30290 self.write(", ");
30291 self.generate_expression(expression)?;
30292 }
30293 self.write(")");
30294 Ok(())
30295 }
30296
30297 fn generate_unicode_string(&mut self, e: &UnicodeString) -> Result<()> {
30298 self.write("U&");
30300 self.generate_expression(&e.this)?;
30301 if let Some(escape) = &e.escape {
30302 self.write_space();
30303 self.write_keyword("UESCAPE");
30304 self.write_space();
30305 self.generate_expression(escape)?;
30306 }
30307 Ok(())
30308 }
30309
30310 fn generate_uniform(&mut self, e: &Uniform) -> Result<()> {
30311 self.write_keyword("UNIFORM");
30313 self.write("(");
30314 self.generate_expression(&e.this)?;
30315 self.write(", ");
30316 self.generate_expression(&e.expression)?;
30317 if let Some(gen) = &e.gen {
30318 self.write(", ");
30319 self.generate_expression(gen)?;
30320 }
30321 if let Some(seed) = &e.seed {
30322 self.write(", ");
30323 self.generate_expression(seed)?;
30324 }
30325 self.write(")");
30326 Ok(())
30327 }
30328
30329 fn generate_unique_column_constraint(&mut self, e: &UniqueColumnConstraint) -> Result<()> {
30330 self.write_keyword("UNIQUE");
30332 if e.nulls.is_some() {
30334 self.write(" NULLS NOT DISTINCT");
30335 }
30336 if let Some(this) = &e.this {
30337 self.write_space();
30338 self.generate_expression(this)?;
30339 }
30340 if let Some(index_type) = &e.index_type {
30341 self.write(" USING ");
30342 self.generate_expression(index_type)?;
30343 }
30344 if let Some(on_conflict) = &e.on_conflict {
30345 self.write_space();
30346 self.generate_expression(on_conflict)?;
30347 }
30348 for opt in &e.options {
30349 self.write_space();
30350 self.generate_expression(opt)?;
30351 }
30352 Ok(())
30353 }
30354
30355 fn generate_unique_key_property(&mut self, e: &UniqueKeyProperty) -> Result<()> {
30356 self.write_keyword("UNIQUE KEY");
30358 self.write(" (");
30359 for (i, expr) in e.expressions.iter().enumerate() {
30360 if i > 0 {
30361 self.write(", ");
30362 }
30363 self.generate_expression(expr)?;
30364 }
30365 self.write(")");
30366 Ok(())
30367 }
30368
30369 fn generate_rollup_property(&mut self, e: &RollupProperty) -> Result<()> {
30370 self.write_keyword("ROLLUP");
30372 self.write(" (");
30373 for (i, index) in e.expressions.iter().enumerate() {
30374 if i > 0 {
30375 self.write(", ");
30376 }
30377 self.generate_identifier(&index.name)?;
30378 self.write("(");
30379 for (j, col) in index.expressions.iter().enumerate() {
30380 if j > 0 {
30381 self.write(", ");
30382 }
30383 self.generate_identifier(col)?;
30384 }
30385 self.write(")");
30386 }
30387 self.write(")");
30388 Ok(())
30389 }
30390
30391 fn generate_unix_to_str(&mut self, e: &UnixToStr) -> Result<()> {
30392 self.write_keyword("UNIX_TO_STR");
30394 self.write("(");
30395 self.generate_expression(&e.this)?;
30396 if let Some(format) = &e.format {
30397 self.write(", '");
30398 self.write(format);
30399 self.write("'");
30400 }
30401 self.write(")");
30402 Ok(())
30403 }
30404
30405 fn generate_unix_to_time(&mut self, e: &UnixToTime) -> Result<()> {
30406 use crate::dialects::DialectType;
30407 let scale = e.scale.unwrap_or(0); match self.config.dialect {
30410 Some(DialectType::Snowflake) => {
30411 self.write_keyword("TO_TIMESTAMP");
30413 self.write("(");
30414 self.generate_expression(&e.this)?;
30415 if let Some(s) = e.scale {
30416 if s > 0 {
30417 self.write(", ");
30418 self.write(&s.to_string());
30419 }
30420 }
30421 self.write(")");
30422 }
30423 Some(DialectType::BigQuery) => {
30424 match scale {
30427 0 => {
30428 self.write_keyword("TIMESTAMP_SECONDS");
30429 self.write("(");
30430 self.generate_expression(&e.this)?;
30431 self.write(")");
30432 }
30433 3 => {
30434 self.write_keyword("TIMESTAMP_MILLIS");
30435 self.write("(");
30436 self.generate_expression(&e.this)?;
30437 self.write(")");
30438 }
30439 6 => {
30440 self.write_keyword("TIMESTAMP_MICROS");
30441 self.write("(");
30442 self.generate_expression(&e.this)?;
30443 self.write(")");
30444 }
30445 _ => {
30446 self.write_keyword("TIMESTAMP_SECONDS");
30448 self.write("(CAST(");
30449 self.generate_expression(&e.this)?;
30450 self.write(&format!(" / POWER(10, {}) AS INT64))", scale));
30451 }
30452 }
30453 }
30454 Some(DialectType::Spark) => {
30455 match scale {
30460 0 => {
30461 self.write_keyword("CAST");
30462 self.write("(");
30463 self.write_keyword("FROM_UNIXTIME");
30464 self.write("(");
30465 self.generate_expression(&e.this)?;
30466 self.write(") ");
30467 self.write_keyword("AS TIMESTAMP");
30468 self.write(")");
30469 }
30470 3 => {
30471 self.write_keyword("TIMESTAMP_MILLIS");
30472 self.write("(");
30473 self.generate_expression(&e.this)?;
30474 self.write(")");
30475 }
30476 6 => {
30477 self.write_keyword("TIMESTAMP_MICROS");
30478 self.write("(");
30479 self.generate_expression(&e.this)?;
30480 self.write(")");
30481 }
30482 _ => {
30483 self.write_keyword("TIMESTAMP_SECONDS");
30484 self.write("(");
30485 self.generate_expression(&e.this)?;
30486 self.write(&format!(" / POWER(10, {}))", scale));
30487 }
30488 }
30489 }
30490 Some(DialectType::Databricks) => {
30491 match scale {
30495 0 => {
30496 self.write_keyword("CAST");
30497 self.write("(");
30498 self.write_keyword("FROM_UNIXTIME");
30499 self.write("(");
30500 self.generate_expression(&e.this)?;
30501 self.write(") ");
30502 self.write_keyword("AS TIMESTAMP");
30503 self.write(")");
30504 }
30505 3 => {
30506 self.write_keyword("TIMESTAMP_MILLIS");
30507 self.write("(");
30508 self.generate_expression(&e.this)?;
30509 self.write(")");
30510 }
30511 6 => {
30512 self.write_keyword("TIMESTAMP_MICROS");
30513 self.write("(");
30514 self.generate_expression(&e.this)?;
30515 self.write(")");
30516 }
30517 _ => {
30518 self.write_keyword("TIMESTAMP_SECONDS");
30519 self.write("(");
30520 self.generate_expression(&e.this)?;
30521 self.write(&format!(" / POWER(10, {}))", scale));
30522 }
30523 }
30524 }
30525 Some(DialectType::Presto) | Some(DialectType::Trino) => {
30526 if scale == 0 {
30529 self.write_keyword("FROM_UNIXTIME");
30530 self.write("(");
30531 self.generate_expression(&e.this)?;
30532 self.write(")");
30533 } else {
30534 self.write_keyword("FROM_UNIXTIME");
30535 self.write("(CAST(");
30536 self.generate_expression(&e.this)?;
30537 self.write(&format!(" AS DOUBLE) / POW(10, {}))", scale));
30538 }
30539 }
30540 Some(DialectType::DuckDB) => {
30541 match scale {
30545 0 => {
30546 self.write_keyword("TO_TIMESTAMP");
30547 self.write("(");
30548 self.generate_expression(&e.this)?;
30549 self.write(")");
30550 }
30551 3 => {
30552 self.write_keyword("EPOCH_MS");
30553 self.write("(");
30554 self.generate_expression(&e.this)?;
30555 self.write(")");
30556 }
30557 6 => {
30558 self.write_keyword("MAKE_TIMESTAMP");
30559 self.write("(");
30560 self.generate_expression(&e.this)?;
30561 self.write(")");
30562 }
30563 _ => {
30564 self.write_keyword("TO_TIMESTAMP");
30565 self.write("(");
30566 self.generate_expression(&e.this)?;
30567 self.write(&format!(" / POWER(10, {}))", scale));
30568 self.write_keyword(" AT TIME ZONE");
30569 self.write(" 'UTC'");
30570 }
30571 }
30572 }
30573 Some(DialectType::Redshift) => {
30574 self.write("(TIMESTAMP 'epoch' + ");
30577 if scale == 0 {
30578 self.generate_expression(&e.this)?;
30579 } else {
30580 self.write("(");
30581 self.generate_expression(&e.this)?;
30582 self.write(&format!(" / POWER(10, {}))", scale));
30583 }
30584 self.write(" * INTERVAL '1 SECOND')");
30585 }
30586 _ => {
30587 self.write_keyword("TO_TIMESTAMP");
30589 self.write("(");
30590 self.generate_expression(&e.this)?;
30591 if let Some(s) = e.scale {
30592 self.write(", ");
30593 self.write(&s.to_string());
30594 }
30595 self.write(")");
30596 }
30597 }
30598 Ok(())
30599 }
30600
30601 fn generate_unpivot_columns(&mut self, e: &UnpivotColumns) -> Result<()> {
30602 if !matches!(&*e.this, Expression::Null(_)) {
30604 self.write_keyword("NAME");
30605 self.write_space();
30606 self.generate_expression(&e.this)?;
30607 }
30608 if !e.expressions.is_empty() {
30609 self.write_space();
30610 self.write_keyword("VALUE");
30611 self.write_space();
30612 for (i, expr) in e.expressions.iter().enumerate() {
30613 if i > 0 {
30614 self.write(", ");
30615 }
30616 self.generate_expression(expr)?;
30617 }
30618 }
30619 Ok(())
30620 }
30621
30622 fn generate_user_defined_function(&mut self, e: &UserDefinedFunction) -> Result<()> {
30623 if e.wrapped.is_some() {
30625 self.write("(");
30626 }
30627 self.generate_expression(&e.this)?;
30628 if e.wrapped.is_some() {
30629 self.write(")");
30630 }
30631 self.write("(");
30632 for (i, expr) in e.expressions.iter().enumerate() {
30633 if i > 0 {
30634 self.write(", ");
30635 }
30636 self.generate_expression(expr)?;
30637 }
30638 self.write(")");
30639 Ok(())
30640 }
30641
30642 fn generate_using_template_property(&mut self, e: &UsingTemplateProperty) -> Result<()> {
30643 self.write_keyword("USING TEMPLATE");
30645 self.write_space();
30646 self.generate_expression(&e.this)?;
30647 Ok(())
30648 }
30649
30650 fn generate_utc_time(&mut self, _e: &UtcTime) -> Result<()> {
30651 self.write_keyword("UTC_TIME");
30653 Ok(())
30654 }
30655
30656 fn generate_utc_timestamp(&mut self, _e: &UtcTimestamp) -> Result<()> {
30657 self.write_keyword("UTC_TIMESTAMP");
30659 Ok(())
30660 }
30661
30662 fn generate_uuid(&mut self, e: &Uuid) -> Result<()> {
30663 use crate::dialects::DialectType;
30664 let func_name = match self.config.dialect {
30666 Some(DialectType::Snowflake) => "UUID_STRING",
30667 Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) => "GEN_RANDOM_UUID",
30668 Some(DialectType::BigQuery) => "GENERATE_UUID",
30669 _ => {
30670 if let Some(name) = &e.name {
30671 name.as_str()
30672 } else {
30673 "UUID"
30674 }
30675 }
30676 };
30677 self.write_keyword(func_name);
30678 self.write("(");
30679 if let Some(this) = &e.this {
30680 self.generate_expression(this)?;
30681 }
30682 self.write(")");
30683 Ok(())
30684 }
30685
30686 fn generate_var_map(&mut self, e: &VarMap) -> Result<()> {
30687 self.write_keyword("MAP");
30689 self.write("(");
30690 let mut first = true;
30691 for (k, v) in e.keys.iter().zip(e.values.iter()) {
30692 if !first {
30693 self.write(", ");
30694 }
30695 self.generate_expression(k)?;
30696 self.write(", ");
30697 self.generate_expression(v)?;
30698 first = false;
30699 }
30700 self.write(")");
30701 Ok(())
30702 }
30703
30704 fn generate_vector_search(&mut self, e: &VectorSearch) -> Result<()> {
30705 self.write_keyword("VECTOR_SEARCH");
30707 self.write("(");
30708 self.generate_expression(&e.this)?;
30709 if let Some(col) = &e.column_to_search {
30710 self.write(", ");
30711 self.generate_expression(col)?;
30712 }
30713 if let Some(query_table) = &e.query_table {
30714 self.write(", ");
30715 self.generate_expression(query_table)?;
30716 }
30717 if let Some(query_col) = &e.query_column_to_search {
30718 self.write(", ");
30719 self.generate_expression(query_col)?;
30720 }
30721 if let Some(top_k) = &e.top_k {
30722 self.write(", ");
30723 self.generate_expression(top_k)?;
30724 }
30725 if let Some(dist_type) = &e.distance_type {
30726 self.write(", ");
30727 self.generate_expression(dist_type)?;
30728 }
30729 self.write(")");
30730 Ok(())
30731 }
30732
30733 fn generate_version(&mut self, e: &Version) -> Result<()> {
30734 use crate::dialects::DialectType;
30740 let skip_for = matches!(self.config.dialect, Some(DialectType::Hive) | Some(DialectType::Spark));
30741 if !skip_for {
30742 self.write_keyword("FOR");
30743 self.write_space();
30744 }
30745 match e.this.as_ref() {
30747 Expression::Identifier(ident) => {
30748 self.write_keyword(&ident.name);
30749 }
30750 _ => {
30751 self.generate_expression(&e.this)?;
30752 }
30753 }
30754 self.write_space();
30755 self.write_keyword(&e.kind);
30756 if let Some(expression) = &e.expression {
30757 self.write_space();
30758 self.generate_expression(expression)?;
30759 }
30760 Ok(())
30761 }
30762
30763 fn generate_view_attribute_property(&mut self, e: &ViewAttributeProperty) -> Result<()> {
30764 self.generate_expression(&e.this)?;
30766 Ok(())
30767 }
30768
30769 fn generate_volatile_property(&mut self, e: &VolatileProperty) -> Result<()> {
30770 if e.this.is_some() {
30772 self.write_keyword("NOT VOLATILE");
30773 } else {
30774 self.write_keyword("VOLATILE");
30775 }
30776 Ok(())
30777 }
30778
30779 fn generate_watermark_column_constraint(&mut self, e: &WatermarkColumnConstraint) -> Result<()> {
30780 self.write_keyword("WATERMARK FOR");
30782 self.write_space();
30783 self.generate_expression(&e.this)?;
30784 self.write_space();
30785 self.write_keyword("AS");
30786 self.write_space();
30787 self.generate_expression(&e.expression)?;
30788 Ok(())
30789 }
30790
30791 fn generate_week(&mut self, e: &Week) -> Result<()> {
30792 self.write_keyword("WEEK");
30794 self.write("(");
30795 self.generate_expression(&e.this)?;
30796 if let Some(mode) = &e.mode {
30797 self.write(", ");
30798 self.generate_expression(mode)?;
30799 }
30800 self.write(")");
30801 Ok(())
30802 }
30803
30804 fn generate_when(&mut self, e: &When) -> Result<()> {
30805 self.write_keyword("WHEN");
30809 self.write_space();
30810
30811 if let Some(matched) = &e.matched {
30813 match matched.as_ref() {
30815 Expression::Boolean(b) if b.value => {
30816 self.write_keyword("MATCHED");
30817 }
30818 _ => {
30819 self.write_keyword("NOT MATCHED");
30820 }
30821 }
30822 } else {
30823 self.write_keyword("NOT MATCHED");
30824 }
30825
30826 if self.config.matched_by_source {
30831 if let Some(source) = &e.source {
30832 if let Expression::Boolean(b) = source.as_ref() {
30833 if b.value {
30834 self.write_space();
30836 self.write_keyword("BY SOURCE");
30837 }
30838 } else {
30840 self.write_space();
30842 self.write_keyword("BY SOURCE");
30843 }
30844 }
30845 }
30846
30847 if let Some(condition) = &e.condition {
30849 self.write_space();
30850 self.write_keyword("AND");
30851 self.write_space();
30852 self.generate_expression(condition)?;
30853 }
30854
30855 self.write_space();
30856 self.write_keyword("THEN");
30857 self.write_space();
30858
30859 self.generate_merge_action(&e.then)?;
30862
30863 Ok(())
30864 }
30865
30866 fn generate_merge_action(&mut self, action: &Expression) -> Result<()> {
30867 match action {
30868 Expression::Tuple(tuple) => {
30869 let elements = &tuple.expressions;
30870 if elements.is_empty() {
30871 return self.generate_expression(action);
30872 }
30873 match &elements[0] {
30875 Expression::Var(v) if v.this == "INSERT" => {
30876 self.write_keyword("INSERT");
30877 let mut values_idx = 1;
30878 if elements.len() > 1 {
30880 if let Expression::Tuple(cols) = &elements[1] {
30881 if elements.len() > 2 {
30883 self.write(" (");
30885 for (i, col) in cols.expressions.iter().enumerate() {
30886 if i > 0 { self.write(", "); }
30887 self.generate_expression(col)?;
30888 }
30889 self.write(")");
30890 values_idx = 2;
30891 } else {
30892 values_idx = 1;
30894 }
30895 }
30896 }
30897 if values_idx < elements.len() {
30899 let is_row = matches!(&elements[values_idx], Expression::Var(v) if v.this == "ROW");
30901 if !is_row {
30902 self.write_space();
30903 self.write_keyword("VALUES");
30904 }
30905 self.write(" ");
30906 if let Expression::Tuple(vals) = &elements[values_idx] {
30907 self.write("(");
30908 for (i, val) in vals.expressions.iter().enumerate() {
30909 if i > 0 { self.write(", "); }
30910 self.generate_expression(val)?;
30911 }
30912 self.write(")");
30913 } else {
30914 self.generate_expression(&elements[values_idx])?;
30915 }
30916 }
30917 }
30918 Expression::Var(v) if v.this == "UPDATE" => {
30919 self.write_keyword("UPDATE");
30920 if elements.len() > 1 {
30921 self.write_space();
30922 self.write_keyword("SET");
30923 if self.config.pretty {
30925 self.write_newline();
30926 self.indent_level += 1;
30927 self.write_indent();
30928 } else {
30929 self.write_space();
30930 }
30931 if let Expression::Tuple(assignments) = &elements[1] {
30932 for (i, assignment) in assignments.expressions.iter().enumerate() {
30933 if i > 0 { self.write(", "); }
30934 if !self.merge_strip_qualifiers.is_empty() {
30936 self.generate_merge_set_assignment(assignment)?;
30937 } else {
30938 self.generate_expression(assignment)?;
30939 }
30940 }
30941 } else {
30942 self.generate_expression(&elements[1])?;
30943 }
30944 if self.config.pretty {
30945 self.indent_level -= 1;
30946 }
30947 }
30948 }
30949 _ => {
30950 self.generate_expression(action)?;
30952 }
30953 }
30954 }
30955 Expression::Var(v) if v.this == "INSERT" || v.this == "UPDATE" || v.this == "DELETE" || v.this == "DO NOTHING" => {
30956 self.write_keyword(&v.this);
30957 }
30958 _ => {
30959 self.generate_expression(action)?;
30960 }
30961 }
30962 Ok(())
30963 }
30964
30965 fn generate_merge_set_assignment(&mut self, assignment: &Expression) -> Result<()> {
30967 match assignment {
30968 Expression::Eq(eq) => {
30969 let stripped_left = self.strip_merge_qualifier(&eq.left);
30971 self.generate_expression(&stripped_left)?;
30972 self.write(" = ");
30973 self.generate_expression(&eq.right)?;
30974 Ok(())
30975 }
30976 other => self.generate_expression(other),
30977 }
30978 }
30979
30980 fn strip_merge_qualifier(&self, expr: &Expression) -> Expression {
30982 match expr {
30983 Expression::Column(col) => {
30984 if let Some(ref table_ident) = col.table {
30985 if self.merge_strip_qualifiers.iter().any(|n| n.eq_ignore_ascii_case(&table_ident.name)) {
30986 let mut col = col.clone();
30988 col.table = None;
30989 return Expression::Column(col);
30990 }
30991 }
30992 expr.clone()
30993 }
30994 Expression::Dot(dot) => {
30995 if let Expression::Identifier(id) = &dot.this {
30997 if self.merge_strip_qualifiers.iter().any(|n| n.eq_ignore_ascii_case(&id.name)) {
30998 return Expression::Identifier(dot.field.clone());
30999 }
31000 }
31001 expr.clone()
31002 }
31003 _ => expr.clone(),
31004 }
31005 }
31006
31007 fn generate_whens(&mut self, e: &Whens) -> Result<()> {
31008 for (i, expr) in e.expressions.iter().enumerate() {
31010 if i > 0 {
31011 if self.config.pretty {
31013 self.write_newline();
31014 self.write_indent();
31015 } else {
31016 self.write_space();
31017 }
31018 }
31019 self.generate_expression(expr)?;
31020 }
31021 Ok(())
31022 }
31023
31024 fn generate_where(&mut self, e: &Where) -> Result<()> {
31025 self.write_keyword("WHERE");
31027 self.write_space();
31028 self.generate_expression(&e.this)?;
31029 Ok(())
31030 }
31031
31032 fn generate_width_bucket(&mut self, e: &WidthBucket) -> Result<()> {
31033 self.write_keyword("WIDTH_BUCKET");
31035 self.write("(");
31036 self.generate_expression(&e.this)?;
31037 if let Some(min_value) = &e.min_value {
31038 self.write(", ");
31039 self.generate_expression(min_value)?;
31040 }
31041 if let Some(max_value) = &e.max_value {
31042 self.write(", ");
31043 self.generate_expression(max_value)?;
31044 }
31045 if let Some(num_buckets) = &e.num_buckets {
31046 self.write(", ");
31047 self.generate_expression(num_buckets)?;
31048 }
31049 self.write(")");
31050 Ok(())
31051 }
31052
31053 fn generate_window(&mut self, e: &WindowSpec) -> Result<()> {
31054 self.generate_window_spec(e)
31056 }
31057
31058 fn generate_window_spec(&mut self, e: &WindowSpec) -> Result<()> {
31059 let mut has_content = false;
31061
31062 if !e.partition_by.is_empty() {
31064 self.write_keyword("PARTITION BY");
31065 self.write_space();
31066 for (i, expr) in e.partition_by.iter().enumerate() {
31067 if i > 0 {
31068 self.write(", ");
31069 }
31070 self.generate_expression(expr)?;
31071 }
31072 has_content = true;
31073 }
31074
31075 if !e.order_by.is_empty() {
31077 if has_content {
31078 self.write_space();
31079 }
31080 self.write_keyword("ORDER BY");
31081 self.write_space();
31082 for (i, ordered) in e.order_by.iter().enumerate() {
31083 if i > 0 {
31084 self.write(", ");
31085 }
31086 self.generate_expression(&ordered.this)?;
31087 if ordered.desc {
31088 self.write_space();
31089 self.write_keyword("DESC");
31090 } else if ordered.explicit_asc {
31091 self.write_space();
31092 self.write_keyword("ASC");
31093 }
31094 if let Some(nulls_first) = ordered.nulls_first {
31095 self.write_space();
31096 self.write_keyword("NULLS");
31097 self.write_space();
31098 if nulls_first {
31099 self.write_keyword("FIRST");
31100 } else {
31101 self.write_keyword("LAST");
31102 }
31103 }
31104 }
31105 has_content = true;
31106 }
31107
31108 if let Some(frame) = &e.frame {
31110 if has_content {
31111 self.write_space();
31112 }
31113 self.generate_window_frame(frame)?;
31114 }
31115
31116 Ok(())
31117 }
31118
31119 fn generate_with_data_property(&mut self, e: &WithDataProperty) -> Result<()> {
31120 self.write_keyword("WITH");
31122 self.write_space();
31123 if e.no.is_some() {
31124 self.write_keyword("NO");
31125 self.write_space();
31126 }
31127 self.write_keyword("DATA");
31128
31129 if let Some(statistics) = &e.statistics {
31131 self.write_space();
31132 self.write_keyword("AND");
31133 self.write_space();
31134 match statistics.as_ref() {
31136 Expression::Boolean(b) if !b.value => {
31137 self.write_keyword("NO");
31138 self.write_space();
31139 }
31140 _ => {}
31141 }
31142 self.write_keyword("STATISTICS");
31143 }
31144 Ok(())
31145 }
31146
31147 fn generate_with_fill(&mut self, e: &WithFill) -> Result<()> {
31148 self.write_keyword("WITH FILL");
31150
31151 if let Some(from_) = &e.from_ {
31152 self.write_space();
31153 self.write_keyword("FROM");
31154 self.write_space();
31155 self.generate_expression(from_)?;
31156 }
31157
31158 if let Some(to) = &e.to {
31159 self.write_space();
31160 self.write_keyword("TO");
31161 self.write_space();
31162 self.generate_expression(to)?;
31163 }
31164
31165 if let Some(step) = &e.step {
31166 self.write_space();
31167 self.write_keyword("STEP");
31168 self.write_space();
31169 self.generate_expression(step)?;
31170 }
31171
31172 if let Some(interpolate) = &e.interpolate {
31173 self.write_space();
31174 self.write_keyword("INTERPOLATE");
31175 self.write(" (");
31176 self.generate_interpolate_item(interpolate)?;
31178 self.write(")");
31179 }
31180
31181 Ok(())
31182 }
31183
31184 fn generate_interpolate_item(&mut self, expr: &Expression) -> Result<()> {
31186 match expr {
31187 Expression::Alias(alias) => {
31188 self.generate_identifier(&alias.alias)?;
31190 self.write_space();
31191 self.write_keyword("AS");
31192 self.write_space();
31193 self.generate_expression(&alias.this)?;
31194 }
31195 Expression::Tuple(tuple) => {
31196 for (i, item) in tuple.expressions.iter().enumerate() {
31197 if i > 0 { self.write(", "); }
31198 self.generate_interpolate_item(item)?;
31199 }
31200 }
31201 other => {
31202 self.generate_expression(other)?;
31203 }
31204 }
31205 Ok(())
31206 }
31207
31208 fn generate_with_journal_table_property(&mut self, e: &WithJournalTableProperty) -> Result<()> {
31209 self.write_keyword("WITH JOURNAL TABLE");
31211 self.write("=");
31212 self.generate_expression(&e.this)?;
31213 Ok(())
31214 }
31215
31216 fn generate_with_operator(&mut self, e: &WithOperator) -> Result<()> {
31217 self.generate_expression(&e.this)?;
31219 self.write_space();
31220 self.write_keyword("WITH");
31221 self.write_space();
31222 self.write_keyword(&e.op);
31223 Ok(())
31224 }
31225
31226 fn generate_with_procedure_options(&mut self, e: &WithProcedureOptions) -> Result<()> {
31227 self.write_keyword("WITH");
31229 self.write_space();
31230 for (i, expr) in e.expressions.iter().enumerate() {
31231 if i > 0 {
31232 self.write(", ");
31233 }
31234 self.generate_expression(expr)?;
31235 }
31236 Ok(())
31237 }
31238
31239 fn generate_with_schema_binding_property(&mut self, e: &WithSchemaBindingProperty) -> Result<()> {
31240 self.write_keyword("WITH");
31242 self.write_space();
31243 self.generate_expression(&e.this)?;
31244 Ok(())
31245 }
31246
31247 fn generate_with_system_versioning_property(&mut self, e: &WithSystemVersioningProperty) -> Result<()> {
31248 let mut parts = Vec::new();
31254
31255 if let Some(this) = &e.this {
31256 let mut s = String::from("HISTORY_TABLE=");
31258 let mut gen = Generator::new();
31259 gen.generate_expression(this)?;
31260 s.push_str(&gen.output);
31261 parts.push(s);
31262 }
31263
31264 if let Some(data_consistency) = &e.data_consistency {
31265 let mut s = String::from("DATA_CONSISTENCY_CHECK=");
31266 let mut gen = Generator::new();
31267 gen.generate_expression(data_consistency)?;
31268 s.push_str(&gen.output);
31269 parts.push(s);
31270 }
31271
31272 if let Some(retention_period) = &e.retention_period {
31273 let mut s = String::from("HISTORY_RETENTION_PERIOD=");
31274 let mut gen = Generator::new();
31275 gen.generate_expression(retention_period)?;
31276 s.push_str(&gen.output);
31277 parts.push(s);
31278 }
31279
31280 self.write_keyword("SYSTEM_VERSIONING");
31281 self.write("=");
31282
31283 if !parts.is_empty() {
31284 self.write_keyword("ON");
31285 self.write("(");
31286 self.write(&parts.join(", "));
31287 self.write(")");
31288 } else if e.on.is_some() {
31289 self.write_keyword("ON");
31290 } else {
31291 self.write_keyword("OFF");
31292 }
31293
31294 if e.with_.is_some() {
31296 let inner = self.output.clone();
31297 self.output.clear();
31298 self.write("WITH(");
31299 self.write(&inner);
31300 self.write(")");
31301 }
31302
31303 Ok(())
31304 }
31305
31306 fn generate_with_table_hint(&mut self, e: &WithTableHint) -> Result<()> {
31307 self.write_keyword("WITH");
31309 self.write(" (");
31310 for (i, expr) in e.expressions.iter().enumerate() {
31311 if i > 0 {
31312 self.write(", ");
31313 }
31314 self.generate_expression(expr)?;
31315 }
31316 self.write(")");
31317 Ok(())
31318 }
31319
31320 fn generate_xml_element(&mut self, e: &XMLElement) -> Result<()> {
31321 self.write_keyword("XMLELEMENT");
31324 self.write("(");
31325
31326 if e.evalname.is_some() {
31327 self.write_keyword("EVALNAME");
31328 } else {
31329 self.write_keyword("NAME");
31330 }
31331 self.write_space();
31332 self.generate_expression(&e.this)?;
31333
31334 for expr in &e.expressions {
31335 self.write(", ");
31336 self.generate_expression(expr)?;
31337 }
31338 self.write(")");
31339 Ok(())
31340 }
31341
31342 fn generate_xml_get(&mut self, e: &XMLGet) -> Result<()> {
31343 self.write_keyword("XMLGET");
31345 self.write("(");
31346 self.generate_expression(&e.this)?;
31347 self.write(", ");
31348 self.generate_expression(&e.expression)?;
31349 if let Some(instance) = &e.instance {
31350 self.write(", ");
31351 self.generate_expression(instance)?;
31352 }
31353 self.write(")");
31354 Ok(())
31355 }
31356
31357 fn generate_xml_key_value_option(&mut self, e: &XMLKeyValueOption) -> Result<()> {
31358 self.generate_expression(&e.this)?;
31360 if let Some(expression) = &e.expression {
31361 self.write("(");
31362 self.generate_expression(expression)?;
31363 self.write(")");
31364 }
31365 Ok(())
31366 }
31367
31368 fn generate_xml_table(&mut self, e: &XMLTable) -> Result<()> {
31369 self.write_keyword("XMLTABLE");
31371 self.write("(");
31372
31373 if self.config.pretty {
31374 self.indent_level += 1;
31375 self.write_newline();
31376 self.write_indent();
31377 self.generate_expression(&e.this)?;
31378
31379 if let Some(passing) = &e.passing {
31380 self.write_newline();
31381 self.write_indent();
31382 self.write_keyword("PASSING");
31383 if let Expression::Tuple(tuple) = passing.as_ref() {
31384 for expr in &tuple.expressions {
31385 self.write_newline();
31386 self.indent_level += 1;
31387 self.write_indent();
31388 self.generate_expression(expr)?;
31389 self.indent_level -= 1;
31390 }
31391 } else {
31392 self.write_newline();
31393 self.indent_level += 1;
31394 self.write_indent();
31395 self.generate_expression(passing)?;
31396 self.indent_level -= 1;
31397 }
31398 }
31399
31400 if e.by_ref.is_some() {
31401 self.write_newline();
31402 self.write_indent();
31403 self.write_keyword("RETURNING SEQUENCE BY REF");
31404 }
31405
31406 if !e.columns.is_empty() {
31407 self.write_newline();
31408 self.write_indent();
31409 self.write_keyword("COLUMNS");
31410 for (i, col) in e.columns.iter().enumerate() {
31411 self.write_newline();
31412 self.indent_level += 1;
31413 self.write_indent();
31414 self.generate_expression(col)?;
31415 self.indent_level -= 1;
31416 if i < e.columns.len() - 1 {
31417 self.write(",");
31418 }
31419 }
31420 }
31421
31422 self.indent_level -= 1;
31423 self.write_newline();
31424 self.write_indent();
31425 self.write(")");
31426 return Ok(());
31427 }
31428
31429 if let Some(namespaces) = &e.namespaces {
31431 self.write_keyword("XMLNAMESPACES");
31432 self.write("(");
31433 if let Expression::Tuple(tuple) = namespaces.as_ref() {
31435 for (i, expr) in tuple.expressions.iter().enumerate() {
31436 if i > 0 {
31437 self.write(", ");
31438 }
31439 if !matches!(expr, Expression::Alias(_)) {
31442 self.write_keyword("DEFAULT");
31443 self.write_space();
31444 }
31445 self.generate_expression(expr)?;
31446 }
31447 } else {
31448 if !matches!(namespaces.as_ref(), Expression::Alias(_)) {
31450 self.write_keyword("DEFAULT");
31451 self.write_space();
31452 }
31453 self.generate_expression(namespaces)?;
31454 }
31455 self.write("), ");
31456 }
31457
31458 self.generate_expression(&e.this)?;
31460
31461 if let Some(passing) = &e.passing {
31463 self.write_space();
31464 self.write_keyword("PASSING");
31465 self.write_space();
31466 if let Expression::Tuple(tuple) = passing.as_ref() {
31468 for (i, expr) in tuple.expressions.iter().enumerate() {
31469 if i > 0 {
31470 self.write(", ");
31471 }
31472 self.generate_expression(expr)?;
31473 }
31474 } else {
31475 self.generate_expression(passing)?;
31476 }
31477 }
31478
31479 if e.by_ref.is_some() {
31481 self.write_space();
31482 self.write_keyword("RETURNING SEQUENCE BY REF");
31483 }
31484
31485 if !e.columns.is_empty() {
31487 self.write_space();
31488 self.write_keyword("COLUMNS");
31489 self.write_space();
31490 for (i, col) in e.columns.iter().enumerate() {
31491 if i > 0 {
31492 self.write(", ");
31493 }
31494 self.generate_expression(col)?;
31495 }
31496 }
31497
31498 self.write(")");
31499 Ok(())
31500 }
31501
31502 fn generate_xor(&mut self, e: &Xor) -> Result<()> {
31503 if let Some(this) = &e.this {
31506 self.generate_expression(this)?;
31507 if let Some(expression) = &e.expression {
31508 self.write_space();
31509 self.write_keyword("XOR");
31510 self.write_space();
31511 self.generate_expression(expression)?;
31512 }
31513 }
31514
31515 for (i, expr) in e.expressions.iter().enumerate() {
31517 if i > 0 || e.this.is_some() {
31518 self.write_space();
31519 self.write_keyword("XOR");
31520 self.write_space();
31521 }
31522 self.generate_expression(expr)?;
31523 }
31524 Ok(())
31525 }
31526
31527 fn generate_zipf(&mut self, e: &Zipf) -> Result<()> {
31528 self.write_keyword("ZIPF");
31530 self.write("(");
31531 self.generate_expression(&e.this)?;
31532 if let Some(elementcount) = &e.elementcount {
31533 self.write(", ");
31534 self.generate_expression(elementcount)?;
31535 }
31536 if let Some(gen) = &e.gen {
31537 self.write(", ");
31538 self.generate_expression(gen)?;
31539 }
31540 self.write(")");
31541 Ok(())
31542 }
31543}
31544
31545impl Default for Generator {
31546 fn default() -> Self {
31547 Self::new()
31548 }
31549}
31550
31551#[cfg(test)]
31552mod tests {
31553 use super::*;
31554 use crate::parser::Parser;
31555
31556 fn roundtrip(sql: &str) -> String {
31557 let ast = Parser::parse_sql(sql).unwrap();
31558 Generator::sql(&ast[0]).unwrap()
31559 }
31560
31561 #[test]
31562 fn test_simple_select() {
31563 let result = roundtrip("SELECT 1");
31564 assert_eq!(result, "SELECT 1");
31565 }
31566
31567 #[test]
31568 fn test_select_from() {
31569 let result = roundtrip("SELECT a, b FROM t");
31570 assert_eq!(result, "SELECT a, b FROM t");
31571 }
31572
31573 #[test]
31574 fn test_select_where() {
31575 let result = roundtrip("SELECT * FROM t WHERE x = 1");
31576 assert_eq!(result, "SELECT * FROM t WHERE x = 1");
31577 }
31578
31579 #[test]
31580 fn test_select_join() {
31581 let result = roundtrip("SELECT * FROM a JOIN b ON a.id = b.id");
31582 assert_eq!(result, "SELECT * FROM a JOIN b ON a.id = b.id");
31583 }
31584
31585 #[test]
31586 fn test_insert() {
31587 let result = roundtrip("INSERT INTO t (a, b) VALUES (1, 2)");
31588 assert_eq!(result, "INSERT INTO t (a, b) VALUES (1, 2)");
31589 }
31590
31591 #[test]
31592 fn test_pretty_print() {
31593 let ast = Parser::parse_sql("SELECT a, b FROM t WHERE x = 1").unwrap();
31594 let result = Generator::pretty_sql(&ast[0]).unwrap();
31595 assert!(result.contains('\n'));
31596 }
31597
31598 #[test]
31599 fn test_window_function() {
31600 let result = roundtrip("SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
31601 assert_eq!(result, "SELECT ROW_NUMBER() OVER (PARTITION BY category ORDER BY id)");
31602 }
31603
31604 #[test]
31605 fn test_window_function_with_frame() {
31606 let result = roundtrip("SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
31607 assert_eq!(result, "SELECT SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)");
31608 }
31609
31610 #[test]
31611 fn test_aggregate_with_filter() {
31612 let result = roundtrip("SELECT COUNT(*) FILTER (WHERE status = 1) FROM orders");
31613 assert_eq!(result, "SELECT COUNT(*) FILTER(WHERE status = 1) FROM orders");
31614 }
31615
31616 #[test]
31617 fn test_subscript() {
31618 let result = roundtrip("SELECT arr[0]");
31619 assert_eq!(result, "SELECT arr[0]");
31620 }
31621
31622 #[test]
31624 fn test_create_table() {
31625 let result = roundtrip("CREATE TABLE users (id INT, name VARCHAR(100))");
31626 assert_eq!(result, "CREATE TABLE users (id INT, name VARCHAR(100))");
31627 }
31628
31629 #[test]
31630 fn test_create_table_with_constraints() {
31631 let result = roundtrip("CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)");
31632 assert_eq!(result, "CREATE TABLE users (id INT PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL)");
31633 }
31634
31635 #[test]
31636 fn test_create_table_if_not_exists() {
31637 let result = roundtrip("CREATE TABLE IF NOT EXISTS t (id INT)");
31638 assert_eq!(result, "CREATE TABLE IF NOT EXISTS t (id INT)");
31639 }
31640
31641 #[test]
31642 fn test_drop_table() {
31643 let result = roundtrip("DROP TABLE users");
31644 assert_eq!(result, "DROP TABLE users");
31645 }
31646
31647 #[test]
31648 fn test_drop_table_if_exists_cascade() {
31649 let result = roundtrip("DROP TABLE IF EXISTS users CASCADE");
31650 assert_eq!(result, "DROP TABLE IF EXISTS users CASCADE");
31651 }
31652
31653 #[test]
31654 fn test_alter_table_add_column() {
31655 let result = roundtrip("ALTER TABLE users ADD COLUMN email VARCHAR(255)");
31656 assert_eq!(result, "ALTER TABLE users ADD COLUMN email VARCHAR(255)");
31657 }
31658
31659 #[test]
31660 fn test_alter_table_drop_column() {
31661 let result = roundtrip("ALTER TABLE users DROP COLUMN email");
31662 assert_eq!(result, "ALTER TABLE users DROP COLUMN email");
31663 }
31664
31665 #[test]
31666 fn test_create_index() {
31667 let result = roundtrip("CREATE INDEX idx_name ON users(name)");
31668 assert_eq!(result, "CREATE INDEX idx_name ON users(name)");
31669 }
31670
31671 #[test]
31672 fn test_create_unique_index() {
31673 let result = roundtrip("CREATE UNIQUE INDEX idx_email ON users(email)");
31674 assert_eq!(result, "CREATE UNIQUE INDEX idx_email ON users(email)");
31675 }
31676
31677 #[test]
31678 fn test_drop_index() {
31679 let result = roundtrip("DROP INDEX idx_name");
31680 assert_eq!(result, "DROP INDEX idx_name");
31681 }
31682
31683 #[test]
31684 fn test_create_view() {
31685 let result = roundtrip("CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
31686 assert_eq!(result, "CREATE VIEW active_users AS SELECT * FROM users WHERE active = 1");
31687 }
31688
31689 #[test]
31690 fn test_drop_view() {
31691 let result = roundtrip("DROP VIEW active_users");
31692 assert_eq!(result, "DROP VIEW active_users");
31693 }
31694
31695 #[test]
31696 fn test_truncate() {
31697 let result = roundtrip("TRUNCATE TABLE users");
31698 assert_eq!(result, "TRUNCATE TABLE users");
31699 }
31700
31701 #[test]
31702 fn test_string_literal_escaping_default() {
31703 let result = roundtrip("SELECT 'hello'");
31705 assert_eq!(result, "SELECT 'hello'");
31706
31707 let result = roundtrip("SELECT 'it''s a test'");
31709 assert_eq!(result, "SELECT 'it''s a test'");
31710 }
31711
31712 #[test]
31713 fn test_string_literal_escaping_mysql() {
31714 use crate::dialects::DialectType;
31715
31716 let config = GeneratorConfig {
31717 dialect: Some(DialectType::MySQL),
31718 ..Default::default()
31719 };
31720
31721 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
31722 let mut gen = Generator::with_config(config.clone());
31723 let result = gen.generate(&ast[0]).unwrap();
31724 assert_eq!(result, "SELECT 'hello'");
31725
31726 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
31728 let mut gen = Generator::with_config(config.clone());
31729 let result = gen.generate(&ast[0]).unwrap();
31730 assert_eq!(result, "SELECT 'it''s'");
31731 }
31732
31733 #[test]
31734 fn test_string_literal_escaping_postgres() {
31735 use crate::dialects::DialectType;
31736
31737 let config = GeneratorConfig {
31738 dialect: Some(DialectType::PostgreSQL),
31739 ..Default::default()
31740 };
31741
31742 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
31743 let mut gen = Generator::with_config(config.clone());
31744 let result = gen.generate(&ast[0]).unwrap();
31745 assert_eq!(result, "SELECT 'hello'");
31746
31747 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
31749 let mut gen = Generator::with_config(config.clone());
31750 let result = gen.generate(&ast[0]).unwrap();
31751 assert_eq!(result, "SELECT 'it''s'");
31752 }
31753
31754 #[test]
31755 fn test_string_literal_escaping_bigquery() {
31756 use crate::dialects::DialectType;
31757
31758 let config = GeneratorConfig {
31759 dialect: Some(DialectType::BigQuery),
31760 ..Default::default()
31761 };
31762
31763 let ast = Parser::parse_sql("SELECT 'hello'").unwrap();
31764 let mut gen = Generator::with_config(config.clone());
31765 let result = gen.generate(&ast[0]).unwrap();
31766 assert_eq!(result, "SELECT 'hello'");
31767
31768 let ast = Parser::parse_sql("SELECT 'it''s'").unwrap();
31770 let mut gen = Generator::with_config(config.clone());
31771 let result = gen.generate(&ast[0]).unwrap();
31772 assert_eq!(result, "SELECT 'it\\'s'");
31773 }
31774
31775}